2 # Copyright (C) 2009 Anton Khirnov <wyskas@gmail.com>
4 # Nephilim is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # Nephilim is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Nephilim. If not, see <http://www.gnu.org/licenses/>.
18 from PyQt4
import QtGui
,QtCore
19 from PyQt4
.QtCore
import QVariant
23 from ..plugin
import Plugin
28 import LyricWiki_client
29 _available_sites
.append('lyricwiki')
33 class wgLyrics(QtGui
.QWidget
):
34 txtView
= None # text-object
37 def __init__(self
, p
, parent
=None):
38 QtGui
.QWidget
.__init
__(self
, parent
)
40 self
.logger
= p
.logger
43 self
.txtView
= QtGui
.QTextEdit(self
)
44 self
.txtView
.setReadOnly(True)
46 self
.setLayout(QtGui
.QVBoxLayout())
47 self
.layout().setSpacing(0)
48 self
.layout().setMargin(0)
49 self
.layout().addWidget(self
.txtView
)
51 self
.connect(self
.p
, QtCore
.SIGNAL('new_lyrics_fetched'), self
.set_lyrics
)
53 def set_lyrics(self
, song
, lyrics
):
55 return self
.txtView
.clear()
57 if song
!= self
.p
.mpclient().current_song():
62 self
.txtView
.insertHtml('<b>%s</b>\n<br /><u>%s</u><br />'\
63 '<br />\n\n'%(song
.title(), song
.artist()))
68 self
.logger
.info('Setting new lyrics.')
69 self
.txtView
.insertPlainText(lyrics
)
71 self
.logger
.info('Lyrics not found.')
72 self
.txtView
.insertPlainText('Lyrics not found.')
79 DEFAULTS
= {'sites' : ['lyricwiki'], 'lyricdir' : '$musicdir/$songdir',
80 'lyricname' : '.lyrics_nephilim_$artist_$album_$title', 'store' : True}
83 self
.o
= wgLyrics(self
)
84 for site
in _available_sites
:
85 if site
in self
.settings().value('%s/sites'%self
.name()).toStringList():
86 self
.sites
.append(site
)
87 self
.connect(self
.mpclient(), QtCore
.SIGNAL('song_changed'), self
.refresh
)
91 self
.disconnect(self
.mpclient(), QtCore
.SIGNAL('song_changed'), self
.refresh
)
93 return "Show (and fetch) the lyrics of the currently playing song."
95 def _get_dock_widget(self
):
96 return self
._create
_dock
(self
.o
)
98 class FetchThread(QtCore
.QThread
):
99 def __init__(self
, parent
, fetch_func
, song
):
100 QtCore
.QThread
.__init
__(self
)
101 self
.setParent(parent
)
102 self
.fetch_func
= fetch_func
105 self
.fetch_func(self
.song
)
108 self
.logger
.info('Autorefreshing lyrics.')
109 song
= self
.mpclient().current_song()
111 return self
.o
.set_lyrics(None, None)
113 (self
.lyrics_dir
, self
.lyrics_path
) = misc
.generate_metadata_path(song
,
114 self
.settings().value(self
.name() + '/lyricdir').toString(),
115 self
.settings().value(self
.name() + '/lyricname').toString())
117 self
.logger
.info('Trying to read lyrics from file %s.'%self
.lyrics_path
)
118 file = open(self
.lyrics_path
, 'r')
119 lyrics
= file.read().decode('utf-8')
122 return self
.emit(QtCore
.SIGNAL('new_lyrics_fetched'), song
, lyrics
)
124 self
.logger
.info('Error reading lyrics file: %s.'%e)
127 thread
= self
.FetchThread(self
, self
._fetch
_lyrics
, song
)
130 def _fetch_lyrics(self
, song
):
131 self
.logger
.info('Trying to download lyrics from internet.')
133 for site
in self
.sites
:
134 self
.logger
.info('Trying %s.'%site
)
135 lyrics
= eval('self.fetch_%s(song)'%site
)
138 file = open(self
.lyrics_path
, 'w')
139 file.write(lyrics
.encode('utf-8'))
142 self
.logger
.error('Error saving lyrics: %s'%e)
143 return self
.emit(QtCore
.SIGNAL('new_lyrics_fetched'), song
, lyrics
)
145 self
.emit(QtCore
.SIGNAL('new_lyrics_fetched'), song
, None)
147 def fetch_lyricwiki(self
, song
):
148 soap
= LyricWiki_client
.LyricWikiBindingSOAP("http://lyricwiki.org/server.php")
149 req
= LyricWiki_client
.getSongRequest()
150 req
.Artist
= song
.artist().encode('utf-8').decode('iso8859').encode('utf-8')
151 req
.Song
= song
.title().encode('utf-8').decode('iso8859').encode('utf-8')
153 result
= soap
.getSong(req
).Return
.Lyrics
.decode('utf-8').encode('iso8859').decode('utf-8')
154 except socket
.error
, e
:
155 self
.logger
.error('Error downloading lyrics from LyricWiki: %s.'%e)
158 return result
if result
!= 'Not found' else None
160 class SettingsWidgetLyrics(Plugin
.SettingsWidget
):
165 def __init__(self
, plugin
):
166 Plugin
.SettingsWidget
.__init
__(self
, plugin
)
167 self
.settings().beginGroup(self
.plugin
.name())
170 # store lyrics groupbox
171 self
.store
= QtGui
.QGroupBox('Store lyrics.')
172 self
.store
.setToolTip('Should %s store its own copy of lyrics?'%misc
.APPNAME
)
173 self
.store
.setCheckable(True)
174 self
.store
.setChecked(self
.settings().value('store').toBool())
175 self
.store
.setLayout(QtGui
.QGridLayout())
178 self
.lyricdir
= QtGui
.QLineEdit(self
.settings().value('lyricdir').toString())
179 self
.lyricdir
.setToolTip('Where should %s store lyrics.\n'
180 '$musicdir will be expanded to path to MPD music library (as set by user)\n'
181 '$songdir will be expanded to path to the song (relative to $musicdir\n'
182 'other tags same as in lyricname'
184 self
.lyricname
= QtGui
.QLineEdit(self
.settings().value('lyricname').toString())
185 self
.lyricname
.setToolTip('Filename for %s lyricsfiles.\n'
186 'All tags supported by MPD will be expanded to their\n'
187 'values for current song, e.g. $title, $track, $artist,\n'
188 '$album, $genre etc.'%misc
.APPNAME
)
189 self
.store
.layout().addWidget(QtGui
.QLabel('Lyrics directory'), 0, 0)
190 self
.store
.layout().addWidget(self
.lyricdir
, 0, 1)
191 self
.store
.layout().addWidget(QtGui
.QLabel('Lyrics filename'), 1, 0)
192 self
.store
.layout().addWidget(self
.lyricname
, 1, 1)
194 self
.setLayout(QtGui
.QVBoxLayout())
195 self
.layout().addWidget(self
.store
)
197 self
.settings().endGroup()
199 def save_settings(self
):
200 self
.settings().beginGroup(self
.plugin
.name())
201 self
.settings().setValue('lyricdir', QVariant(self
.lyricdir
.text()))
202 self
.settings().setValue('lyricname', QVariant(self
.lyricname
.text()))
203 self
.settings().setValue('store', QVariant(self
.store
.isChecked()))
204 self
.settings().endGroup()
205 self
.plugin
.refresh()
207 def get_settings_widget(self
):
208 return self
.SettingsWidgetLyrics(self
)