from PyQt4 import QtGui,QtCore import re from thread import start_new_thread from traceback import print_exc from misc import * from clSettings import settings,mpdSettings from clMonty import monty from clPlugin import * class ResetEvent(QtCore.QEvent): song=None def __init__(self, song=None): QtCore.QEvent.__init__(self,QtCore.QEvent.User) self.song=song class AddHtmlEvent(QtCore.QEvent): html=None def __init__(self,html): QtCore.QEvent.__init__(self,QtCore.QEvent.User) self.html=html LY_DEFAULT_ENGINE='http://www.google.com/search?q=lyrics+"$artist"+"$title"' LY_DEFAULT_SITES='azlyrics.com

.*?

(.*?)

\n'\ 'oldielyrics.com song_in_top2.*?

(.*?)(.*?)

\n'\ class wgLyrics(QtGui.QWidget): " contains the lyrics" txt=None def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.txt=QtGui.QTextEdit(parent) self.txt.setReadOnly(True) layout=QtGui.QVBoxLayout() layout.addWidget(self.txt) self.setLayout(layout) monty.addListener('onSongChange', self.onSongChange) monty.addListener('onReady', self.onReady) monty.addListener('onDisconnect', self.onDisconnect) def onSongChange(self, params): song=monty.getCurrentSong() try: song._data['file'] except: self.resetTxt() return self.resetTxt(song) start_new_thread(self.fetchLyrics, (song,)) def customEvent(self, event): if isinstance(event,ResetEvent): self.resetTxt(event.song) elif isinstance(event,AddHtmlEvent): self.txt.insertHtml(event.html) def onReady(self, params): self.onSongChange(None) _mutex=QtCore.QMutex() _fetchCnt=0 def fetchLyrics(self, song): # only allow 1 instance to look lyrics! self._mutex.lock() if self._fetchCnt: self._mutex.unlock() return self._fetchCnt=1 self._mutex.unlock() QtCore.QCoreApplication.postEvent(self, ResetEvent(song)) # save the data to file! save_dir=settings.get('lyrics.dir', '/holy_grail') fInfo=QtCore.QFileInfo(save_dir) if fInfo.isDir(): lyFName='%s/%s - %s.txt'%(save_dir,song.getArtist(),song.getTitle()) else: lyFName=None # does the file exist? if yes, read that one! try: # we have it: load, and return! file=open(lyFName, 'r') QtCore.QCoreApplication.postEvent(self, AddHtmlEvent(file.read())) file.close() self._fetchCnt=0 return except: pass # fetch from inet QtCore.QCoreApplication.postEvent(self, AddHtmlEvent('Searching lyrics ...')) lines=settings.get('lyrics.sites', LY_DEFAULT_SITES).split('\n') sites={} for line in lines: if line.strip(): sites[line[0:line.find('\t')]]=line[line.find('\t'):].strip() # construct URL to search! SE=settings.get('lyrics.engine', LY_DEFAULT_ENGINE) try: ret=fetch(SE, sites, song, {}) if ret: txt='%s

%s'%(ret[0],ret[1],ret[1]) # save for later use! if lyFName: # we can't save if the path isn't correct try: file=open(lyFName, 'w') file.write(ret[0]) file.close() except: # probably a wrong path! pass else: txt="No lyrics found :'(" QtCore.QCoreApplication.postEvent(self, ResetEvent(song)) QtCore.QCoreApplication.postEvent(self, AddHtmlEvent(txt)) except: print_exc() QtCore.QCoreApplication.postEvent(self, ResetEvent(song)) QtCore.QCoreApplication.postEvent(self, AddHtmlEvent('Woops, site unavailable!'\ '
You have an internet connection?')) self._fetchCnt=0 def onDisconnect(self, params): self.resetTxt() def resetTxt(self, song=None): self.txt.clear() if song: self.txt.insertHtml('%s\n
%s
'\ '
\n\n'%(song.getTitle(), song.getArtist())) class pluginLyrics(Plugin): o=None def __init__(self, winMain): Plugin.__init__(self, winMain, 'Lyrics') def _load(self): self.o=wgLyrics(None) def getInfo(self): return "Show (and fetch) the lyrics of the currently playing song." def _getDockWidget(self): return self._createDock(self.o) def _getSettings(self): sites=QtGui.QTextEdit() sites.insertPlainText(settings.get('lyrics.sites', LY_DEFAULT_SITES)) return [ ['lyrics.engine', 'Search engine', 'The URL that is used to search. $artist, $title and $album are replaced in the URL.', QtGui.QLineEdit(settings.get('lyrics.engine', LY_DEFAULT_ENGINE))], ['lyrics.sites', 'Sites & regexes', 'This field contains all sites, together with the regex needed to fetch the lyrics.\nEvery line must look like this: $domain $regex-start(.*?)$regex-end\n$domain is the domain of the lyrics website, $regex-start is the regex indicating the start of the lyrics, $regex-end indicates the end. E.g. foolyrics.org (.*?)', sites], ['lyrics.dir', 'Lyrics directory', 'Directory where lyrics should be stored and retrieved.', QtGui.QLineEdit(settings.get('lyrics.dir'))], ] def afterSaveSettings(self): self.o.onSongChange(None)