Greasy Fork

Show Pitchfork Ratings for Albums

Display the album ratings at the top level color-coded so you can decide which reviews you want to read without clicking

// ==UserScript==
// @name              Show Pitchfork Ratings for Albums
// @version           2.0.0
// @namespace         https://github.com/csavio/pitchfork-ratings/
// @include           https://www.pitchforkmedia.com/*
// @include           https://pitchforkmedia.com/*
// @include           https://www.pitchfork.com/*
// @include           https://pitchfork.com/*
// @description       Display the album ratings at the top level color-coded so you can decide which reviews you want to read without clicking
// ==/UserScript==

const debugmode = false;
const styles = `
<style>
#main-content {margin-top:50px;}
span.rating {font-size: 12pt; background:white; position:absolute; display:block; padding:10px 13px; top:8px; left:8px; z-index:2; font-famlily:sans-serif; font-weight:bold; border-radius: 5px;}
.orange {color:orange}
.green {color:green}
.red {color:red}
.spotifyButton {width: 100px; height: 50px; display:inline-block; position:absolute; top: 8px; right: 8px; border-radius: 5px; background: white;}
</style>
`;
const spotifySvg = `
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 800 356" fill="none">
<path d="M253.545 120.731C222.015 119.476 195.446 144.055 194.193 175.631C192.94 207.206 217.488 233.814 249.012 235.069C280.542 236.324 307.111 211.746 308.364 180.17C309.612 148.594 285.069 121.981 253.545 120.731ZM277.659 204.55C276.949 205.805 275.565 206.432 274.218 206.244C273.806 206.187 273.393 206.051 273.007 205.831C265.456 201.527 257.226 198.724 248.547 197.5C239.869 196.277 231.185 196.7 222.741 198.755C220.908 199.2 219.065 198.076 218.621 196.24C218.177 194.405 219.3 192.558 221.133 192.114C230.417 189.855 239.963 189.389 249.498 190.733C259.033 192.077 268.077 195.158 276.385 199.89C278.02 200.826 278.594 202.908 277.664 204.55H277.659ZM285.168 189.531C284.004 191.685 281.309 192.491 279.158 191.324C270.323 186.539 260.756 183.396 250.725 181.984C240.694 180.572 230.636 180.954 220.824 183.114C220.292 183.229 219.764 183.25 219.253 183.177C217.472 182.926 215.947 181.597 215.54 179.73C215.012 177.335 216.527 174.966 218.918 174.438C229.764 172.048 240.882 171.625 251.962 173.183C263.038 174.742 273.612 178.214 283.377 183.506C285.534 184.672 286.333 187.366 285.168 189.525V189.531ZM293.492 172.597C292.395 174.71 290.113 175.803 287.889 175.489C287.288 175.406 286.698 175.217 286.129 174.925C275.842 169.564 264.761 166.024 253.195 164.397C241.628 162.771 229.999 163.116 218.636 165.428C215.681 166.029 212.804 164.115 212.203 161.16C211.603 158.201 213.514 155.319 216.464 154.718C229.049 152.16 241.916 151.779 254.714 153.578C267.513 155.377 279.774 159.299 291.168 165.234C293.842 166.625 294.881 169.925 293.492 172.603V172.597Z" fill="#231F20"/>
<path d="M354.337 207.803C344.484 207.803 336.024 204.388 332.489 200.507C332.155 200.126 332.108 199.916 332.108 199.451V187.899C332.108 187.35 332.573 187.141 332.949 187.606C337.199 192.919 346.254 197.26 353.664 197.26C359.559 197.26 363.517 195.66 363.517 190.43C363.517 187.308 362.045 185.284 354.003 183.009L349.371 181.702C338.635 178.669 332.108 175.081 332.108 164.795C332.108 155.69 340.526 147.679 354.588 147.679C361.491 147.679 368.353 149.828 372.311 152.783C372.645 153.034 372.776 153.29 372.776 153.75V164.251C372.776 164.968 372.186 165.177 371.637 164.717C368.436 162.06 362.249 158.478 354.922 158.478C347.596 158.478 344.144 161.767 344.144 164.8C344.144 168.006 346.374 168.89 354.332 171.253L358.29 172.435C370.541 176.101 375.554 181.247 375.554 189.766C375.554 200.727 366.463 207.813 354.337 207.813V207.803ZM440.18 185.792C440.18 179.087 444.811 174.114 451.339 174.114C457.866 174.114 462.451 179.087 462.451 185.792C462.451 192.496 457.819 197.469 451.339 197.469C444.858 197.469 440.18 192.496 440.18 185.792ZM451.292 207.803C464.89 207.803 474.362 198.065 474.362 185.792C474.362 173.518 464.89 163.78 451.292 163.78C437.694 163.78 428.263 173.434 428.263 185.792C428.263 198.149 437.652 207.803 451.292 207.803ZM533.39 161.255V164.795H526.231C525.85 164.795 525.641 165.004 525.641 165.386V173.816C525.641 174.198 525.85 174.407 526.231 174.407H533.39V206.197C533.39 206.579 533.599 206.788 533.98 206.788H544.758C545.139 206.788 545.348 206.579 545.348 206.197V174.407H554.57L567.959 203.541L560.758 219.391C560.549 219.857 560.8 220.066 561.223 220.066H572.716C573.097 220.066 573.264 219.982 573.431 219.6L597.217 165.464C597.384 165.083 597.175 164.79 596.752 164.79H585.974C585.593 164.79 585.426 164.873 585.259 165.255L574.397 191.398L563.494 165.255C563.327 164.873 563.16 164.79 562.779 164.79H545.348V162.008C545.348 157.453 548.424 155.345 552.377 155.345C554.732 155.345 557.301 156.569 559.113 157.662C559.536 157.913 559.828 157.62 559.661 157.238L555.87 148.176C555.745 147.883 555.578 147.71 555.28 147.543C553.426 146.575 550.398 145.728 547.447 145.728C538.523 145.728 533.385 152.558 533.385 161.244L533.39 161.255ZM406.499 207.546C417.277 207.546 425.021 198.227 425.021 185.708C425.021 173.188 417.188 164.037 406.41 164.037C398.41 164.037 393.778 168.926 391.084 173.816V165.386C391.084 165.004 390.875 164.795 390.494 164.795H379.925C379.543 164.795 379.334 165.004 379.334 165.386V219.48C379.334 219.862 379.543 220.071 379.925 220.071H390.494C390.875 220.071 391.084 219.862 391.084 219.48V197.851C393.778 202.74 398.326 207.546 406.493 207.546H406.499ZM496.424 207.379C499.96 207.379 503.37 206.453 505.39 205.272C505.683 205.104 505.725 204.937 505.725 204.639V196.627C505.725 196.204 505.516 196.078 505.135 196.292C503.913 196.967 502.315 197.516 500.127 197.516C496.675 197.516 494.487 195.492 494.487 191.021V174.407H505.014C505.396 174.407 505.604 174.198 505.604 173.816V165.386C505.604 165.004 505.396 164.795 505.014 164.795H494.487V153.792C494.487 153.327 494.195 153.076 493.772 153.41L474.952 168.252C474.701 168.461 474.618 168.675 474.618 169.01V173.816C474.618 174.198 474.827 174.407 475.208 174.407H482.534V192.789C482.534 202.74 488.257 207.379 496.43 207.379H496.424ZM508.591 152.317C508.591 156.114 511.537 158.98 515.578 158.98C519.62 158.98 522.649 156.114 522.649 152.317C522.649 148.521 519.704 145.655 515.578 145.655C511.453 145.655 508.591 148.521 508.591 152.317ZM510.231 206.793H521.009C521.39 206.793 521.599 206.584 521.599 206.202V165.391C521.599 165.009 521.39 164.8 521.009 164.8H510.231C509.85 164.8 509.641 165.009 509.641 165.391V206.202C509.641 206.584 509.85 206.793 510.231 206.793ZM390.833 185.629C392.77 179.134 397.23 174.161 403.292 174.161C409.355 174.161 413.057 178.543 413.057 185.713C413.057 192.883 409.057 197.349 403.292 197.349C397.527 197.349 392.765 191.785 390.833 185.629Z" fill="#231F20"/>
<path d="M611.024 167.274C610.47 166.317 609.703 165.569 608.721 165.025C607.739 164.486 606.643 164.214 605.421 164.214C604.199 164.214 603.102 164.486 602.12 165.025C601.139 165.569 600.371 166.317 599.818 167.274C599.264 168.231 598.987 169.313 598.987 170.521C598.987 171.729 599.264 172.791 599.818 173.748C600.371 174.705 601.139 175.453 602.12 175.997C603.102 176.54 604.199 176.807 605.421 176.807C606.643 176.807 607.739 176.535 608.721 175.997C609.703 175.458 610.47 174.705 611.024 173.748C611.577 172.791 611.854 171.719 611.854 170.521C611.854 169.324 611.577 168.231 611.024 167.274ZM610.016 173.214C609.567 174.009 608.94 174.626 608.141 175.076C607.342 175.521 606.434 175.746 605.426 175.746C604.418 175.746 603.483 175.521 602.684 175.076C601.885 174.632 601.264 174.009 600.82 173.214C600.376 172.425 600.157 171.525 600.157 170.521C600.157 169.517 600.376 168.623 600.82 167.839C601.264 167.054 601.885 166.437 602.684 165.993C603.483 165.548 604.397 165.323 605.426 165.323C606.455 165.323 607.342 165.548 608.141 165.993C608.94 166.437 609.567 167.059 610.016 167.854C610.465 168.649 610.69 169.543 610.69 170.547C610.69 171.552 610.465 172.425 610.016 173.22V173.214Z" fill="#231F20"/>
<path d="M607.608 170.401C608.036 170.087 608.251 169.669 608.251 169.151C608.251 168.634 608.042 168.194 607.624 167.88C607.206 167.567 606.6 167.41 605.807 167.41H603.008V173.267H604.36V170.94H605.097L606.877 173.267H608.538L606.59 170.799C607.003 170.72 607.352 170.589 607.614 170.396L607.608 170.401ZM605.593 169.883H604.36V168.45H605.64C606.021 168.45 606.313 168.508 606.517 168.628C606.721 168.749 606.825 168.932 606.825 169.183C606.825 169.418 606.715 169.596 606.506 169.711C606.292 169.831 605.99 169.889 605.593 169.889V169.883Z" fill="#231F20"/>
</svg>
`;
const loccheck = setInterval(checkLoc, 300);
let firstrun = true;
let initloc = window.location.href;
const ratingChecked = [];

