~ubuntu-branches/ubuntu/karmic/quodlibet/karmic

« back to all changes in this revision

Viewing changes to qltk/lyrics.py

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna
  • Date: 2009-01-30 23:55:34 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090130235534-l4e72ulw0vqfo17w
Tags: 2.0-1ubuntu1
* Merge from Debian experimental (LP: #276856), remaining Ubuntu changes:
  + debian/patches/40-use-music-profile.patch:
    - Use the "Music and Movies" pipeline per default.
* Refresh the above patch for new upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2005 Eduardo Gonzalez, Joe Wreschnig
2
 
#
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
6
 
#
7
 
# $Id: lyrics.py 3518 2006-06-27 22:48:01Z piman $
8
 
 
9
 
# FIXME:
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.
13
 
 
14
 
import os
15
 
import threading
16
 
import urllib
17
 
 
18
 
import gobject
19
 
import gtk
20
 
 
21
 
import const
22
 
import qltk
23
 
import util
24
 
 
25
 
from xml.dom import minidom
26
 
 
27
 
class LyricsPane(gtk.VBox):
28
 
    def __init__(self, song):
29
 
        super(LyricsPane, self).__init__(spacing=12)
30
 
        self.set_border_width(12)
31
 
        view = gtk.TextView()
32
 
        sw = gtk.ScrolledWindow()
33
 
        sw.add(view)
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)
40
 
 
41
 
        lyricname = song.lyric_filename
42
 
        buffer = view.get_buffer()
43
 
 
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)
48
 
 
49
 
        sw.set_shadow_type(gtk.SHADOW_IN)
50
 
        self.pack_start(sw, expand=True)
51
 
 
52
 
        self.pack_start(gtk.Label(_("Lyrics provided by %s.") %(
53
 
            "http://www.leoslyrics.com")), expand=False)
54
 
 
55
 
        bbox = gtk.HButtonBox()
56
 
        bbox.pack_start(save)
57
 
        bbox.pack_start(delete)
58
 
        bbox.pack_start(refresh)
59
 
        bbox.pack_start(add)
60
 
        self.pack_start(bbox, expand=False)
61
 
 
62
 
        save.set_sensitive(False)
63
 
        add.set_sensitive(False)
64
 
        
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)
71
 
 
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')
76
 
 
77
 
        util.website(
78
 
            "http://leoslyrics.com/submit.php?song=%s&artist=%s&album=%s" % (
79
 
            urllib.quote(title),
80
 
            urllib.quote(artist),
81
 
            urllib.quote(album)))
82
 
        add.set_sensitive(False)
83
 
 
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)
90
 
        thread.start()
91
 
        
92
 
    def __search(self, song, buffer, refresh, add):
93
 
        artist = song.comma("artist")
94
 
        title = song.comma("title")
95
 
        
96
 
        try:
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)
107
 
            return
108
 
 
109
 
        sock.close()
110
 
        result_code = xmldoc.getElementsByTagName(
111
 
            'response')[0].getAttribute('code')
112
 
 
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)
118
 
            
119
 
            if len(hids) == 0:
120
 
                gobject.idle_add(
121
 
                    buffer.set_text, _("No lyrics found for this song."))
122
 
                add.set_sensitive(True)
123
 
                return
124
 
             
125
 
            songlist = zip(hids, exacts)
126
 
                
127
 
            xmldoc.unlink()
128
 
            
129
 
            # Show the first match
130
 
            try:
131
 
                sock = urllib.urlopen(
132
 
                    "http://api.leoslyrics.com/api_lyrics.php?auth="
133
 
                    "QuodLibet&hid=%s"%(
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)
140
 
                return
141
 
            sock.close()
142
 
 
143
 
            text = xmldoc.getElementsByTagName('text')[0].firstChild.nodeValue
144
 
            xmldoc.unlink()
145
 
 
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')
149
 
 
150
 
        else:
151
 
            gobject.idle_add(buffer.set_text, _("Unable to download lyrics."))
152
 
            xmldoc.unlink()
153
 
            return
154
 
 
155
 
    def __save(self, save, lyricname, buffer, delete):
156
 
        try: os.makedirs(os.path.dirname(lyricname))
157
 
        except EnvironmentError, err: pass
158
 
 
159
 
        try: f = file(lyricname, "w")
160
 
        except EnvironmentError, err: print err
161
 
        else:
162
 
            start, end = buffer.get_bounds()
163
 
            f.write(buffer.get_text(start, end))
164
 
            f.close()
165
 
        delete.set_sensitive(True)
166
 
        save.set_sensitive(False)
167
 
 
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)