1
# Copyright 2005 Eduardo Gonzalez, Joe Wreschnig
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License version 2 as
5
# published by the Free Software Foundation
7
# $Id: lyrics.py 3518 2006-06-27 22:48:01Z piman $
10
# - Too many buttons -- saving should be automatic?
11
# - Make purpose of 'Add' button clearer.
12
# - Indicate when the match was fuzzy in the buffer text.
25
from xml.dom import minidom
27
class LyricsPane(gtk.VBox):
28
def __init__(self, song):
29
super(LyricsPane, self).__init__(spacing=12)
30
self.set_border_width(12)
32
sw = gtk.ScrolledWindow()
34
refresh = qltk.Button(_("_Download"), gtk.STOCK_CONNECT)
35
save = gtk.Button(stock=gtk.STOCK_SAVE)
36
delete = gtk.Button(stock=gtk.STOCK_DELETE)
37
add = gtk.Button(stock=gtk.STOCK_ADD)
38
view.set_wrap_mode(gtk.WRAP_WORD)
39
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
41
lyricname = song.lyric_filename
42
buffer = view.get_buffer()
44
refresh.connect('clicked', self.__refresh, add, buffer, song)
45
save.connect('clicked', self.__save, lyricname, buffer, delete)
46
delete.connect('clicked', self.__delete, lyricname, save)
47
add.connect('clicked', self.__add, song)
49
sw.set_shadow_type(gtk.SHADOW_IN)
50
self.pack_start(sw, expand=True)
52
self.pack_start(gtk.Label(_("Lyrics provided by %s.") %(
53
"http://www.leoslyrics.com")), expand=False)
55
bbox = gtk.HButtonBox()
57
bbox.pack_start(delete)
58
bbox.pack_start(refresh)
60
self.pack_start(bbox, expand=False)
62
save.set_sensitive(False)
63
add.set_sensitive(False)
65
if os.path.exists(lyricname): buffer.set_text(file(lyricname).read())
66
else: buffer.set_text(_("No lyrics found.\n\nYou can click the "
67
"Download button to have Quod Libet search "
68
"for lyrics online. You can also enter them "
69
"yourself and click save."))
70
buffer.connect_object('changed', save.set_sensitive, True)
72
def __add(self, add, song):
73
artist = song.comma('artist').encode('utf-8')
74
title = song.comma('title').encode('utf-8')
75
album = song.comma('album').encode('utf-8')
78
"http://leoslyrics.com/submit.php?song=%s&artist=%s&album=%s" % (
82
add.set_sensitive(False)
84
def __refresh(self, refresh, add, buffer, song):
85
buffer.set_text(_("Searching for lyrics..."))
86
refresh.set_sensitive(False)
87
thread = threading.Thread(
88
target=self.__search, args=(song, buffer, refresh, add))
89
thread.setDaemon(True)
92
def __search(self, song, buffer, refresh, add):
93
artist = song.comma("artist")
94
title = song.comma("title")
97
sock = urllib.urlopen(
98
"http://api.leoslyrics.com/api_search.php?auth="
99
"QuodLibet&artist=%s&songtitle=%s"%(
100
urllib.quote(artist.encode('utf-8')),
101
urllib.quote(title.encode('utf-8'))))
102
xmldoc = minidom.parse(sock).documentElement
103
except Exception, err:
104
try: err = err.strerror.decode(const.ENCODING, 'replace')
105
except: err = _("Unable to download lyrics.")
106
gobject.idle_add(buffer.set_text, err)
110
result_code = xmldoc.getElementsByTagName(
111
'response')[0].getAttribute('code')
113
if result_code == '0': # This is success even if there are no matches.
114
# Grab the first 10 results.
115
matches = xmldoc.getElementsByTagName('result')[:10]
116
hids = map(lambda x: x.getAttribute('hid'), matches)
117
exacts = map(lambda x: x.getAttribute('exactMatch'), matches)
121
buffer.set_text, _("No lyrics found for this song."))
122
add.set_sensitive(True)
125
songlist = zip(hids, exacts)
129
# Show the first match
131
sock = urllib.urlopen(
132
"http://api.leoslyrics.com/api_lyrics.php?auth="
134
urllib.quote(songlist[0][0].encode('utf-8'))))
135
xmldoc = minidom.parse(sock).documentElement
136
except Exception, err:
137
try: err = err.strerror.decode(const.ENCODING, 'replace')
138
except: err = _("Unable to download lyrics.")
139
gobject.idle_add(buffer.set_text, err)
143
text = xmldoc.getElementsByTagName('text')[0].firstChild.nodeValue
146
gobject.idle_add(buffer.set_text, text)
147
gobject.idle_add(refresh.set_sensitive, True)
148
gobject.idle_add(add.set_sensitive, songlist[0][1] == 'false')
151
gobject.idle_add(buffer.set_text, _("Unable to download lyrics."))
155
def __save(self, save, lyricname, buffer, delete):
156
try: os.makedirs(os.path.dirname(lyricname))
157
except EnvironmentError, err: pass
159
try: f = file(lyricname, "w")
160
except EnvironmentError, err: print err
162
start, end = buffer.get_bounds()
163
f.write(buffer.get_text(start, end))
165
delete.set_sensitive(True)
166
save.set_sensitive(False)
168
def __delete(self, delete, lyricname, save):
169
try: os.unlink(lyricname)
170
except EnvironmentError: pass
171
lyricname = os.path.dirname(lyricname)
172
try: os.rmdir(lyricname)
173
except EnvironmentError: pass
174
delete.set_sensitive(False)
175
save.set_sensitive(True)