What.CD Spotify

Add a Spotify link & embedded player to torrents on What.CD

// ==UserScript==
// @name         What.CD Spotify 
// @namespace    https://greasyfork.org/users/62518
// @description  Add a Spotify link & embedded player to torrents on What.CD
// @version      0.32
// @match        https://what.cd/*
// @grant        GM_registerMenuCommand
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==
// spacepandas edit hack thing, credits to orkyl and aphex80 for all the actual work

var maxSizeCache = 1000;
var stringSimilarityThreshold = 0.6;
localStorage.what = localStorage.what || JSON.stringify([]);

var curColor = GM_getValue("color", "black");
var curPosition = GM_getValue("position", "above");

GM_registerMenuCommand("What.CD Spotify: Switch widget theme colors", function() {
    if (curColor === "black") {
        if(confirm("Switch to white Spotify widget theme?")) {
            GM_setValue("color", "white");
            location.reload();
        }
    } else if (curColor === "white")  {
        if(confirm("Switch to black Spotify widget theme?")) {
            GM_setValue("color", "black");
            location.reload();
        }
    }   
});

GM_registerMenuCommand("What.CD Spotify: Switch widget position relative to artwork", function() {
    if (curPosition === "above") {
        if(confirm("Move the Spotify widget below Album/Artist artwork?")) {
            GM_setValue("position", "below");
            location.reload();
        }
    } else if (curPosition === "below")  {
        if(confirm("Move the Spotify widget above Album/Artist artwork?")) {
            GM_setValue("position", "above");
            location.reload();
        }
    }   
});

function createSpotifyLink(link, imageSource) {
    var a = document.createElement('a');
    a.href = link;
    a.title = 'Listen in Spotify';
    var img = document.createElement('img');
    img.style.border = 'none';
    img.style.marginLeft = '3px';
    img.style.marginRight = '3px';
    img.src = imageSource;
    img.width = 15;
    a.appendChild(img);
    return a;
}

function createSpotifyLinkGreen(link) {
    return createSpotifyLink(link, 'data:image/png;charset=utf-8;base64,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');
}

function createSpotifyLinkBlue(link) {
    return createSpotifyLink(link, 'data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKnGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4zMDA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjY1NTM1PC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zMDA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6OTNkMzUxMGItNTUxNi00ZGVmLTlkZTEtODk4MzJhMDRjYTk1PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA1LTA5VDAxOjM5OjQyKzAyOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjkzZDM1MTBiLTU1MTYtNGRlZi05ZGUxLTg5ODMyYTA0Y2E5NTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChNYWNpbnRvc2gpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICAgICA8c3RFdnQ6Y2hhbmdlZD4vPC9zdEV2dDpjaGFuZ2VkPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA1LTA5VDAxOjQwOjQ0KzAyOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjAwZTBhNmVhLWRjOWEtNGMxNi04NzM3LTJkNjYyZDQ0ODY3Mzwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgPC9yZGY6U2VxPgogICAgICAgICA8L3htcE1NOkhpc3Rvcnk+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6MDBlMGE2ZWEtZGM5YS00YzE2LTg3MzctMmQ2NjJkNDQ4NjczPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6MDgzODgzNGEtMzY2YS0xMTc4LWI3YTctZTczODljZjUxOTUzPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNS0wNS0wOFQyMjo1NToxMyswMjowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TWV0YWRhdGFEYXRlPjIwMTUtMDUtMDlUMDE6NDA6NDQrMDI6MDA8L3htcDpNZXRhZGF0YURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE1LTA1LTA5VDAxOjQwOjQ0KzAyOjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAo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');
}

function getCache(key) {
    var list = JSON.parse(localStorage.what);
    var res = null;
    $(list).each(function(i, el) {
        if (el.key === key) {
            res = el.value;
            return false;
        }
    });
    return res;
}

function setCache(o) {
    var list = JSON.parse(localStorage.what);
    if (list.length == maxSizeCache) {
        list.shift();
    }
    list.push(o);
    localStorage.what = JSON.stringify(list);
}

