(no commit message)
[paste/456.git] / 0-patch.diff
1 diff --git a/plugins/lyrics/lyrics.py b/plugins/lyrics/lyrics.py
2 index 13124b3..c0f8de1 100644
3 --- a/plugins/lyrics/lyrics.py
4 +++ b/plugins/lyrics/lyrics.py
5 @@ -32,6 +32,7 @@ import urllib.request
6  import rb
7  from gi.repository import Gtk, Gio, GObject, Peas
8  from gi.repository import RB
9 +from gi.repository import Gst, GstPbutils
10  
11  import LyricsParse
12  from LyricsConfigureDialog import LyricsConfigureDialog
13 @@ -132,22 +133,33 @@ def build_cache_path(artist, title):
14         return os.path.join(artist_folder, title[:128] + '.lyric')
15  
16  class LyricGrabber(object):
17 +       """
18 +       Fetch lyrics from several sources.
19 +
20 +       1. Local cache file
21 +       2. Lyric tags in file meta data
22 +       3. Online services
23 +       """
24         def __init__(self, db, entry):
25                 self.db = db
26                 self.entry = entry
27 -               
28 +
29                 (self.artist, self.title) = parse_song_data(self.db, self.entry)
30  
31                 self.cache_path = build_cache_path(self.artist, self.title)
32  
33         def verify_lyric(self):
34                 return os.path.exists(self.cache_path)
35 -         
36 +
37         def search_lyrics(self, callback, cache_only=False):
38 +               """
39 +               Fetch lyrics from cache.
40 +
41 +               If no cache file exist, tag extraction is tried next.
42 +               """
43                 self.callback = callback
44 -               
45 +
46                 status = self.verify_lyric()
47 -               
48                 if status:
49                         f = open(self.cache_path, 'rt')
50                         text = f.read()
51 @@ -155,20 +167,73 @@ class LyricGrabber(object):
52                         self.callback(text)
53                 elif cache_only:
54                         self.callback(_("No lyrics found"))
55 -               elif self.artist == "" and self.title == "":
56 -                       self.callback(_("No lyrics found"))
57                 else:
58 -                       def lyric_callback (text):
59 -                               if text is not None:
60 -                                       f = open(self.cache_path, 'wt')
61 -                                       f.write (text)
62 -                                       f.close ()
63 -                                       self.callback(text)
64 -                               else:
65 -                                       self.callback(_("No lyrics found"))
66 +                       self.search_tags()
67 +
68 +       def search_tags(self):
69 +               """
70 +               Initiate fetching meta tags.
71 +
72 +               Result will be handled in search_tags_result
73 +               """
74 +               location = self.entry.get_playback_uri()
75 +               self.discoverer = GstPbutils.Discoverer(timeout=Gst.SECOND*3)
76 +               self.discoverer.connect('discovered', self.search_tags_result)
77 +               self.discoverer.start()
78 +               self.discoverer.discover_uri_async(location)
79 +
80 +       def search_tags_result(self, discoverer, info, error):
81 +               """
82 +               Extract lyrics from the file meta data (tags).
83 +
84 +               If no lyrics tags are found, online services are tried next.
85 +
86 +               Supported file formats and lyrics tags:
87 +               - ogg/vorbis files with "LYRICS" and "SYNCLYRICS" tag
88 +               """
89 +               tags = info.get_tags()
90 +               if tags is None:
91 +                       self.search_online()
92 +                       return
93  
94 +               for i in range(tags.get_tag_size("extended-comment")):
95 +                       (exists, value) = tags.get_string_index("extended-comment", i)
96 +                       #ogg/vorbis unsynchronized lyrics
97 +                       if exists and value.startswith("LYRICS"):
98 +                               text = value.replace("LYRICS=", "")
99 +                               self.lyrics_found(text)
100 +                               return
101 +                       #ogg/vorbis synchronized lyrics
102 +                       elif exists and value.startswith("SYNCLYRICS"):
103 +                               text = value.replace("SYNCLYRICS=", "")
104 +                               self.lyrics_found(text)
105 +                               return
106 +
107 +               self.search_online()
108 +
109 +       def search_online(self):
110 +               """Initiate searching the online lyrics services"""
111 +               if self.artist == "" and self.title == "":
112 +                       self.callback(_("No lyrics found"))
113 +               else:
114                         parser = LyricsParse.Parser(self.artist, self.title)
115 -                       parser.get_lyrics(lyric_callback)
116 +                       parser.get_lyrics(self.search_online_result)
117 +
118 +       def search_online_result(self, text):
119 +               """Handle the result of searching online lyrics services"""
120 +               if text is not None:
121 +                       self.lyrics_found(text)
122 +               else:
123 +                       self.callback(_("No lyrics found"))
124 +
125 +
126 +       def lyrics_found(self, text):
127 +               f = open(self.cache_path, 'wt')
128 +               f.write(text)
129 +               f.close()
130 +
131 +               self.callback(text)
132 +
133  
134  class LyricPane(object):
135         def __init__(self, db, song_info):