# # Copyright (C) 2009 Anton Khirnov # # Nephilim is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Nephilim is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Nephilim. If not, see . # from PyQt4 import QtGui,QtCore from PyQt4.QtCore import QVariant import logging import socket from ..plugin import Plugin from .. import misc _available_sites = [] try: import LyricWiki_client _available_sites.append('lyricwiki') except ImportError: pass class wgLyrics(QtGui.QWidget): txtView = None # text-object p = None # plugin def __init__(self, p, parent=None): QtGui.QWidget.__init__(self, parent) self.p = p self.curLyrics = '' self.txtView = QtGui.QTextEdit(self) self.txtView.setReadOnly(True) self.setLayout(QtGui.QVBoxLayout()) self.layout().setSpacing(0) self.layout().setMargin(0) self.layout().addWidget(self.txtView) self.connect(self.p, QtCore.SIGNAL('new_lyrics_fetched'), self.set_lyrics) def set_lyrics(self, song, lyrics): if not song: return if song != self.p.mpclient().current_song(): return self.txtView.clear() if song: self.txtView.insertHtml('%s\n
%s
'\ '
\n\n'%(song.title(), song.artist())) else: return if lyrics: self.txtView.insertPlainText(lyrics) else: self.txtView.insertPlainText('Lyrics not found.') class Lyrics(Plugin): o = None sites = [] lyrics_dir = None lyrics_path = None DEFAULTS = {'sites' : ['lyricwiki'], 'lyricdir' : '$musicdir/$songdir', 'lyricname' : '.lyrics_nephilim_$artist_$album_$title', 'store' : True} def _load(self): self.o = wgLyrics(self) for site in _available_sites: if site in self.settings().value('%s/sites'%self.name()).toStringList(): self.sites.append(site) self.connect(self.mpclient(), QtCore.SIGNAL('song_changed'), self.refresh) def _unload(self): self.o = None self.sites = [] self.disconnect(self.mpclient(), QtCore.SIGNAL('song_changed'), self.refresh) def info(self): return "Show (and fetch) the lyrics of the currently playing song." def _get_dock_widget(self): return self._create_dock(self.o) class FetchThread(QtCore.QThread): def __init__(self, parent, fetch_func, song): QtCore.QThread.__init__(self) self.setParent(parent) self.fetch_func = fetch_func self.song = song def run(self): self.fetch_func(self.song) def refresh(self): song = self.mpclient().current_song() if not song: return self.o.set_lyrics(None, None) (self.lyrics_dir, self.lyrics_path) = misc.generate_metadata_path(self.parent(), song, self.settings().value(self.name() + '/lyricdir').toString(), self.settings().value(self.name() + '/lyricname').toString()) try: file = open(self.lyrics_path, 'r') lyrics = file.read().decode('utf-8') file.close() if lyrics: return self.emit(QtCore.SIGNAL('new_lyrics_fetched'), song, lyrics) except IOError, e: logging.info('Error reading lyrics file: %s.'%e) thread = self.FetchThread(self, self._fetch_lyrics, song) thread.start() def _fetch_lyrics(self, song): lyrics = None for site in self.sites: lyrics = eval('self.fetch_%s(song)'%site) if lyrics: try: file = open(self.lyrics_path, 'w') file.write(lyrics.encode('utf-8')) file.close() except IOError, e: logging.error('Error saving lyrics: %s'%e) return self.emit(QtCore.SIGNAL('new_lyrics_fetched'), song, lyrics) self.emit(QtCore.SIGNAL('new_lyrics_fetched'), song, None) def fetch_lyricwiki(self, song): soap = LyricWiki_client.LyricWikiBindingSOAP("http://lyricwiki.org/server.php") req = LyricWiki_client.getSongRequest() req.Artist = song.artist().encode('utf-8').decode('iso8859').encode('utf-8') req.Song = song.title().encode('utf-8').decode('iso8859').encode('utf-8') try: result = soap.getSong(req).Return.Lyrics.decode('utf-8').encode('iso8859').decode('utf-8') except socket.error, e: logging.error('Error downloading lyrics from LyricWiki: %s.'%e) return None return result if result != 'Not found' else None class SettingsWidgetLyrics(Plugin.SettingsWidget): lyricdir = None lyricname = None store = None def __init__(self, plugin): Plugin.SettingsWidget.__init__(self, plugin) self.settings().beginGroup(self.plugin.name()) # store lyrics groupbox self.store = QtGui.QGroupBox('Store lyrics.') self.store.setToolTip('Should %s store its own copy of lyrics?'%misc.APPNAME) self.store.setCheckable(True) self.store.setChecked(self.settings().value('store').toBool()) self.store.setLayout(QtGui.QGridLayout()) # paths to lyrics self.lyricdir = QtGui.QLineEdit(self.settings().value('lyricdir').toString()) self.lyricdir.setToolTip('Where should %s store lyrics.\n' '$musicdir will be expanded to path to MPD music library (as set by user)\n' '$songdir will be expanded to path to the song (relative to $musicdir\n' 'other tags same as in lyricname' %misc.APPNAME) self.lyricname = QtGui.QLineEdit(self.settings().value('lyricname').toString()) self.lyricname.setToolTip('Filename for %s lyricsfiles.\n' 'All tags supported by MPD will be expanded to their\n' 'values for current song, e.g. $title, $track, $artist,\n' '$album, $genre etc.'%misc.APPNAME) self.store.layout().addWidget(QtGui.QLabel('Lyrics directory'), 0, 0) self.store.layout().addWidget(self.lyricdir, 0, 1) self.store.layout().addWidget(QtGui.QLabel('Lyrics filename'), 1, 0) self.store.layout().addWidget(self.lyricname, 1, 1) self.setLayout(QtGui.QVBoxLayout()) self.layout().addWidget(self.store) self.settings().endGroup() def save_settings(self): self.settings().beginGroup(self.plugin.name()) self.settings().setValue('lyricdir', QVariant(self.lyricdir.text())) self.settings().setValue('lyricname', QVariant(self.lyricname.text())) self.settings().setValue('store', QVariant(self.store.isChecked())) self.settings().endGroup() self.plugin.o.refresh() def get_settings_widget(self): return self.SettingsWidgetLyrics(self)