function getSpotifyArtistId(whatArtist, onSuccess) {

    var cachedArtistId = getCache(whatArtist);
    if (cachedArtistId !== null && cachedArtistId !== '') {
        onSuccess(cachedArtistId);
        return;
    }

    var encodedArtist = whatArtist.replace(" ", "+").replace("&", "");
    if (encodedArtist === '') {
        onSuccess('');
        return;
    }

    $.get('https://api.spotify.com/v1/search?q=' + encodedArtist + '&type=artist', function(data) {
        var artists = data.artists.items;
        if (artists !== null && artists.length > 0) {
            var bestArtistId = null;
            var rank = 0;
            $(artists).each(function(i, artist) {
                if (rank < sSimilarity(artist.name.toUpperCase(), whatArtist.toUpperCase())) {
                    rank = sSimilarity(artist.name.toUpperCase(), whatArtist.toUpperCase());
                    bestArtistId = artist.id;
                }
            });
            setCache({ key: whatArtist, value: bestArtistId });
            onSuccess(bestArtistId);
        } else {
            onSuccess('');
        }
    });
}

function getSpotifyArtistAlbums(artistId, onSuccess) {

    $.get('https://api.spotify.com/v1/artists/' + artistId + '/albums?limit=50', function(data) {
        var albumItems = data.items;
        var albums = [];
        $(albumItems).each(function(i, albumItem) {
            albums.push({ name : albumItem.name, id : albumItem.id });
        });
        onSuccess(albums);
    });
}

function getSpotifyArtistAlbumId(artistId, whatAlbum, onSuccess) {

    var cachedAlbumId = getCache(whatAlbum);
    if (cachedAlbumId !== null && cachedAlbumId !== '') {
        onSuccess(cachedAlbumId);
        return;
    }

    $.get('https://api.spotify.com/v1/artists/' + artistId + '/albums', function(data) {
        var albums = data.items;
        var albumId = "";
        if (albums !== null && albums.length > 0) {
            $(albums).each(function(j, album) {
                if (sSimilarity(album.name.toUpperCase(), whatAlbum.toUpperCase()) >= stringSimilarityThreshold) {
                    albumId = album.id;
                    return false;
                }
            });
            setCache({ key: whatAlbum, value: albumId });
            onSuccess(albumId);
        } else {
            onSuccess('');
        }
    });
}

// DOM methods

var dom = {
  id: function (id) { return document.getElementById(id); },
  qs: function (s, p) { return (p || document).querySelector(s); },
  qsa: function (s, p) { return (p || document).querySelectorAll(s); },
  cl: function (cl, p) { return (p || document).getElementsByClassName(cl); },
  tag: function (tag, p) { return (p || document).getElementsByTagName(tag); },
  txt: function (txt) { return document.createTextNode(txt); },
  app: function (parent, var_args) {
    for (var i = 1, il = arguments.length; i < il; ++i) {
      var child = arguments[i];
      if (typeof child == 'string') child = this.txt(child);
      if (child) parent.appendChild(child);
  }
},
mk: function (tag, attr, var_args) {
    var elem = document.createElement(tag);
    if (attr) for (var a in attr) if (attr.hasOwnProperty(a)) elem[a] = attr[a];
    if (arguments.length > 2) {
      var args = Array.prototype.slice.call(arguments, 2);
      args.unshift(elem);
      this.app.apply(this, args);
  }
  return elem;
},
par: function (tag, el) {
    do el = el.parentNode;
    while (el && el.tagName != tag.toUpperCase());
    return el;
}
};

