The branch, eden has been updated
via 6f886cdf7395d6b46811baa28d0da2133fcd760b (commit)
from ce997933af5df742af3f993439499eda2ab66fd5 (commit)
- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=6f886cdf7395d6b46811baa28d0da2133fcd760b
commit 6f886cdf7395d6b46811baa28d0da2133fcd760b
Author: amet <[email protected]>
Date: Sat Apr 14 22:39:09 2012 +0400
[script.cu.lyrics] -2.0.6
2.0.6
- Try all enabled scrapers until lyrics are found, thx to Yann Rouillard
- Try to correctly decode the artist/title for a radio stream, thx to Yann
Rouillard
- Gracefully handle the case where lyrics are not available due to
licensing issue, thx to Yann Rouillard
2.0.5
- lyricsmode search improvements, thx to chninkel
diff --git a/script.cu.lyrics/addon.xml b/script.cu.lyrics/addon.xml
index c6e9af7..329fef5 100644
--- a/script.cu.lyrics/addon.xml
+++ b/script.cu.lyrics/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.cu.lyrics"
name="CU Lyrics"
- version="2.0.4"
+ version="2.0.6"
provider-name="Amet">
<requires>
<import addon="xbmc.python" version="2.0"/>
diff --git a/script.cu.lyrics/changelog.txt b/script.cu.lyrics/changelog.txt
index 8f50a24..9864c14 100644
--- a/script.cu.lyrics/changelog.txt
+++ b/script.cu.lyrics/changelog.txt
@@ -1,3 +1,11 @@
+2.0.6
+- Try all enabled scrapers until lyrics are found, thx to Yann Rouillard
+- Try to correctly decode the artist/title for a radio stream, thx to Yann
Rouillard
+- Gracefully handle the case where lyrics are not available due to licensing
issue, thx to Yann Rouillard
+
+2.0.5
+- lyricsmode search improvements, thx to chninkel
+
2.0.4
- added lyricwiki service
diff --git a/script.cu.lyrics/resources/lib/gui.py
b/script.cu.lyrics/resources/lib/gui.py
index ec23e6a..a4fc80d 100755
--- a/script.cu.lyrics/resources/lib/gui.py
+++ b/script.cu.lyrics/resources/lib/gui.py
@@ -17,6 +17,8 @@ __settings__ = sys.modules[ "__main__" ].__settings__
__language__ = sys.modules[ "__main__" ].__language__
__cwd__ = sys.modules[ "__main__" ].__cwd__
+LYRIC_SCRAPER_DIR = os.path.join(__cwd__, "resources", "lib", "scrapers")
+
class GUI( xbmcgui.WindowXMLDialog ):
def __init__( self, *args, **kwargs ):
xbmcgui.WindowXMLDialog.__init__( self )
@@ -24,20 +26,21 @@ class GUI( xbmcgui.WindowXMLDialog ):
self.current_song = Song.current()
self.current_file = xbmc.Player().getPlayingFile()
self.song_info = xbmc.Player().getMusicInfoTag().getTitle()
+ self.scrapers = []
def onInit( self ):
self.setup_all()
def setup_all( self ):
self.setup_variables()
- self.get_scraper()
+ self.get_scraper_list()
self.getMyPlayer()
- def get_scraper( self ):
- exec ( "from scrapers.%s import lyricsScraper as lyricsScraper" %
(__settings__.getSetting( "scraper")))
- self.LyricsScraper = lyricsScraper.LyricsFetcher()
- self.scraper_title = lyricsScraper.__title__
- self.scraper_exceptions = lyricsScraper.__allow_exceptions__
+ def get_scraper_list( self ):
+ for scraper in os.listdir(LYRIC_SCRAPER_DIR):
+ if os.path.isdir(os.path.join(LYRIC_SCRAPER_DIR, scraper)) and
__settings__.getSetting( scraper ) == "true":
+ exec ( "from scrapers.%s import lyricsScraper as
lyricsScraper_%s" % (scraper, scraper))
+ exec (
"self.scrapers.append(lyricsScraper_%s.LyricsFetcher())" % scraper)
def setup_variables( self ):
self.artist = None
@@ -66,7 +69,10 @@ class GUI( xbmcgui.WindowXMLDialog ):
lyrics, error = self.get_lyrics_from_file( song, next_song )
if ( lyrics is None ):
- lyrics, error = self.LyricsScraper.get_lyrics_thread( song )
+ for scraper in self.scrapers:
+ lyrics, error = scraper.get_lyrics_thread( song )
+ if lyrics is not None:
+ break
if ( lyrics is not None ):
try:
diff --git
a/script.cu.lyrics/resources/lib/scrapers/lyricsmode/lyricsScraper.py
b/script.cu.lyrics/resources/lib/scrapers/lyricsmode/lyricsScraper.py
index ca8d309..90d5b97 100644
--- a/script.cu.lyrics/resources/lib/scrapers/lyricsmode/lyricsScraper.py
+++ b/script.cu.lyrics/resources/lib/scrapers/lyricsmode/lyricsScraper.py
@@ -139,6 +139,8 @@ class LyricsFetcher:
self.clean_lyrics_regex = re.compile( "<.+?>" )
self.normalize_lyrics_regex = re.compile( "&#[x]*(?P<name>[0-9]+);*" )
self.clean_br_regex = re.compile( "<br[ /]*>[\s]*", re.IGNORECASE )
+ self.search_results_regex = re.compile("<a
href=\"[^\"]+\">([^<]+)</a></td>[^<]+<td><a href=\"([^\"]+)\"
class=\"b\">[^<]+</a></td>", re.IGNORECASE)
+ self.next_results_regex = re.compile("<A href=\"([^\"]+)\"
class=\"pages\">next .</A>", re.IGNORECASE)
def get_lyrics_start(self, *args):
lyricThread = threading.Thread(target=self.get_lyrics_thread,
args=args)
@@ -151,17 +153,51 @@ class LyricsFetcher:
l.song = song
try: # below is borowed from XBMC Lyrics
url = "http://www.lyricsmode.com/lyrics/%s/%s/%s.html" %
(song.artist.lower()[:1],song.artist.lower().replace(" ","_"),
song.title.lower().replace(" ","_"), )
- print "Search url: %s" % (url)
- song_search = urllib.urlopen(url).read()
+ lyrics_found = False
+ while True:
+ print "Search url: %s" % (url)
+ song_search = urllib.urlopen(url).read()
+ if song_search.find("<div id='songlyrics_h' class='dn'>") >= 0:
+ break
+
+ if lyrics_found:
+ # if we're here, we found the lyrics page but it didn't
+ # contains the lyrics part (licensing issue or some bug)
+ return None, "No lyrics found"
+
+ # Let's try to use the research box if we didn't yet
+ if not 'search' in url:
+ url = "http://www.lyricsmode.com/search.php?what=songs&s="
+ urllib.quote_plus(song.title.lower())
+ else:
+ # the search gave more than on result, let's try to find
our song
+ url = ""
+ start = song_search.find('<!--output-->')
+ end = song_search.find('<!--/output-->', start)
+ results = self.search_results_regex.findall(song_search,
start, end)
+
+ for result in results:
+ if result[0].lower() in song.artist.lower():
+ url = "http://www.lyricsmode.com" + result[1]
+ lyrics_found = True
+ break
+
+ if not url:
+ # Is there a next page of results ?
+ match =
self.next_results_regex.search(song_search[end:])
+ if match:
+ url = "http://www.lyricsmode.com/search.php" +
match.group(1)
+ else:
+ return None, "No lyrics found"
+
lyr = song_search.split("<div id='songlyrics_h'
class='dn'>")[1].split('<!-- /SONG LYRICS -->')[0]
lyr = self.clean_br_regex.sub( "\n", lyr ).strip()
lyr = self.clean_lyrics_regex.sub( "", lyr ).strip()
lyr = self.normalize_lyrics_regex.sub( lambda m: unichr( int(
m.group( 1 ) ) ), lyr.decode("ISO-8859-1") )
lir = []
for line in lyr.splitlines():
- line.strip()
- if line.find("Lyrics from:") < 0:
- lir.append(line)
+ line.strip()
+ if line.find("Lyrics from:") < 0:
+ lir.append(line)
lyr = u"\n".join( lir )
l.lyrics = lyr
l.source = __title__
diff --git a/script.cu.lyrics/resources/lib/song.py
b/script.cu.lyrics/resources/lib/song.py
index 697dd8f..d0fbbb3 100644
--- a/script.cu.lyrics/resources/lib/song.py
+++ b/script.cu.lyrics/resources/lib/song.py
@@ -2,6 +2,7 @@ import os
import utilities
import xbmc
import sys
+import re
__cwd__ = sys.modules[ "__main__" ].__cwd__
__profile__ = sys.modules[ "__main__" ].__profile__
@@ -28,22 +29,41 @@ class Song:
@staticmethod
def current():
- song = Song()
- song.title = xbmc.getInfoLabel( "MusicPlayer.Title" )
- song.artist = xbmc.getInfoLabel( "MusicPlayer.Artist")
-
+ song = Song.by_offset(0)
+
+ if not song.artist and not xbmc.getInfoLabel(
"MusicPlayer.TimeRemaining"):
+ # no artist and infinite playing time ? We probably listen to a
radio
+ # which usually set the song title as "Artist - Title" (via ICY
StreamTitle)
+ sep = song.title.find("-")
+ if sep > 1:
+ song.artist = song.title[:sep - 1].strip()
+ song.title = song.title[sep + 1:].strip()
+ # The title in the radio often contains some additional
+ # bracketed information at the end:
+ # Radio version, short version, year of the song...
+ # It often disturbs the lyrics search so we remove it
+ song.title = re.sub(r'\([^\)]*\)$', '', song.title)
+
print "Current Song: %s:%s" % (song.artist, song.title)
-
return song
@staticmethod
def next():
+ song = Song.by_offset(1)
+ print "Next Song: %s:%s" % (song.artist, song.title)
+
+ return song
+
+ @staticmethod
+ def by_offset(offset = 0):
song = Song()
- song.title = xbmc.getInfoLabel( "MusicPlayer.offset(1).Title" )
+ if offset > 0:
+ offset_str = ".offset(%i)" % offset
+ else:
+ offset_str = ""
+ song.title = xbmc.getInfoLabel( "MusicPlayer%s.Title" % offset_str)
song.title = utilities.deAccent(song.title)
- song.artist = xbmc.getInfoLabel( "MusicPlayer.offset(1).Artist")
+ song.artist = xbmc.getInfoLabel( "MusicPlayer%s.Artist" % offset_str)
song.artist = utilities.deAccent(song.artist)
- print "Next Song: %s:%s" % (song.artist, song.title)
-
return song
diff --git a/script.cu.lyrics/resources/settings.xml
b/script.cu.lyrics/resources/settings.xml
index 6503a0f..12cbab5 100644
--- a/script.cu.lyrics/resources/settings.xml
+++ b/script.cu.lyrics/resources/settings.xml
@@ -5,6 +5,10 @@
<setting id="save_lyrics" type="bool" label="30101" default="true"/>
<setting id="show_embeded_lyrics" type="bool" label="30107"
default="true"/>
<setting id="save_embeded_lyrics" type="bool" visible= "eq(-1,true)"
enable="eq(-1,true)" label="30108" default="false"/>
- <setting id="scraper" type="fileenum" mask="/" label="30109"
default="lyricstime" values="/resources/lib/scrapers" />
+ </category>
+ <category label="30109">
+ <setting id="lyricsmode" type="bool" label="Lyrics Mode" default="true"/>
+ <setting id="lyricstime" type="bool" label="lyrics.time" default="true"/>
+ <setting id="lyricwiki" type="bool" label="Lyrics Wiki" default="true"/>
</category>
</settings>
-----------------------------------------------------------------------
Summary of changes:
script.cu.lyrics/addon.xml | 2 +-
script.cu.lyrics/changelog.txt | 8 +++
script.cu.lyrics/resources/lib/gui.py | 20 ++++++---
.../lib/scrapers/lyricsmode/lyricsScraper.py | 46 +++++++++++++++++--
script.cu.lyrics/resources/lib/song.py | 38 ++++++++++++----
script.cu.lyrics/resources/settings.xml | 6 ++-
6 files changed, 97 insertions(+), 23 deletions(-)
hooks/post-receive
--
Scripts
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons