public
Description: A Last.fm scrobbling addon for Songbird
Homepage: http://getsongbird.com/
Clone URL: git://github.com/ianloic/songbird-lastfm.git
try scrobbling using the playback history service
ianloic (author)
Tue Jul 08 12:39:43 -0700 2008
commit  dd559a5017e0fe02e05c024fcba78e6a9e948a83
tree    3af8f19d4ae4af3395297ce009958fb08921671b
parent  cce05aea00fd5dd16ca08683d7d9353581dbe025
...
5
6
7
 
 
 
 
8
9
10
...
23
24
25
26
 
27
28
29
...
164
165
166
167
168
169
170
 
171
172
173
 
 
174
175
176
...
178
179
180
181
 
182
183
184
...
436
437
438
 
 
439
440
441
442
443
444
445
446
447
 
 
 
 
 
448
449
450
 
 
 
 
 
 
 
 
451
 
 
 
 
 
 
 
 
 
452
453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
455
456
457
458
459
460
 
 
 
461
462
463
464
465
466
467
468
 
 
 
 
 
 
 
469
470
471
...
5
6
7
8
9
10
11
12
13
14
...
27
28
29
 
30
31
32
33
...
168
169
170
 
 
 
 
171
172
173
174
175
176
177
178
179
...
181
182
183
 
184
185
186
187
...
439
440
441
442
443
444
445
446
 
 
 
 
 
 
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
 
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
 
 
 
 
 
 
497
498
499
500
 
 
 
 
 
 
 
501
502
503
504
505
506
507
508
509
510
0
@@ -5,6 +5,10 @@ const Ci = Components.interfaces;
0
 const Cr = Components.results;
0
 const Cu = Components.utils;
0
 
0
+// our annotations
0
+const ANNOTATION_SCROBBLED = 'http://www.songbirdnest.com/lastfm#scrobbled';
0
+const ANNOTATION_HIDDEN = 'http://www.songbirdnest.com/lastfm#hidden';
0
+
0
 // import the XPCOM helper
0
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
0
 
0
@@ -23,7 +27,7 @@ const LOGIN_FIELD_PASSWORD = 'password';
0
 
0
 // helper for enumerating enumerators. duh.
