1 Components.utils.import(
"resource://gre/modules/XPCOMUtils.jsm");
2 Components.utils.import(
"resource://app/jsmodules/sbLibraryUtils.jsm");
3 Components.utils.import(
"resource://app/jsmodules/sbProperties.jsm");
5 const Cc = Components.classes;
6 const Ci = Components.interfaces;
7 const Cr = Components.results;
8 var
JSON =
Cc[
"@mozilla.org/dom/json;1"].createInstance(
Ci.nsIJSON);
10 const DESCRIPTION =
"mashTape Provider: UberMash Artist Info Provider";
11 const CID =
"{7792e470-75ec-11dd-ad8b-0800200c9a66}";
12 const CONTRACTID =
"@songbirdnest.com/mashTape/provider/info/UberMash;1";
16 this.wrappedJSObject =
this;
17 Components.utils.import(
"resource://mashtape/mtUtils.jsm");
19 if (typeof(
language) ==
"undefined") {
21 var prefBranch =
Cc[
"@mozilla.org/preferences-service;1"]
22 .getService(
Ci.nsIPrefService).getBranch(
"general.");
23 var locale = prefBranch.getCharPref(
"useragent.locale");
28 mtUtils.log(
"Info",
"language set to " +
language);
34 "Musicmoz":
"MusicMoz",
36 "Wikipedia":
"Wikipedia",
37 "OfficialHomepage":
"Homepage",
41 "Purevolume":
"PureVolume"
46 var
strings = Components.classes[
"@mozilla.org/intl/stringbundle;1"]
47 .getService(Components.interfaces.nsIStringBundleService)
48 .createBundle(
"chrome://mashtape/locale/mashtape.properties");
51 .getService(
Ci.fuelIApplication);
59 Ci.sbIMashTapeProvider]),
61 providerName:
"Last.fm + MusicBrainz + Freebase",
64 providerIconBio :
"chrome://mashtape/content/tabs/lastfm.png",
65 providerIconDiscography:
"chrome://mashtape/content/tabs/musicbrainz.png",
66 providerIconMembers:
"chrome://mashtape/content/tabs/freebase.png",
67 providerIconTags:
"chrome://mashtape/content/tabs/lastfm.png",
68 providerIconLinks:
"chrome://mashtape/content/tabs/musicbrainz.png",
72 var bioReq =
Cc[
"@mozilla.org/xmlextras/xmlhttprequest;1"]
73 .createInstance(
Ci.nsIXMLHttpRequest);
74 var
url =
"http://ws.audioscrobbler.com/2.0/?method=artist.getinfo" +
75 "&api_key=ad68d3b69dee88a912b193a35d235a5b" +
77 var prefBranch =
Cc[
"@mozilla.org/preferences-service;1"]
78 .getService(
Ci.nsIPrefService).getBranch(
"extensions.mashTape.");
79 var autolocalise = prefBranch.getBoolPref(
"info.autolocalise");
80 if (autolocalise && language)
82 mtUtils.log(
"Info",
"Last.FM Bio URL: " + url);
83 bioReq.open(
"GET", url,
true);
84 bioReq.onreadystatechange =
function(ev) {
85 return function(artistName, updateFn) {
86 if (bioReq.readyState != 4)
88 if (bioReq.status == 200) {
89 var xmlText = bioReq.responseText.replace(
90 /<\?xml
version=
"1.0" encoding=
"[uU][tT][fF]-8"\?>/,
92 var x =
new XML(xmlText);
96 for each (var img
in x.artist.image) {
97 if (img.@size.toString() ===
"small") {
99 }
else if (img.@size.toString() ===
"large") {
101 }
else if (img.@size.toString() ===
"medium") {
106 bio.provider =
"Last.fm";
107 bio.bioUrl =
"http://www.last.fm/music/" + artistName;
108 bio.bioEditUrl =
"http://www.last.fm/music/" +
109 artistName +
"/+wiki/edit";
110 var bioContent =x.artist.bio.content.toString().split(
"\n");
111 if (bioContent.length == 0 ||
112 (x.artist.bio.content.toString() ==
""))
115 updateFn.wrappedJSObject.update(
CONTRACTID, bio,
"bio");
121 while (bioContent[bioContent.length-1].match(/^\s*$/))
123 bio.bioText =
"<p>" + bioContent.join(
"</p><p>") +
"</p>";
124 bio.bioText = bio.bioText.replace(/http:\/\/ws.audioscrobbler.com/g,
'http://last.fm');
126 updateFn.wrappedJSObject.update(
CONTRACTID, bio,
"bio");
127 updateFn.wrappedJSObject.update(
CONTRACTID, imgUrl,
"photo");
134 var tagsReq =
Cc[
"@mozilla.org/xmlextras/xmlhttprequest;1"]
135 .createInstance(
Ci.nsIXMLHttpRequest);
136 var url =
"http://ws.audioscrobbler.com/1.0/artist/" +
137 escape(
artist) +
"/toptags.xml";
138 mtUtils.log(
"Info",
"Last.FM Tags URL: " + url);
139 tagsReq.open(
"GET", url,
true);
142 tagsReq.onreadystatechange =
function() {
143 if (this.readyState != 4)
145 if (this.status == 200) {
146 var xmlText = this.responseText.replace(
147 /<\?xml
version=
"1.0" encoding=
"[uU][tT][fF]-8"\?>/,
149 var x =
new XML(xmlText);
151 var
data =
new Object;
152 data.provider =
"Last.fm";
153 data.url =
"http://www.last.fm/music/" +
155 data.tags =
new Array();
156 for each (var
tag in x..tag) {
164 if (
data.tags.length == 0) {
165 this.updateFn.wrappedJSObject.update(
CONTRACTID,
178 triggerFreebase:
function(
artist, updateFn) {
179 var req =
Cc[
"@mozilla.org/xmlextras/xmlhttprequest;1"]
180 .createInstance(
Ci.nsIXMLHttpRequest);
182 var
url =
'http://www.freebase.com/api/service/mqlread?queries={' +
183 '"qDiscography":{"query":[{"album":[{"id":null,"name":null,"release_date":null}],"id":null,"name":"' + (
artist) +
'","type":"/music/artist"}]},' +
184 '"qMembers":{"query":[{"member":[{"*":null}],"name":"' + (
artist) +
'","type":"/music/musical_group"}]},' +
185 '"qArticle":{"query":[{"/common/topic/article":[{"*":null}],"name":"' + (
artist) +
'","type":"/music/artist"}]},' +
186 '"qImages":{"query":[{"/common/topic/image":[{"*":null}],"name":"' + (
artist) +
'","type":"/music/artist"}]},' +
187 '"qLinks":{"query":[{"/common/topic/webpage":[{"*":null}],"name":"' + (
artist) +
'","type":"/music/artist"}]}' +
189 mtUtils.log(
"Info",
"Freebase URL: " + url);
190 req.open(
"GET", url,
true);
191 req.updateFn = updateFn;
192 req.onreadystatechange =
function() {
193 if (this.readyState != 4)
195 if (this.status == 200) {
196 var results = JSON.decode(this.responseText);
198 if (typeof(results.qMembers.result) ==
'undefined' ||
199 results.qMembers.result.length == 0)
202 this.updateFn.wrappedJSObject.update(
CONTRACTID,
205 var
data =
new Object;
206 data.provider =
"Freebase";
207 data.url =
"http://www.freebase.com";
208 data.members =
new Array();
209 if (typeof(results.qMembers.result[0].member) !=
212 var members = results.qMembers.result[0].member;
213 for (var
i in members)
214 data.members.push(members[
i].member);
216 this.updateFn.wrappedJSObject.update(
CONTRACTID,
224 triggerMusicBrainz:
function(
artist, updateFn) {
226 var req =
Cc[
"@mozilla.org/xmlextras/xmlhttprequest;1"]
227 .createInstance(
Ci.nsIXMLHttpRequest);
229 "http://musicbrainz.org/ws/1/artist/?type=xml&inc=sa-Album&query=";
230 mtUtils.log(
"Info",
"MusicBrainz URL: " + url +
232 req.open(
"GET", url +
artist,
true);
233 req.updateFn = updateFn;
234 req.onreadystatechange =
function() {
235 if (this.readyState != 4)
237 if (this.status == 200) {
238 var xmlText = this.responseText.replace(
239 /<\?xml
version=
"1.0" encoding=
"[uU][tT][fF]-8"\?>/,
241 var x =
new XML(xmlText);
243 var mbns =
new Namespace(
'http://musicbrainz.org/ns/mmd-1.0#');
244 var extns =
new Namespace(
'http://musicbrainz.org/ns/ext-1.0#');
247 this.updateFn.wrappedJSObject.update(
CONTRACTID,
253 mtUtils.log(
"Info",
"MBID: " + mbId);
255 var req =
Cc[
"@mozilla.org/xmlextras/xmlhttprequest;1"]
256 .createInstance(
Ci.nsIXMLHttpRequest);
257 var url =
"http://musicbrainz.org/ws/1/artist/" + mbId +
258 "?type=xml&inc=url-rels";
259 req.open(
"GET", url,
true);
260 req.updateFn = updateFn;
262 req.onreadystatechange =
function() {
263 if (this.readyState != 4)
265 if (this.status != 200)
267 var xmlText = this.responseText.replace(
268 /<\?xml
version=
"1.0" encoding=
"[uU][tT][fF]-8"\?>/,
270 var x =
new XML(xmlText);
272 new Namespace(
'http://musicbrainz.org/ns/mmd-1.0#');
274 var
data =
new Object;
275 data.provider =
"MusicBrainz";
276 data.url =
"http://www.musicbrainz.org/artist/" + this.mbId;
277 data.links =
new Array();
278 if (x..mbns::relation.length() == 0) {
279 this.updateFn.wrappedJSObject.update(
CONTRACTID,
283 for each (var link
in x..mbns::relation) {
284 var type = link.@type.toString();
285 var url = link.@
target.toString();
288 if (typeof(linkMap[type]) !=
'undefined')
289 name = linkMap[type];
292 if (type ==
"Wikipedia") {
293 var country = url.substr(7,2);
294 name +=
" (" + country +
")";
296 data.links.push({name:
name, url:url});
302 this.updateFn.wrappedJSObject.update(
CONTRACTID,
311 var req =
Cc[
"@mozilla.org/xmlextras/xmlhttprequest;1"]
312 .createInstance(
Ci.nsIXMLHttpRequest);
313 var url =
"http://musicbrainz.org/ws/1/release/?type=xml" +
314 "&artist=" +
artist +
"&releasetypes=Album+Official&limit=100";
315 mtUtils.log(
"Info",
"MusicBrainz Discography URL: " + url);
316 req.open(
"GET", url,
true);
317 req.updateFn = updateFn;
318 req.albumMetadata = this.getAlbumMetadata;
320 req.onreadystatechange =
function() {
321 if (this.readyState != 4)
323 if (this.status == 200) {
324 var xmlText = this.responseText.replace(
325 /<\?xml
version=
"1.0" encoding=
"[uU][tT][fF]-8"\?>/,
327 var x =
new XML(xmlText);
328 var mbns =
new Namespace(
'http://musicbrainz.org/ns/mmd-1.0#');
329 var
data =
new Object;
330 if (x..mbns::release.length() == 0) {
331 this.updateFn.wrappedJSObject.update(
CONTRACTID,
332 null,
"discography");
335 for each (var release
in x..mbns::release) {
339 var releaseDate =
"9999";
340 var usRelease =
false;
342 if (event.@country.toUpperCase() ==
"US")
344 if (event.@
date.toString() < releaseDate) {
345 releaseDate =
event.@
date.toString();
348 if (releaseDate ==
"" || releaseDate ==
"9999")
352 var disableAmazon = Application.prefs.getValue(
353 "extensions.mashTape.info.amazonstore.disabled",
355 var asin = release.mbns::asin.toString();
358 if (!disableAmazon && asin !=
"") {
359 link =
"http://www.amazon.com/gp/product/" + asin;
360 tooltip = strings.GetStringFromName(
361 "extensions.mashTape.info.amazon");
366 var title = release.mbns::title.toString();
370 asin: release.mbns::asin.toString(),
372 release_date: releaseDate,
373 artistMbid: release.mbns::artist.@
id.toString(),
374 artistName: release.mbns::artist.mbns::name.toString(),
381 if (typeof(
data[title]) !=
"undefined" && !usRelease)
390 for (var
i in
data) {
391 if (typeof(data[
i]) ==
"object") {
393 this.albumMetadata(i, data, this.updateFn);
401 getAlbumMetadata :
function(
i,
data, updateFn) {
402 var
url =
"http://ws.audioscrobbler.com/2.0/?method=album.getinfo" +
403 "&api_key=ad68d3b69dee88a912b193a35d235a5b" +
404 "&mbid=" + data[
i].mbid;
405 var req =
Cc[
"@mozilla.org/xmlextras/xmlhttprequest;1"]
406 .createInstance(
Ci.nsIXMLHttpRequest);
407 mtUtils.log(
"Info",
"Last.fm Album URL: " + url);
408 req.open(
"GET", url,
true);
409 req.updateFn = updateFn;
412 req.onreadystatechange =
function() {
413 if (this.readyState != 4)
415 if (this.status == 200) {
416 var xmlText = req.responseText.replace(
417 /<\?xml
version=
"1.0" encoding=
"[uU][tT][fF]-8"\?>/,
"");
418 mtUtils.log(
"Info",
"albumMetadata: " +
419 this.data[this.
i].mbid +
" complete! " +
420 this.data.pending +
" left.");
421 var x =
new XML(xmlText);
422 var url = x.album.url.toString();
424 this.data[this.
i].link =
url;
425 this.data[this.
i].tooltip = strings.GetStringFromName(
426 "extensions.mashTape.info.lastfm");
429 for each (var image
in x..image) {
430 if (image.@size.toString() ==
"medium")
431 artwork = image.toString();
433 this.data[this.
i].artwork = artwork;
436 if (this.data.pending == 0) {
437 var results =
new Object;
438 results.discography =
new Array();
440 for each (var item
in this.data) {
441 if (typeof(item) ==
"object") {
442 if (item.artistName ==
this.data.artist)
443 mbId = item.artistMbid;
444 results.discography.push(item);
448 if (results.length == 0)
449 this.updateFn.wrappedJSObject.update(
CONTRACTID,
450 null,
"discography");
452 results.provider =
"MusicBrainz";
453 results.url =
"http://www.musicbrainz.org/artist/" + mbId;
454 this.updateFn.wrappedJSObject.update(
CONTRACTID,
455 results,
"discography");
462 query:
function(
artist, updateFn) {
463 this.triggerLastFM(
artist, updateFn);
464 this.triggerFreebase(
artist, updateFn);
465 this.triggerMusicBrainz(
artist, updateFn);
471 return XPCOMUtils.generateModule([
ArtistInfo]);
nsString encodeURIComponent(const nsString &c)
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
sbOSDControlService prototype QueryInterface
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
var getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('Songbird SBProperties artist
sbDeviceFirmwareAutoCheckForUpdate prototype classID
dataSBGenres SBProperties tag
_getSelectedPageStyle s i
function NSGetModule(compMgr, fileSpec)