GNOME Bugzilla – Bug 334488
last.fm submission for ipod songs
Last modified: 2007-08-22 08:08:42 UTC
Since the songs on an ipod can now be read without problem with libgpod, it would be cool if rhythmbox would submit the recently played tracks on the ipod to last.fm (if last.fm submitting is active) too. It could just submit the songs played since rb has last seen the ipod. Or maybe someone knows how the mac itunes plugin decides what songs to submit.
The iPod has two fields for play count, one for "playcount since last sync" and the other one for "total playcount" (or "playcount when the ipod was last synced"), I guess the mac itunes plugin uses that.
*** Bug 346495 has been marked as a duplicate of this bug. ***
iPodScrobbler.py uses file "iPod_Control/iTunes/Play Counts". Here is what to do with "Play Counts" file according to iPodScrobbler.py: # bigstring contains the whole file "Play Counts" # the record structure is as follows: # a file header contains info about the list of items # it has n number of entries all of the same length # read the header if bigstring[:4]=='mhdp': headerformat = '<4sLLL' header_bytes=struct.calcsize(headerformat) (headID, headLen, entryLen, numEntries)=struct.unpack(headerformat,bigstring[:header_bytes]) else: sys.stderr.write('Error: file \"'+playCountsFilename+'\" is not a valid Play Counts file.\n') return playcountsdict # do a length/size sanity check of the Play Counts file first if len(bigstring) != (headLen+(entryLen*numEntries)): sys.stderr.write('Error: Play Counts file \"'+playCountsFilename+'\" has corrupt length info.\n') return playcountsdict else: # entry format and size varies depending on iPod Firmware version fieldformat = '' pad_bytes = 0 if entryLen == 16: fieldformat = '<LLLL' elif entryLen == 20: fieldformat = '<LLLL4s' elif entryLen>20: pad_bytes=entryLen-16 fieldformat = '<LLLL'+str(pad_bytes)+'s' else: pad_bytes=entryLen-12 fieldformat = '<LLL'+str(pad_bytes)+'s' playcount=0 lastplayed=0 for i in range(numEntries): offset = headLen + (i * entryLen) rating=0 bookmark=0 if entryLen == 16: (playcount,lastplayed,bookmark,rating) = struct.unpack(fieldformat, bigstring[offset:offset+en elif entryLen == 20: (playcount,lastplayed,bookmark,rating,unknown) = struct.unpack(fieldformat, bigstring[offset:o elif entryLen>20: (playcount,lastplayed,bookmark,rating,unknown) = struct.unpack(fieldformat, bigstring[offset:o else: (playcount,lastplayed,unknown) = struct.unpack(fieldformat, bigstring[offset:offset+entryLen]) if verbose>2: sys.stdout.write(str(i)+': playcount:'+str(playcount)+' lastplayed:'+str(lastplayed+iPodDateOf playcountsdict[i]=(playcount,lastplayed,rating/20) if verbose>2: sys.stdout.write('Play Counts file entry length is:'+str(entryLen)+' bytes.\n') if verbose>0: sys.stdout.write('Play counts file contains '+str(len(playcountsdict))+' entries.\n') return playcountsdict
Created attachment 80604 [details] [review] ipod patch So I played a bit with this bug. This patch is obviously not qualified to get into any SCM. An important missing piece is how to limit tracks for submitting (iPodScrobbler may use last played time, but that's an option). Now we need a way to feed this to audioscrobbler plugin. (I fed it manually by appending stdout to audioscrobbler.queue). And we may need to load audioscrobbler plugin before ipod plugin but not submit anything right after startup. Or we may move the code to audioscrobbler plugin.. (maybe either make audioscrobbler plugin directly link to libgpod or request ipod plugin to provide playcounts). Anyone is welcome to improve (or rewrite) the patch as I likely have no time for this in the moment.
Created attachment 86077 [details] [review] Work in progress patch Here is a work in progress patch which is not meant to be included in svn trunk for now, I post it to let people now I'm working on it. The major pieces are in place, ie the ipod plugin emits rb:offlinePlay signals for each song that was read on the iPod since last sync, and the audioscrobbler plugin does what is has to do upon receiving that signal. I moved around some code in the audioscrobbler plugin to make it more readable/make those changes easier, this unfortunately makes the diff bigger and thus less readable :-/ A few missing things that comes to mind: * if a song has been submitted to last.fm which is more recent than the time the songs on the ipod were played, the ipod songs will be dropped by last.fm * if a song has been played several times offline, only the most recent play will be sent to last.fm * nothing is done to make sure the audioscrobbler plugin is loaded before the ipod plugin. If the ipod plugin is loaded first and emits its rb:offlinePlay signals before the audioscrobbler plugin starts, nothing will be sent to last.fm * the data on the ipod about recently played files isn't cleared after being processed, so the if you unplug/replug the ipod, the same data will be sent again
This patch needs work after the landing of the async iPod database saving in trunk. It has also to be adapted for various rb-audioscrobbler changes
Created attachment 89569 [details] [review] Patch against svn trunk
Comment on attachment 89569 [details] [review] Patch against svn trunk This patch makes too many changes to rb-audioscrobbler.c, some of which are unnecessary, I hope I didn't screw up while merging that patch with trunk
(In reply to comment #5) > > * if a song has been submitted to last.fm which is more recent than the time > the songs on the ipod were played, the ipod songs will be dropped by last.fm > * if a song has been played several times offline, only the most recent play > will be sent to last.fm => Those 2 items should be much easier to fix with the 1.2 audioscrobbler protocol, I'd tend to punt them for now (which means people must sync their iPod with last.fm before starting to play any other song with rb) > * nothing is done to make sure the audioscrobbler plugin is loaded before the > ipod plugin. If the ipod plugin is loaded first and emits its rb:offlinePlay > signals before the audioscrobbler plugin starts, nothing will be sent to > last.fm => this still needs to be fixed > * the data on the ipod about recently played files isn't cleared after being > processed, so the if you unplug/replug the ipod, the same data will be sent > again > => the PlayCounts file is removed after having been read, so this should be fixed
I committed the latest patch to svn.
I opened bug #464451 to keep track of the known limitations, closing that one.
Reading the rhythmbox ChangeLog, it seems this feature was added in the latest 0.11.2 version. Unfortunately, it seems it is not working yet. Opening rhythmbox and going to the plugin configuration, it is shown that some tracks were send to the last.fm server. Those tracks never show up there. Also, because the plugin "cleans up" the Play Count file, there is no way to use another program to submit those played tracks.
Which iPod model ? Does last.fm display a box saying spam protection triggered or something ?
It is a fifth generation video ipod. There is no "spam protection" message or anything.