Hello everyone!
A new gPodder release is out so it's time to start adding features ;)
If you have a player that is capable of running the Rockbox firmware[1] you
can enable logging everything you play to an audioscrobbler portable player
format logfile[2]. (Go to: Settings-->General Settings-->Playback-->Last.fm
Log and set it to "Yes")
I wrote a patch that is able to use this logfile to mark episodes that you've
listened to as played in gPodder while you're syncing. For this to work you
must be using gPodder's tag update feature (set update_tags to True) because
the audioscrobbler logfile only reports the metadata of the tracks you've
listened to not an actual filename.
In Rockbox the audioscrobbler logfile is named .scrobbler.log and is stored in
the root directory of the player. The code is able to find the root directory
of the player (its mount point) and from there it searches for the logfile
using os.walk(). If other players support this type of logging it would be as
trivial as adding the filename they use to the list and everything
should "just work"(tm).
To enable this feature apply the attached patch and set "use_scrobbler_log" to
True in the gPodder config editor. It might not work for files you've
downloaded before enabling the "update_tags" feature. (Maybe once you enable
use_scrobbler_log gPodder should check to see if update_tags is enabled...)
Let me know what you think,
nick
[1] http://www.rockbox.org
[2] http://www.audioscrobbler.net/wiki/Portable_Player_Logging
Index: src/gpodder/config.py
===================================================================
--- src/gpodder/config.py (revision 635)
+++ src/gpodder/config.py (working copy)
@@ -97,6 +97,7 @@
'on_quit_systray': (bool, False),
'create_m3u_playlists': (bool, False),
'max_episodes_per_feed': (int, 200),
+ 'use_scrobbler_log': (bool, False),
# Window and paned positions
'main_window_x': ( int, 100 ),
Index: src/gpodder/sync.py
===================================================================
--- src/gpodder/sync.py (revision 635)
+++ src/gpodder/sync.py (working copy)
@@ -408,15 +408,23 @@
self.destination = gl.config.mp3_player_folder
self.buffer_size = 1024*1024 # 1 MiB
+ self.scrobbler_log = []
def open(self):
self.notify('status', _('Opening MP3 player'))
if util.directory_is_writable(self.destination):
self.notify('status', _('MP3 player opened'))
+ # if different players use other filenames besides
+ # .scrobbler.log, add them to this list
+ scrobbler_log_filenames = ['.scrobbler.log']
+ if gl.config.use_scrobbler_log:
+ log_location = self.find_scrobbler_log(self.find_mount_point(), scrobbler_log_filenames)
+ if os.path.isfile(log_location) and self.load_audioscrobbler_log(log_location):
+ log('Using scrobbler.log data to mark tracks as played', sender=self)
return True
else:
return False
-
+
def add_track(self, episode):
self.notify('status', _('Adding %s') % episode.title)
@@ -459,6 +467,11 @@
log('Cannot create folder on MP3 player: %s', folder, sender=self)
return False
+ if ( gl.config.use_scrobbler_log and not episode.is_played()
+ and [ episode.channel.title, episode.title ] in self.scrobbler_log ):
+ log('Marking "%s" from "%s" as played' % (episode.title, episode.channel.title), sender=self)
+ gl.history_mark_played(episode.url)
+
if not os.path.exists(to_file):
log('Copying %s => %s', os.path.basename(from_file), to_file.decode(self.enc), sender=self)
return self.copy_file_progress(from_file, to_file)
@@ -545,3 +558,44 @@
dotfiles = glob.glob(os.path.join(directory, '.*'))
return len(files+dotfiles) == 0
+ def find_mount_point(self):
+ """ If possible, find the mountpoint of the device using self.destination """
+ sync_dir = self.destination
+ while os.path.split(sync_dir)[0] != '/':
+ if os.path.ismount(sync_dir):
+ return sync_dir
+ else:
+ sync_dir = os.path.split(sync_dir)[0]
+ return ''
+
+ def find_scrobbler_log(self, mount_point, log_filenames):
+ """ find an audioscrobbler log file from log_filenames in the mount_point dir """
+ for i in os.walk(mount_point):
+ for log_file in log_filenames:
+ if log_file in i[2]:
+ return os.path.join(i[0], log_file)
+ return ''
+
+ def load_audioscrobbler_log(self, log_file):
+ """ Retrive track title and artist info for all the entries
+ in an audioscrobbler portable player format logfile
+ http://www.audioscrobbler.net/wiki/Portable_Player_Logging """
+ try:
+ log('Opening %s as AudioScrobbler log.' % log_file, sender=self)
+ f = open(log_file, 'r')
+ entries = f.readlines()
+ f.close()
+ except IOError, ioerror:
+ log('Error, file %s cannot be read.' % log_file, sender=self)
+ return False
+
+ # regex that can be used to get all the data from a scrobbler.log entry
+ entry_re = re.compile('^(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)$')
+ for entry in entries:
+ match_obj = re.match(entry_re, entry)
+ # L means at least 50% of the track was listened to (S means < 50%)
+ if match_obj and match_obj.group(6).strip().lower() == 'l':
+ # append [artist_name, track_name]
+ self.scrobbler_log.append([match_obj.group(1), match_obj.group(3)])
+
+ return True
_______________________________________________
gpodder-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/gpodder-devel