There are 14 previous versions of this script.
// ==UserScript==
// @name MusicBrainz Artist releases-urls
// @description Display releases urls (AMZ, Discogs, Wikipedia) on the artist page
// @version 2009-06-16_01
// @author Aurelien Mino <aurelien.mino@gmail.com>
// @licence GPL (http://www.gnu.org/copyleft/gpl.html)
//
// @include http://*musicbrainz.org/release-group/*
// @include http://*musicbrainz.org/show/release-group/*
// @include http://*musicbrainz.org/show/artist/releases.html?*
// ==/UserScript==
(function () {
// Script Update Checker
// -- http://userscripts.org/scripts/show/20145
var SUC_script_num = 7947; // Change this to the number given to the script by userscripts.org (check the address bar)
var SUC_script_name = "MusicBrainz Artist releases-urls";
try{function updateCheck(forced){if ((forced) || (parseInt(GM_getValue('SUC_last_update', '0')) + 86400000 <= (new Date().getTime()))){try{GM_xmlhttpRequest({method: 'GET',url: 'http://userscripts.org/scripts/source/'+SUC_script_num+'.meta.js?'+new Date().getTime(),headers: {'Cache-Control': 'no-cache'},onload: function(resp){var local_version, remote_version, rt, script_name;rt=resp.responseText;GM_setValue('SUC_last_update', new Date().getTime()+'');remote_version=parseInt(/@uso:version\s*(.*?)\s*$/m.exec(rt)[1]);local_version=parseInt(GM_getValue('SUC_current_version', '-1'));if(local_version!=-1){script_name = (/@name\s*(.*?)\s*$/m.exec(rt))[1];GM_setValue('SUC_target_script_name', script_name);if (remote_version > local_version){if(confirm('There is an update available for the Greasemonkey script "'+script_name+'."\nWould you like to go to the install page now?')){GM_openInTab('http://userscripts.org/scripts/show/'+SUC_script_num);GM_setValue('SUC_current_version', remote_version);}}else if (forced)alert('No update is available for "'+script_name+'."');}else GM_setValue('SUC_current_version', remote_version+'');}});}catch (err){if (forced)alert('An error occurred while checking for updates:\n'+err);}}}GM_registerMenuCommand(GM_getValue('SUC_target_script_name', '???') + ' - Manual Update Check', function(){updateCheck(true);});updateCheck(false);}catch(err){}
// old update system (TODO: delete them in 2 months)
var version_scriptNum = SUC_script_num;
var version_timestamp = 1247779053585; // Used to differentiate one version of the script from an older one. Use the Date.getTime() function to get a value for this.
try {
function updateCheck(forced) {if((forced)||(parseInt(GM_getValue("lastUpdate", "0")) + 86400000 <= (new Date().getTime()))) {try {GM_xmlhttpRequest({method: "GET",url: "http://userscripts.org/scripts/review/" + version_scriptNum + "?" + new Date().getTime(),headers: {'Cache-Control': 'no-cache'},onload: function(xhrResponse) {GM_setValue("lastUpdate", new Date().getTime() + ""); var rt = xhrResponse.responseText.replace(/ ?/gm, " ").replace(/<li>/gm, "\n").replace(/<[^>]*>/gm, ""); var scriptName = (/@name\s*(.*?)\s*$/m.exec(rt))[1]; GM_setValue("targetScriptName", scriptName); if (parseInt(/version_timestamp\s*=\s*([0-9]+)/.exec(rt)[1]) > version_timestamp) {if (confirm("There is an update available for the Greasemonkey script \"" + scriptName + ".\"\nWould you like to go to the install page now?")) {GM_openInTab("http://userscripts.org/scripts/show/" + version_scriptNum);}} else if (forced) {alert("No update is available for \"" + scriptName + ".\"");}}});} catch (err) {if (forced) {alert("An error occurred while checking for updates:\n" + err);}}}} GM_registerMenuCommand(GM_getValue("targetScriptName", "???") + " - Manual Update Check", function() {updateCheck(true);}); updateCheck(false);
} catch(e) {}
// Definitions: relations-type and corresponding icons we are going to treat
var relationsIconsURLs = {
"AmazonAsin": "http://amazon.fr/favicon.ico",
"Discogs": "http://www.discogs.com/images/favicon.ico",
"Wikipedia": "http://fr.wikipedia.org/favicon.ico",
"IMDb": "http://www.imdb.com/favicon.ico",
"CreativeCommonsLicensedDownload": "http://creativecommons.org/favicon.ico",
"CoverArtLink": "http://cdcovers.to/favicon.ico",
"PartOfSet": "http://oldwiki.musicbrainz.org/-/musicbrainz/img/moin-inter.png",
"FirstAlbumRelease": "http://oldwiki.musicbrainz.org/-/musicbrainz/img/moin-www.png",
"Remaster": "http://oldwiki.musicbrainz.org/-/musicbrainz/img/moin-www.png"
};
// DEBUG: on/off
var DEBUG = false;
// Determine listing mode (full or compact)
var listingMode;
if (document.getElementById('CompactReleaseList')) {
listingMode = "compact";
} else {
listingMode = "full";
}
// Get pageType (label or artist)
var pageType = undefined;
if (window.location.href.match(/artist/) || window.location.href.match(/release-group/)) {
pageType = 'artist';
} else if (window.location.href.match(/label/)) {
pageType = 'label';
}
// Call the MB webservice
var url = 'http://' + window.location.host + '/ws/1/'+pageType+'/' + getArtistMBID() + '/?type=xml&inc=release-rels+url-rels+sa-Official';
myGM_log('url: ' + url);
GM_xmlhttpRequest({
method:"GET",
url:url,
headers:{
"User-Agent":"monkeyagent",
"Accept":"text/monkey,text/xml",
},
onload:function(response) {
var xmldoc = new DOMParser().parseFromString(response.responseText,"text/xml");
xmlhttpChange(xmldoc);
}
});
// Analyze XmlHttp response
function xmlhttpChange(xmldoc) {
// Get releases
var releases;
if (listingMode == "compact") {
releases = getElementsByClassName(document, "td", "rname");
} else if (listingMode == "full") {
releases = getElementsByClassName(document, "table", "releasebegin");
}
// Parse each release
for (var i in releases)
{
var release = releases[i];
// Get the release id
var release_mbid = getReleaseMBID(release, listingMode);
myGM_log('Release MBID: '+release_mbid);
// Create emplacement for each icon releation, which will be filled if relation exists later
// and save reference of each emplacement in a map
var relationsColumnsMap = {};
for (var relationType in relationsIconsURLs) {
var relationElement;
if (listingMode == "compact") {
relationElement = document.createElement("td");
var insertAnchor = getFirstElementByClassName(release.parentNode,"td", "rtag");
// In case that user is not logged
if (insertAnchor === null) {
insertAnchor = release;
}
release.parentNode.insertBefore(relationElement, insertAnchor);
} else if (listingMode == "full") {
relationElement = document.createElement("span");
var tableTracksID = 'tracks::' + release.id.match(/release::(.+)/)[1];
var statisticsTD = getFirstElementByClassName(document.getElementById(tableTracksID), "td", "statistics");
statisticsTD.appendChild(relationElement);
relationElement.style.paddingRight = "8px";
}
relationsColumnsMap[relationType] = relationElement;
relationElement.empty = true;
}
// Examine the url-relations, if any
var xpathExpr = "//mb:release[@id='" + release_mbid + "'][1]//mb:relation";
var relations = xmldoc.evaluate(xpathExpr, xmldoc, NSResolver, XPathResult.ANY_TYPE, null);
myGM_log("XPath: "+xpathExpr);
var relation = relations.iterateNext();
while(relation) {
var relationType = relation.getAttribute("type");
myGM_log('relationType : '+relationType);
// Check if we treat this relation type, and so if we have created a column (relationElement) for it
// then check if this column is still empty, or it has already been filled
var relationElement = relationsColumnsMap[relationType];
if (relationElement && relationElement.empty) {
var relationLink = document.createElement("a");
relationLink.href = relation.getAttribute("target");
relationElement.appendChild(relationLink);
var relationImg = document.createElement("img");
relationImg.src = relationsIconsURLs[relationType];
relationLink.appendChild(relationImg);
relationElement.empty = false;
}
relation = relations.iterateNext();
}
} // End of parsing releases
// Some additionnal esthetic details
if (listingMode == "compact") {
var h2Elements = document.getElementById('CompactReleaseList').getElementsByTagName('h2');
for (var i in h2Elements) {
var titleTD = h2Elements[i].parentNode;
if(titleTD) { titleTD.colSpan += getSizeOfHashTable(relationsIconsURLs); }
}
}
}
// Obtain the artist MBID
function getArtistMBID() {
var artistbox = getFirstElementByClassName(document, "td", "links");
var link = artistbox.getElementsByTagName("a")[0];
var artist_mbid = link.href.match(/id=(.+)&/)[1];
return artist_mbid;
}
// Obtain an release MBID from the html element provided, and according to the listing mode
function getReleaseMBID(releaseElement, listingMode) {
if (listingMode == "compact") {
var links = releaseElement.getElementsByTagName("a");
for (var j in links) {
if (links[j].href && links[j].href.match(/\/release\//)) {
return links[j].href.match(/release\/(.+)\.html/)[1];
}
}
} else if (listingMode == "full") {
var link = getFirstElementByClassName(releaseElement, "td", "title").getElementsByTagName("a")[0];
if (link.href && link.href.match(/\/release\//)) {
return link.href.match(/release\/(.+)\.html/)[1];
}
}
}
// Helper function for getting html element by class name
// Written by Jonathan Snook, http://www.snook.ca/jonathan
// Add-ons by Robert Nyman, http://www.robertnyman.com
function getElementsByClassName(oElm, strTagName, strClassName){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = [];
strClassName = strClassName.replace(/\-/g, "\\-");
var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
var oElement;
for(var i=0; i<arrElements.length; i++){
oElement = arrElements[i];
if(oRegExp.test(oElement.className)){
arrReturnElements.push(oElement);
}
}
return (arrReturnElements);
}
// Helper function for getting the first html element with specified class name
// derived from function getElementsByClassName()
function getFirstElementByClassName(oElm, strTagName, strClassName){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = [];
strClassName = strClassName.replace(/\-/g, "\\-");
var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
var oElement;
for(var i=0; i<arrElements.length; i++){
oElement = arrElements[i];
if(oRegExp.test(oElement.className)){
return oElement;
}
}
return null;
}
// Helper function needed for resolving MB namespace in xpath expression
function NSResolver(prefix) {
if(prefix == 'mb') {
return 'http://musicbrainz.org/ns/mmd-1.0#';
}
else {
//this shouldn't ever happen
return null;
}
}
function getSizeOfHashTable(ht) {
var l = ht.length ? --ht.length : 0;
for (var k in ht) {
l++;
}
return l;
}
// Activable GM_log
function myGM_log(message) {
if(DEBUG) {
var logged = false;
try {
GM_log(message);
logged = true;
} catch(e) {}
try {
opera.postError(message);
logged = true;
} catch(e) {}
if (!logged) {
alert(message);
}
}
}
})();
