2012-03-28 21:55:12 +00:00
// ==UserScript==
2012-03-28 21:55:40 +00:00
// @name Import Discogs releases to MusicBrainz
2012-03-28 21:55:12 +00:00
// @namespace http://userscripts.org/users/22504
2012-03-28 21:57:01 +00:00
// @include http://*.discogs.com/*release/*
2012-03-28 21:55:12 +00:00
// ==/UserScript==
// Script Update Checker
// -- http://userscripts.org/scripts/show/20145
2012-03-28 21:55:40 +00:00
var version _scriptNum = 36376 ; // Change this to the number given to the script by userscripts.org (check the address bar)
2012-03-28 21:58:02 +00:00
var version _timestamp = 1263489365220 ; // Used to differentiate one version of the script from an older one. Use the Date.getTime() function to get a value for this.
2012-03-28 21:55:12 +00:00
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 ) { }
// Discogs API KEY (you may need to add yours if you encounter limit issues)
var discogsApiKey = "84b3bec008" ;
// Discogs Webservice URL
2012-03-28 21:57:01 +00:00
var discogsWsUrl = window . location . href . replace ( /http:\/\/(www\.|)discogs\.com\/(.*\/|)release\// , 'http://discogs.com/release/' ) + "?f=xml&api_key=" + discogsApiKey ;
2012-03-28 21:57:28 +00:00
console . log ( discogsWsUrl ) ;
2012-03-28 21:55:12 +00:00
// Grabs information from Discogs
2012-03-28 21:55:58 +00:00
2012-03-28 21:55:12 +00:00
GM _xmlhttpRequest ( {
method : "GET" ,
url : discogsWsUrl ,
headers : {
"User-Agent" : "monkeyagent" ,
"Accept" : "text/monkey,text/xml" ,
} ,
onload : function ( response ) {
var xmldoc = new DOMParser ( ) . parseFromString ( response . responseText , "text/xml" ) ;
2012-03-28 21:55:58 +00:00
var releases = parseReleases ( xmldoc ) ;
insertLinks ( releases ) ;
2012-03-28 21:55:12 +00:00
}
} ) ;
2012-03-28 21:56:32 +00:00
/ *
var xmlhttp = new XMLHttpRequest ( ) ;
xmlhttp . onreadystatechange = function ( ) { var releases = parseReleases ( xmlhttp . responseXML ) ; insertLinks ( releases ) ; } ;
xmlhttp . open ( "GET" , url , true ) ;
xmlhttp . send ( null ) ;
* /
2012-03-28 21:55:12 +00:00
2012-03-28 21:56:32 +00:00
// Analyze Discogs data and cook the import URL
2012-03-28 21:55:58 +00:00
function parseReleases ( xmldoc ) {
var releases = [ ] ;
2012-03-28 21:55:12 +00:00
var xpathExpr , resultNodes ;
// Compute artist(s) name(s)
2012-03-28 21:55:58 +00:00
var releaseArtist = "" ;
xpathExpr = "//release/artists/artist/*[name()='name' or name()='join']" ;
2012-03-28 21:55:12 +00:00
resultNodes = xmldoc . evaluate ( xpathExpr , xmldoc , null , XPathResult . ORDERED _NODE _SNAPSHOT _TYPE , null ) ;
2012-03-28 21:55:58 +00:00
releaseArtist = cookArtistName ( resultNodes ) ;
2012-03-28 21:55:12 +00:00
2012-03-28 21:55:58 +00:00
// Grab release title
2012-03-28 21:55:12 +00:00
var releaseTitle ;
xpathExpr = "//release/title" ;
releaseTitle = xmldoc . evaluate ( xpathExpr , xmldoc , null , XPathResult . FIRST _ORDERED _NODE _TYPE , null ) . singleNodeValue . textContent ;
2012-03-28 21:55:58 +00:00
// Grab tracks
var tracks = [ ] ;
2012-03-28 21:55:12 +00:00
xpathExpr = "//tracklist/track" ;
resultNodes = xmldoc . evaluate ( xpathExpr , xmldoc , null , XPathResult . ORDERED _NODE _SNAPSHOT _TYPE , null ) ;
for ( var i = 0 ; i < resultNodes . snapshotLength ; i ++ ) {
2012-03-28 21:55:58 +00:00
var track = new Object ( ) ;
var trackNode = resultNodes . snapshotItem ( i ) ;
track . title = trackNode . getElementsByTagName ( "title" ) . item ( 0 ) . textContent ;
track . duration = trackNode . getElementsByTagName ( "duration" ) . item ( 0 ) . textContent ;
// Track artist
var trackArtist ;
xpathExpr = ".//artists//*[name()='name' or name()='join']" ;
trackArtist = cookArtistName ( xmldoc . evaluate ( xpathExpr , trackNode , null , XPathResult . ORDERED _NODE _SNAPSHOT _TYPE , null ) ) ;
if ( trackArtist != "" )
track . artist = trackArtist ;
// Track position and release number
var trackPosition = trackNode . getElementsByTagName ( "position" ) . item ( 0 ) . textContent ;
var releaseNumber = 1 ;
2012-03-28 21:57:28 +00:00
// Multi discs e.g. 1.1 or 1-1
2012-03-28 21:56:32 +00:00
var tmp = trackPosition . match ( /^(\d)(?=(-|\.)\d*)/ ) ;
2012-03-28 21:55:58 +00:00
if ( tmp && tmp [ 0 ] ) {
releaseNumber = tmp [ 0 ] ;
2012-03-28 21:57:28 +00:00
} else {
// Vinyls disc numbering: A1, B3, ...
2012-03-28 21:58:02 +00:00
tmp = trackPosition . match ( /^([A-Za-z])\d*/ ) ;
2012-03-28 21:57:28 +00:00
if ( tmp && tmp [ 0 ] ) {
var code = tmp [ 0 ] . charCodeAt ( 0 ) - 65 ;
releaseNumber = ( code - code % 2 ) / 2 + 1 ;
}
}
2012-03-28 21:55:58 +00:00
// Create release if needed
if ( ! releases [ releaseNumber - 1 ] ) {
releases . push ( new Object ( ) ) ;
releases [ releaseNumber - 1 ] . tracks = [ ] ;
}
2012-03-28 21:56:32 +00:00
// Trackposition is empty e.g. for release title
if ( trackPosition != "" && trackPosition != null )
releases [ releaseNumber - 1 ] . tracks . push ( track ) ;
2012-03-28 21:55:12 +00:00
}
2012-03-28 21:55:58 +00:00
// Fill releases info
for ( var i = 0 ; i < releases . length ; i ++ ) {
releases [ i ] . artist = releaseArtist ;
releases [ i ] . title = releaseTitle ;
if ( releases . length > 1 )
releases [ i ] . title += " (disc " + ( i + 1 ) + ")" ;
}
2012-03-28 21:57:28 +00:00
console . log ( releases ) ;
2012-03-28 21:55:58 +00:00
return releases ;
2012-03-28 21:55:12 +00:00
}
2012-03-28 21:55:58 +00:00
// Insert links in Discogs page
function insertLinks ( releases ) {
2012-03-28 21:55:12 +00:00
2012-03-28 21:57:28 +00:00
var mbUI = document . createElement ( 'div' ) ;
mbUI . innerHTML = "<h3>MusicBrainz</h3>" ;
mbUI . className = "section" ;
var mbContentBlock = document . createElement ( 'div' ) ;
mbContentBlock . className = "section_content" ;
mbUI . appendChild ( mbContentBlock ) ;
var innerHTML = '' ;
2012-03-28 21:55:58 +00:00
if ( releases . length == 1 ) {
2012-03-28 21:57:28 +00:00
innerHTML += '<div><a target="_blank" href="' + cookImportUrl ( releases [ 0 ] ) + '">Import release</a></div>' ;
2012-03-28 21:55:58 +00:00
} else {
for ( var i = 0 ; i < releases . length ; i ++ ) {
2012-03-28 21:57:28 +00:00
innerHTML += '<div><a target="_blank" href="' + cookImportUrl ( releases [ i ] ) + '">Import disc ' + ( i + 1 ) + '</a></div>' ;
2012-03-28 21:55:58 +00:00
}
}
2012-03-28 21:57:28 +00:00
mbContentBlock . innerHTML = innerHTML ;
2012-03-28 21:55:12 +00:00
2012-03-28 21:57:28 +00:00
var prevNode = document . body . querySelector ( "div.section.ratings" ) ;
prevNode . parentNode . insertBefore ( mbUI , prevNode ) ;
2012-03-28 21:55:12 +00:00
}
2012-03-28 21:55:58 +00:00
// Helper function: compute artist name from a XPATH resultNodes
function cookArtistName ( nodes ) {
var artistName = "" ;
for ( var i = 0 ; i < nodes . snapshotLength ; i ++ ) {
artistName += ( i == 0 ? "" : " " ) + nodes . snapshotItem ( i ) . textContent ;
}
return artistName ;
}
// Helper function: compute url for a release object
function cookImportUrl ( release ) {
var importURL = "http://musicbrainz.org/cdi/enter.html?&artistname=" + encodeURIComponent ( release . artist ) + "&releasename=" + encodeURIComponent ( release . title ) ;
// Multiple artists on tracks?
var artists = [ ] ;
for ( var i = 0 ; i < release . tracks . length ; i ++ ) {
if ( release . tracks [ i ] . artist )
artists . push ( release . tracks [ i ] . artist ) ;
}
if ( artists . length > 1 )
importURL += "&hasmultipletrackartists=1&artistid=1" ;
else
importURL += "&hasmultipletrackartists=0&artistid=2" ;
// Add tracks
for ( var i = 0 ; i < release . tracks . length ; i ++ ) {
importURL += "&track" + i + "=" + encodeURIComponent ( release . tracks [ i ] . title ) ;
importURL += "&tracklength" + i + "=" + encodeURIComponent ( release . tracks [ i ] . duration ) ;
if ( artists . length > 1 && release . tracks [ i ] . artist ) {
importURL += "&tr" + i + "_artistedit=1" ;
importURL += "&tr" + i + "_artistname=" + encodeURIComponent ( release . tracks [ i ] . artist ) ;
}
}
importURL += '&tracks=' + release . tracks . length ;
return importURL ;
2012-03-28 21:57:28 +00:00
}