MusicBrainz Artist releases-urls

By murdos Last update Nov 1, 2008 — Installed 444 times.

There are 5 previous versions of this script.

// ==UserScript==
// @name           MusicBrainz Artist releases-urls
// @description    Display releases urls (AMZ, Discogs, Wikipedia) on the artist page
// @version        2008-10-30-01
// @author         Aurelien Mino <aurelien.mino@gmail.com>
// @licence        GPL (http://www.gnu.org/copyleft/gpl.html)
//
// @include        http://*musicbrainz.org/artist/*
// @include        http://*musicbrainz.org/show/artist/*

// ==/UserScript==

(function () {

// Script Update Checker
// -- http://userscripts.org/scripts/show/20145
var version_scriptNum = 7947; // Change this to the number given to the script by userscripts.org (check the address bar)
var version_timestamp = 1225358517184; // 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(/&nbsp;?/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://wiki.musicbrainz.org/-/musicbrainz/img/moin-inter.png",
                            "FirstAlbumRelease": "http://wiki.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/)) {
	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);

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = xmlhttpChange;
xmlhttp.open("GET", url, true);
xmlhttp.send(null);

// Analyze XmlHttp response
function xmlhttpChange() {

	// create XMLDOM object if xmlhttp shows "loaded"
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
	{
	
		var xmldoc = xmlhttp.responseXML;
		
		// 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);
		}
	}
}

})();