Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
// ==UserScript==
// @name Spotify Links On iTunes
// @description Add a Spotify link and embedded player on iTunes album/artist pages
// @author mirka
// @include https://itunes.apple.com/*/artist/*
// @include https://itunes.apple.com/artist/*
// @include https://itunes.apple.com/*/album/*
// @include https://itunes.apple.com/album/*
// @namespace http://jaguchi.com
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js
// @version 3.0
// ==/UserScript==
(function () {
/*=========================================
User preferences
===========================================*/
// Set this to false if you want the Spotify link to open in the Web Player
var open_in_app = true;
// Set this to false if you don't want an embedded Spotify player (album pages only)
var embed_player = true;
/*=========================================
Link insertion handlers
===========================================*/
var insertLink = {
album: function (uri) {
var view_in_itunes_btn = $("div#left-stack a.action.view-in-itunes")[0];
insertSpotifyLinkAfter(view_in_itunes_btn, uri);
$("#spotify-btn").css({margin: "-4px 0 12px 0"});
},
artist: function (uri) {
var view_in_itunes_btn = $("div#title a.action.view-in-itunes")[0];
insertSpotifyLinkAfter(view_in_itunes_btn, uri);
},
};
function insertSpotifyLinkAfter(target, uri) {
var text = target.firstChild.textContent.replace("iTunes", "Spotify");
var btn;
var btn_css = {
background: "linear-gradient(rgb(30, 215, 96), rgb(29, 185, 84))",
backgroundColor: "rgb(41, 210, 100)",
border: "1px solid rgb(21, 183, 68)",
borderRadius: "15px",
color: "#fff",
display: "inline-block",
fontSize: "95%",
fontWeight: "bold",
padding: "1px 8px",
textAlign: "center",
textDecoration: "none",
verticalAlign: "text-bottom",
};
// Workaround for English locales where capitalization in the
// span text doesn't match the button img
if (text == "View In Spotify") {
text = "View in Spotify";
}
$(target).after("<a href='" + uri + "' id='spotify-btn'>" + text + "</a>");
btn = $("#spotify-btn")[0];
$(btn).css(btn_css);
if (!uri) {
btn.textContent = "Not on Spotify";
btn.removeAttribute("href");
btn.style.background = "";
btn.style.backgroundColor = "#ddd";
btn.style.border = "none";
}
}
function insertSpotifyPlayer(uri) {
function collapseiTunesTracklist() {
var itunes_tracklist = $("table.tracklist-table")[0];
var expand_link = $("<a/>", {
href: "#",
text: "+ Expand iTunes tracklist",
click: function (e) {
e.preventDefault();
$(itunes_tracklist).css({ display: "block", });
$(expand_link).remove();
},
css: {
display: "block",
textAlign: "center",
},
});
$(itunes_tracklist).before(expand_link);
$(itunes_tracklist).css({ display: "none", });
}
var target = $("div.track-list")[0];
var player = $("<iframe/>", {
src: "https://embed.spotify.com/?uri=" + uri,
width: "640",
height: "720",
frameborder: "0",
allowtransparency: "true",
css: {
marginBottom: "2em",
}
});
$(target).before(player);
collapseiTunesTracklist();
}
/*=========================================
Spotify search handlers
===========================================*/
function searchAlbum(is_alt_query) {
var album = $("h1[itemprop=name]")[0].textContent;
var artist = $("h2[itemprop=name]")[0].textContent;
var album_excludes = ["live", "remastered", "compilation", "original (motion picture )?soundtrack", "bonus track version", "(deluxe|exclusive|expanded|revised) (version|edition)", "(music|soundtrack) from the (motion picture|film score)", "feat\. .+"];
var character_regex = /[:&,/()]/g;
var album_regex;
var query;
if (is_alt_query) {
album_regex = new RegExp("\\((" + album_excludes.join("|") + ")\\)", "ig");
album = album.replace(album_regex, "");
album = album.replace(/\[.+\]/, ""); // remove bracketed fragment
album = album.replace(/(- (single|ep))$/i, "");
album = album.replace(/(version|edition)\)/i, "");
album = album.replace(character_regex, "");
if (/,|&/.test(artist)) {
artist = artist.match(/^(.+?)(,|&)/)[1]; // extract first fragment
}
artist = artist.replace(character_regex, "");
query = album + " " + artist;
} else {
query = "album:\"" + album + "\"" + " artist:\"" + artist + "\"";
}
searchSpotify(query, "album", is_alt_query);
}
function searchArtist() {
var artist = $("h1[itemprop=name]")[0].textContent;
var query = "artist:\"" + artist + "\"";
searchSpotify(query, "artist");
}
function searchSpotify(query, type, is_alt_query) { // type = "album" or "artist"
var app_uri, external_uri;
$.ajax({
url: "https://api.spotify.com/v1/search",
data: {
q: query,
type: type,
limit: 1,
},
success: function (obj) {
var match_count = obj[type + "s"].total;
if (match_count == 0) {
if (type == "album" && !is_alt_query) {
searchAlbum(true); // try an alternative query
return;
}
} else { // at least one match
app_uri = obj[type + "s"].items[0].uri;
external_uri = obj[type + "s"].items[0].external_urls.spotify;
if (type == "album" && embed_player) {
insertSpotifyPlayer(external_uri);
}
}
insertLink[type](open_in_app ? app_uri : external_uri);
}
});
}
/*=========================================
Page type (album/artist) detection
===========================================*/
if ( /\/album\//.test(window.location.pathname) ) {
searchAlbum();
} else {
searchArtist();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment