MythTV  master
gomaudio.py
Go to the documentation of this file.
1 # -*- Mode: python; coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*-
2 """
3 Scraper for http://newlyrics.gomtv.com/
4 
5 edge
6 """
7 
8 import sys
9 import os
10 import socket
11 import hashlib
12 import urllib
13 import re
14 import unicodedata
15 from optparse import OptionParser
16 from common import utilities
17 from common import audiofile
18 
19 __author__ = "Paul Harrison and edge'"
20 __title__ = "GomAudio"
21 __description__ = "Search http://newlyrics.gomtv.com for lyrics"
22 __priority__ = "135"
23 __version__ = "0.1"
24 __syncronized__ = True
25 
26 debug = False
27 
28 socket.setdefaulttimeout(10)
29 
30 GOM_URL = "http://newlyrics.gomtv.com/cgi-bin/lyrics.cgi?cmd=find_get_lyrics&file_key=%s&title=%s&artist=%s&from=gomaudio_local"
31 
32 def remove_accents(data):
33  nfkd_data = unicodedata.normalize('NFKD', data)
34  return u"".join([c for c in nfkd_data if not unicodedata.combining(c)])
35 
36 
37 class gomClient(object):
38  '''
39  privide Gom specific function, such as key from mp3
40  '''
41  @staticmethod
42  def GetKeyFromFile(file):
43  musf = audiofile.AudioFile()
44  musf.Open(file)
45  buf = musf.ReadAudioStream(100*1024) # 100KB from audio data
46  musf.Close()
47  # calculate hashkey
48  m = hashlib.md5(); m.update(buf);
49  return m.hexdigest()
50 
51  @staticmethod
52  def mSecConv(msec):
53  s,ms = divmod(msec/10,100)
54  m,s = divmod(s,60)
55  return m,s,ms
56 
58  def __init__( self ):
59  self.base_url = "http://newlyrics.gomtv.com/"
60 
61  def get_lyrics(self, lyrics):
62  utilities.log(debug, "%s: searching lyrics for %s - %s - %s" % (__title__, lyrics.artist, lyrics.album, lyrics.title))
63  key = None
64  try:
65  ext = os.path.splitext(lyrics.filename.decode("utf-8"))[1].lower()
66  sup_ext = ['.mp3', '.ogg', '.wma', '.flac', '.ape', '.wav']
67  if ext in sup_ext:
68  key = gomClient.GetKeyFromFile(lyrics.filename)
69  if not key:
70  return False
71  url = GOM_URL %(key, urllib.quote(remove_accents(lyrics.title.decode('utf-8')).encode('euc-kr')), (remove_accents(lyrics.artist.decode('utf-8')).encode('euc-kr')))
72  response = urllib.urlopen(url)
73  Page = response.read()
74  except:
75  utilities.log(True, "%s: %s::%s (%d) [%s]" % (
76  __title__, self.__class__.__name__,
77  sys.exc_info()[ 2 ].tb_frame.f_code.co_name,
78  sys.exc_info()[ 2 ].tb_lineno,
79  sys.exc_info()[ 1 ]
80  ))
81  return False
82 
83  if Page[:Page.find('>')+1] != '<lyrics_reply result="0">':
84  return False
85  syncs = re.compile('<sync start="(\d+)">([^<]*)</sync>').findall(Page)
86  lyrline = []
87  lyrline.append( "[ti:%s]" %lyrics.title )
88  lyrline.append( "[ar:%s]" %lyrics.artist )
89  for sync in syncs:
90  # timeformat conversion
91  t = "%02d:%02d.%02d" % gomClient.mSecConv( int(sync[0]) )
92  # unescape string
93  try:
94  s = unicode(sync[1], "euc-kr").encode("utf-8").replace("&apos;","'").replace("&quot;",'"')
95  lyrline.append( "[%s]%s" %(t,s) )
96  except:
97  pass
98  lyrics.lyrics = '\n'.join( lyrline )
99  return True
100 
102  found = False
103  lyrics = utilities.Lyrics()
104  lyrics.source = __title__
105  lyrics.syncronized = __syncronized__
106  lyrics.artist = 'Robb Benson'
107  lyrics.album = 'Demo Tracks'
108  lyrics.title = 'Lone Rock'
109  lyrics.filename = os.path.dirname(os.path.abspath(__file__)) + '/examples/taglyrics.mp3'
110 
111  fetcher = LyricsFetcher()
112  found = fetcher.get_lyrics(lyrics)
113 
114  if found:
115  utilities.log(True, "Everything appears in order.")
116  sys.exit(0)
117 
118  utilities.log(True, "The lyrics for the test search failed!")
119  sys.exit(1)
120 
121 def buildLyrics(lyrics):
122  from lxml import etree
123  xml = etree.XML(u'<lyrics></lyrics>')
124  etree.SubElement(xml, "artist").text = lyrics.artist
125  etree.SubElement(xml, "album").text = lyrics.album
126  etree.SubElement(xml, "title").text = lyrics.title
127  etree.SubElement(xml, "syncronized").text = 'True' if __syncronized__ else 'False'
128  etree.SubElement(xml, "grabber").text = lyrics.source
129 
130  lines = lyrics.lyrics.splitlines()
131  for line in lines:
132  etree.SubElement(xml, "lyric").text = line
133 
134  utilities.log(True, etree.tostring(xml, encoding='UTF-8', pretty_print=True,
135  xml_declaration=True))
136  sys.exit(0)
137 
139  from lxml import etree
140  version = etree.XML(u'<grabber></grabber>')
141  etree.SubElement(version, "name").text = __title__
142  etree.SubElement(version, "author").text = __author__
143  etree.SubElement(version, "command").text = 'gomaudio.py'
144  etree.SubElement(version, "type").text = 'lyrics'
145  etree.SubElement(version, "description").text = __description__
146  etree.SubElement(version, "version").text = __version__
147  etree.SubElement(version, "priority").text = __priority__
148  etree.SubElement(version, "syncronized").text = 'True' if __syncronized__ else 'False'
149 
150  utilities.log(True, etree.tostring(version, encoding='UTF-8', pretty_print=True,
151  xml_declaration=True))
152  sys.exit(0)
153 
154 def main():
155  global debug
156 
157  parser = OptionParser()
158 
159  parser.add_option('-v', "--version", action="store_true", default=False,
160  dest="version", help="Display version and author")
161  parser.add_option('-t', "--test", action="store_true", default=False,
162  dest="test", help="Test grabber with a know good search")
163  parser.add_option('-s', "--search", action="store_true", default=False,
164  dest="search", help="Search for lyrics.")
165  parser.add_option('-a', "--artist", metavar="ARTIST", default=None,
166  dest="artist", help="Artist of track.")
167  parser.add_option('-b', "--album", metavar="ALBUM", default=None,
168  dest="album", help="Album of track.")
169  parser.add_option('-n', "--title", metavar="TITLE", default=None,
170  dest="title", help="Title of track.")
171  parser.add_option('-f', "--filename", metavar="FILENAME", default=None,
172  dest="filename", help="Filename of track.")
173  parser.add_option('-d', '--debug', action="store_true", default=False,
174  dest="debug", help=("Show debug messages"))
175 
176  opts, args = parser.parse_args()
177 
178  lyrics = utilities.Lyrics()
179  lyrics.source = __title__
180  lyrics.syncronized = __syncronized__
181 
182  if opts.debug:
183  debug = True
184 
185  if opts.version:
186  buildVersion()
187 
188  if opts.test:
190 
191  if opts.artist:
192  lyrics.artist = opts.artist
193  if opts.album:
194  lyrics.album = opts.album
195  if opts.title:
196  lyrics.title = opts.title
197  if opts.filename:
198  lyrics.filename = opts.filename
199 
200  fetcher = LyricsFetcher()
201  if fetcher.get_lyrics(lyrics):
202  buildLyrics(lyrics)
203  sys.exit(0)
204  else:
205  utilities.log(True, "No lyrics found for this track")
206  sys.exit(1)
207 
208 
209 if __name__ == '__main__':
210  main()
gomaudio.gomClient
Definition: gomaudio.py:37
gomaudio.LyricsFetcher.get_lyrics
def get_lyrics(self, lyrics)
Definition: gomaudio.py:61
gomaudio.LyricsFetcher.base_url
base_url
Definition: gomaudio.py:59
gomaudio.gomClient.mSecConv
def mSecConv(msec)
Definition: gomaudio.py:52
gomaudio.gomClient.GetKeyFromFile
def GetKeyFromFile(file)
Definition: gomaudio.py:42
gomaudio.LyricsFetcher
Definition: gomaudio.py:57
gomaudio.LyricsFetcher.__init__
def __init__(self)
Definition: gomaudio.py:58
gomaudio.performSelfTest
def performSelfTest()
Definition: gomaudio.py:101
gomaudio.buildLyrics
def buildLyrics(lyrics)
Definition: gomaudio.py:121
gomaudio.buildVersion
def buildVersion()
Definition: gomaudio.py:138
musicbrainzngs.compat.unicode
unicode
Definition: compat.py:50
gomaudio.main
def main()
Definition: gomaudio.py:154
gomaudio.remove_accents
def remove_accents(data)
Definition: gomaudio.py:32