tinyjacky / Rightmove Listing Enhanced

// ==UserScript==
// @name         Rightmove Listing Enhanced
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  try to take over the world!
// @author       You
// @license      MIT
// @match        https://www.rightmove.co.uk/property-*/find.html*
// @icon         https://www.google.com/s2/favicons?domain=rightmove.co.uk
// @require      http://code.jquery.com/jquery-latest.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.core.js
// @connect      localhost
// @connect      bestmove.loophole.site
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @resource     MATERIAL_ICONS https://fonts.googleapis.com/icon?family=Material+Icons
// ==/UserScript==

/* globals $ */

const propertyCoordinatePair = (property) => `${property.location.latitude},${property.location.longitude}`;

const loadScores = function(properties) {
    const scoreParams = {
      coordinate_pairs: properties.map(propertyCoordinatePair),
    };

    GM_xmlhttpRequest({
      method: 'GET',
      url: `http://bestmove.loophole.site/scores?${$.param(scoreParams)}`,
      responseType: 'json',
      onload: function(res) {
         const payload = res.response;

         properties.forEach((property) => {
            const coordinatePair = propertyCoordinatePair(property);
            const propertyScore = payload[coordinatePair];

            $(`#property-${property.id} .propertyCard-priceLink`).last().append(
                `
                <div class="score-section">
                  <span class="material-icons">security</span><span class="score-text">${propertyScore.scores?.crime_score?.toFixed(1)}</span>
                  <span class="material-icons">shopping_cart</span><span class="score-text">${propertyScore.scores?.total_groceries_count}</span>
                  <a href="https://www.google.com/maps/dir/${coordinatePair}/birmingham+new+street+station/data=!4m2!4m1!3e3" target="_blank">
                    <span class="material-icons">directions_bus_filled</span><span class="score-text">${propertyScore.scores?.distance_to_town_center?.toFixed(1)}</span>
                  </a>
                  <a href="http://www.google.com/maps/place/${coordinatePair}/@${propertyCoordinatePair(property)},13z" target="_blank"><span class="material-icons">map</span><span class="score-text">${propertyScore.postcode}</span></a>
                  <a href="https://www.streetcheck.co.uk/postcode/${propertyScore.postcode.split(' ').join('')}" target="_blank"><span class="material-icons">groups</span></a>
                </div>
                `
            );
         });
      }
    });
};

(function() {
    'use strict';

    GM_addStyle(GM_getResourceText("MATERIAL_ICONS"));
    GM_addStyle(
      `
        .score-section .material-icons {
          font-size: 18px;
        }

        .score-section .score-text {
          vertical-align: top;
          margin-right: 5px;
        }

        .score-section a {
          color: inherit;
        }
      `
    );

    loadScores(unsafeWindow.jsonModel.properties);
})();

(function(open) {
    XMLHttpRequest.prototype.open = function() {
        this.addEventListener("readystatechange", function() {
            console.log(this.readyState);
            if(this.readyState === 4) {
              const response = JSON.parse(this.responseText);
              if (response.properties) { loadScores(response.properties) };
            }
        }, false);
        open.apply(this, arguments);
    };
})(XMLHttpRequest.prototype.open);