function embedSpotifyPlaylist(id) {
    var themecolor = GM_getValue("color", "black");
    var h = "320"; // height must be at least 80px more than width (minimum: 250px) or the compact player is rendered
    // frameborder & allowtransparency values required to render correctly!

    var url = "https://embed.spotify.com/?uri=" + id + "&theme=" + themecolor;

    var box = dom.mk('div', {className: 'box'},
        dom.mk('div', {className: 'head'},
          dom.mk('strong', null, 'Listen')),
        dom.mk('div', {className: 'player'},
            dom.mk('a', {position: "relative", left: "-16px"},
                dom.mk('p', null,
                    dom.mk('iframe', {src: url, width: "240px", height: h, frameborder: "0", allowtransparency: "true", style: "border:none;"})))));

    var elem = dom.cl('box')[0];

    if(GM_getValue("position", "above") === "above") {
        elem.parentNode.insertBefore(box, elem);
    } else {
        if(dom.cl('box_image')[0] === null) {
            elem.parentNode.insertBefore(box, elem);
        }
        elem.appendChild(box);
    }

}


/*************************************/
/************* Top 10 ****************/
/*************************************/
if (window.location.href.indexOf('top10.php') > -1) {
    var processTable = function (table) {
        var groups = $('div.group_info', table);
        $(groups).each(function(i, group) {
            var whatArtist = $(group).find('a[href*="artist.php"]')[0];
            var whatAlbum = $(group).find('a[href*="torrents.php?id"]')[0];
            whatAlbum = $(whatAlbum).text();
            whatArtist = $(whatArtist).text();

            getSpotifyArtistId(whatArtist, function(artistId) {
                if (artistId !== '' && artistId !== undefined) {
                    getSpotifyArtistAlbumId(artistId, whatAlbum, function(albumId) {
                        var a = null;
                        if (albumId !== '') {
                            a = createSpotifyLinkGreen('spotify:album:' + albumId);
                        } else {
                            a = createSpotifyLinkBlue('spotify:artist:' + artistId);
                        }
                        $(group).prepend(a);
                    });
                }
            });
        });
    };

    $('.torrent_table').each(function () { processTable(this); });

    new MutationObserver(function (mutes) {
        mutes.forEach(function (m) {
            $(m.addedNodes).each(function () {
                if (this.nodeName == 'TABLE') processTable(this);
            });
        });
    }).observe(document.querySelector('.thin'), { childList: true });
}

/*************************************/
/*********** Artist page *************/
/*************************************/
if (window.location.href.indexOf('artist.php') > -1) {
    var whatArtist = $('h2').text();
    getSpotifyArtistId(whatArtist, function(artistId) {
        if (artistId !== '' && artistId !== undefined) {
            var a = createSpotifyLinkBlue('spotify:artist:' + artistId);
            $('h2').append(a);
            embedSpotifyPlaylist('spotify:artist:' + artistId); 
            
            getSpotifyArtistAlbums(artistId, function(albums) {
                var groups = $('#torrents_album, #torrents_ep').find('div.group_info');
                $(groups).each(function(i, group) {
                    var whatAlbum = $(group).find('a[href*="torrents.php?id"]')[0];
                    whatAlbum = $(whatAlbum).text();
                    var album = $.grep(albums, function(album) {
                        return sSimilarity(album.name.toUpperCase(), whatAlbum.toUpperCase()) >= stringSimilarityThreshold;
                    });
                    if (album.length > 0) {
                        setCache({ key: whatAlbum, value: album[0].id });
                        var a = createSpotifyLinkGreen('spotify:album:' + album[0].id);
                        $(group).prepend(a);
                    }
                });
            });
        }
    });
}

/*************************************/
/*********** Torrent page ************/
/*************************************/
if (window.location.href.indexOf('torrents.php?id') > -1) {
    var whatArtist = $('h2 > a').text();
    var whatAlbum = $('h2 > span').text();

    getSpotifyArtistId(whatArtist, function(artistId) {
        if (artistId !== '' && artistId !== undefined) {
            getSpotifyArtistAlbumId(artistId, whatAlbum, function(albumId) {
                var a = null;
                if (albumId !== '') {
                    a = createSpotifyLinkGreen('spotify:album:' + albumId);
                    embedSpotifyPlaylist('spotify:album:' + albumId);
                } else {
                    a = createSpotifyLinkBlue('spotify:artist:' + artistId);
                }
                $('h2').append(a);
            });
        }
    });
}