if (debugmode === true) {
    debugger;
}

async function getLinks(mylinks, counter) {
    mylinks = mylinks || '';
    counter = counter || 0;
    const tempLink = mylinks.replace(/https:\/\/pitchfork\.com/, '');
    if (document.querySelectorAll(`a[href="${tempLink}] span.rating`).length === 0) {
        // Pure JavaScript using fetch
        try {
            const response = await fetch(mylinks);
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            const html = await response.text();

            const parser = new DOMParser();
            const doc = parser.parseFromString(html, 'text/html');
            const element = doc.querySelector('p[class*="Rating-"]');

            if (element) {
                let rating = element.textContent;
                rating = parseFloat(rating);
                let spanclass = '';
                if (rating > 5.0 && rating <= 6.9) {
                    spanclass = 'orange';
                }
                else if (rating > 6.9) {
                    spanclass = 'green';
                }
                else {
                    spanclass = 'red';
                }

                const album = encodeURIComponent(doc.querySelector(`h1[data-testid="ContentHeaderHed"]`).textContent);
                const artist = encodeURIComponent(doc.querySelector(`a[href^="/artists"]`).textContent)
                document.querySelector(`a[href="${tempLink}"]`).insertAdjacentHTML(
                    'beforeend',
                    `<span class="rating ${spanclass}">${(Number.isInteger(rating)) ? rating + '.0' : rating}</span>
                    <span class="spotifyButton"><a href="https://open.spotify.com/search/artist:${artist}%20album:${album}" target="_blank">${spotifySvg}</a></span>`
                );
            } else {
                return null;
            }
        } catch (error) {
            console.error("Error fetching or parsing HTML:", error);
            return null;
        }
    }

}

function checkLoc() {
    var loc = window.location.href;

    // Only do something if the location has changed and it is an album review listing
    if ((firstrun || loc != initloc) && window.location.href.match(/(\/reviews\/)|(\/best\/)/)) {
        document.querySelector('head').insertAdjacentHTML('beforeend', styles);
        firstrun = false;
        setTimeout(function () {
            document.querySelectorAll("a[href^='/reviews/albums/']").forEach(async (node) => {
                const myhref = node.href;
                // There are two links so make sure the rating is added only once
                if (node.href.match(/reviews\/albums\/[\w\d.]+/) && !ratingChecked.includes(myhref)) {
                    ratingChecked.push(myhref);
                    await getLinks(myhref);
                }
            });
        }, 2000);
    }

    initloc = window.location.href;
}