0
 function enumerate(enumerator, func) {
0
- while(enumerator.hasMoreEntries()) {
0
+ while(enumerator.hasMoreElements()) {
0
     try {
0
       func(enumerator.getNext());
0
     } catch(e) {
0
@@ -164,13 +168,12 @@ function sbLastFm() {
0
     this.listeners.each(function(l) { l.onShouldScrobbleChanged(val); });
0
   });
0
 
0
- // add ourselves as a playlist playback listener
0
- Cc['@songbirdnest.com/Songbird/PlaylistPlayback;1']
0
- .getService(Ci.sbIPlaylistPlayback).addListener(this);
0
-
0
+ // get the playback history service
0
   this._playbackHistory =
0
       Cc['@songbirdnest.com/Songbird/PlaybackHistoryService;1']
0
       .getService(Ci.sbIPlaybackHistoryService);
0
+ // add ourselves as a playlist history listener
0
+ this._playbackHistory.addListener(this);
0
 }
0
 // XPCOM Magic
0
 sbLastFm.prototype.classDescription = 'Songbird Last.fm Service'
0
@@ -178,7 +181,7 @@ sbLastFm.prototype.contractID = '@songbirdnest.com/lastfm;1';
0
 sbLastFm.prototype.classID =
0
     Components.ID('13bc0c9e-5c37-4528-bcf0-5fe37fcdc37a');
0
 sbLastFm.prototype.QueryInterface =
0
- XPCOMUtils.generateQI([Components.interfaces.sbIPlaylistPlaybackListener]);
0
+ XPCOMUtils.generateQI([Components.interfaces.sbIPlaybackHistoryListener]);
0
 
0
 // failure handling
0
 sbLastFm.prototype.hardFailure =
0
@@ -436,36 +439,72 @@ function sbLastFm_post(url, body, success, hardfailure, badsession) {
0
   xhr.open('POST', url, true);
0
   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
0
   xhr.send(body);
0
+ dump('POSTed: '+body+'\n');
0
+ dump('to: '+url+'\n');
0
 }
0
 
0
 
0
-// sbIPlaylistPlaybackListener
0
-sbLastFm.prototype.onStop = function sbLastFm_onStop() {
0
- try {
0
- dump('sbLastFm.onStop()\n');
0
- dump('entries: '+this._playbackHistory.entries+'\n');
0
- dump('entries.hasMoreElements(): '+this._playbackHistory.entries.hasMoreElements()+'\n');
0
+// sbIPlaybackHistoryListener
0
+sbLastFm.prototype.onEntriesAdded =
0
+function sbLastFm_onEntriesAdded(aEntries) {
0
+ dump('\n\n\n!!!!!! onEntriesAdded\n\n\n');
0
+ var entry_list = [];
0
   enumerate(this._playbackHistory.entries,
0
             function(e) {
0
               e.QueryInterface(Ci.sbIPlaybackHistoryEntry);
0
+ function checkAnnotation(id) {
0
+ try {
0
+ e.annotations.getPropertyValue(id);
0
+ return true;
0
+ } catch(e) {
0
+ return false;
0
+ }
0
+ }
0
               dump(' history entry: '+e+'\n');
0
+ dump(' trackName: '+e.item.getProperty(SBProperties.trackName)+'\n');
0
+ dump(' scrobbled: '+checkAnnotation(ANNOTATION_SCROBBLED)+'\n');
0
+ dump(' hidden: '+checkAnnotation(ANNOTATION_HIDDEN)+'\n');
0
+ dump(' timestamp: '+e.timestamp+'\n');
0
+ if (!checkAnnotation(ANNOTATION_SCROBBLED) &&
0
+ !checkAnnotation(ANNOTATION_HIDDEN)) {
0
+ dump('scrobble this\n');
0
+ entry_list.push(e);
0
+ }
0
             });
0
- } catch(e) { Cu.reportError(e); }
0
+
0
+ // create the scrobble list in the reverse order
0
+ var scrobble_list = [];
0
+ if (entry_list.length > 0) {
0
+ for (var i=entry_list.length-1; i>=0; i--) {
0
+ scrobble_list.push(
0
+ new PlayedTrack(entry_list[i].item,
0
+ Math.round(entry_list[i].timestamp/1000)));
0
+ }
0
+ this.submit(scrobble_list, function success() {
0
+ // on success mark all these as scrobbled
0
+ dump('entry_list: '+entry_list.toSource()+'\n');
0
+ for (i=0; i<entry_list.length; i++) {
0
+ dump('el['+i+']='+entry_list[i]+'\n');
0
+ var annotations = entry_list[i].annotations;
0
+ annotations.QueryInterface(Ci.sbIMutablePropertyArray);
0
+ annotations.appendProperty(ANNOTATION_SCROBBLED, 'true');
0
+ }
0
+ }, function failure() {
0
+ dump('FAILURE\n');
0
+ });
0
+ }
0
 }
0
-sbLastFm.prototype.onBeforeTrackChange =
0
-function sbLastFm_onBeforeTrackChange(aItem, aView, aIndex) {
0
- dump('sbLastFm.onBeforeTrackChange('+aItem+')\n');
0
- var timestamp = Math.round(Date.now()/1000).toString();
0
- this.submit([new PlayedTrack(aItem, timestamp)],
0
- function() { }, function() { });
0
+sbLastFm.prototype.onEntriesUpdated =
0
+function sbLastFm_onEntriesUpdated(aEntries) {
0
+
0
 }
0
-sbLastFm.prototype.onTrackChange =
0
-function sbLastFm_onTrackChange(aItem, aView, aIndex) {
0
- dump('sbLastFm.onTrackChange('+aItem+')\n');
0
- // ugh - we need to add our own entries to the history service now
0
- // this will go away once Aus is done
0
- this._playbackHistory.createEntry(aItem, (new Date()).getTime(), 1000, null);
0
- dump('added a history entry\n');
0
+sbLastFm.prototype.onEntriesRemoved =
0
+function sbLastFm_onEntriesRemoved(aEntries) {
0
+
0
+}
0
+sbLastFm.prototype.onEntriesCleared =
0
+function sbLastFm_onEntriesCleared() {
0
+
0
 }
0
 
0
 

Comments

    No one has commented yet.