/*************************************/
/******* Bookmark artist page ********/
/*************************************/
if (window.location.href.indexOf('bookmarks.php?type=artists') > -1) {
    var tds = $('.artist_table').find('.rowa, .rowb').find('td');
    var artists = $('.artist_table').find('a[href*="artist.php?id"]');
    $(artists).each(function(i, artistElement) {
        artist = $(artistElement).text();
        getSpotifyArtistId(artist, function(artistId) {
            if (artistId !== '') {
                var a = createSpotifyLinkGreen('spotify:artist:' + artistId);
                var x = $('div.group_info')[i];
                $(tds[i]).prepend(a);
            } 
        });
    });
}

/*************************************/
/******* Bookmark torrent page *******/
/*************************************/
if (window.location.href.indexOf('bookmarks.php?type=torrents') > -1) {
    var groups = $('.group');
    $(groups).each(function(i, group) {
        var whatArtistElement = $(group).find('a[href*="artist.php"]')[0];
        var whatAlbumElement = $(group).find('a[href*="torrents.php?id"]')[0];
        whatAlbum = $(whatAlbumElement).text();
        whatArtist = $(whatArtistElement).text();

        getSpotifyArtistId(whatArtist, function(artistId) {
            if (artistId !== '' && artistId !== undefined) {
                getSpotifyArtistAlbumId(artistId, whatAlbum, function(albumId) {
                    var a = null;
                    if (albumId !== '') {
                        a = createSpotifyLinkGreen('spotify:album:' + albumId);
                    } else {
                        a = createSpotifyLinkBlue('spotify:artist:' + artistId);
                    }
                    $(whatArtistElement).before(a);
                });
            }
        });
    });
}

var sSimilarity = function(sa1, sa2){
    // Compare two strings to see how similar they are.
    // Answer is returned as a value from 0 - 1
    // 1 indicates a perfect similarity (100%) while 0 indicates no similarity (0%)
    // Algorithm is set up to closely mimic the mathematical formula from
    // the article describing the algorithm, for clarity. 
    // Algorithm source site: http://www.catalysoft.com/articles/StrikeAMatch.html
    // (Most specifically the slightly cryptic variable names were written as such
    // to mirror the mathematical implementation on the source site)
    //
    // 2014-04-03
    // Found out that the algorithm is an implementation of the Sørensen–Dice coefficient [1]
    // [1] http://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient
    //
    // The algorithm is an n-gram comparison of bigrams of characters in a string


    // for my purposes, comparison should not check case or whitespace
    var s1 = sa1.replace(/\s/g, "").toLowerCase();
    var s2 = sa2.replace(/\s/g, "").toLowerCase();

    function intersect(arr1, arr2) {
        // I didn't write this.  I'd like to come back sometime
        // and write my own intersection algorithm.  This one seems
        // clean and fast, though.  Going to try to find out where
        // I got it for attribution.  Not sure right now.
        var r = [], o = {}, l = arr2.length, i, v;
        for (i = 0; i < l; i++) {
            o[arr2[i]] = true;
        }
        l = arr1.length;
        for (i = 0; i < l; i++) {
            v = arr1[i];
            if (v in o) {
                r.push(v);
            }
        }
        return r;
    }

    var pairs = function(s){
        // Get an array of all pairs of adjacent letters in a string
        var pairs = [];
        for(var i = 0; i < s.length - 1; i++){
            pairs[i] = s.slice(i, i+2);
        }
        return pairs;
    };

    //console.log(intersect(pairs(s1), pairs(s2)))
    var similarity_num = 2 * intersect(pairs(s1), pairs(s2)).length;
    var similarity_den = pairs(s1).length + pairs(s2).length;
    var similarity = similarity_num / similarity_den;
    return similarity;
};