gazza911 / TVmaze - Link Press Sites

// ==UserScript==
// @name         TVmaze - Link Press Sites
// @namespace    TVmaze
// @version      1.01
// @description  Add a link to press sites on show page
// @author       gazza911
// @match        https://www.tvmaze.com/shows/*/*
// @match        https://www.tvmaze.com/news/create*
// @match        https://www.tvmaze.com/news/update*
// @updateURL https://openuserjs.org/meta/gazza911/TVmaze_-_Link_Press_Sites.meta.js
// @grant        GM_getValue
// @grant        GM_setValue
// @license      MIT
// ==/UserScript==

const thisVersion = "1.01";

var permalinks = GM_getValue("tvmaze_pressSites", {}),
    defaults = {
        "United States": {
            "ABC": {
                urls: ["https://www.wdtvpress.com/abc/shows/{show-hyphenated-name}"],
                validate: true,
                allowRedirects: true
            },
            "Animal Planet": {
                urls: ["https://press.discovery.com/us/apl/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Bravo": {
                urls: ["https://www.nbcumv.com/programming/bravo/{show-hyphenated-name}",
                       "https://www.nbcumv.com/search/results?f1[]=33132&term={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "CBS": {
                urls: ["https://www.viacomcbspressexpress.com/cbs-entertainment/releases?show={show-hyphenated-name}",
                       "https://www.viacomcbspressexpress.com/cbs-entertainment/releases?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Comedy Central": {
                urls: ["https://press.cc.com/series/{show-hyphenated-name}",
                      "https://press.cc.com/search/{show-name}"],
                validate: true,
                allowRedirects: false
            },
            "Cooking Channel": {
                urls: ["https://press.discovery.com/us/cook/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Discovery Channel": {
                urls: ["https://press.discovery.com/us/dsc/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}",
                      "https://corporate.discovery.com/?search={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Disney Channel": {
                urls: ["https://www.wdtvpress.com/disneychannel/shows/{show-hyphenated-name}"],
                validate: true,
                allowRedirects: true
            },
            "DIY Network": {
                urls: ["https://press.discovery.com/us/diy/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "E!": {
                urls: ["https://www.nbcumv.com/programming/e-entertainment/{show-hyphenated-name}",
                       "https://www.nbcumv.com/search/results?f1[]=33136&term={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Food Network": {
                urls: ["https://press.discovery.com/us/food/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "FOX": {
                urls: ["https://www.foxflash.com/shows/{show-hyphenated-name}/releases/",
                      "https://www.foxflash.com/search?type=releases&q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Hallmark Channel": {
                urls: ["https://www.crownmediapress.com/Search?keyword={show-name}&SiteID=142&NodeID=144"],
                validate: true,
                allowRedirects: true
            },
            "HGTV": {
                urls: ["https://press.discovery.com/us/hgtv/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Hulu": {
                urls: ["https://www.hulu.com/press/show/{show-hyphenated-name}/",
                      "https://www.hulu.com/press/show/"],
                validate: true,
                allowRedirects: true
            },
            "National Geographic Channel": {
                urls: ["https://www.natgeotvpressroom.com/index/searchResults?sort=name&search[keywords]={show-name}&search[exact]=exact&search[section]=title&limit=20"],
                validate: false,
                allowRedirects: true
            },
            "NBC": {
                urls: ["https://www.nbcumv.com/programming/nbc-entertainment/{show-hyphenated-name}",
                       "https://www.nbcumv.com/search/results?f1[]=33129&term={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Oprah Winfrey Network": {
                urls: ["https://press.discovery.com/us/own/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Oxygen": {
                urls: ["https://www.nbcumv.com/programming/oxygen-media/{show-hyphenated-name}",
                       "https://www.nbcumv.com/search/results?f1[]=33140&term={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Paramount Network": {
                urls: ["https://www.paramountnetwork.com/press/shows/{show-hyphenated-name}/",
                       "https://www.paramountnetwork.com/press/?s={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Science": {
                urls: ["https://press.discovery.com/us/sci/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Smithsonian Channel": {
                urls: ["https://www.smithsonianchannel.com/press"],
                validate: false,
                allowRedirects: true
            },
            "SyFy": {
                urls: ["https://www.nbcumv.com/programming/syfy/{show-hyphenated-name}",
                       "https://www.nbcumv.com/search/results?f1[]=33143&term={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Telemundo": {
                urls: ["https://www.nbcumv.com/programming/telemundo/{show-hyphenated-name}",
                       "https://www.nbcumv.com/search/results?f1[]=33144&term={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "The CW": {
                urls: ["https://www.cwtvpr.com/the-cw/releases?show={show-hyphenated-name}",
                       "https://www.cwtvpr.com/the-cw/releases?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "TLC": {
                urls: ["https://press.discovery.com/us/tlc/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "Travel Channel": {
                urls: ["https://press.discovery.com/us/trv/programs/{show-hyphenated-name}/",
                      "https://press.discovery.com/us/search/?q={show-name}"],
                validate: true,
                allowRedirects: true
            },
            "USA Network": {
                urls: ["https://www.nbcumv.com/programming/usa-network/{show-hyphenated-name}",
                       "https://www.nbcumv.com/search/results?f1[]=33145&term={show-name}"],
                validate: true,
                allowRedirects: true
            }
        },
        "United Kingdom": {
            "Channel 4": {
                urls: ["https://www.channel4.com/press/content-search?search={show-name}"],
                validate: false,
                allowRedirects: true
            },
            "Comedy Central": {
                urls: ["https://press.cc.com/series/{show-hyphenated-name}",
                      "https://press.cc.com/search/{show-name}"],
                validate: true,
                allowRedirects: false
            }
        },
        "Global": {
            "Netflix": {
                urls: ["https://media.netflix.com/en/search?term={show-name}"],
                validate: false,
                allowRedirects: true
            },
        },
        "Mappings": {
            "United Kingdom": {
                "BBC[\\s\\w]+": {
                    urls: ["https://www.bbc.co.uk/mediacentre/search?lang=en&term={show-name}&search=Search"],
                    validate: false,
                    allowRedirects: true
                },
                "ITV(\\d|\\s[\\s\\w]+)": {
                    urls: ["https://www.itv.com/presscentre/search/site/{show-name}"],
                    validate: false,
                    allowRedirects: true
                },
                "Sky (1|Arts|Atlantic|Cinema([\\s\\w])*|Crime|Movies([\\s\\w])*|News([\\s\\w])*|Sports([\\s\\w])*)":  {
                    urls: ["https://www.skygroup.sky/corporate/media-centre?search={show-name}"],
                    validate: false,
                    allowRedirects: true
                }
            },
            "United States": {
                "Adult Swim|Boomerang|Cartoon Network|TBS|TNT": {
                    urls: ["https://pressroom.warnermediagroup.com/us/search?search_api_fulltext={show-name}&type=media_release"],
                    validate: false,
                    allowRedirects: true
                },
                "Nick Jr.|Nickelodeon|Nicktoons": {
                    urls: ["https://www.nickpress.com/series/{show-hyphenated-name}",
                           "https://www.nickpress.com/search/{show-name}"],
                    validate: true,
                    allowRedirects: true
                }
            }
        }
    },
    version = GM_getValue("tvmaze_pressSites_version", "");

if(Object.keys(permalinks).length === 0) {
    permalinks = Object.assign({}, defaults);
}

if(version.length > 0 && version !== thisVersion) {
    //No editing logic yet, so always force refresh
    reset("", true);
}

GM_setValue("tvmaze_pressSites_version", thisVersion);

setLinks();

function setLinks() {
    if (window.location.pathname.search("/news/") === 0) {
        var curPage = $("ul.breadcrumbs a:eq(2)").attr("href");
        var id = curPage.split("/")[2];
        $.get("https://api.tvmaze.com/shows/" + id, function(data) {
            var uri = data.url;
            var show = data.name;
            uri = uri.substring(uri.lastIndexOf("/") + 1);
            if (data.network) {
                getPress(data.network.country.name, data.network.name, show, uri, $(".field-news-url label"));
            }
            if (data.webChannel) {
                var country = data.webChannel.country;
                var countryName = "";
                if (country) {
                    countryName = country.name;
                }
                getPress(country, data.webChannel.name, show, uri, $(".field-news-url label"));
            }
        });
    } else {
        $("#general-info-panel > div[class!='action-buttons-dropdown']").each(function(index, row) {
            checkRow(row);
        });
    }
}

async function checkRow(row) {
    var attrName = $(row).children("strong").text();
    if (attrName === "Network: " || attrName === "Web channel: ") {
        var entity = $(row).find("a").text();
        var $country = $(row).find("img");
        var countryName = "";
        if ($country.length === 1) {
            countryName = $country.attr("title");
            if (countryName.length > 0) {
                countryName = countryName.trim();
            }
        }
        var uri = window.location.pathname;
        uri = uri.substring(uri.lastIndexOf("/") + 1);
        await getPress(countryName, entity, $("header.columns h1").text(), uri, $("#general-info-panel div:last"));
        return;
    }
}

async function checkUrl(url, allowRedirect) {
    return $.ajax({
        method: "GET",
        dataType: "JSONP",
        url: url
    }).then(function(xhr) {
        if (allowRedirect || xhr.status !== 302) {
            return true;
        }
    }).catch(function(err) {
        if (err.status === 200 || (allowRedirect && err.status === 302)) {
            //Browser rejects, but server returned success
            return true;
        }
        return false;
    });
}

async function getPress(countryName, entity, showName, showHyphenatedName, $pressArea) {
    var countryLinks = permalinks[(countryName.length > 0) ? countryName : "Global"] || {};
    var pressSites = { urls: [] };
    if (Object.keys(countryLinks).length > 0) {
        pressSites = countryLinks[entity] || { urls: [] };
    }
    if (pressSites.urls.length === 0) {
        //check any regex mappings
        countryLinks = permalinks.Mappings[(countryName.length > 0) ? countryName : "Global"] || {};
        if (Object.keys(countryLinks).length > 0) {
            for (const [key, val] of Object.entries(countryLinks)) {
                var regex = new RegExp("^" + key + "$");
                if (regex.test(entity)) {
                    pressSites = val;
                    break;
                }
            }
        }
    }
    var found = false;
    for (var i = 0; i < pressSites.urls.length; i++) {
        var pressSite = pressSites.urls[i];
        if (pressSite && pressSite.length > 0) {
            pressSite = pressSite.replace("{show-name}", encodeURI(showName));
            pressSite = pressSite.replace("{show-hyphenated-name}", showHyphenatedName);
            if (pressSites.validate) {
                var xhr = await checkUrl(pressSite, pressSites.allowRedirects);
                found = (xhr === true);
            } else {
                found = true;
            }
            if (found) {
                $pressArea.append(" <a href='" + pressSite + "' target='_blank'>(Press)</a>");
                break;
            }
        }
    }
}

function reset(message, force) {
    var perform;
    if (force) {
        perform = true;
    }
    else {
        perform = confirm(message.length > 0 ? message : "Are you sure that you want to reset the permalink formats? You will loose any custom formats");
    }
    if (perform) {
        permalinks = Object.assign({}, defaults);
        GM_setValue("tvmaze_pressSites", permalinks);
    }
}