var info_discogs = function() { var me = "discogs"; var medebug = 'DISCOGS PLUGIN'; function getURLs(urls) { var html = ""; for (var i in urls) { if (urls[i] != "") { var u = urls[i]; var d = u.match(/https*:\/\/(.*?)(\/|$)/); if (d == null) { d = [u,u]; u = 'http://'+u; } if (u.match(/wikipedia/i)) { html += '
  • Wikipedia ('+d[1]+')
  • '; } else if (u.match(/facebook/i)) { html += '
  • Facebook
  • '; } else { html += '
  • '+d[1]+'
  • '; } } } return html; } function getBestImage(images) { var image = null; var types = ['primary', 'secondary']; var index = -1; while (image === null && types.length > 0) { var type = types.shift(); var maxsize = 0; for (var i in images) { if (images[i].resource_url && images[i].type == type) { var size = images[i].height*images[i].width; if (size > maxsize) { image = images[i].resource_url; maxsize = size; } } } } return image; } function compareArtists(art1, art2) { var a1 = mungeArtist(art1); var a2 = mungeArtist(art2); if (a1 == a2) { return true; } return tryWithoutAccents(a1, a2); } function tryWithoutAccents(a1, a2) { return (a1.normalize("NFD").replace(/[\u0300-\u036f]/g, "") == a2.normalize("NFD").replace(/[\u0300-\u036f]/g, "")); } function mungeArtist(n) { n = n.replace(/ \(\d+\)$/, ''); var p = n.split(' '); for (var i in prefs.nosortprefixes) { if (p[0].toLowerCase() == prefs.nosortprefixes[i].toLowerCase()) { p.shift(); break; } } var retval = p.join(' ').toLowerCase(); retval.replace(/ featuring .+$/, ''); retval.replace(/ feat\. .+$/, ''); debug.debug(medebug,'Munged artist',n,'to',retval); return retval; } function getReleaseHTML(data) { var html = ""; debug.trace(medebug,"Generating release HTML for",data.id); if (data.data.releases.length > 0) { html += '
    PAGES: '; for (var i = 1; i <= data.data.pagination.pages; i++) { if (i == data.data.pagination.page) { html += " "+i+""; } else { var a = data.data.pagination.urls.last || data.data.pagination.urls.first; var b = a.match(/artists\/(\d+)\/releases/); if (b && b[1]) { html += ' '+i+''; } } } html += '
    '; html += '
    '; html += ''; for (var i in data.data.releases) { html += ''; if (data.data.releases[i].thumb) { html += ''; } else { html += ''; } if (data.data.releases[i].year) { html += ''; } else { html += ''; } if (data.data.releases[i].title) { html += ''; } else { html += ''; } if (data.data.releases[i].artist) { html += ''; } else { html += ''; } if (data.data.releases[i].format) { html += ''; } else { html += ''; } if (data.data.releases[i].label) { html += ''; } else { html += ''; } html += ''; } html += '
    '+language.gettext("title_year")+''+language.gettext("title_title")+'' +language.getUCtext("label_artist")+''+language.gettext("title_type")+''+language.gettext("title_label")+'
    '+data.data.releases[i].year+''+ data.data.releases[i].title+ ''; if (data.data.releases[i].role && data.data.releases[i].role != 'Main') { var r = data.data.releases[i].role; r = r.replace(/([a-z])([A-Z])/, '$1 $2'); html += '
    ('+r+')' } if (data.data.releases[i].trackinfo) { html += '
    ('+data.data.releases[i].trackinfo+')' } html += '
    '+data.data.releases[i].artist+''+data.data.releases[i].format+''+data.data.releases[i].label+'
    '; html += '
    '+language.gettext("label_pages")+': '; for (var i = 1; i <= data.data.pagination.pages; i++) { if (i == data.data.pagination.page) { html += " "+i+""; } else { var a = data.data.pagination.urls.last || data.data.pagination.urls.first; var b = a.match(/artists\/(\d+)\/releases/); if (b && b[1]) { html += ' '+i+''; } } } html += '
    '; } debug.trace(medebug,"Returning release HTML for",data.id); return html; } function getStyles(styles) { var html = '
    '; return html; } function getGenres(genres) { var html = '
    '; return html; } function getTracklist(tracks) { var html = '
    '+language.gettext("discogs_tracklisting")+'
    '; for (var i in tracks) { if (tracks[i].position == "") { html += ''; } else { html += ''; html += ''; html += ''; } } html += '
    '+tracks[i].title+'
    '+tracks[i].position+''+tracks[i].title+''; if (tracks[i].artists && tracks[i].artists.length > 0) { html += '
    '; var jp = ""; for (var k in tracks[i].artists) { if (jp != "") { html += " "+jp+" "; } html += tracks[i].artists[k].name; jp = tracks[i].artists[k].join; } html += ''; } if (tracks[i].extraartists) { for (var j in tracks[i].extraartists) { html += '
    '+tracks[i].extraartists[j].role+ ' - '+tracks[i].extraartists[j].name+''; } } html += '
    '+tracks[i].duration+'
    '; return html; } return { getRequirements: function(parent) { return ["musicbrainz"]; }, collection: function(parent, artistmeta, albummeta, trackmeta) { debug.trace(medebug, "Creating data collection"); var self = this; var displaying = false; var artisttimer; var albumtimer; var tracktimer; this.populate = function() { debug.log(medebug,'Populating'); parent.updateData({ discogs: { triedsearch: false, triedmunge: false } }, artistmeta ); parent.updateData({ discogs: { album: {}, triedmusicbrainz: false, triedsearch: false, triedmunge: false } }, albummeta ); parent.updateData({ discogs: { track: {}, triedsearch: false, triedmunge: false } }, trackmeta ); self.album.populate(); self.track.populate(); } this.displayData = function() { displaying = true; self.artist.doBrowserUpdate(); self.album.doBrowserUpdate(); self.track.doBrowserUpdate(); } this.stopDisplaying = function(waitingon) { displaying = false; clearTimeout(artisttimer); clearTimeout(albumtimer); clearTimeout(tracktimer); } this.handleClick = function(source, element, event) { debug.trace(medebug,parent.nowplayingindex,source,"is handling a click event"); if (element.hasClass('clickdoartist')) { var targetdiv = element.parent().next(); if (!(targetdiv.hasClass('full')) && element.isClosed()) { doSomethingUseful(targetdiv, language.gettext("info_gettinginfo")); targetdiv.slideToggle('fast'); getArtistData(element.attr('name')); element.toggleOpen(); targetdiv.addClass('underline'); } else { var id = element.attr('name'); if (element.isOpen()) { element.toggleClosed(); targetdiv.removeClass('underline'); } else { element.toggleOpen(); targetdiv.addClass('underline'); } targetdiv.slideToggle('fast'); } } else if (element.hasClass('clickreleasepage')) { var targetdiv = element.parent().parent().parent().attr("name"); element.parent().parent().parent().addClass("expectingpage_"+element.text()); doSomethingUseful(element.parent().parent(), language.gettext("info_gettinginfo")); getArtistReleases(element.attr('name'), element.text()); } else if (element.hasClass('clickdodiscography')) { var targetdiv = element.parent().next(); if (!(targetdiv.hasClass('full')) && element.isClosed()) { doSomethingUseful(targetdiv, language.gettext("info_gettinginfo")); targetdiv.addClass("expectingpage_1"); getArtistReleases(element.attr('name'), 1); element.toggleOpen(); targetdiv.slideToggle('fast'); } else { if (element.isOpen()) { element.toggleClosed(); } else { element.toggleOpen(); } targetdiv.slideToggle('fast'); } } else if (element.hasClass('clickzoomimage')) { imagePopup.create(element, event, element.next().val()); } else if (element.hasClass('clickgetdiscstuff')) { var link = element.next().val(); var b = link.match(/(releases\/\d+)|(masters\/\d+)/); if (b && b[0]) { debug.log("DISCOGS","Getting info for",b[0]) discogs.album.getInfo('', b[0], function(data) { debug.trace("DISCOGS", "Got Data",data); if (data.data.uri) { debug.trace("DISCOGS", "Opening Data",data.data.uri); var box = element.parent(); box.empty(); var newlink = $(''+data.data.title+'').appendTo(box); window.open(data.data.uri, '_blank'); } }, function(data) { infobar.error(language.gettext('label_general_error')); } ); } } else if (element.hasClass('clickexpandbox')) { var id = element.attr('name'); var expandingframe = element.parent().parent().parent().parent(); var content = expandingframe.html(); content=content.replace(/'); // Inline links using an artist id p = p.replace(/\[a=*(\d+?)\]/g, '$1'); // Inline links using an artist name var reg = /\[a=*(.+?)\]/g; var matches = [...p.matchAll(reg)]; for (var i in matches) { p = p.replace(matches[i][0], ''+matches[i][1]+'') } // Same ofr inline label links p = p.replace(/\[l=*(.\d+?)\]/g, '$1'); reg = /\[l=*(.+?)\]/g; matches = [...p.matchAll(reg)]; for (var i in matches) { p = p.replace(matches[i][0], ''+matches[i][1]+'') } // Same for inline master links p = p.replace(/\[m=*(\d+?)\]/g, '$1'); var reg = /\[m=*(.+?)\]/g; var matches = [...p.matchAll(reg)]; for (var i in matches) { p = p.replace(matches[i][0], ''+matches[i][1]+'') } // Same for inline release links p = p.replace(/\[r=*(\d+?)\]/g, '$1'); var reg = /\[r=*(.+?)\]/g; var matches = [...p.matchAll(reg)]; for (var i in matches) { p = p.replace(matches[i][0], ''+matches[i][1]+'') } p = p.replace(/\[url=*(.+?)\](.+?)\[\/url\]/g, '$2'); p = p.replace(/\[b\]/g, ''); p = p.replace(/\[\/b\]/g, ''); p = p.replace(/\[i\]/g, ''); p = p.replace(/\[\/i\]/g, ''); // Discogs profiles come with a bunch of references to other artists formatted as [a123456] // (where 123456 is the discogs artist id). formatNotes replaces these with spans so we can // get the arist bio and update the displayed items without having to resort to replacing // all the html in the div every time. // To avoid getting the artist data every time we display the html, we'll also check to see // if we already have the data and use it now if we do. // Not only that they've started doing [r=123456] to denote a release! (See Hawkwind) var m = p.match(//g); if (m) { for(var i in m) { var n = m[i].match(//); if (n && n[1]) { debug.shout(medebug,"Found unpopulated artist reference",n[1]); if (artistmeta.discogs['artist_'+n[1]] === undefined) { debug.trace(medebug,parent.nowplayingindex," ... retrieivng data"); discogs.artist.getInfo( n[1], n[1], self.artist.extraResponseHandler2, self.artist.extraResponseHandler2 ); } else { debug.trace(medebug,parent.nowplayingindex," ... displaying what we've already got"); var name = artistmeta.discogs['artist_'+n[1]].data.name; var link = artistmeta.discogs['artist_'+n[1]].data.uri; p = p.replace(new RegExp(''+n[1]+'<\/span>', 'g'), ''+name+''); } } } } var m = p.match(//g); if (m) { for(var i in m) { var n = m[i].match(//); if (n && n[1]) { debug.shout(medebug, "Found unpopulated master reference", n[1]); discogs.album.getInfo( n[1], 'masters/'+n[1], self.artist.gotExtraAlbumInfo, self.artist.gotExtraAlbumInfo ); } } } var m = p.match(//g); if (m) { for(var i in m) { var n = m[i].match(//); if (n && n[1]) { debug.shout(medebug, "Found unpopulated release reference", n[1]); discogs.album.getInfo( n[1], 'releases/'+n[1], self.artist.gotExtraAlbumInfo2, self.artist.gotExtraAlbumInfo2 ); } } } var m = p.match(//g); if (m) { for(var i in m) { var n = m[i].match(//); if (n && n[1]) { debug.shout(medebug, "Found unpopulated label reference", n[1]); discogs.label.getInfo( n[1], n[1], self.artist.gotExtraLabelInfo, self.artist.gotExtraLabelInfo ); } } } return p; } function getAlbumHTML(data, order) { debug.trace(medebug,"Creating HTML from release/master data",data); if (data.error && data.master === undefined && data.release === undefined) { return '

    '+data.error.error+'

    '; } var html = '
    '; html += '
    '; for (var i in order) { if (data[order[i]] && data[order[i]].data.styles && data[order[i]].data.styles.length > 0) { html += getStyles(data[order[i]].data.styles); break; } } for (var i in order) { if (data[order[i]] && data[order[i]].data.genres && data[order[i]].data.genres.length > 0) { html += getGenres(data[order[i]].data.genres); break; } } if (data.release && data.release.data.companies && data.release.data.companies.length > 0) { html += '
    • '+language.gettext("discogs_companies")+'
    • '; for (var i in data.release.data.companies) { html += '
    • '+data.release.data.companies[i].entity_type_name+ " "+data.release.data.companies[i].name+'
    • '; } html += '
    '; } html += '
    '; html += '
    '; var image = null; for (var i in order) { if (data[order[i]] && data[order[i]].data.images) { image = getBestImage(data[order[i]].data.images); if (image !== null) { break; } } } if (image !== null) { html += ''; html += ''; } if (data.master && data.master.data.notes) { var n = formatNotes(data.master.data.notes); html += '

    '+n+'

    '; } if (data.release && data.release.data.notes) { var n = formatNotes(data.release.data.notes); html += '

    '+n+'

    '; } if (data.release && data.release.data.extraartists && data.release.data.extraartists.length > 0) { html += '
    '+language.gettext("discogs_personnel")+'
    '; for (var i in data.release.data.extraartists) { html += '
    '+data.release.data.extraartists[i].role+' '+data.release.data.extraartists[i].name+'
    '; } } for (var i in order) { if (data[order[i]] && data[order[i]].data.tracklist && data[order[i]].data.tracklist.length > 0) { html += '
    '; html += getTracklist(data[order[i]].data.tracklist); break; } } html += '
    '; html += '
    '; return html; } function getArtistHTML(data, expand) { if (data.error) { return '

    '+data.error+'

    '; } debug.trace(medebug, "Creating Artist HTML",data); var html = ''; if (artistmeta.discogs.possibilities && artistmeta.discogs.possibilities.length > 1) { html += '
    '+ '
    '+ '
    All possibilities for "'+ artistmeta.name+'"
    '+ '
    '; for (var i in artistmeta.discogs.possibilities) { html += '
    '; if (artistmeta.discogs.possibilities[i].image) { html += ''; } else { html += ''; } html += ''+artistmeta.discogs.possibilities[i].name+''; html += '
    '; } html += '
    '; html += '
    '; } html += '
    '; html += '
    '; if (data.data.realname && data.data.realname != "") { html += '
    • '+language.gettext("discogs_realname")+' '+data.data.realname+'
    • '; } if (data.data.aliases && data.data.aliases.length > 0) { html += '
      • '+language.gettext("discogs_aliases")+'
      • '; for (var i in data.data.aliases) { html += '
      • '+data.data.aliases[i].name+'
      • '; } html += '
      '; } if (data.data.namevariations && data.data.namevariations.length > 0) { html += '
      • '+language.gettext("discogs_alsoknown")+'
      • '; for (var i in data.data.namevariations) { html += '
      • '+data.data.namevariations[i]+'
      • '; } html += '
      '; } if (data.data.urls && data.data.urls.length > 0) { html += '
      • '+language.gettext("discogs_external")+'
      • '; html += getURLs(data.data.urls); html += '
      '; } html += '
    '; html += '
    '; html += '
    '; var image = null; if (data.data.images) { image = getBestImage(data.data.images); } if (image !== null) { html += ''; html += ''; } if (expand) { html += ''; } if (data.data.profile) { var p = formatNotes(data.data.profile); html += '

    '+p+'

    '; } html += '
    '; html += '
    '; html += '
    '; if (data.data.members && data.data.members.length > 0) { html += '
    '+language.gettext("discogs_bandmembers")+'
    '; html += doMembers(data.data.members); } if (data.data.groups && data.data.groups.length > 0) { html += '
    '+language.gettext("discogs_memberof")+'
    '; html += doMembers(data.data.groups); } html += '
    '; html += ''; html += ''+language.gettext("discogs_discography", [data.data.name.toUpperCase()])+'
    '; html += ''; return html; } function doMembers(members) { var html = ""; for (var i in members) { html += '
    '; html += ''; var n = members[i].name; n = n.replace(/ \(\d+\)$/, ''); html += ''+n+''; html += '
    '; html += ''; } return html; } function getSearchArtistForAlbum() { var a = (albummeta.artist && albummeta.artist != "") ? albummeta.artist : parent.playlistinfo.trackartist; if (a == "Various Artists") { a = "Various"; } return a; } function getSearchArtist() { return artistmeta.name; } this.artist = function() { var retries = 10; var force = false; return { populate: function() { // The link will either be /artist/[number] in which case we can use it // Or it'll be /artist/Artist+Name which we can't use // artistlink is what musicbrainz will try to give us. If it's undefined it means musicbrainz // hasn't yet come up with any sort of answer. If it's null it means musicbrainz failed to find one // or we gave up waiting for musicbrainz. // artistid is what we're trying to find. (All we have at the initial stage is an artist name). // If it's undefined it means we haven't even looked yet. If it's null it means we looked and failed. // Let's look at what we're doing here, because this is hard. // 1. Wait to see if musicbrainz can find a link to discogs for us. This is good because it will // have come via the MUSICBRAINZ_ARTISTID tag (althought possible it might have come from an MB tag found by Last.FM) // 2. We wait for up to 20 seconds for that to happen, then give up. If MB doesn't find one it sents it to null. // 3. In the meantime, the track may have found an aristuri for us. This is likely to be accurate, and probably more // accurate than the one MB gave us (since that may have come bia Last.FM) so if there is one, we use it. // 4. If we didn't get a link, or it didn't work, we search. First we search for the artist name as it stands. // Then if that didn't give us anything useful we munge it (remove (digits) from the end, The from the beginning // ' featuring some shithead' from the end etc) and try again. if (artistmeta.discogs.artistinfo === undefined && (artistmeta.discogs.artistid === undefined || artistmeta.discogs.artistid === null)) { if (artistmeta.discogs.artistlink === undefined) { debug.shout(medebug,parent.nowplayingindex,"Artist asked to populate but no link yet"); retries--; if (retries == 0 || artistmeta.discogs.artisturi !== undefined) { debug.warn(medebug,parent.nowplayingindex,"Artist giving up waiting for bloody musicbrainz"); artistmeta.discogs.artistlink = null; } else { artisttimer = setTimeout(self.artist.populate, 2000); return; } } // artisturi is returned by the track, if it finds a suitable match. It's likely to be more accurate than // anything returned by musicbrainz (except if local tracks are tagged with mb artist ids I guess) var link = (artistmeta.discogs.artisturi === undefined) ? artistmeta.discogs.artistlink : artistmeta.discogs.artisturi; if (link !== undefined && link !== null) { var s = link.split('/').pop() if (s.match(/^\d+$/)) { debug.mark(medebug,parent.nowplayingindex,"Artist asked to populate, using supplied link",s); artistmeta.discogs.artistid = s; discogs.artist.getInfo( 'artist_'+s, s, self.artist.artistResponseHandler, self.artist.artistResponseHandler ); return; } else { debug.log(medebug,'Artist link was useless',s); } } if (artistmeta.discogs.triedsearch && artistmeta.discogs.triedmunge) { self.artist.abjectFailure(); } else { self.artist.search(artistmeta.discogs.triedsearch ? mungeArtist(getSearchArtist()) : getSearchArtist()); } } else { debug.mark(medebug,parent.nowplayingindex,"Artist is already populated"); } }, search: function(name) { debug.log(medebug,'Searching for artist',name); discogs.artist.search(name, self.artist.searchResponse, self.artist.abjectFailure); }, searchResponse: function(data) { debug.log(medebug,'Got artist search response', data); if (artistmeta.discogs.triedsearch) { artistmeta.discogs.triedmunge = true; } else { artistmeta.discogs.triedsearch = true; } artistmeta.discogs.possibilities = new Array(); if (data.data.results && data.data.results.length > 0) { for (var i in data.data.results) { if (artistmeta.discogs.triedmunge) { var amatch = mungeArtist(getSearchArtist()); } else { var amatch = getSearchArtist(); } if (compareArtists(data.data.results[i].title, amatch)) { debug.log(medebug,'Found Artist index',i,data.data.results[i].title); artistmeta.discogs.possibilities.push({ name: data.data.results[i].title, link: data.data.results[i].resource_url, image: data.data.results[i].thumb }); } } if (artistmeta.discogs.possibilities.length > 0) { artistmeta.discogs.artistlink = artistmeta.discogs.possibilities[0].link; artistmeta.discogs.currentposs = 0; } } self.artist.populate(); }, artistResponseHandler: function(data) { debug.log(medebug,parent.nowplayingindex,"got artist data",data); if (data) { artistmeta.discogs['artist_'+artistmeta.discogs.artistid] = data; self.artist.doBrowserUpdate(); } else { self.artist.abjectFailure(); artistmeta.videos.youtube = null; } }, abjectFailure: function() { debug.fail(medebug,"Failed to find any artist data"); artistmeta.discogs.artistinfo = {error: language.gettext("discogs_nonsense")}; self.artist.doBrowserUpdate(); }, extraResponseHandler: function(data) { debug.mark(medebug,parent.nowplayingindex,"got extra artist data for",data.id,data); if (data) { artistmeta.discogs[data.id] = data; putArtistData(artistmeta.discogs[data.id], data.id); } }, extraResponseHandler2: function(data) { debug.mark(medebug,parent.nowplayingindex,"got stupidly extra artist data for",data.id,data); if (data) { artistmeta.discogs['artist_'+data.id] = data; if (data.data) { // Fill in any [a123456] or [a=123456] links in the main text body. $('span.artists[name="'+data.data.id+'"]').html(data.data.name); $('span.artists[name="'+data.data.id+'"]').wrap(''); } } }, gotExtraAlbumInfo: function(data) { debug.mark(medebug, 'got extra album info',data); if (data) { artistmeta.discogs['masters_'+data.id] = data; if (data.data) { // Fill in any [m123456] or [m=123456] links in the main text body. $('span.masters[name="'+data.data.id+'"]').html(data.data.title); $('span.masters[name="'+data.data.id+'"]').wrap(''); } } }, gotExtraAlbumInfo2: function(data) { debug.mark(medebug, 'got extra album info',data); if (data) { artistmeta.discogs['releases_'+data.id] = data; if (data.data) { // Fill in any [r123456] or [r=123456] links in the main text body. $('span.releases[name="'+data.data.id+'"]').html(data.data.title); $('span.releases[name="'+data.data.id+'"]').wrap(''); } } }, gotExtraLabelInfo: function(data) { debug.mark(medebug, 'got extra label info',data); if (data) { if (data.data) { // Fill in any [l123456] or [l=123456] links in the main text body. $('span.labels[name="'+data.data.id+'"]').html(data.data.name); $('span.labels[name="'+data.data.id+'"]').wrap(''); } } }, releaseResponseHandler: function(data) { debug.mark(medebug,parent.nowplayingindex,"got release data for",data.id,data); if (data) { artistmeta.discogs[data.id+"_"+data.data.pagination.page] = data; putArtistReleases(artistmeta.discogs[data.id+"_"+data.data.pagination.page], data.id); } }, doBrowserUpdate: function() { if (displaying) { debug.mark(medebug,parent.nowplayingindex,"artist was asked to display"); // Any errors (such as failing to find the artist) go under artistinfo. Originally, this was where the actual artist info would go // too, but then this bright spark had the idea to index all the artist info by the artist ID. This is indeed useful. // But if there was an error in the initial search we don't know the ID. Hence artistinfo still exists and has to be checked. var up = null; if (artistmeta.discogs.artistinfo && artistmeta.discogs.artistinfo.error) { up = { name: artistmeta.name, link: null, data: '

    '+artistmeta.discogs.artistinfo.error+'

    '} } else if (artistmeta.discogs.artistid !== null && artistmeta.discogs['artist_'+artistmeta.discogs.artistid] !== undefined) { up = { name: artistmeta.name, link: artistmeta.discogs['artist_'+artistmeta.discogs.artistid].data.uri, data: getArtistHTML(artistmeta.discogs['artist_'+artistmeta.discogs.artistid], false)} } if (up !== null) { browser.Update( null, 'artist', me, parent.nowplayingindex, up, false, self.artist.force ); } } } } }(); this.album = function() { var retries = 12; return { populate: function() { if (albummeta.discogs.album.error === undefined && albummeta.discogs.album.master === undefined) { if (albummeta.discogs.albumlink === undefined) { debug.shout(medebug,parent.nowplayingindex,"Album asked to populate but no link yet"); retries--; if (retries == 0) { debug.warn(medebug,parent.nowplayingindex,"Album giving up waiting for bloody musicbrainz"); albummeta.discogs.albumlink = null; } else { albumtimer = setTimeout(self.album.populate, 2000); return; } } if (albummeta.discogs.albumlink === null && albummeta.discogs.triedmusicbrainz == false) { debug.fail(medebug,parent.nowplayingindex,"Album asked to populate but no link could be found"); if (albummeta.musicbrainz.album_releasegroupid !== null && albummeta.musicbrainz.album_releasegroupid !== undefined) { debug.mark(medebug,parent.nowplayingindex," ... trying the album release group"); musicbrainz.releasegroup.getInfo( albummeta.musicbrainz.album_releasegroupid, '', self.album.mbRgHandler, self.album.mbRgHandler ); return; } } else if (albummeta.discogs.albumlink !== null) { var b = albummeta.discogs.albumlink.match(/releases*\/(\d+)/); if (b && b[1]) { debug.mark(medebug,parent.nowplayingindex,"Found album release link",b[1]); discogs.album.getInfo( b[1], 'releases/'+b[1], self.album.albumResponseHandler, self.album.albumResponseErrorHandler ); return; } var b = albummeta.discogs.albumlink.match(/masters*\/(\d+)/); if (b && b[1]) { debug.mark(medebug,parent.nowplayingindex,"Found album master link",b[1]); discogs.album.getInfo( b[1], 'masters/'+b[1], self.album.albumResponseHandler, self.album.albumResponseErrorHandler ); return; } } if (albummeta.discogs.triedsearch && albummeta.discogs.triedmunge) { self.album.abjectFailure(); } else { self.album.search(albummeta.discogs.triedsearch ? mungeArtist(getSearchArtistForAlbum()) : getSearchArtistForAlbum()); } } else { debug.mark(medebug,parent.nowplayingindex,"Album is already populated, I think"); } }, search: function(artist) { debug.log(medebug, 'Searching for album',artist,albummeta.name); discogs.album.search(artist, albummeta.name, self.album.searchResponse, self.album.abjectFailure); }, searchResponse: function(data) { debug.log(medebug, 'Got album search results', data); if (albummeta.discogs.triedsearch) { albummeta.discogs.triedmunge = true; } else { albummeta.discogs.triedsearch = true; } if (data.data.results && data.data.results.length > 0) { var best = -1; var besta = 0; find_best_album: { for (var i in data.data.results) { if (data.data.results[i].format && data.data.results[i].master_url) { for (var j in data.data.results[i].format) { if (getSearchArtistForAlbum() == "Various" && data.data.results[i].format[j] == "Compilation") { debug.log(medebug, 'Using Compilation Result'); best = i; break find_best_album; } else if (data.data.results[i].format[j] == 'Album' && besta == 0) { besta = i; } } } } } best = (best >= 0) ? best : besta; albummeta.discogs.albumlink = data.data.results[best].master_url; debug.log(medebug,'Using album search result', best, albummeta.discogs.albumlink); } self.album.populate(); }, albumResponseHandler: function(data) { debug.mark(medebug,parent.nowplayingindex,"Got album data",data); if (data.data.master_id) { // If this key exists, then we have retrieved a release page - this data is useful but we also // want the master release info. (Links that come to us from musicbrainz could be either master or release). // We will only display when we have the master info. Since we can't go back from master to release // then if we got a master link from musicbrainz that's all we're ever going to get. albummeta.discogs.album.release = data; discogs.album.getInfo( '', 'masters/'+data.data.master_id, self.album.albumResponseHandler, self.album.albumResponseErrorHandler ); } else { albummeta.discogs.album.master = data; self.album.doBrowserUpdate(); } }, albumResponseErrorHandler: function(data) { debug.fail(medebug,"Error in album request",data); albummeta.discogs.album.error = data; self.album.doBrowserUpdate(); }, mbRgHandler: function(data) { debug.mark(medebug,parent.nowplayingindex,"got musicbrainz release group data for",parent.playlistinfo.album, data); if (data.error) { debug.fail(medebug,parent.nowplayingindex," ... MB error",data); } else { for (var i in data.relations) { if (data.relations[i].type == "discogs") { debug.mark(medebug,parent.nowplayingindex,"has found a Discogs album link",data.relations[i].url.resource); albummeta.discogs.albumlink = data.relations[i].url.resource; self.album.populate(); return; } } } debug.log(medebug,'No useful info in MB release group data'); albummeta.discogs.triedmusicbrainz = true; self.album.populate(); }, abjectFailure: function() { debug.fail(medebug,"Completely failed to find the album"); albummeta.discogs.album.error = {error: language.gettext("discogs_noalbum")}; self.album.doBrowserUpdate(); }, doBrowserUpdate: function() { if (displaying && albummeta.discogs.album !== undefined && (albummeta.discogs.album.error !== undefined || albummeta.discogs.album.master !== undefined || albummeta.discogs.album.release !== undefined)) { debug.mark(medebug,parent.nowplayingindex,"album was asked to display"); if (parent.playlistinfo.type == 'stream') { browser.Update(null, 'album', me, parent.nowplayingindex, { name: "", link: "", data: null } ); } else { browser.Update( null, 'album', me, parent.nowplayingindex, { name: albummeta.name, link: (albummeta.discogs.album.master === undefined) ? null : albummeta.discogs.album.master.data.uri, data: getAlbumHTML(albummeta.discogs.album, ['master', 'release']) } ); } } }, } }(); this.track = function() { var retries = 15; return { populate: function() { if (trackmeta.discogs.track.error === undefined && trackmeta.discogs.track.master === undefined) { if (trackmeta.discogs.tracklink === undefined) { debug.trace(medebug,parent.nowplayingindex,"Track asked to populate but no link yet"); retries--; if (retries == 0) { debug.warn(medebug,parent.nowplayingindex,"Track giving up on bloody musicbrainz"); trackmeta.discogs.tracklink = null; } else { tracktimer = setTimeout(self.track.populate, 2000); return; } } if (trackmeta.discogs.tracklink === null) { debug.mark(medebug,parent.nowplayingindex,"No track link found by musicbrainz"); } else { var b = trackmeta.discogs.tracklink.match(/releases*\/(\d+)/); if (b && b[1]) { debug.mark(medebug,parent.nowplayingindex,"Track Link is useful - Track is populating",b[1]); discogs.track.getInfo( b[1], 'releases/'+b[1], self.track.trackResponseHandler, self.track.trackResponseErrorHandler ); return; } var b = trackmeta.discogs.tracklink.match(/masters*\/(\d+)/); if (b && b[1]) { debug.mark(medebug,parent.nowplayingindex,"Track Link is useful - Track is populating",b[1]); discogs.track.getInfo( b[1], 'masters/'+b[1], self.track.trackResponseHandler, self.track.trackResponseErrorHandler ); return; } } if (trackmeta.discogs.triedsearch && trackmeta.discogs.triedmunge) { self.track.abjectFailure(); } else { self.track.search(trackmeta.discogs.triedsearch ? mungeArtist(artistmeta.name) : artistmeta.name); } } else { debug.mark(medebug,parent.nowplayingindex,"Track is already populated, probably"); self.artist.populate(); } }, search: function(artist) { debug.log(medebug,'Searching for track',artist,trackmeta.name); discogs.track.search(artist, trackmeta.name, self.track.searchResponse, self.track.abjectFailure); }, searchResponse: function(data) { debug.log(medebug, 'Got track search results', data); if (trackmeta.discogs.triedsearch) { trackmeta.discogs.triedmunge = true; } else { trackmeta.discogs.triedsearch = true; } if (data.data.results && data.data.results.length > 0) { var best = 0; find_best: { for (var i in data.data.results) { if (trackmeta.discogs.triedmunge) { var amatch = mungeArtist(artistmeta.name) } else { var amatch = artistmeta.name.toLowerCase(); } if (data.data.results[i].format && data.data.results[i].resource_url && data.data.results[i].title.toLowerCase() == amatch+' - '+trackmeta.name.toLowerCase()) { debug.log(medebug,'Found Artist - Title match'); for (var j in data.data.results[i].format) { if (data.data.results[i].format[j] == 'Single') { best = i; break find_best; } } } } } trackmeta.discogs.tracklink = data.data.results[best].resource_url; debug.log(medebug,'Using track search result', best, trackmeta.discogs.tracklink); } self.track.populate(); }, trackResponseHandler: function(data) { debug.mark(medebug,parent.nowplayingindex,"Got track data",data); if (data.data.master_id) { // If this key exists, then we have retrieved a release page - this data is useful but we also // want the master release info. (Links that come to us from musicbrainz could be either master or release). // We will only display when we have the master info. Since we can't go back from master to release // then if we got a master link from musicbrainz that's all we're ever going to get. trackmeta.discogs.track.release = data; discogs.track.getInfo( '', 'masters/'+data.data.master_id, self.track.trackResponseHandler, self.track.trackResponseErrorHandler ); } else { trackmeta.discogs.track.master = data; if (artistmeta.discogs.artisturi === undefined) { if (data.data.artists) { for (var i in data.data.artists) { if (compareArtists(data.data.artists[i].name, getSearchArtist())) { debug.log(medebug,'Using artist link from found track',data.data.artists[i].resource_url); artistmeta.discogs.artisturi = data.data.artists[i].resource_url; } } } } self.artist.populate(); self.track.doBrowserUpdate(); } }, trackResponseErrorHandler: function(data) { debug.fail(medebug,"Got error in track request",data); trackmeta.discogs.track.error = data; self.track.doBrowserUpdate(); }, abjectFailure: function() { debug.fail(medebug,"Completely failed to find the track"); trackmeta.discogs.track.error = {error: language.gettext("discogs_notrack")}; self.track.doBrowserUpdate(); self.artist.populate(); }, doBrowserUpdate: function() { if (displaying && trackmeta.discogs.track !== undefined && (trackmeta.discogs.track.error !== undefined || trackmeta.discogs.track.master !== undefined)) { debug.mark(medebug,parent.nowplayingindex,"track was asked to display"); browser.Update( null, 'track', me, parent.nowplayingindex, { name: trackmeta.name, link: (trackmeta.discogs.track.master === undefined) ? null : trackmeta.discogs.track.master.data.uri, data: getAlbumHTML(trackmeta.discogs.track, ['master', 'release']) } ); } }, } }(); } } }(); nowplaying.registerPlugin("discogs", info_discogs, "icon-discogs", "button_discogs");