1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#!/usr/bin/env python
# Copyright (C) 2009 by Silviu Grijincu <silviu.grijincu@gmail.com>.
# Published under the terms of the GNU General Public License (GPL).
# INFO
# lyrics.py fetches lyrics from http://lyricwiki.org/.
# The script is triggered by a key that is not already
# in use by shell-fm and must be set. (See bellow)
# INSTALL
# Save lyrics.py in the ~/.shell-fm/scripts/ directory.
# (if the directories do not exist please create them)
# To enable the plugin you must have a configuration file.
# 1.Create a file named shell-fm.rc in the ~/.shell-fm/ directory.
# 2.Put the following line in shell-fm.rc file :
# key0x?? = /usr/bin/python ~/.shell-fm/scripts/lyrics.py %a %t
# 4.Replace ?? with the ASCII hex code of the triggering key you wold like to use.
# for example, to use ` (backquote) as a trigger replace ?? with 60 as bellow:
# key0x60 = /usr/bin/python ~/.shell-fm/scripts/lyrics.py %a %t
from urllib2 import *
from sys import argv
class LyricSource:
"A lyric soruce"
def __init__(self, artist, title):
"init a Lyric source"
self.artist = artist
self.title = title
def get_lyrics(self):
"get lyrics."
return (False, "this is a dummy lyric source, no lyric can be found")
class DummyLyricSource(LyricSource):
def __init__(self, artist, title):
LyricSource.__init__(self, artist, title)
def get_lyrics(self):
return (False, "dummy error message from DummyLyricSource")
class LyricWiki(LyricSource):
def __init__(self, artist, title):
LyricSource.__init__(self, artist, title)
self.URL = 'http://lyricwiki.org/'
def canonical(self, str):
# capitalize every word after an ' ' and
# replace ' ' with '_'
return "_".join(map((lambda x : x.capitalize()), str.split(' ')))
def get_url(self):
return self.URL + self.canonical(self.artist) + ':' + self.canonical(self.title)
def get_html(self, url):
try:
html = urlopen(url).read()
return (True, html)
except HTTPError, e:
errmsg = 'The server couldn\'t fulfill the request for ' + url
errmsg += 'Error code: ' + str(e.code)
return (False, errmsg)
except URLError, e:
errmsg = 'We failed to reach the server ' + url
errmsg += 'Reason: ' + str(e.reason)
return (False, errmsg)
else:
return (False, "unexpected path reached in LyricWiki.get_html")
def filter_html_markers(self, html):
rules = ( ('<br />', '\n '),
('<br>', '\n '),
('>', '>'),
('<', '<'),
(' ', ' '))
for (x, y) in rules:
html = html.replace(x, y)
return ' ' + html
def parse_lyrics(self, html, url):
instrumental = html.find('This song is an instrumental.')
if instrumental <> -1:
return (True, 'This song is instrumental.')
start_marker = '<div class=\'lyricbox\' >'
found = html.find(start_marker)
if found == -1:
return (False, 'Lyrics not found at ' + url + '.')
start = found + len(start_marker)
end = html.find('\n', start)
lyrics = self.filter_html_markers(html[start:end])
return (True, lyrics)
def get_lyrics(self):
url = self.get_url()
(success, msg) = self.get_html(url)
if success == False:
return (False, msg)
html = msg
return self.parse_lyrics(html, url)
debug=False
def main(argv):
artist = argv[1]
title = argv[2]
# TODO: after adding a new LyricSouce class, append
# an object of that class here
lyric_sources = (LyricWiki(artist, title), DummyLyricSource(artist, title))
lyrics = map( (lambda x : x.get_lyrics()), lyric_sources)
# print the first lyrics found
for (success, lyric) in lyrics:
if success == True:
print lyric
return
if debug:
# if no lyrics found, print all error messages
for (success, errmsg) in lyrics:
print errmsg
else:
print 'Lyrics not found.'
if __name__ == "__main__":
main(argv)
|