home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.4)
-
- import os
- import gtk
- import gobject
- import urllib
- import re
- from xml.dom import minidom
- from gettext import gettext as _
- import rb
- import rhythmdb
- from Loader import Loader
- ui_str = '\n<ui>\n <menubar name="MenuBar">\n <menu name="ViewMenu" action="View">\n <menuitem name="ViewSongLyrics" action="ViewSongLyrics"/>\n </menu>\n </menubar>\n</ui>\n'
- LYRICS_FOLDER = '~/.gnome2/rhythmbox/lyrics'
- LYRIC_TITLE_STRIP = [
- '\\(live[^\\)]*\\)',
- '\\(acoustic[^\\)]*\\)',
- '\\([^\\)]*mix\\)',
- '\\([^\\)]*version\\)',
- '\\([^\\)]*edit\\)',
- '\\(feat[^\\)]*\\)']
- LYRIC_TITLE_REPLACE = [
- ('/', '-'),
- ('&', 'and')]
- LYRIC_ARTIST_REPLACE = [
- ('/', '-'),
- ('&', 'and')]
-
- def create_lyrics_view():
- view = gtk.TextView()
- view.set_wrap_mode(gtk.WRAP_WORD)
- view.set_editable(False)
- sw = gtk.ScrolledWindow()
- sw.add(view)
- sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- sw.set_shadow_type(gtk.SHADOW_IN)
- vbox = gtk.VBox(spacing = 12)
- vbox.pack_start(sw, expand = True)
- return (vbox, view.get_buffer())
-
-
- class LyricWindow(gtk.Window):
-
- def __init__(self, db, entry):
- gtk.Window.__init__(self)
- self.set_border_width(12)
- title = db.entry_get(entry, rhythmdb.PROP_TITLE)
- artist = db.entry_get(entry, rhythmdb.PROP_ARTIST)
- self.set_title(title + ' - ' + artist + ' - Lyrics')
- close = gtk.Button(stock = gtk.STOCK_CLOSE)
- close.connect('clicked', (lambda w: self.destroy()))
- (lyrics_view, buffer) = create_lyrics_view()
- self.buffer = buffer
- bbox = gtk.HButtonBox()
- bbox.set_layout(gtk.BUTTONBOX_END)
- bbox.pack_start(close)
- lyrics_view.pack_start(bbox, expand = False)
- self.buffer.set_text(_('Searching for lyrics...'))
- self.add(lyrics_view)
- self.set_default_size(400, 300)
- self.show_all()
-
-
-
- class LyricPane(object):
-
- def __init__(self, db, song_info):
- (self.view, self.buffer) = create_lyrics_view()
- self.view.show_all()
- self.page_num = song_info.append_page(_('Lyrics'), self.view)
- self.db = db
- self.song_info = song_info
- self.have_lyrics = 0
- self.visible = 0
- self.entry = self.song_info.get_property('current-entry')
- self.entry_change_id = song_info.connect('notify::current-entry', self.entry_changed)
- nb = self.view.get_parent()
- self.switch_page_id = nb.connect('switch-page', self.switch_page_cb)
-
-
- def entry_changed(self, pspec, duh):
- self.entry = self.song_info.get_property('current-entry')
- self.have_lyrics = 0
- if self.visible != 0:
- self.get_lyrics()
-
-
-
- def switch_page_cb(self, notebook, page, page_num):
- if self.have_lyrics != 0:
- return None
-
- if page_num != self.page_num:
- self.visible = 0
- return None
-
- self.visible = 1
- self.get_lyrics()
-
-
- def get_lyrics(self):
- if self.entry is None:
- return None
-
- self.buffer.set_text(_('Searching for lyrics...'))
- lyrics_grabber = LyricGrabber()
- lyrics_grabber.get_lyrics(self.db, self.entry, self.buffer.set_text)
-
-
-
- class LyricGrabber(object):
-
- def __init__(self):
- self.loader = Loader()
-
-
- def _build_cache_path(self, artist, title):
- lyrics_folder = os.path.expanduser(LYRICS_FOLDER)
- if not os.path.exists(lyrics_folder):
- os.mkdir(lyrics_folder)
-
- return lyrics_folder + '/%s - %s.txt' % (artist, title)
-
-
- def get_lyrics(self, db, entry, callback):
- self.callback = callback
- artist = db.entry_get(entry, rhythmdb.PROP_ARTIST).lower()
- title = db.entry_get(entry, rhythmdb.PROP_TITLE).lower()
- for exp in LYRIC_ARTIST_REPLACE:
- p = re.compile(exp[0])
- artist = p.sub(exp[1], artist)
-
- for exp in LYRIC_TITLE_REPLACE:
- p = re.compile(exp[0])
- title = p.sub(exp[1], title)
-
- for exp in LYRIC_TITLE_STRIP:
- p = re.compile(exp)
- title = p.sub('', title)
-
- title = title.strip()
- artist = artist.strip()
- self.cache_path = self._build_cache_path(artist, title)
- if os.path.exists(self.cache_path):
- self.loader.get_url(self.cache_path, callback)
- return None
-
- url = 'http://api.leoslyrics.com/api_search.php?auth=Rhythmbox&artist=%s&songtitle=%s' % (urllib.quote(artist.encode('utf-8')), urllib.quote(title.encode('utf-8')))
- self.loader.get_url(url, self.search_results)
-
-
- def search_results(self, data):
- if data is None:
- self.callback('Server did not respond.')
- return None
-
-
- try:
- xmldoc = minidom.parseString(data).documentElement
- except:
- self.callback("Couldn't parse search results.")
- return None
-
- result_code = xmldoc.getElementsByTagName('response')[0].getAttribute('code')
- if result_code != '0':
- self.callback('Server is busy, try again later.')
- xmldoc.unlink()
- return None
-
- matches = xmldoc.getElementsByTagName('result')[:10]
- hids = map((lambda x: x.getAttribute('hid')), matches)
- if len(hids) == 0:
- self.callback('Unable to find lyrics for this track.')
- xmldoc.unlink()
- return None
-
- xmldoc.unlink()
- url = 'http://api.leoslyrics.com/api_lyrics.php?auth=Rhythmbox&hid=%s' % urllib.quote(hids[0].encode('utf-8'))
- self.loader.get_url(url, self.lyrics)
-
-
- def lyrics(self, data):
- if data is None:
- self.callback('Unable to find lyrics for this track.')
- return None
-
-
- try:
- xmldoc = minidom.parseString(data).documentElement
- except:
- self.callback('Unable to parse the lyrics returned.')
- return None
-
- text = xmldoc.getElementsByTagName('title')[0].firstChild.nodeValue
- text += ' - ' + xmldoc.getElementsByTagName('artist')[0].getElementsByTagName('name')[0].firstChild.nodeValue + '\n\n'
- text += xmldoc.getElementsByTagName('text')[0].firstChild.nodeValue
- xmldoc.unlink()
- text += '\n\n' + _('Lyrics provided by leoslyrics.com')
- f = file(self.cache_path, 'w')
- f.write(text)
- f.close()
- self.callback(text)
-
-
-
- class LyricsDisplayPlugin(rb.Plugin):
-
- def __init__(self):
- rb.Plugin.__init__(self)
- self.window = None
-
-
- def activate(self, shell):
- self.action = gtk.Action('ViewSongLyrics', _('Song L_yrics'), _('Display lyrics for the playing song'), 'rb-song-lyrics')
- self.activate_id = self.action.connect('activate', self.show_song_lyrics, shell)
- self.action_group = gtk.ActionGroup('SongLyricsPluginActions')
- self.action_group.add_action(self.action)
- uim = shell.get_ui_manager()
- uim.insert_action_group(self.action_group, 0)
- self.ui_id = uim.add_ui_from_string(ui_str)
- uim.ensure_update()
- sp = shell.get_player()
- self.pec_id = sp.connect('playing-song-changed', self.playing_entry_changed)
- self.playing_entry_changed(sp, sp.get_playing_entry())
- self.csi_id = shell.connect('create_song_info', self.create_song_info)
-
-
- def deactivate(self, shell):
- uim = shell.get_ui_manager()
- uim.remove_ui(self.ui_id)
- uim.remove_action_group(self.action_group)
- self.action_group = None
- self.action = None
- sp = shell.get_player()
- sp.disconnect(self.pec_id)
- if self.window is not None:
- self.window.destroy()
-
-
-
- def playing_entry_changed(self, sp, entry):
- if entry is not None:
- self.action.set_sensitive(True)
- else:
- self.action.set_sensitive(False)
-
-
- def show_song_lyrics(self, action, shell):
- if self.window is not None:
- self.window.destroy()
-
- db = shell.get_property('db')
- sp = shell.get_player()
- entry = sp.get_playing_entry()
- if entry is None:
- return None
-
- self.window = LyricWindow(db, entry)
- lyrics_grabber = LyricGrabber()
- lyrics_grabber.get_lyrics(db, entry, self.window.buffer.set_text)
-
-
- def create_song_info(self, shell, song_info, is_multiple):
- if is_multiple is False:
- x = LyricPane(shell.get_property('db'), song_info)
-
-
-
-