[Assorted-commits] SF.net SVN: assorted:[1392] music-labeler/trunk/src/ml.py
Brought to you by:
yangzhang
From: <yan...@us...> - 2009-05-07 07:16:08
|
Revision: 1392 http://assorted.svn.sourceforge.net/assorted/?rev=1392&view=rev Author: yangzhang Date: 2009-05-07 07:16:07 +0000 (Thu, 07 May 2009) Log Message: ----------- - added pylast api support to show top tags on last.fm - added thread-safe callbacks to enable asynchronous calls from helper threads into the blocking pylast api - fixed show_popup to be connected to configure-event - fixed dir of skipping forward/backward in the music - fixed scrolling Modified Paths: -------------- music-labeler/trunk/src/ml.py Modified: music-labeler/trunk/src/ml.py =================================================================== --- music-labeler/trunk/src/ml.py 2009-05-07 07:16:03 UTC (rev 1391) +++ music-labeler/trunk/src/ml.py 2009-05-07 07:16:07 UTC (rev 1392) @@ -2,18 +2,17 @@ from __future__ import with_statement from gtk import * -from cgi import escape from cStringIO import StringIO -import itertools, gst, urllib +import itertools, gst, urllib, cgi, collections, pylast, contextlib import gtk.keysyms as k, gtk.gdk as gdk -from os.path import expanduser from path import path -from collections import defaultdict +# Last.FM administrivia +lastfm_apikey = '3222517b613ce7a7091f1aff29edd67a' + # Quod Libet messiness. sys.path.append('/usr/share/quodlibet/') -import util -import formats +import util, formats util.gettext_install() from browsers.playlists import Playlist quote, unquote = Playlist.quote, Playlist.unquote @@ -24,7 +23,7 @@ def debug(*args): if do_debug: print ' '.join(map(str,args)) -cap = 50 +cap = 30 def trunc(s): s = str(s) return s[:cap] + '...' if len(s) > cap else s @@ -33,6 +32,12 @@ # GTK+ helpers. +...@co...ntextmanager +def gdksync(): + gdk.threads_enter() + try: yield + finally: gdk.threads_leave() + def connecting(widget, signal): def wrapper(handler): widget.connect(signal, handler) @@ -48,6 +53,8 @@ # Main GUI layer. def labeler(pls, labels, track_paths): + gdk.threads_init() + sep = ';' player = gst.element_factory_make('playbin') @@ -74,7 +81,20 @@ def make_e(track_path): meta = formats.MusicFile(track_path) + def clean(s): return trunc(cgi.escape(s)) + caption = '%s - %s' % (clean(meta.get('artist', '[Unknown Artist]')), + clean(meta.get('title', '[Untitled]'))) + disp = Label(caption) + try: artist = pylast.Artist(meta['artist'], lastfm_apikey, '', '') + except KeyError: pass + else: + def cb(artist, tags): + with gdksync(): + tagstr = cgi.escape(', '.join([tag.getName() for tag in tags][:5])) + disp.set_markup(disp.get_text() + ' <i>(%s)</i>' % tagstr) + artist.async_call(artist.getTopTags, cb) + def refresh(): 'Called when the list is changed.' labels.sort(key = str.lower) @@ -138,12 +158,12 @@ else: i += 1 pieces += [m[lasti:]] - m = ''.join(('<b>' + escape(p[0]) + '</b>' + m = ''.join(('<b>' + cgi.escape(p[0]) + '</b>' if type(p) == tuple - else escape(p)) + else cgi.escape(p)) for p in pieces) else: - m = escape(m) + m = cgi.escape(m) l.append([m]) # Something is always selected in the list. t.get_selection().select_path(0) @@ -189,6 +209,8 @@ if itr is not None: (pos,) = l.get_path(itr) pos += dir + if pos == -1: pos = len(l) - 1 + if pos == len(l): pos = 0 else: pos = 0 if ev.keyval == k.Down else len(l) - 1 if 0 <= pos < len(l): @@ -205,7 +227,7 @@ ev.state & gdk.CONTROL_MASK: # Seek forward/backward 5 seconds. pos = player.query_position(timefmt)[0] - dir = 1 if ev.keyval == k.comma else 1 + dir = -1 if ev.keyval == k.comma else 1 debug('seek from', pos / 1e9, 'to', pos + dir * 5e9) player.seek_simple(timefmt, gst.SEEK_FLAG_FLUSH, pos + dir * 5e9) return True @@ -250,6 +272,7 @@ refresh() @connecting_after(e, 'focus-in-event') # TODO hack; too early on resizes + @connecting_after(e, 'configure-event') def show_popup(*args): # Play the track if not already playing. uri = 'file://' + urllib.quote(track_path) @@ -274,9 +297,7 @@ tw.move(ex+ew,ey) row = rows.next() - caption = '%s - %s' % (trunc(meta.get('artist', '[Unknown Artist]')), - trunc(meta.get('title', '[Untitled]'))) - tab.attach(Label(str = caption), 0, 1, row, row+1) + tab.attach(disp, 0, 1, row, row+1) tab.attach(e, 1, 2, row, row+1) es.append(e) return e @@ -295,7 +316,7 @@ main() # Update playlists in memory. - newpls = defaultdict(set) + newpls = collections.defaultdict(set) for track_path, e in path2e.iteritems(): # Remove from all playlists. for pl in pls.itervalues(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |