diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/changelog rhythmbox-plugin-llyrics-1.1/debian/changelog --- rhythmbox-plugin-llyrics-0.5.4/debian/changelog 2014-04-22 18:14:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/changelog 2016-02-05 21:43:05.000000000 +0000 @@ -1,3 +1,9 @@ +rhythmbox-plugin-llyrics (1.1-1~rb3) trusty; urgency=medium + + * new upstream release + + -- fossfreedom Fri, 05 Feb 2016 21:42:02 +0000 + rhythmbox-plugin-llyrics (0.5.4-1~rb3) trusty; urgency=low * bug fix to stop UI freezes diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/control rhythmbox-plugin-llyrics-1.1/debian/control --- rhythmbox-plugin-llyrics-0.5.4/debian/control 2014-03-24 23:50:56.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/control 2016-02-05 21:51:32.000000000 +0000 @@ -2,14 +2,14 @@ Section: misc Priority: extra Maintainer: fossfreedom -Build-Depends: debhelper (>= 8.0.0) -Standards-Version: 3.9.4 +Build-Depends: debhelper (>= 9) +Standards-Version: 3.9.6 Homepage: https://github.com/dmo60/lLyrics Vcs-Git: git://github.com/dmo60/lLyrics.git Vcs-Browser: https://github.com/dmo60/lLyrics.git Package: rhythmbox-plugin-llyrics Architecture: all -Depends: ${misc:Depends}, python3-lxml +Depends: ${misc:Depends}, python3-lxml, python3-chardet Description: rhythmbox alternative lyrics plugin lyrics plugin for rhythmbox 3.0 and above diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/install rhythmbox-plugin-llyrics-1.1/debian/install --- rhythmbox-plugin-llyrics-0.5.4/debian/install 2013-11-01 20:57:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/install 2016-02-05 21:58:02.000000000 +0000 @@ -1,3 +1,7 @@ -lLyrics/* /usr/lib/rhythmbox/plugins/lLyrics +lLyrics/*.py /usr/lib/rhythmbox/plugins/lLyrics +lLyrics/*.plugin /usr/lib/rhythmbox/plugins/lLyrics +lLyrics/*.png /usr/lib/rhythmbox/plugins/lLyrics schema/* /usr/share/glib-2.0/schemas/ -debian/locale/* /usr/share/rhythmbox/plugins/lLyrics/locale +lLyrics/locale/de /usr/share/locale/ +lLyrics/locale/fr /usr/share/locale/ +lLyrics/locale/pl /usr/share/locale/ Binary files /tmp/tmpDlQlJg/ZfCtmvM9Up/rhythmbox-plugin-llyrics-0.5.4/debian/locale/de/LC_MESSAGES/lLyrics.mo and /tmp/tmpDlQlJg/Ku5Ts16dxv/rhythmbox-plugin-llyrics-1.1/debian/locale/de/LC_MESSAGES/lLyrics.mo differ diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/locale/de.po rhythmbox-plugin-llyrics-1.1/debian/locale/de.po --- rhythmbox-plugin-llyrics-0.5.4/debian/locale/de.po 2014-04-07 17:12:20.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/locale/de.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -# German translations for PACKAGE package. -# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# timo , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-03-31 18:45+0200\n" -"PO-Revision-Date: 2012-08-05 12:01+0200\n" -"Last-Translator: Timo Loewe \n" -"Language-Team: German\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: ../lLyrics.py:276 ../lLyrics.py:295 -msgid "Lyrics" -msgstr "Liedtexte" - -#: ../lLyrics.py:277 -msgid "Display lyrics for the current playing song" -msgstr "Zeige Liedtext für den gerade gespielten Titel" - -#: ../lLyrics.py:281 -msgid "Show lyrics" -msgstr "Liedtext anzeigen" - -#: ../lLyrics.py:282 -msgid "Search and display lyrics for this song" -msgstr "Suche und zeige Liedtext für diesen Titel" - -#. create save and cancel buttons for edited lyrics -#: ../lLyrics.py:343 -msgid "Save" -msgstr "Speichern" - -#: ../lLyrics.py:345 -msgid "Cancel" -msgstr "Abbrechen" - -#. button for closing on demand lyrics -#: ../lLyrics.py:352 -msgid "Back to playing song" -msgstr "Zurück zum aktuellen Titel" - -#: ../lLyrics.py:388 ../lLyrics.py:431 -msgid "External" -msgstr "Extern" - -#: ../lLyrics.py:390 ../lLyrics.py:433 ../lLyrics.py:882 -msgid "From cache file" -msgstr "Aus Cache Datei" - -#: ../lLyrics.py:394 ../Config.py:314 -msgid "Sources" -msgstr "Quellen" - -#: ../lLyrics.py:398 -msgid "Scan next source" -msgstr "Durchsuche nächste Quelle" - -#: ../lLyrics.py:399 -msgid "Scan all sources" -msgstr "Durchsuche alle Quellen" - -#: ../lLyrics.py:401 -msgid "Search online" -msgstr "Online suchen" - -#: ../lLyrics.py:403 -msgid "Mark as instrumental" -msgstr "Als instrumental markieren" - -#: ../lLyrics.py:405 -msgid "Clear lyrics" -msgstr "Liedtext löschen" - -#: ../lLyrics.py:406 -msgid "Edit lyrics" -msgstr "Liedtext bearbeiten" - -#: ../lLyrics.py:410 -msgid "Preferences" -msgstr "Einstellungen" - -#: ../lLyrics.py:671 -msgid "lLyrics Preferences" -msgstr "lLyrics Einstellungen" - -#: ../lLyrics.py:731 ../lLyrics.py:756 ../lLyrics.py:788 ../lLyrics.py:818 -msgid "searching lyrics..." -msgstr "suche Liedtexte..." - -#: ../lLyrics.py:932 -msgid "No lyrics found" -msgstr "Keine Liedtexte gefunden" - -#: ../Config.py:148 -msgid "Show sidebar on first playback" -msgstr "Seitenleiste bei Wiedergabestart einblenden" - -#: ../Config.py:161 -msgid "Save lyrics " -msgstr "Liedtexte speichern" - -#: ../Config.py:164 -msgid "" -"Whether to automatically save retrieved lyrics in the folder specified below" -msgstr "" -"Speichert gefundene Liedtexte automatisch im nachfolgend ausgewählten Ordner" - -#: ../Config.py:184 -msgid "default" -msgstr "Standardeinstellung" - -#: ../Config.py:187 -msgid "Folder for lyrics" -msgstr "Ordner für Liedtexte" - -#: ../Config.py:201 -msgid "Always ignore parentheses in song title" -msgstr "Klammern im Songtitel immer ignorieren" - -#: ../Config.py:204 -msgid "" -"When turned off, only parentheses containing specific strings (e.g. 'remix', " -"'live', 'edit', etc) are filtered" -msgstr "" -"Falls ausgeschaltet, werden nur Klammern mit bestimmten Zeichenketten (z.B. " -"'remix', 'live', 'edit', etc) gefiltert" - -#. check buttons for lyric sources -#: ../Config.py:223 -msgid "Sources:" -msgstr "Quellen:" - -#: ../Config.py:254 -msgid "" -"Warning: 'External' calls the Rhythmbox built-in lyrics plugin. It can not " -"be guaranteed that the provided engines work properly. If you experience any " -"problems, deactivate this option." -msgstr "" -"Warnung: 'Extern' nutzt das Rhythmbox-interne Liedtexte Plugin. Es kann " -"nicht garantiert werden, dass dieses korrekt funktioniert. Falls Probleme " -"auftreten, deaktivieren Sie diese Option." - -#: ../Config.py:279 -msgid "Hide sidebar label" -msgstr "Verstecke die Überschrift der Seitenleiste" - -#: ../Config.py:293 -msgid "Show lyrics in left sidebar instead of right one" -msgstr "Zeige Liedtexte in der linken statt der rechten Seitenleiste" - -#: ../Config.py:296 -msgid "" -"You have to disable and re-enable this plugin or restart Rhythmbox to apply " -"changes here" -msgstr "" -"Zum Anwenden der Änderung muss das Plugin de- und reaktiviert oder Rhythmbox " -"neu gestartet werden" - -#: ../Config.py:313 -msgid "General" -msgstr "Allgemein" - -#: ../Config.py:315 -msgid "Appearance" -msgstr "Erscheinungsbild" Binary files /tmp/tmpDlQlJg/ZfCtmvM9Up/rhythmbox-plugin-llyrics-0.5.4/debian/locale/fr/LC_MESSAGES/lLyrics.mo and /tmp/tmpDlQlJg/Ku5Ts16dxv/rhythmbox-plugin-llyrics-1.1/debian/locale/fr/LC_MESSAGES/lLyrics.mo differ diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/locale/fr.po rhythmbox-plugin-llyrics-1.1/debian/locale/fr.po --- rhythmbox-plugin-llyrics-0.5.4/debian/locale/fr.po 2014-04-07 17:12:20.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/locale/fr.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -# French translations for PACKAGE package. -# Copyright (C) 2014 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Meradi , 2014. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-03-31 18:45+0200\n" -"PO-Revision-Date: 2014-03-30 17:50+0200\n" -"Last-Translator: Meradi \n" -"Language-Team: French\n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -#: ../lLyrics.py:276 ../lLyrics.py:295 -msgid "Lyrics" -msgstr "Paroles" - -#: ../lLyrics.py:277 -msgid "Display lyrics for the current playing song" -msgstr "Afficher les paroles du morceau en cours de lecture" - -#: ../lLyrics.py:281 -msgid "Show lyrics" -msgstr "Afficher les paroles" - -#: ../lLyrics.py:282 -msgid "Search and display lyrics for this song" -msgstr "Chercher et afficher les paroles de ce morceau" - -#. create save and cancel buttons for edited lyrics -#: ../lLyrics.py:343 -msgid "Save" -msgstr "Enregistrer" - -#: ../lLyrics.py:345 -msgid "Cancel" -msgstr "Annuler" - -#. button for closing on demand lyrics -#: ../lLyrics.py:352 -msgid "Back to playing song" -msgstr "Retourner au morceau en cours de lecture" - -#: ../lLyrics.py:388 ../lLyrics.py:431 -msgid "External" -msgstr "Externe" - -#: ../lLyrics.py:390 ../lLyrics.py:433 ../lLyrics.py:882 -msgid "From cache file" -msgstr "A partir du fichier de cache " - -#: ../lLyrics.py:394 ../Config.py:314 -msgid "Sources" -msgstr "Sources" - -#: ../lLyrics.py:398 -msgid "Scan next source" -msgstr "Chercher la source suivante" - -#: ../lLyrics.py:399 -msgid "Scan all sources" -msgstr "Chercher tous les sources" - -#: ../lLyrics.py:401 -msgid "Search online" -msgstr "Chercher en ligne" - -#: ../lLyrics.py:403 -msgid "Mark as instrumental" -msgstr "Marquer ce morceau comme instrumental" - -#: ../lLyrics.py:405 -msgid "Clear lyrics" -msgstr "Effacer les paroles" - -#: ../lLyrics.py:406 -msgid "Edit lyrics" -msgstr "Modifier les paroles" - -#: ../lLyrics.py:410 -msgid "Preferences" -msgstr "Préférences" - -#: ../lLyrics.py:671 -msgid "lLyrics Preferences" -msgstr "Préférences de lLyrics" - -#: ../lLyrics.py:731 ../lLyrics.py:756 ../lLyrics.py:788 ../lLyrics.py:818 -msgid "searching lyrics..." -msgstr "Recherche des paroles..." - -#: ../lLyrics.py:932 -msgid "No lyrics found" -msgstr "Aucune paroles trouvées" - -#: ../Config.py:148 -msgid "Show sidebar on first playback" -msgstr "Afficher le paneau latérale en début de lecture" - -#: ../Config.py:161 -msgid "Save lyrics " -msgstr "Enregistrer les paroles" - -#: ../Config.py:164 -msgid "" -"Whether to automatically save retrieved lyrics in the folder specified below" -msgstr "" -"Enregistrer les paroles trouvées automatiquement dans le dossier sélectionné " -"ci-dessous" - -#: ../Config.py:184 -msgid "default" -msgstr "défault" - -#: ../Config.py:187 -msgid "Folder for lyrics" -msgstr "Dossier où enregistrer les paroles" - -#: ../Config.py:201 -msgid "Always ignore parentheses in song title" -msgstr "Ignorer toujours les parenthèses dans le titre des morceaux" - -#: ../Config.py:204 -msgid "" -"When turned off, only parentheses containing specific strings (e.g. 'remix', " -"'live', 'edit', etc) are filtered" -msgstr "" -"Si désactivé, seules certaines chaînes de caractères (par exemple « remix », " -"« live », « edit », etc) seront filtrées" - -#. check buttons for lyric sources -#: ../Config.py:223 -msgid "Sources:" -msgstr "Sources" - -#: ../Config.py:254 -msgid "" -"Warning: 'External' calls the Rhythmbox built-in lyrics plugin. It can not " -"be guaranteed that the provided engines work properly. If you experience any " -"problems, deactivate this option." -msgstr "" - -#: ../Config.py:279 -msgid "Hide sidebar label" -msgstr "Cacher le titre du paneau latérale" - -#: ../Config.py:293 -msgid "Show lyrics in left sidebar instead of right one" -msgstr "Afficher les paroles dans le paneau latérale gauche" - -#: ../Config.py:296 -msgid "" -"You have to disable and re-enable this plugin or restart Rhythmbox to apply " -"changes here" -msgstr "" -"Vous devez désactiver et réactiver ce plugin ou redémarrer Rhythmbox pour " -"appliquerles changements" - -#: ../Config.py:313 -msgid "General" -msgstr "Géneral" - -#: ../Config.py:315 -msgid "Appearance" -msgstr "Apparence" diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/locale/messages.pot rhythmbox-plugin-llyrics-1.1/debian/locale/messages.pot --- rhythmbox-plugin-llyrics-0.5.4/debian/locale/messages.pot 2014-04-07 17:12:20.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/locale/messages.pot 1970-01-01 00:00:00.000000000 +0000 @@ -1,165 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-03-31 18:45+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../lLyrics.py:276 ../lLyrics.py:295 -msgid "Lyrics" -msgstr "" - -#: ../lLyrics.py:277 -msgid "Display lyrics for the current playing song" -msgstr "" - -#: ../lLyrics.py:281 -msgid "Show lyrics" -msgstr "" - -#: ../lLyrics.py:282 -msgid "Search and display lyrics for this song" -msgstr "" - -#. create save and cancel buttons for edited lyrics -#: ../lLyrics.py:343 -msgid "Save" -msgstr "" - -#: ../lLyrics.py:345 -msgid "Cancel" -msgstr "" - -#. button for closing on demand lyrics -#: ../lLyrics.py:352 -msgid "Back to playing song" -msgstr "" - -#: ../lLyrics.py:388 ../lLyrics.py:431 -msgid "External" -msgstr "" - -#: ../lLyrics.py:390 ../lLyrics.py:433 ../lLyrics.py:882 -msgid "From cache file" -msgstr "" - -#: ../lLyrics.py:394 ../Config.py:314 -msgid "Sources" -msgstr "" - -#: ../lLyrics.py:398 -msgid "Scan next source" -msgstr "" - -#: ../lLyrics.py:399 -msgid "Scan all sources" -msgstr "" - -#: ../lLyrics.py:401 -msgid "Search online" -msgstr "" - -#: ../lLyrics.py:403 -msgid "Mark as instrumental" -msgstr "" - -#: ../lLyrics.py:405 -msgid "Clear lyrics" -msgstr "" - -#: ../lLyrics.py:406 -msgid "Edit lyrics" -msgstr "" - -#: ../lLyrics.py:410 -msgid "Preferences" -msgstr "" - -#: ../lLyrics.py:671 -msgid "lLyrics Preferences" -msgstr "" - -#: ../lLyrics.py:731 ../lLyrics.py:756 ../lLyrics.py:788 ../lLyrics.py:818 -msgid "searching lyrics..." -msgstr "" - -#: ../lLyrics.py:932 -msgid "No lyrics found" -msgstr "" - -#: ../Config.py:148 -msgid "Show sidebar on first playback" -msgstr "" - -#: ../Config.py:161 -msgid "Save lyrics " -msgstr "" - -#: ../Config.py:164 -msgid "" -"Whether to automatically save retrieved lyrics in the folder specified below" -msgstr "" - -#: ../Config.py:184 -msgid "default" -msgstr "" - -#: ../Config.py:187 -msgid "Folder for lyrics" -msgstr "" - -#: ../Config.py:201 -msgid "Always ignore parentheses in song title" -msgstr "" - -#: ../Config.py:204 -msgid "" -"When turned off, only parentheses containing specific strings (e.g. 'remix', " -"'live', 'edit', etc) are filtered" -msgstr "" - -#. check buttons for lyric sources -#: ../Config.py:223 -msgid "Sources:" -msgstr "" - -#: ../Config.py:254 -msgid "" -"Warning: 'External' calls the Rhythmbox built-in lyrics plugin. It can not " -"be guaranteed that the provided engines work properly. If you experience any " -"problems, deactivate this option." -msgstr "" - -#: ../Config.py:279 -msgid "Hide sidebar label" -msgstr "" - -#: ../Config.py:293 -msgid "Show lyrics in left sidebar instead of right one" -msgstr "" - -#: ../Config.py:296 -msgid "" -"You have to disable and re-enable this plugin or restart Rhythmbox to apply " -"changes here" -msgstr "" - -#: ../Config.py:313 -msgid "General" -msgstr "" - -#: ../Config.py:315 -msgid "Appearance" -msgstr "" diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/locale/POTFILES.in rhythmbox-plugin-llyrics-1.1/debian/locale/POTFILES.in --- rhythmbox-plugin-llyrics-0.5.4/debian/locale/POTFILES.in 2014-04-07 17:12:20.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/locale/POTFILES.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -lLyrics.py -Config.py diff -Nru rhythmbox-plugin-llyrics-0.5.4/debian/locale/TRANSLATIONS rhythmbox-plugin-llyrics-1.1/debian/locale/TRANSLATIONS --- rhythmbox-plugin-llyrics-0.5.4/debian/locale/TRANSLATIONS 2014-04-07 17:12:20.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/debian/locale/TRANSLATIONS 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -Help with translation is appreciated! - -If you want to provide locales for your language, start like this: - -1) Run "intltool-update -p -g messages". - This will recreate the messages.pot file so that is up to date with the latest lLyrics source files. - -2) Run "msginit --locale=YOUR_LANGUAGE_CODE". - Replace YOUR_LANGUAGE_CODE with your appropriate language short cut, e.g. "fr" for French or "ru" for Russian. - This will create a new .po file with your language code. - -Now you can translate all messages in the .po file into your language. The original string is given by "msgid", your translation should go to "msgstr". - Binary files /tmp/tmpDlQlJg/ZfCtmvM9Up/rhythmbox-plugin-llyrics-0.5.4/img/screenshot.png and /tmp/tmpDlQlJg/Ku5Ts16dxv/rhythmbox-plugin-llyrics-1.1/img/screenshot.png differ Binary files /tmp/tmpDlQlJg/ZfCtmvM9Up/rhythmbox-plugin-llyrics-0.5.4/img/screenshot-small.png and /tmp/tmpDlQlJg/Ku5Ts16dxv/rhythmbox-plugin-llyrics-1.1/img/screenshot-small.png differ diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/AZLyricsParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/AZLyricsParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/AZLyricsParser.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/AZLyricsParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -18,26 +18,26 @@ import Util + class Parser(object): - def __init__(self, artist, title): self.artist = artist self.title = title self.lyrics = "" - + def parse(self): # remove unwanted characters from artist and title strings clean_artist = self.artist if clean_artist.startswith("the "): clean_artist = clean_artist[4:] - clean_artist = clean_artist.replace("and", "") + clean_artist = clean_artist.replace(" and ", "") clean_artist = clean_artist.replace(" ", "") clean_artist = Util.remove_punctuation(clean_artist) - + clean_title = self.title clean_title = clean_title.replace(" ", "") clean_title = Util.remove_punctuation(clean_title) - + # create lyrics Url url = "http://www.azlyrics.com/lyrics/" + clean_artist + "/" + clean_title + ".html" print("azlyrics Url " + url) @@ -46,30 +46,29 @@ except: print("could not connect to azlyrics.com") return "" - + resp = Util.bytes_to_string(resp) self.lyrics = self.get_lyrics(resp) self.lyrics = string.capwords(self.lyrics, "\n").strip() - + return self.lyrics - + def get_lyrics(self, resp): # cut HTML source to relevant part - start = resp.find("") + start = resp.find("that. -->") if start == -1: print("lyrics start not found") return "" - resp = resp[(start+25):] - end = resp.find("") + resp = resp[(start + 9):] + end = resp.find("") if end == -1: print("lyrics end not found ") return "" - resp = resp[:(end-1)] - + resp = resp[:(end - 1)] + # replace unwanted parts - resp = resp.replace("
", "") + resp = resp.replace("
", "") resp = resp.replace("", "") resp = resp.replace("", "") - + return resp - diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/ChartlyricsParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/ChartlyricsParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/ChartlyricsParser.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/ChartlyricsParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -24,8 +24,8 @@ import Util + class Parser(HTMLParser): - def __init__(self, artist, title): HTMLParser.__init__(self) self.artist = artist @@ -33,15 +33,15 @@ self.tag = None self.correct = True self.lyrics = "" - + # define handler for parsing def handle_starttag(self, tag, attrs): self.tag = tag - + # definde handler for parsing def handle_endtag(self, tag): self.tag = None - + # definde handler for parsing def handle_data(self, data): if self.tag == "lyricsong": @@ -54,20 +54,20 @@ return if self.correct and self.tag == "lyric": self.lyrics = data - + def parse(self): # API searchLyric request - url = "http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect?artist=" + urllib.parse.quote(self.artist) + "&song=" + urllib.parse.quote(self.title) + url = "http://api.chartlyrics.com/apiv1.asmx/SearchLyricDirect?artist=" + urllib.parse.quote( + self.artist) + "&song=" + urllib.parse.quote(self.title) print("call chartlyrics API: " + url) try: resp = urllib.request.urlopen(url, None, 3).read() except: print("could not connect to chartlyric.com API") - + resp = Util.bytes_to_string(resp) self.feed(resp) - + self.lyrics = string.capwords(self.lyrics, "\n").strip() - + return self.lyrics - \ No newline at end of file diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/Config.py rhythmbox-plugin-llyrics-1.1/lLyrics/Config.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/Config.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/Config.py 2016-02-05 21:35:45.000000000 +0000 @@ -26,15 +26,14 @@ import lLyrics import lLyrics_rb3compat as Compat - DCONF_DIR = 'org.gnome.rhythmbox.plugins.llyrics' + class Config(object): - def __init__(self): self.settings = Gio.Settings(DCONF_DIR) - - def check_active_sources(self): + + def check_active_sources(self): # remove invalid entries changed = False entries = self.settings["active-sources"] @@ -43,11 +42,11 @@ entries.remove(source) changed = True print("remove invalid entry in active-sources: " + source) - + # update key, if changed if changed: self.settings["active-sources"] = entries - + def check_scanning_order(self): # remove invalid entries changed = False @@ -57,27 +56,27 @@ entries.remove(source) changed = True print("remove invalid entry in scanning-order: " + source) - + # fill up missing keys for source in lLyrics.LYRICS_SOURCES: if source not in entries: entries.append(source) changed = True print("append missing entry in scanning-order: " + source) - + # update key, if changed if changed: self.settings["scanning-order"] = entries - + def check_lyrics_folder(self): folder = self.settings["lyrics-folder"] changed = False - + # expand user directory if "~" in folder: folder = os.path.expanduser(folder) changed = True - + # path not set or invalid if not folder or not os.path.exists(folder): folder = os.path.join(RB.user_cache_dir(), "lyrics") @@ -86,13 +85,13 @@ os.mkdir(folder) changed = True print("invalid path in lyrics-folder, set to default") - + if changed: self.settings["lyrics-folder"] = folder - + def get_settings(self): return self.settings - + def get_lyrics_sources(self): self.check_active_sources() self.check_scanning_order() @@ -100,30 +99,29 @@ for source in self.settings["scanning-order"]: if source in self.settings["active-sources"]: lyrics_sources.append(source) - + return lyrics_sources - + def get_show_first(self): return self.settings["show-first"] - + def get_cache_lyrics(self): return self.settings["cache-lyrics"] - + def get_lyrics_folder(self): self.check_lyrics_folder() return self.settings["lyrics-folder"] - + def get_ignore_brackets(self): return self.settings["ignore-brackets"] - + def get_left_sidebar(self): return self.settings["left-sidebar"] - + def get_hide_label(self): return self.settings["hide-label"] - - - + + class ConfigDialog(GObject.Object, PeasGtk.Configurable): __gtype_name__ = 'lLyricsConfigDialog' object = GObject.property(type=GObject.Object) @@ -138,93 +136,94 @@ # page 1 for general settings page1 = Gtk.VBox() - + # switch for show-first hbox = Gtk.HBox() switch = Gtk.Switch() switch.set_active(self.settings["show-first"]) switch.connect("notify::active", self.switch_toggled, "show-first") - + label = Gtk.Label("" + _("Show sidebar on first playback") + "") label.set_use_markup(True) - + hbox.pack_start(label, False, False, 5) hbox.pack_start(switch, False, False, 5) page1.pack_start(hbox, False, False, 10) - + # switch for cache-lyrics hbox = Gtk.HBox() switch = Gtk.Switch() switch.set_active(self.settings["cache-lyrics"]) switch.connect("notify::active", self.switch_toggled, "cache-lyrics") - + label = Gtk.Label("" + _("Save lyrics ") + "") label.set_use_markup(True) - - descr = Gtk.Label("" + _("Whether to automatically save retrieved lyrics in the folder specified below") + "") + + descr = Gtk.Label( + "" + _("Whether to automatically save retrieved lyrics in the folder specified below") + "") descr.set_alignment(0, 0) descr.set_margin_left(15) descr.set_line_wrap(True) descr.set_use_markup(True) - + hbox.pack_start(label, False, False, 5) hbox.pack_start(switch, False, False, 5) vbox = Gtk.VBox() vbox.pack_start(hbox, False, False, 0) vbox.pack_start(descr, False, False, 0) page1.pack_start(vbox, False, False, 10) - + # file chooser for lyrics-folder hbox = Gtk.HBox() file_chooser = Gtk.FileChooserButton() file_chooser.set_action(Gtk.FileChooserAction.SELECT_FOLDER) file_chooser.set_current_folder(self.settings["lyrics-folder"]) file_chooser.connect("current-folder-changed", self.folder_set) - + default_button = Gtk.Button(_("default")) default_button.connect("clicked", self.set_folder_default, file_chooser) - + label = Gtk.Label("" + _("Folder for lyrics") + "") label.set_use_markup(True) - + hbox.pack_start(label, False, False, 5) hbox.pack_start(file_chooser, True, True, 5) hbox.pack_start(default_button, False, False, 5) page1.pack_start(hbox, False, False, 10) - + # switch for ignore-brackets hbox = Gtk.HBox() switch = Gtk.Switch() switch.set_active(self.settings["ignore-brackets"]) switch.connect("notify::active", self.switch_toggled, "ignore-brackets") - + label = Gtk.Label("" + _("Always ignore parentheses in song title") + "") label.set_use_markup(True) - + descr = Gtk.Label("" + _("When turned off, only parentheses containing specific strings " - "(e.g. 'remix', 'live', 'edit', etc) are filtered") + "") + "(e.g. 'remix', 'live', 'edit', etc) are filtered") + "") descr.set_alignment(0, 0) descr.set_margin_left(15) descr.set_line_wrap(True) descr.set_use_markup(True) - + hbox.pack_start(label, False, False, 5) hbox.pack_start(switch, False, False, 5) vbox = Gtk.VBox() vbox.pack_start(hbox, False, False, 0) vbox.pack_start(descr, False, False, 0) - + page1.pack_start(vbox, False, False, 10) - + # page 2 for sources settings page2 = Gtk.VBox() - + # check buttons for lyric sources label = Gtk.Label("" + _("Sources:") + "") label.set_alignment(0, 0) label.set_padding(5, 0) label.set_use_markup(True) - + vbox = Gtk.VBox() vbox.set_margin_left(30) vbox.set_margin_top(5) @@ -235,102 +234,91 @@ check.set_active(source in self.settings["active-sources"]) check.connect("toggled", self.source_toggled, source) hbox.pack_start(check, True, True, 3) - + button_up = Gtk.Button('\u2191') button_up.connect("clicked", self.reorder_sources, source, hbox, vbox, "up") hbox.pack_start(button_up, False, False, 3) if self.settings["scanning-order"].index(source) == 0: button_up.set_sensitive(False) - + button_down = Gtk.Button('\u2193') button_down.connect("clicked", self.reorder_sources, source, hbox, vbox, "down") hbox.pack_start(button_down, False, False, 3) if self.settings["scanning-order"].index(source) == len(self.settings["scanning-order"]) - 1: button_down.set_sensitive(False) - + vbox.pack_start(hbox, False, False, 0) - - warn = Gtk.Label("" + - _("Warning: 'External' calls the Rhythmbox built-in lyrics plugin. " - "It can not be guaranteed that the provided engines work properly. " - "If you experience any problems, deactivate this option.") - + "") - warn.set_alignment(0, 0) - warn.set_margin_left(15) - warn.set_line_wrap(True) - warn.set_use_markup(True) - + vbox2 = Gtk.VBox() vbox2.pack_start(label, False, False, 0) vbox2.pack_start(vbox, False, False, 0) - vbox2.pack_start(warn, False, False, 0) - + page2.pack_start(vbox2, False, False, 10) - + # page 3 for appearance settings page3 = Gtk.VBox() - + # switch for hide-label hbox = Gtk.HBox() switch = Gtk.Switch() switch.set_active(self.settings["hide-label"]) switch.connect("notify::active", self.switch_toggled, "hide-label") - + label = Gtk.Label("" + _("Hide sidebar label") + "") label.set_use_markup(True) - + hbox.pack_start(label, False, False, 5) hbox.pack_start(switch, False, False, 5) - + page3.pack_start(hbox, False, False, 10) - + # switch for left-sidebar hbox = Gtk.HBox() switch = Gtk.Switch() switch.set_active(self.settings["left-sidebar"]) switch.connect("notify::active", self.switch_toggled, "left-sidebar") - + label = Gtk.Label("" + _("Show lyrics in left sidebar instead of right one") + "") label.set_use_markup(True) - + descr = Gtk.Label("" + _("You have to disable and re-enable this plugin or restart Rhythmbox " "to apply changes here") + "") descr.set_alignment(0, 0) descr.set_margin_left(15) descr.set_line_wrap(True) descr.set_use_markup(True) - + hbox.pack_start(label, False, False, 5) hbox.pack_start(switch, False, False, 5) vbox = Gtk.VBox() vbox.pack_start(hbox, False, False, 0) vbox.pack_start(descr, False, False, 0) - + page3.pack_start(vbox, False, False, 10) - + # create a notebook as top level container nb = Gtk.Notebook() nb.append_page(page1, Gtk.Label(_("General"))) nb.append_page(page2, Gtk.Label(_("Sources"))) nb.append_page(page3, Gtk.Label(_("Appearance"))) - + nb.show_all() nb.set_size_request(300, -1) - + return nb - + def switch_toggled(self, switch, active, key): self.settings[key] = switch.get_active() - + def source_toggled(self, checkbutton, source): entries = self.settings["active-sources"] if checkbutton.get_active(): entries.append(source) else: entries.remove(source) - + self.settings["active-sources"] = entries - + def reorder_sources(self, button, source, hbox, vbox, direction): rows = vbox.get_children() if direction == "up": @@ -349,20 +337,19 @@ if new_index == 1: rows[1].get_children()[1].set_sensitive(False) rows[0].get_children()[1].set_sensitive(True) - + vbox.reorder_child(hbox, new_index) - + entries = self.settings["scanning-order"] entries.remove(source) entries.insert(new_index, source) self.settings["scanning-order"] = entries - + def folder_set(self, file_chooser): new_folder = file_chooser.get_current_folder() if self.settings["lyrics-folder"] != new_folder: print("folder changed") self.settings["lyrics-folder"] = new_folder - + def set_folder_default(self, button, file_chooser): file_chooser.set_current_folder(os.path.join(RB.user_cache_dir(), "lyrics")) - \ No newline at end of file diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/DarklyricsParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/DarklyricsParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/DarklyricsParser.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/DarklyricsParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -19,19 +19,19 @@ import Util + class Parser(object): - def __init__(self, artist, title): self.artist = artist self.title = title self.lyrics = "" - + def parse(self): # remove unwanted characters from artist and title strings clean_artist = self.artist clean_artist = Util.remove_punctuation(clean_artist) clean_artist = clean_artist.replace(" ", "") - + # create artist Url url = "http://www.darklyrics.com/" + clean_artist[:1] + "/" + clean_artist + ".html" print("darklyrics artist Url " + url) @@ -40,9 +40,9 @@ except: print("could not connect to darklyrics.com") return "" - + resp = Util.bytes_to_string(resp) - + # find title with lyrics url match = re.search("" + self.title + "
", resp, re.I) if match is None: @@ -55,25 +55,26 @@ except: print("could not connect to darklyrics.com") return "" - + resp = Util.bytes_to_string(resp) - - self.track_no = url.split("#")[1] - + + self.track_no = url.split("#")[1] + self.lyrics = self.get_lyrics(resp) self.lyrics = string.capwords(self.lyrics, "\n").strip() - + return self.lyrics - + def get_lyrics(self, resp): # search for the relevant lyrics - match = re.search("

" + self.track_no + "\. " + self.title + "

", resp, re.I) + match = re.search("

" + self.track_no + "\. " + self.title + "

", + resp, re.I) if match is None: print("lyrics start not found") return "" start = match.end() resp = resp[start:] - + end = resp.find("

", "") resp = resp.replace("", "") resp = resp.replace("", "") - + return resp - diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/GeniusParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/GeniusParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/GeniusParser.py 1970-01-01 00:00:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/GeniusParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Parser for Genius.com +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import urllib.request, urllib.error, urllib.parse +import re +import string + +from html.parser import HTMLParser + +import Util + + +class Parser(object): + def __init__(self, artist, title): + self.artist = artist + self.title = title + self.lyrics = "" + + def parse(self): + # remove punctuation from artist/title + self.artist = self.artist.replace("+", "and") + clean_artist = Util.remove_punctuation(self.artist) + clean_title = Util.remove_punctuation(self.title) + + # create lyrics Url + url = "http://genius.com/" + clean_artist.replace(" ", "-") + "-" + clean_title.replace(" ", "-") + "-lyrics" + print("rapgenius Url " + url) + try: + resp = urllib.request.urlopen(Util.add_request_header(url), None, 3).read() + except: + print("could not connect to genius.com") + return "" + + resp = Util.bytes_to_string(resp) + + self.lyrics = self.get_lyrics(resp) + self.lyrics = string.capwords(self.lyrics, "\n").strip() + + return self.lyrics + + def get_lyrics(self, resp): + # cut HTML source to relevant part + start = resp.find("") + if end == -1: + print("lyrics end not found ") + return "" + resp = resp[:end] + + # replace unwanted parts + resp = re.sub("]*>", "", resp) + resp = re.sub("]*>", "", resp) + resp = resp.replace("", "") + resp = resp.replace("
", "") + resp = resp.replace("
", "") + resp = resp.replace("

", "") + resp = resp.replace("

", "") + resp = resp.strip() + + return resp diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/LetrasTerraParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/LetrasTerraParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/LetrasTerraParser.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/LetrasTerraParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -15,107 +15,106 @@ import urllib.request, urllib.parse import string - -from html.parser import HTMLParser +import html import Util + class Parser(object): - def __init__(self, artist, title): self.artist = artist self.title = title self.lyrics = "" - - def parse(self): + + def parse(self): + self.artist = self.artist.replace("+", "and") artist = urllib.parse.quote(self.artist) title = urllib.parse.quote(self.title) join = urllib.parse.quote(' - ') - + # create artist Url url = "http://letras.mus.br/winamp.php?t=%s%s%s" % (artist, join, title) - + print("letras.terra.com.br Url " + url) try: resp = urllib.request.urlopen(url, None, 3).read() except: print("could not connect to letras.terra.com.br") return "" - + resp = Util.bytes_to_string(resp) - + if not self.verify(resp): return "" - + self.lyrics = self.get_lyrics(resp) self.lyrics = string.capwords(self.lyrics, "\n").strip() - + return self.lyrics - + def get_lyrics(self, resp): # cut HTML source to relevant part - start = resp.find("

") + start = resp.find("

") if start == -1: print("lyrics start not found") return "" - resp = resp[(start+3):] - end = resp.find("

") if end == -1: print("lyrics end not found ") return "" - resp = resp[:(end)] - + resp = resp[:end] + # replace unwanted parts - resp = resp.replace("
", "") - resp = resp.replace("

", "") - resp = resp.replace("

", "\n") - - resp = HTMLParser().unescape(resp) - + resp = resp.replace("
", "\n") + resp = resp.replace("

", "\n\n") + + resp = html.unescape(resp) + return resp - + def verify(self, resp): - # verify song artitst/title + # verify song artist/title title = resp start = title.find("

") if start == -1: print("no title found") return False - title = title[(start+4):] - + title = title[(start + 4):] + start = title.find(">") if start == -1: print("no title start found") return False - title = title[(start+1):] - + title = title[(start + 1):] + end = title.find("") if end == -1: print("no title end found") return False - title = HTMLParser().unescape(title[:end]).lower() - + title = html.unescape(title[:end]).lower() + artist = resp start = artist.find("

") if start == -1: print("no artist found") return False - artist = artist[(start+4):] - + artist = artist[(start + 4):] + start = artist.find(">") if start == -1: print("no artist start found") return False - artist = artist[(start+1):] - + artist = artist[(start + 1):] + end = artist.find("") if end == -1: print("no artist end found") return False - artist = HTMLParser().unescape(artist[:end]).lower() - + artist = html.unescape(artist[:end]).lower() + if self.artist != artist or self.title != title: print("wrong artist/title! " + artist + " - " + title) return False - + return True diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/lLyrics.py rhythmbox-plugin-llyrics-1.1/lLyrics/lLyrics.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/lLyrics.py 2014-04-22 18:12:34.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/lLyrics.py 2016-02-05 21:35:45.000000000 +0000 @@ -33,15 +33,12 @@ import LyricwikiParser import MetrolyricsParser import LetrasTerraParser -import LyrdbParser import AZLyricsParser -import LeoslyricsParser import LyricsmaniaParser import DarklyricsParser -import RapgeniusParser +import GeniusParser import LyricsNMusicParser import VagalumeParser -import External import Util from lLyrics_rb3compat import ActionGroup @@ -51,8 +48,8 @@ from Config import ConfigDialog import gettext -gettext.install('lLyrics', os.path.dirname(__file__) + "/locale/") +gettext.install('lLyrics', os.path.dirname(__file__) + "/locale/") view_menu_ui = """ @@ -92,98 +89,88 @@ """ +LYRICS_TITLE_STRIP = ["\(live[^\)]*\)", "\(acoustic[^\)]*\)", "\([^\)]*mix\)", "\([^\)]*version\)", "\([^\)]*edit\)", + "\(feat[^\)]*\)", "\([^\)]*bonus[^\)]*track[^\)]*\)"] +LYRICS_TITLE_REPLACE = [("/", "-"), (" & ", " and ")] +LYRICS_ARTIST_REPLACE = [("/", "-"), (" & ", " and ")] -LYRICS_TITLE_STRIP=["\(live[^\)]*\)", "\(acoustic[^\)]*\)", "\([^\)]*mix\)", "\([^\)]*version\)", "\([^\)]*edit\)", - "\(feat[^\)]*\)", "\([^\)]*bonus[^\)]*track[^\)]*\)"] -LYRICS_TITLE_REPLACE=[("/", "-"), (" & ", " and ")] -LYRICS_ARTIST_REPLACE=[("/", "-"), (" & ", " and ")] - -LYRICS_SOURCES=["Lyricwiki.org", "Letras.terra.com.br", "Metrolyrics.com", "AZLyrics.com", "Lyricsnmusic.com", "Lyricsmania.com", - "Vagalume.com.br", "Rapgenius.com", "Darklyrics.com", "Chartlyrics.com", "Leoslyrics.com", "Lyrdb.com", "External"] - +LYRICS_SOURCES = ["Lyricwiki.org", "Letras.terra.com.br", "Metrolyrics.com", "AZLyrics.com", "Lyricsnmusic.com", + "Lyricsmania.com", "Vagalume.com.br", "Genius.com", "Darklyrics.com", "Chartlyrics.com"] class lLyrics(GObject.Object, Peas.Activatable): __gtype_name__ = 'lLyrics' object = GObject.property(type=GObject.Object) - - - + def __init__(self): GObject.Object.__init__(self) GObject.threads_init() Gdk.threads_init() - - def do_activate(self): # Get references for the Shell and the Shell-player self.shell = self.object self.player = self.shell.props.shell_player self.appshell = ApplicationShell(self.shell) - + # Create dictionary which assigns sources to their corresponding modules self.dict = dict({"Lyricwiki.org": LyricwikiParser, "Letras.terra.com.br": LetrasTerraParser, - "Metrolyrics.com": MetrolyricsParser, "AZLyrics.com": AZLyricsParser, - "Lyricsmania.com": LyricsmaniaParser, "Chartlyrics.com": ChartlyricsParser, - "Lyrdb.com": LyrdbParser, "Leoslyrics.com": LeoslyricsParser, - "Darklyrics.com": DarklyricsParser, "Rapgenius.com": RapgeniusParser, - "Lyricsnmusic.com": LyricsNMusicParser, "Vagalume.com.br": VagalumeParser, - "External": External}) + "Metrolyrics.com": MetrolyricsParser, "AZLyrics.com": AZLyricsParser, + "Lyricsmania.com": LyricsmaniaParser, "Chartlyrics.com": ChartlyricsParser, + "Darklyrics.com": DarklyricsParser, "Genius.com": GeniusParser, + "Lyricsnmusic.com": LyricsNMusicParser, "Vagalume.com.br": VagalumeParser}) self.add_builtin_lyrics_sources() - + # Get the user preferences config = Config() self.settings = config.get_settings() self.get_user_preferences(self.settings, None, config) # Watch for setting changes self.skc_id = self.settings.connect('changed', self.get_user_preferences, config) - + self.position = RB.ShellUILocation.RIGHT_SIDEBAR if self.left_sidebar: self.position = RB.ShellUILocation.SIDEBAR - + # Initialize the UI self.lmui_id = None - self.tbui_id = None + self.tbui_id = None self.init_sidebar() self.init_menu() - + # Create flag, used to pop out sidebar on initial start of playback self.first = True self.visible = False - + # Event flag indicates whether the user is currently editing lyrics self.edit_event = threading.Event() self.edit_event.set() - + self.current_source = None self.tags = None self.current_tag = None self.showing_on_demand = False self.was_corrected = False - + # Search lyrics if already playing (this will be the case if user reactivates plugin during playback) if self.player.props.playing: - self.search_lyrics(self.player, self.player.get_playing_entry()) + self.search_lyrics(self.player, self.player.get_playing_entry()) # Search lyrics everytime the song changes self.psc_id = self.player.connect('playing-song-changed', self.search_lyrics) # Connect to elapsed-changed signal to handle synchronized lyrics self.pec_id = self.player.connect('elapsed-changed', self.elapsed_changed) - + print("activated plugin lLyrics") - - def do_deactivate(self): if self.visible: - self.shell.remove_widget (self.vbox, self.position) - + self.shell.remove_widget(self.vbox, self.position) + self.settings.disconnect(self.skc_id) if self.psc_id is not None: self.player.disconnect(self.psc_id) self.player.disconnect(self.pec_id) - + self.appshell.cleanup() self.vbox = None @@ -222,13 +209,11 @@ self.position = None self.hbox = None self.back_button = None - + self.shell = None print("deactivated plugin lLyrics") - - - + def add_builtin_lyrics_sources(self): # find and append path for built-in lyrics plugin for p in sys.path: @@ -239,9 +224,7 @@ else: print("Path to built-in lyrics plugin could not be detected") return - - - + def get_user_preferences(self, settings, key, config): self.sources = config.get_lyrics_sources() self.show_first = config.get_show_first() @@ -250,71 +233,67 @@ self.ignore_brackets = config.get_ignore_brackets() self.left_sidebar = config.get_left_sidebar() self.hide_label = config.get_hide_label() - + # if this is called in do_activate or we need a reload to apply, return here if key is None or key in ["left-sidebar"]: return - + if key == "hide-label": if self.hide_label: self.label.hide() else: self.label.show() - return + return - - def insert_ui(self): self.appshell.add_app_menuitems(view_menu_ui, 'lLyricsPluginToggleActions', 'view') - self.appshell.add_browser_menuitems(context_ui, 'lLyricsPluginPopupActions') - - - + self.appshell.add_browser_menuitems(context_ui, 'lLyricsPluginPopupActions') + def init_menu(self): # add actions self.toggle_action_group = ActionGroup(self.shell, 'lLyricsPluginToggleActions') self.toggle_action_group.add_action(func=self.toggle_visibility, - action_name='ToggleLyricSideBar', label=_("Lyrics"), action_state=ActionGroup.TOGGLE, - action_type='app', accel="l", tooltip=_("Display lyrics for the current playing song")) + action_name='ToggleLyricSideBar', label=_("Lyrics"), + action_state=ActionGroup.TOGGLE, + action_type='app', accel="l", + tooltip=_("Display lyrics for the current playing song")) self.appshell.insert_action_group(self.toggle_action_group) - + self.context_action_group = ActionGroup(self.shell, 'lLyricsPluginPopupActions') self.context_action_group.add_action(action_name="lLyricsPopupAction", label=_("Show lyrics"), - tooltip=_("Search and display lyrics for this song"), func=self.context_action_callback) + tooltip=_("Search and display lyrics for this song"), + func=self.context_action_callback) self.appshell.insert_action_group(self.context_action_group) - + self.insert_ui() - - - - + def init_sidebar(self): self.vbox = Gtk.VBox() - - hbox_header = Gtk.HBox(); - + + hbox_header = Gtk.HBox() + self.label = Gtk.Label(_("Lyrics")) self.label.set_use_markup(True) self.label.set_padding(3, 10) self.label.set_alignment(0, 0) - + self.menu = self.get_button_menu() self.set_menu_sensitive(False) - + # menu without toolbar icon_factory = Gtk.IconFactory() pxbf = GdkPixbuf.Pixbuf.new_from_file(os.path.dirname(__file__) + "/menu-arrow.png") icon_factory.add("llyrics_menu", Gtk.IconSet.new_from_pixbuf(pxbf)) icon_factory.add_default() - - menu_button = Gtk.Image.new_from_stock("llyrics_menu", Gtk.IconSize.SMALL_TOOLBAR); - eventBox = Gtk.EventBox(); - eventBox.add(menu_button); - eventBox.connect("button-press-event", self.popup_menu, self.menu) - + + menu_button = Gtk.Image.new_from_stock("llyrics_menu", Gtk.IconSize.SMALL_TOOLBAR) + event_box = Gtk.EventBox() + event_box.add(menu_button) + event_box.connect("button-press-event", self.popup_menu, self.menu) + hbox_header.pack_start(self.label, True, True, 0) - hbox_header.pack_end(eventBox, False, False, 5) - + hbox_header.pack_end(event_box, False, False, 5) + # create a TextView for displaying lyrics self.textview = Gtk.TextView() self.textview.set_editable(False) @@ -324,22 +303,22 @@ self.textview.set_pixels_above_lines(5) self.textview.set_pixels_below_lines(5) self.textview.set_wrap_mode(Gtk.WrapMode.WORD) - + # create a ScrollView sw = Gtk.ScrolledWindow() sw.add(self.textview) sw.set_shadow_type(Gtk.ShadowType.IN) - + # initialize a TextBuffer to store lyrics in self.textbuffer = Gtk.TextBuffer() self.textview.set_buffer(self.textbuffer) - + # tag to style headers bold and underlined - self.tag = self.textbuffer.create_tag(None, underline=Pango.Underline.SINGLE, weight=600, + self.tag = self.textbuffer.create_tag(None, underline=Pango.Underline.SINGLE, weight=600, pixels_above_lines=10, pixels_below_lines=20) # tag to highlight synchronized lyrics self.sync_tag = self.textbuffer.create_tag(None, weight=600) - + # create save and cancel buttons for edited lyrics save_button = Gtk.Button.new_with_label(_("Save")) save_button.connect("clicked", self.save_button_callback) @@ -348,54 +327,51 @@ self.hbox = Gtk.HBox() self.hbox.pack_start(save_button, True, True, 3) self.hbox.pack_start(cancel_button, True, True, 3) - + # button for closing on demand lyrics self.back_button = Gtk.Button.new_with_label(_("Back to playing song")) self.back_button.connect("clicked", self.back_button_callback) - + # pack everything into side pane - self.vbox.pack_start(hbox_header, False, False, 0); + self.vbox.pack_start(hbox_header, False, False, 0) self.vbox.pack_start(sw, True, True, 0) self.vbox.pack_end(self.hbox, False, False, 3) - self.vbox.pack_end(self.back_button, False, False, 3) + self.vbox.pack_end(self.back_button, False, False, 3) self.vbox.show_all() self.hbox.hide() self.back_button.hide() - + if self.hide_label: self.label.hide() - - self.vbox.set_size_request(200, -1) + self.visible = False - - - + def get_button_menu(self): - menu = Gtk.Menu(); - + menu = Gtk.Menu() + self.radio_sources = Gtk.Menu() - + item_unselect = Gtk.RadioMenuItem.new_with_label([], "SelectNothing") item_unselect.connect("activate", self.scan_selected_source_callback, "SelectNothing") self.radio_sources.append(item_unselect) - + last_item = item_unselect - + for entry in LYRICS_SOURCES[:-1]: - last_item = self.add_radio_menu_item(self.radio_sources, entry, self.scan_selected_source_callback, last_item) - - self.radio_sources.append(Gtk.SeparatorMenuItem()) - last_item = self.add_radio_menu_item(self.radio_sources, _("External"), self.scan_selected_source_callback, last_item) + last_item = self.add_radio_menu_item(self.radio_sources, entry, self.scan_selected_source_callback, + last_item) + self.radio_sources.append(Gtk.SeparatorMenuItem()) - self.add_radio_menu_item(self.radio_sources, _("From cache file"), self.scan_selected_source_callback, last_item) - - self.radio_sources.show_all(); - - item_sources = Gtk.MenuItem(_("Sources")); - item_sources.set_submenu(self.radio_sources); + self.add_radio_menu_item(self.radio_sources, _("From cache file"), self.scan_selected_source_callback, + last_item) + + self.radio_sources.show_all() + + item_sources = Gtk.MenuItem(_("Sources")) + item_sources.set_submenu(self.radio_sources) menu.append(item_sources) - + self.add_menu_item(menu, _("Scan next source"), self.scan_next_action_callback) self.add_menu_item(menu, _("Scan all sources"), self.scan_all_action_callback) menu.append(Gtk.SeparatorMenuItem()) @@ -405,68 +381,55 @@ menu.append(Gtk.SeparatorMenuItem()) self.add_menu_item(menu, _("Clear lyrics"), self.clear_action_callback) self.add_menu_item(menu, _("Edit lyrics"), self.edit_action_callback) - + # add preferences item menu.append(Gtk.SeparatorMenuItem()) self.add_menu_item(menu, _("Preferences"), self.preferences_dialog_action_callback) - + menu.show_all() - + # hide the SelectNothing choice item_unselect.hide() - + return menu - - - + def add_menu_item(self, menu, label, callback): item = Gtk.MenuItem(label) - item.connect("activate", callback) + item.connect("activate", callback) menu.append(item) - - - + def add_radio_menu_item(self, menu, label, callback, last): group = last.get_group() item = Gtk.RadioMenuItem.new_with_label(group, label) - if label == _("External"): - label = "External" if label == _("From cache file"): label = "From cache file" item.connect("toggled", callback, label) menu.append(item) - + return item - - - + def set_menu_sensitive(self, sensitive): index = 0 for item in self.menu: # 'Preferences' option should always be sensitive - if index == len(self.menu)-1: + if index == len(self.menu) - 1: continue item.set_sensitive(sensitive) index += 1 - - - + def set_radio_menu_item_active(self, itemlabel): for item in self.radio_sources: if item.get_label() == itemlabel: item.set_active(True) break - - - + def popup_menu(self, widget, event, menu): - menu.popup(None, None, lambda x,y: (event.x_root+event.x, event.y_root+event.y, True), None, event.button, event.time) - - - + menu.popup(None, None, lambda x, y: (event.x_root + event.x, event.y_root + event.y, True), None, event.button, + event.time) + def toggle_visibility(self, action, param=None, data=None): action = self.toggle_action_group.get_action('ToggleLyricSideBar') - + if action.get_active(): self.shell.add_widget(self.vbox, self.position, True, True) self.visible = True @@ -475,9 +438,7 @@ else: self.shell.remove_widget(self.vbox, self.position) self.visible = False - - - + def search_lyrics(self, player, entry): # clear sync stuff if self.tags is not None: @@ -485,10 +446,10 @@ self.current_tag = None start, end = self.textbuffer.get_bounds() self.textbuffer.remove_tag(self.sync_tag, start, end) - + if entry is None: return - + # don't show lyrics for podcasts and radio if entry.get_entry_type().get_name() in ('iradio', 'podcast-post'): print("entry type: " + entry.get_entry_type().get_name()) @@ -497,7 +458,7 @@ print('removing the sidebar') self.toggle_action_group.get_action("ToggleLyricSideBar").set_active(False) return - + # pop out sidebar at first playback if self.first and not self.showing_on_demand: self.first = False @@ -505,122 +466,104 @@ self.toggle_action_group.get_action("ToggleLyricSideBar").set_active(True) # toggling the sidebar will start lyrics search again, so we can return here return - + # only do something if visible if not self.visible: return - + # get the song data self.artist = entry.get_string(RB.RhythmDBPropType.ARTIST) self.title = entry.get_string(RB.RhythmDBPropType.TITLE) print("search lyrics for " + self.artist + " - " + self.title) - + self.was_corrected = False - + (self.clean_artist, self.clean_title) = self.clean_song_data(self.artist, self.title) self.path = self.build_cache_path(self.clean_artist, self.clean_title) - + self.scan_all_sources(self.clean_artist, self.clean_title, True) - - def clean_song_data(self, artist, title): # convert to lowercase artist = artist.lower() title = title.lower() - + # remove accents artist = unicodedata.normalize('NFKD', artist) artist = "".join([c for c in artist if not unicodedata.combining(c)]) title = unicodedata.normalize('NFKD', title) title = "".join([c for c in title if not unicodedata.combining(c)]) - + if self.ignore_brackets: LYRICS_TITLE_STRIP.append("\(.*\)") - + # replace ampersands and the like for exp in LYRICS_ARTIST_REPLACE: artist = re.sub(exp[0], exp[1], artist) for exp in LYRICS_TITLE_REPLACE: title = re.sub(exp[0], exp[1], title) - + # strip things like "(live at Somewhere)", "(acoustic)", etc for exp in LYRICS_TITLE_STRIP: - title = re.sub (exp, '', title) - + title = re.sub(exp, '', title) + # compress spaces title = title.strip() artist = artist.strip() - + return (artist, title) - - - + def build_cache_path(self, artist, title): artist_folder = os.path.join(self.lyrics_folder, artist[:128]) - if not os.path.exists (artist_folder): - os.mkdir (artist_folder) - + if not os.path.exists(artist_folder): + os.mkdir(artist_folder) + return os.path.join(artist_folder, title[:128] + '.lyric') - - - + def scan_selected_source_callback(self, action, activated_action): if not action.get_active(): - return - + return + source = activated_action if source == "SelectNothing" or source == self.current_source: return - + self.scan_source(source, self.clean_artist, self.clean_title) - - - + def scan_next_action_callback(self, action): if self.current_source is None or self.current_source == "From cache file": index = 0 else: index = self.sources.index(self.current_source) + 1 - index = index % (len(self.sources)+1) - + index = index % (len(self.sources) + 1) + if index >= len(self.sources): source = "From cache file" else: source = self.sources[index] - + self.scan_source(source, self.clean_artist, self.clean_title) - - - + def scan_all_action_callback(self, action): self.scan_all_sources(self.clean_artist, self.clean_title, False) - - - + def search_online_action_callback(self, action): webbrowser.open("http://www.google.com/search?q=%s+%s+lyrics" % (self.clean_artist, self.clean_title)) - - - + def instrumental_action_callback(self, action): lyrics = "-- Instrumental --" self.write_lyrics_to_cache(self.path, lyrics) self.current_source = None Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.show_lyrics, lyrics) - - - + def save_to_cache_action_callback(self, action): start, end = self.textbuffer.get_bounds() start.forward_lines(1) lyrics = self.textbuffer.get_text(start, end, False) - + self.write_lyrics_to_cache(self.path, lyrics) - - - + def clear_action_callback(self, action): self.textbuffer.set_text("") try: @@ -628,14 +571,12 @@ except: print("No cache file found to clear") print("cleared lyrics") - - - + def edit_action_callback(self, action): # Unset event flag to indicate editing and so block all other threads which # want to display new lyrics until editing is finished. self.edit_event.clear() - + # Conserve lyrics in order to restore original lyrics when editing is canceled start, end = self.textbuffer.get_bounds() self.lyrics_before_edit = self.textbuffer.get_text(start, end, False) @@ -644,98 +585,91 @@ # Conserve cache path in order to be able to correctly save edited lyrics although # the playing song might have changed during editing. self.path_before_edit = self.path - + self.set_menu_sensitive(False) - + # Enable editing and set cursor self.textview.set_cursor_visible(True) self.textview.set_editable(True) cursor = self.textbuffer.get_iter_at_line(1) self.textbuffer.place_cursor(cursor) self.textview.grab_focus() - + self.hbox.show() - - - + def preferences_dialog_action_callback(self, action): content = ConfigDialog().do_create_configure_widget() - + dialog = Gtk.Dialog(_('lLyrics Preferences'), self.shell.get_property('window'), - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, (Gtk.STOCK_OK, Gtk.ResponseType.OK)) - + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + (Gtk.STOCK_OK, Gtk.ResponseType.OK)) + content_area = dialog.get_content_area() content_area.pack_start(content, True, True, 0) - + dialog.show_all() - + dialog.run() - + dialog.hide() - - - + def context_action_callback(self, action, param=None, data=None): page = self.shell.props.selected_page if not hasattr(page, "get_entry_view"): return - + selected = page.get_entry_view().get_selected_entries() if not selected: print("nothing selected") return - + # if multiple selections, take first entry = selected[0] - + self.showing_on_demand = True self.back_button.show() - + # Disconnect from song-changed and elapsed-change signals if self.psc_id: self.player.disconnect(self.psc_id) self.player.disconnect(self.pec_id) self.psc_id = None self.pec_id = None - + if not self.visible: self.toggle_action_group.get_action("ToggleLyricSideBar").set_active(True) - + self.search_lyrics(self.player, entry) - - - + def save_button_callback(self, button): self.textview.set_cursor_visible(False) self.textview.set_editable(False) self.hbox.hide() - + # get lyrics without artist-title header start, end = self.textbuffer.get_bounds() start.forward_lines(1) lyrics = self.textbuffer.get_text(start, end, False) - + # save edited lyrics to cache file and audio tag self.write_lyrics_to_cache(self.path_before_edit, lyrics) - + # If playing song changed, set "searching lyrics..." (might be overwritten # immediately, if thread for the new song already found lyrics) if self.path != self.path_before_edit: self.textbuffer.set_text(_("searching lyrics...")) - + self.set_menu_sensitive(True) - + # Set event flag to indicate end of editing and wake all threads # waiting to display new lyrics. self.edit_event.set() - - - + def cancel_button_callback(self, button): self.textview.set_cursor_visible(False) self.textview.set_editable(False) self.hbox.hide() - + # Restore original lyrics if playing song didn't change, # otherwise set "searching lyrics..." (might be overwritten # immediately, if thread for the new song already found lyrics) @@ -747,83 +681,71 @@ self.textbuffer.apply_tag(self.tag, start, end) else: self.textbuffer.set_text(_("searching lyrics...")) - + self.set_menu_sensitive(True) - + # Set event flag to indicate end of editing and wake all threads # waiting to display new lyrics. self.edit_event.set() - - - + def back_button_callback(self, button): # reconnect to signals self.psc_id = self.player.connect('playing-song-changed', self.search_lyrics) self.pec_id = self.player.connect('elapsed-changed', self.elapsed_changed) - + self.back_button.hide() self.showing_on_demand = False - + playing_entry = self.player.get_playing_entry() - + # if nothing is playing, clear lyrics and return if not playing_entry: self.textbuffer.set_text("") return - + # otherwise search lyrics self.search_lyrics(self.player, playing_entry) - - - + def set_displayed_text(self, text): self.textbuffer.set_text(text) - - - + def scan_source(self, source, artist, title): Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.set_displayed_text, _("searching lyrics...")) - + newthread = Thread(target=self._scan_source_thread, args=(source, artist, title)) newthread.start() - - - + def _scan_source_thread(self, source, artist, title): Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.set_menu_sensitive, False) - + if source == "From cache file": lyrics = self.get_lyrics_from_cache(self.path) - else: + else: lyrics = self.get_lyrics_from_source(source, artist, title) - + # check if playing song changed if artist != self.clean_artist or title != self.clean_title: print("song changed") - return - + return + Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.set_menu_sensitive, True) - + Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.show_lyrics, lyrics) - - - + def scan_all_sources(self, artist, title, cache): if self.edit_event.is_set(): Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.set_displayed_text, _("searching lyrics...")) - + newthread = Thread(target=self._scan_all_sources_thread, args=(artist, title, cache)) newthread.start() - - - + def _scan_all_sources_thread(self, artist, title, cache): Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.set_menu_sensitive, False) - + lyrics = "" if cache: lyrics = self.get_lyrics_from_cache(self.path) - + if lyrics == "": i = 0 while lyrics == "" and i in range(len(self.sources)): @@ -833,38 +755,36 @@ print("song changed") return i += 1 - + # We can't display new lyrics while user is editing! self.edit_event.wait() - + # check if playing song changed if artist != self.clean_artist or title != self.clean_title: print("song changed") return - - if lyrics == "": + + if lyrics == "": # check for lastfm corrections if not self.was_corrected: - self.was_corrected = True - (artist, title, corrected) = Util.get_lastfm_correction(artist, title) + self.was_corrected = True + (artist, title, corrected) = Util.get_lastfm_correction(artist, title) if corrected: (self.clean_artist, self.clean_title) = self.clean_song_data(artist, title) self._scan_all_sources_thread(self.clean_artist, self.clean_title, False) - return - - self.current_source = None - + return + + self.current_source = None + Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.set_menu_sensitive, True) - + Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self.show_lyrics, lyrics) - - - def get_lyrics_from_cache(self, path): + def get_lyrics_from_cache(self, path): self.current_source = "From cache file" - + # try to load lyrics from cache - if os.path.exists (path): + if os.path.exists(path): try: cachefile = open(path, "r") lyrics = cachefile.read() @@ -872,14 +792,12 @@ except: print("error reading cache file") return "" - + print("got lyrics from cache") return lyrics - + return "" - - - + def write_lyrics_to_cache(self, path, lyrics): try: cachefile = open(path, "w+") @@ -888,17 +806,15 @@ print("wrote lyrics to cache file") except: print("error writing lyrics to cache file") - - - + def get_lyrics_from_source(self, source, artist, title): # Playing song might change during search, so we want to # conserve the correct cache path. path = self.path - - print("source: " + source) + + print("source: " + source) self.current_source = source - + parser = self.dict[source].Parser(artist, title) try: lyrics = parser.parse() @@ -906,19 +822,16 @@ print("Error in parser " + source) print(str(e)) return "" - + if lyrics != "": print("got lyrics from source") - if source != "External": - lyrics = "%s\n\n(lyrics from %s)" % (lyrics, source) - + lyrics = "%s\n\n(lyrics from %s)" % (lyrics, source) + if self.cache: self.write_lyrics_to_cache(path, lyrics) - + return lyrics - - - + def show_lyrics(self, lyrics): if self.current_source is None: self.set_radio_menu_item_active("SelectNothing") @@ -926,43 +839,41 @@ self.set_radio_menu_item_active(_("From cache file")) else: self.set_radio_menu_item_active(self.current_source) - + if lyrics == "": print("no lyrics found") lyrics = _("No lyrics found") - else: + else: lyrics, self.tags = Util.parse_lrc(lyrics) - + self.textbuffer.set_text("%s - %s\n%s" % (self.artist, self.title, lyrics)) - + # make 'artist - title' header bold and underlined start = self.textbuffer.get_start_iter() end = start.copy() end.forward_to_line_end() self.textbuffer.apply_tag(self.tag, start, end) - - - + def elapsed_changed(self, player, seconds): if not self.tags or not self.edit_event.is_set(): return - + matching_tag = None for tag in self.tags: time, _ = tag if time > seconds: break matching_tag = tag - + if matching_tag is None or self.current_tag == matching_tag: return - + self.current_tag = matching_tag - + # remove old tag start, end = self.textbuffer.get_bounds() self.textbuffer.remove_tag(self.sync_tag, start, end) - + # highlight next line line = self.tags.index(self.current_tag) + 1 start = self.textbuffer.get_iter_at_line(line) @@ -970,4 +881,3 @@ end.forward_to_line_end() self.textbuffer.apply_tag(self.sync_tag, start, end) self.textview.scroll_to_iter(start, 0.1, False, 0, 0) - diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/lLyrics_rb3compat.py rhythmbox-plugin-llyrics-1.1/lLyrics/lLyrics_rb3compat.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/lLyrics_rb3compat.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/lLyrics_rb3compat.py 2016-02-05 21:35:45.000000000 +0000 @@ -31,16 +31,18 @@ import rb import lxml.etree as ET + def pygobject_version(): ''' returns float of the major and minor parts of a pygobject version e.g. version (3, 9, 5) return float(3.9) ''' to_number = lambda t: ".".join(str(v) for v in t) - + str_version = to_number(GObject.pygobject_version) - - return float(str_version.rsplit('.',1)[0]) + + return float(str_version.rsplit('.', 1)[0]) + PYVER = sys.version_info[0] @@ -54,65 +56,75 @@ import http.client else: import http.client - + + def responses(): - if PYVER >=3: + if PYVER >= 3: return http.client.responses else: return http.client.responses + def unicodestr(param, charset): - if PYVER >=3: - return param#str(param, charset) + if PYVER >= 3: + return param # str(param, charset) else: return str(param, charset) - + + def unicodeencode(param, charset): - if PYVER >=3: - return param#str(param).encode(charset) + if PYVER >= 3: + return param # str(param).encode(charset) else: return str(param).encode(charset) - + + def unicodedecode(param, charset): - if PYVER >=3: + if PYVER >= 3: return param else: return param.decode(charset) + def urlparse(uri): - if PYVER >=3: + if PYVER >= 3: return urllib.parse.urlparse(uri) else: return rb2urlparse(uri) - + + def url2pathname(url): - if PYVER >=3: + if PYVER >= 3: return urllib.request.url2pathname(url) else: return urllib.request.url2pathname(url) + def urlopen(filename): - if PYVER >=3: + if PYVER >= 3: return urllib.request.urlopen(filename) else: return urllib.request.urlopen(filename) - + + def pathname2url(filename): - if PYVER >=3: + if PYVER >= 3: return urllib.request.pathname2url(filename) else: return urllib.request.pathname2url(filename) + def unquote(uri): - if PYVER >=3: + if PYVER >= 3: return urllib.parse.unquote(uri) else: return urllib.parse.unquote(uri) - + + def quote(uri, safe=None): - if PYVER >=3: + if PYVER >= 3: if safe: - return urllib.parse.quote(uri,safe=safe) + return urllib.parse.quote(uri, safe=safe) else: return urllib.parse.quote(uri) else: @@ -120,23 +132,27 @@ return urllib.parse.quote(uri, safe=safe) else: return urllib.parse.quote(uri) - + + def quote_plus(uri): - if PYVER >=3: + if PYVER >= 3: return urllib.parse.quote_plus(uri) else: return urllib.parse.quote_plus(uri) + def is_rb3(*args): if hasattr(RB.Shell.props, 'ui_manager'): return False else: - return True - + return True + + class Menu(object): ''' Menu object used to create window popup menus ''' + def __init__(self, plugin, shell): ''' Initializes the menu. @@ -144,9 +160,9 @@ self.plugin = plugin self.shell = shell self._unique_num = 0 - + self._rbmenu_items = {} - + def add_menu_item(self, menubar, section_name, action): ''' add a new menu item to the popup @@ -165,7 +181,7 @@ :param action: `Action` to associate with the menu item ''' label = action.label - + if is_rb3(self.shell): app = self.shell.props.application item = Gio.MenuItem() @@ -175,14 +191,14 @@ if not section_name in self._rbmenu_items: self._rbmenu_items[section_name] = [] self._rbmenu_items[section_name].append(label) - + app.add_plugin_menu_item(section_name, label, item) else: item = Gtk.MenuItem(label=label) action.associate_menuitem(item) self._rbmenu_items[label] = item bar = self.get_menu_object(menubar) - + if position == -1: bar.append(item) else: @@ -219,15 +235,15 @@ if is_rb3(self.shell): if not section_name in self._rbmenu_items: return - + app = self.shell.props.application - + for menu_item in self._rbmenu_items[section_name]: app.remove_plugin_menu_item(section_name, menu_item) if self._rbmenu_items[section_name]: del self._rbmenu_items[section_name][:] - + else: if not self._rbmenu_items: @@ -239,12 +255,12 @@ for menu_item in self._rbmenu_items: bar.remove(self._rbmenu_items[menu_item]) - #del self._rbmenu_items[:] - + # del self._rbmenu_items[:] + bar.show_all() uim.ensure_update() - - def load_from_file(self, rb2_ui_filename, rb3_ui_filename ): + + def load_from_file(self, rb2_ui_filename, rb3_ui_filename): ''' utility function to load the menu structure :param rb2_ui_filename: `str` RB2.98 and below UI file @@ -254,20 +270,20 @@ try: from coverart_browser_prefs import CoverLocale cl = CoverLocale() - + self.builder.set_translation_domain(cl.Locale.LOCALE_DOMAIN) except: pass - + if is_rb3(self.shell): ui_filename = rb3_ui_filename else: ui_filename = rb2_ui_filename self.ui_filename = ui_filename - + self.builder.add_from_file(rb.find_plugin_file(self.plugin, - ui_filename)) + ui_filename)) def _connect_rb3_signals(self, signals): def _menu_connect(action_name, func): @@ -275,36 +291,36 @@ action.connect('activate', func) action.set_enabled(True) self.shell.props.window.add_action(action) - - for key,value in list(signals.items()): - _menu_connect( key, value) - + + for key, value in list(signals.items()): + _menu_connect(key, value) + def _connect_rb2_signals(self, signals): def _menu_connect(menu_item_name, func): menu_item = self.builder.get_object(menu_item_name) menu_item.connect('activate', func) - - for key,value in list(signals.items()): - _menu_connect( key, value) - + + for key, value in list(signals.items()): + _menu_connect(key, value) + def connect_signals(self, signals): ''' connect all signal handlers with their menuitem counterparts :param signals: `dict` key is the name of the menuitem and value is the function callback when the menu is activated - ''' + ''' if is_rb3(self.shell): self._connect_rb3_signals(signals) else: self._connect_rb2_signals(signals) - + def get_gtkmenu(self, source, popup_name): ''' utility function to obtain the GtkMenu from the menu UI file :param popup_name: `str` is the name menu-id in the UI file ''' item = self.builder.get_object(popup_name) - + if is_rb3(self.shell): app = self.shell.props.application app.link_shared_menus(item) @@ -312,9 +328,9 @@ popup_menu.attach_to_widget(source, None) else: popup_menu = item - + return popup_menu - + def get_menu_object(self, menu_name_or_link): ''' utility function returns the GtkMenuItem/Gio.MenuItem @@ -330,7 +346,7 @@ popup_menu = app.get_plugin_menu(menu_name_or_link) else: popup_menu = item - + return popup_menu def set_sensitive(self, menu_or_action_item, enable): @@ -340,23 +356,24 @@ that is to be enabled/disabled :param enable: `bool` value to enable/disable ''' - + if is_rb3(self.shell): item = self.shell.props.window.lookup_action(menu_or_action_item) item.set_enabled(enable) else: item = self.builder.get_object(menu_or_action_item) item.set_sensitive(enable) - + + class ActionGroup(object): ''' container for all Actions used to associate with menu items ''' # action_state - STANDARD=0 - TOGGLE=1 - + STANDARD = 0 + TOGGLE = 1 + def __init__(self, shell, group_name): ''' constructor @@ -365,12 +382,12 @@ ''' self.group_name = group_name self.shell = shell - + self._actions = {} - + if is_rb3(self.shell): self.actiongroup = Gio.SimpleActionGroup() - else: + else: self.actiongroup = Gtk.ActionGroup(group_name) uim = self.shell.props.ui_manager uim.insert_action_group(self.actiongroup) @@ -378,14 +395,14 @@ @property def name(self): return self.group_name - + def remove_actions(self): ''' utility function to remove all actions associated with the ActionGroup ''' for action in self.actiongroup.list_actions(): self.actiongroup.remove_action(action) - + def get_action(self, action_name): ''' utility function to obtain the Action from the ActionGroup @@ -408,8 +425,8 @@ ''' args['accel'] = accel return self.add_action(func, action_name, **args) - - def add_action(self, func, action_name, **args ): + + def add_action(self, func, action_name, **args): ''' Creates an Action and adds it to the ActionGroup @@ -426,21 +443,21 @@ if 'label' in args: label = args['label'] else: - label=action_name + label = action_name if 'accel' in args: accel = args['accel'] else: accel = None - - state = ActionGroup.STANDARD + + state = ActionGroup.STANDARD if 'action_state' in args: state = args['action_state'] - + if is_rb3(self.shell): if state == ActionGroup.TOGGLE: action = Gio.SimpleAction.new_stateful(action_name, None, - GLib.Variant('b', False)) + GLib.Variant('b', False)) else: action = Gio.SimpleAction.new(action_name, None) @@ -450,7 +467,7 @@ action_type = 'app' app = Gio.Application.get_default() - + if action_type == 'app': app.add_action(action) else: @@ -458,56 +475,58 @@ self.actiongroup.add_action(action) if accel: - app.add_accelerator(accel, action_type+"."+action_name, None) + app.add_accelerator(accel, action_type + "." + action_name, None) else: if 'stock_id' in args: stock_id = args['stock_id'] else: stock_id = Gtk.STOCK_CLEAR - + if state == ActionGroup.TOGGLE: action = Gtk.ToggleAction(label=label, - name=action_name, - tooltip='', stock_id=stock_id) + name=action_name, + tooltip='', stock_id=stock_id) else: action = Gtk.Action(label=label, - name=action_name, - tooltip='', stock_id=stock_id) - + name=action_name, + tooltip='', stock_id=stock_id) + if accel: self.actiongroup.add_action_with_accel(action, accel) else: self.actiongroup.add_action(action) - + act = Action(self.shell, action) act.connect('activate', func, args) act.label = label act.accel = accel - + self._actions[action_name] = act - + return act + class ApplicationShell(object): ''' Unique class that mirrors RB.Application & RB.Shell menu functionality ''' # storage for the instance reference __instance = None - + class __impl: """ Implementation of the singleton interface """ + def __init__(self, shell): self.shell = shell - + if is_rb3(self.shell): self._uids = {} else: self._uids = [] - + self._action_groups = {} - + def insert_action_group(self, action_group): ''' Adds an ActionGroup to the ApplicationShell @@ -515,7 +534,7 @@ :param action_group: `ActionGroup` to add ''' self._action_groups[action_group.name] = action_group - + def lookup_action(self, action_group_name, action_name, action_type='app'): ''' looks up (finds) an action created by another plugin. If found returns @@ -525,7 +544,7 @@ :param action_name: `str` unique name for the action to look for :param action_type: `str` RB2.99+ action type ("win" or "app") ''' - + if is_rb3(self.shell): if action_type == "app": action = self.shell.props.application.lookup_action(action_name) @@ -543,7 +562,7 @@ action = None if actiongroup: action = actiongroup.get_action(action_name) - + if action: return Action(self.shell, action) else: @@ -572,24 +591,24 @@ for elem in root.findall(".//menuitem"): action_name = elem.attrib['action'] item_name = elem.attrib['name'] - + group = self._action_groups[group_name] act = group.get_action(action_name) - + item = Gio.MenuItem() item.set_detailed_action('app.' + action_name) item.set_label(act.label) item.set_attribute_value("accel", GLib.Variant("s", act.accel)) app = Gio.Application.get_default() - index = menu+action_name - app.add_plugin_menu_item(menu, - index, item) + index = menu + action_name + app.add_plugin_menu_item(menu, + index, item) self._uids[index] = menu else: uim = self.shell.props.ui_manager self._uids.append(uim.add_ui_from_string(ui_string)) uim.ensure_update() - + def add_browser_menuitems(self, ui_string, group_name): ''' utility function to add popup menu items to existing browser popups @@ -609,19 +628,19 @@ root = ET.fromstring(ui_string) for elem in root.findall("./popup"): popup_name = elem.attrib['name'] - + menuelem = elem.find('.//menuitem') action_name = menuelem.attrib['action'] item_name = menuelem.attrib['name'] - + group = self._action_groups[group_name] act = group.get_action(action_name) - + item = Gio.MenuItem() item.set_detailed_action('win.' + action_name) item.set_label(act.label) app = Gio.Application.get_default() - + if popup_name == 'QueuePlaylistViewPopup': plugin_type = 'queue-popup' elif popup_name == 'BrowserSourceViewPopup': @@ -632,10 +651,10 @@ plugin_type = 'podcast-episode-popup' else: print(("unknown type %s" % plugin_type)) - - index = plugin_type+action_name + + index = plugin_type + action_name app.add_plugin_menu_item(plugin_type, index, item) - self._uids[index]=plugin_type + self._uids[index] = plugin_type else: uim = self.shell.props.ui_manager self._uids.append(uim.add_ui_from_string(ui_string)) @@ -647,9 +666,8 @@ ''' if is_rb3(self.shell): for uid in self._uids: - - Gio.Application.get_default().remove_plugin_menu_item(self._uids[uid], - uid) + Gio.Application.get_default().remove_plugin_menu_item(self._uids[uid], + uid) else: uim = self.shell.props.ui_manager for uid in self._uids: @@ -674,11 +692,12 @@ """ Delegate access to implementation """ return setattr(self.__instance, attr, value) + class Action(object): ''' class that wraps around either a Gio.Action or a Gtk.Action ''' - + def __init__(self, shell, action): ''' constructor. @@ -688,19 +707,19 @@ ''' self.shell = shell self.action = action - + self._label = '' self._accel = '' self._current_state = False self._do_update_state = True - + def connect(self, address, func, args): self._connect_func = func self._connect_args = args - + if address == 'activate': func = self._activate - + if is_rb3(self.shell): self.action.connect(address, func, args) else: @@ -710,9 +729,9 @@ if self._do_update_state: self._current_state = not self._current_state self.set_state(self._current_state) - + self._connect_func(action, None, self._connect_args) - + @property def label(self): ''' @@ -725,21 +744,21 @@ return self.action.get_label() else: return self._label - + @label.setter def label(self, new_label): if not is_rb3(self.shell): self.action.set_label(new_label) - + self._label = new_label - + @property def accel(self): ''' get the accelerator associated with the Action ''' return self._accel - + @accel.setter def accel(self, new_accelerator): if new_accelerator: @@ -757,7 +776,7 @@ return self.action.get_enabled() else: return self.action.get_sensitive() - + def set_state(self, value): ''' set the state of a stateful action - this is applicable only @@ -774,7 +793,7 @@ self.action.activate(None) else: self.action.activate() - + def set_active(self, value): ''' activate or deactivate a stateful action signal @@ -783,7 +802,7 @@ :param value: `boolean` state value ''' - + if is_rb3(self.shell): self.action.change_state(GLib.Variant('b', value)) self._current_state = value @@ -792,7 +811,7 @@ self._do_update_state = True else: self.action.set_active(value) - + def get_active(self): ''' get the state of the action @@ -812,7 +831,6 @@ ''' if is_rb3(self.shell): - menuitem.set_detailed_action('win.'+self.action.get_name()) + menuitem.set_detailed_action('win.' + self.action.get_name()) else: menuitem.set_related_action(self.action) - Binary files /tmp/tmpDlQlJg/ZfCtmvM9Up/rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/de/LC_MESSAGES/lLyrics.mo and /tmp/tmpDlQlJg/Ku5Ts16dxv/rhythmbox-plugin-llyrics-1.1/lLyrics/locale/de/LC_MESSAGES/lLyrics.mo differ diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/de.po rhythmbox-plugin-llyrics-1.1/lLyrics/locale/de.po --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/de.po 1970-01-01 00:00:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/locale/de.po 2016-02-05 21:35:45.000000000 +0000 @@ -0,0 +1,159 @@ +# German translations for PACKAGE package. +# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# timo , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-04 16:47+0100\n" +"PO-Revision-Date: 2012-08-05 12:01+0200\n" +"Last-Translator: Timo Loewe \n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../lLyrics.py:256 ../lLyrics.py:275 +msgid "Lyrics" +msgstr "Liedtexte" + +#: ../lLyrics.py:259 +msgid "Display lyrics for the current playing song" +msgstr "Zeige Liedtext für den gerade gespielten Titel" + +#: ../lLyrics.py:263 +msgid "Show lyrics" +msgstr "Liedtext anzeigen" + +#: ../lLyrics.py:264 +msgid "Search and display lyrics for this song" +msgstr "Suche und zeige Liedtext für diesen Titel" + +#. create save and cancel buttons for edited lyrics +#: ../lLyrics.py:323 +msgid "Save" +msgstr "Speichern" + +#: ../lLyrics.py:325 +msgid "Cancel" +msgstr "Abbrechen" + +#. button for closing on demand lyrics +#: ../lLyrics.py:332 +msgid "Back to playing song" +msgstr "Zurück zum aktuellen Titel" + +#: ../lLyrics.py:366 ../lLyrics.py:404 ../lLyrics.py:839 +msgid "From cache file" +msgstr "Aus Cache Datei" + +#: ../lLyrics.py:371 ../Config.py:302 +msgid "Sources" +msgstr "Quellen" + +#: ../lLyrics.py:375 +msgid "Scan next source" +msgstr "Durchsuche nächste Quelle" + +#: ../lLyrics.py:376 +msgid "Scan all sources" +msgstr "Durchsuche alle Quellen" + +#: ../lLyrics.py:378 +msgid "Search online" +msgstr "Online suchen" + +#: ../lLyrics.py:380 +msgid "Mark as instrumental" +msgstr "Als instrumental markieren" + +#: ../lLyrics.py:382 +msgid "Clear lyrics" +msgstr "Liedtext löschen" + +#: ../lLyrics.py:383 +msgid "Edit lyrics" +msgstr "Liedtext bearbeiten" + +#: ../lLyrics.py:387 +msgid "Preferences" +msgstr "Einstellungen" + +#: ../lLyrics.py:603 +msgid "lLyrics Preferences" +msgstr "lLyrics Einstellungen" + +#: ../lLyrics.py:660 ../lLyrics.py:683 ../lLyrics.py:713 ../lLyrics.py:737 +msgid "searching lyrics..." +msgstr "suche Liedtexte..." + +#: ../lLyrics.py:845 +msgid "No lyrics found" +msgstr "Keine Liedtexte gefunden" + +#: ../Config.py:146 +msgid "Show sidebar on first playback" +msgstr "Seitenleiste bei Wiedergabestart einblenden" + +#: ../Config.py:159 +msgid "Save lyrics " +msgstr "Liedtexte speichern" + +#: ../Config.py:163 +msgid "" +"Whether to automatically save retrieved lyrics in the folder specified below" +msgstr "" +"Speichert gefundene Liedtexte automatisch im nachfolgend ausgewählten Ordner" + +#: ../Config.py:183 +msgid "default" +msgstr "Standardeinstellung" + +#: ../Config.py:186 +msgid "Folder for lyrics" +msgstr "Ordner für Liedtexte" + +#: ../Config.py:200 +msgid "Always ignore parentheses in song title" +msgstr "Klammern im Songtitel immer ignorieren" + +#: ../Config.py:203 +msgid "" +"When turned off, only parentheses containing specific strings (e.g. 'remix', " +"'live', 'edit', etc) are filtered" +msgstr "" +"Falls ausgeschaltet, werden nur Klammern mit bestimmten Zeichenketten (z.B. " +"'remix', 'live', 'edit', etc) gefiltert" + +#. check buttons for lyric sources +#: ../Config.py:222 +msgid "Sources:" +msgstr "Quellen:" + +#: ../Config.py:267 +msgid "Hide sidebar label" +msgstr "Verstecke die Überschrift der Seitenleiste" + +#: ../Config.py:281 +msgid "Show lyrics in left sidebar instead of right one" +msgstr "Zeige Liedtexte in der linken statt der rechten Seitenleiste" + +#: ../Config.py:284 +msgid "" +"You have to disable and re-enable this plugin or restart Rhythmbox to apply " +"changes here" +msgstr "" +"Zum Anwenden der Änderung muss das Plugin de- und reaktiviert oder Rhythmbox " +"neu gestartet werden" + +#: ../Config.py:301 +msgid "General" +msgstr "Allgemein" + +#: ../Config.py:303 +msgid "Appearance" +msgstr "Erscheinungsbild" Binary files /tmp/tmpDlQlJg/ZfCtmvM9Up/rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/fr/LC_MESSAGES/lLyrics.mo and /tmp/tmpDlQlJg/Ku5Ts16dxv/rhythmbox-plugin-llyrics-1.1/lLyrics/locale/fr/LC_MESSAGES/lLyrics.mo differ diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/fr.po rhythmbox-plugin-llyrics-1.1/lLyrics/locale/fr.po --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/fr.po 1970-01-01 00:00:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/locale/fr.po 2016-02-05 21:35:45.000000000 +0000 @@ -0,0 +1,160 @@ +# French translations for PACKAGE package. +# Copyright (C) 2014 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Meradi , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-04 16:47+0100\n" +"PO-Revision-Date: 2014-03-30 17:50+0200\n" +"Last-Translator: Meradi \n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: ../lLyrics.py:256 ../lLyrics.py:275 +msgid "Lyrics" +msgstr "Paroles" + +#: ../lLyrics.py:259 +msgid "Display lyrics for the current playing song" +msgstr "Afficher les paroles du morceau en cours de lecture" + +#: ../lLyrics.py:263 +msgid "Show lyrics" +msgstr "Afficher les paroles" + +#: ../lLyrics.py:264 +msgid "Search and display lyrics for this song" +msgstr "Chercher et afficher les paroles de ce morceau" + +#. create save and cancel buttons for edited lyrics +#: ../lLyrics.py:323 +msgid "Save" +msgstr "Enregistrer" + +#: ../lLyrics.py:325 +msgid "Cancel" +msgstr "Annuler" + +#. button for closing on demand lyrics +#: ../lLyrics.py:332 +msgid "Back to playing song" +msgstr "Retourner au morceau en cours de lecture" + +#: ../lLyrics.py:366 ../lLyrics.py:404 ../lLyrics.py:839 +msgid "From cache file" +msgstr "A partir du fichier de cache " + +#: ../lLyrics.py:371 ../Config.py:302 +msgid "Sources" +msgstr "Sources" + +#: ../lLyrics.py:375 +msgid "Scan next source" +msgstr "Chercher la source suivante" + +#: ../lLyrics.py:376 +msgid "Scan all sources" +msgstr "Chercher tous les sources" + +#: ../lLyrics.py:378 +msgid "Search online" +msgstr "Chercher en ligne" + +#: ../lLyrics.py:380 +msgid "Mark as instrumental" +msgstr "Marquer ce morceau comme instrumental" + +#: ../lLyrics.py:382 +msgid "Clear lyrics" +msgstr "Effacer les paroles" + +#: ../lLyrics.py:383 +msgid "Edit lyrics" +msgstr "Modifier les paroles" + +#: ../lLyrics.py:387 +msgid "Preferences" +msgstr "Préférences" + +#: ../lLyrics.py:603 +msgid "lLyrics Preferences" +msgstr "Préférences de lLyrics" + +#: ../lLyrics.py:660 ../lLyrics.py:683 ../lLyrics.py:713 ../lLyrics.py:737 +msgid "searching lyrics..." +msgstr "Recherche des paroles..." + +#: ../lLyrics.py:845 +msgid "No lyrics found" +msgstr "Aucune paroles trouvées" + +#: ../Config.py:146 +msgid "Show sidebar on first playback" +msgstr "Afficher le paneau latérale en début de lecture" + +#: ../Config.py:159 +msgid "Save lyrics " +msgstr "Enregistrer les paroles" + +#: ../Config.py:163 +msgid "" +"Whether to automatically save retrieved lyrics in the folder specified below" +msgstr "" +"Enregistrer les paroles trouvées automatiquement dans le dossier sélectionné " +"ci-dessous" + +#: ../Config.py:183 +msgid "default" +msgstr "défault" + +#: ../Config.py:186 +msgid "Folder for lyrics" +msgstr "Dossier où enregistrer les paroles" + +#: ../Config.py:200 +msgid "Always ignore parentheses in song title" +msgstr "Ignorer toujours les parenthèses dans le titre des morceaux" + +#: ../Config.py:203 +msgid "" +"When turned off, only parentheses containing specific strings (e.g. 'remix', " +"'live', 'edit', etc) are filtered" +msgstr "" +"Si désactivé, seules certaines chaînes de caractères (par exemple « remix », " +"« live », « edit », etc) seront filtrées" + +#. check buttons for lyric sources +#: ../Config.py:222 +msgid "Sources:" +msgstr "Sources" + +#: ../Config.py:267 +msgid "Hide sidebar label" +msgstr "Cacher le titre du paneau latérale" + +#: ../Config.py:281 +msgid "Show lyrics in left sidebar instead of right one" +msgstr "Afficher les paroles dans le paneau latérale gauche" + +#: ../Config.py:284 +msgid "" +"You have to disable and re-enable this plugin or restart Rhythmbox to apply " +"changes here" +msgstr "" +"Vous devez désactiver et réactiver ce plugin ou redémarrer Rhythmbox pour " +"appliquerles changements" + +#: ../Config.py:301 +msgid "General" +msgstr "Géneral" + +#: ../Config.py:303 +msgid "Appearance" +msgstr "Apparence" diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/messages.pot rhythmbox-plugin-llyrics-1.1/lLyrics/locale/messages.pot --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/messages.pot 1970-01-01 00:00:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/locale/messages.pot 2016-02-05 21:35:45.000000000 +0000 @@ -0,0 +1,154 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-04 16:47+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../lLyrics.py:256 ../lLyrics.py:275 +msgid "Lyrics" +msgstr "" + +#: ../lLyrics.py:259 +msgid "Display lyrics for the current playing song" +msgstr "" + +#: ../lLyrics.py:263 +msgid "Show lyrics" +msgstr "" + +#: ../lLyrics.py:264 +msgid "Search and display lyrics for this song" +msgstr "" + +#. create save and cancel buttons for edited lyrics +#: ../lLyrics.py:323 +msgid "Save" +msgstr "" + +#: ../lLyrics.py:325 +msgid "Cancel" +msgstr "" + +#. button for closing on demand lyrics +#: ../lLyrics.py:332 +msgid "Back to playing song" +msgstr "" + +#: ../lLyrics.py:366 ../lLyrics.py:404 ../lLyrics.py:839 +msgid "From cache file" +msgstr "" + +#: ../lLyrics.py:371 ../Config.py:302 +msgid "Sources" +msgstr "" + +#: ../lLyrics.py:375 +msgid "Scan next source" +msgstr "" + +#: ../lLyrics.py:376 +msgid "Scan all sources" +msgstr "" + +#: ../lLyrics.py:378 +msgid "Search online" +msgstr "" + +#: ../lLyrics.py:380 +msgid "Mark as instrumental" +msgstr "" + +#: ../lLyrics.py:382 +msgid "Clear lyrics" +msgstr "" + +#: ../lLyrics.py:383 +msgid "Edit lyrics" +msgstr "" + +#: ../lLyrics.py:387 +msgid "Preferences" +msgstr "" + +#: ../lLyrics.py:603 +msgid "lLyrics Preferences" +msgstr "" + +#: ../lLyrics.py:660 ../lLyrics.py:683 ../lLyrics.py:713 ../lLyrics.py:737 +msgid "searching lyrics..." +msgstr "" + +#: ../lLyrics.py:845 +msgid "No lyrics found" +msgstr "" + +#: ../Config.py:146 +msgid "Show sidebar on first playback" +msgstr "" + +#: ../Config.py:159 +msgid "Save lyrics " +msgstr "" + +#: ../Config.py:163 +msgid "" +"Whether to automatically save retrieved lyrics in the folder specified below" +msgstr "" + +#: ../Config.py:183 +msgid "default" +msgstr "" + +#: ../Config.py:186 +msgid "Folder for lyrics" +msgstr "" + +#: ../Config.py:200 +msgid "Always ignore parentheses in song title" +msgstr "" + +#: ../Config.py:203 +msgid "" +"When turned off, only parentheses containing specific strings (e.g. 'remix', " +"'live', 'edit', etc) are filtered" +msgstr "" + +#. check buttons for lyric sources +#: ../Config.py:222 +msgid "Sources:" +msgstr "" + +#: ../Config.py:267 +msgid "Hide sidebar label" +msgstr "" + +#: ../Config.py:281 +msgid "Show lyrics in left sidebar instead of right one" +msgstr "" + +#: ../Config.py:284 +msgid "" +"You have to disable and re-enable this plugin or restart Rhythmbox to apply " +"changes here" +msgstr "" + +#: ../Config.py:301 +msgid "General" +msgstr "" + +#: ../Config.py:303 +msgid "Appearance" +msgstr "" Binary files /tmp/tmpDlQlJg/ZfCtmvM9Up/rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/pl/LC_MESSAGES/lLyrics.mo and /tmp/tmpDlQlJg/Ku5Ts16dxv/rhythmbox-plugin-llyrics-1.1/lLyrics/locale/pl/LC_MESSAGES/lLyrics.mo differ diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/pl.po rhythmbox-plugin-llyrics-1.1/lLyrics/locale/pl.po --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/pl.po 1970-01-01 00:00:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/locale/pl.po 2016-02-05 21:35:45.000000000 +0000 @@ -0,0 +1,161 @@ +# German translations for PACKAGE package. +# Copyright (C) 2015 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Rafał Łasocha , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-04 16:47+0100\n" +"PO-Revision-Date: 2015-06-01 17:09+0200\n" +"Last-Translator: Rafał Łasocha \n" +"Language-Team: Polish\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: ../lLyrics.py:256 ../lLyrics.py:275 +msgid "Lyrics" +msgstr "Treść utworu" + +#: ../lLyrics.py:259 +msgid "Display lyrics for the current playing song" +msgstr "" + +#: ../lLyrics.py:263 +msgid "Show lyrics" +msgstr "Wyświetl treśc tego utworu" + +#: ../lLyrics.py:264 +msgid "Search and display lyrics for this song" +msgstr "" + +#. create save and cancel buttons for edited lyrics +#: ../lLyrics.py:323 +msgid "Save" +msgstr "Zapisz" + +#: ../lLyrics.py:325 +msgid "Cancel" +msgstr "Anuluj" + +#. button for closing on demand lyrics +#: ../lLyrics.py:332 +msgid "Back to playing song" +msgstr "Wróć do aktualnie odtwarzanego utworu" + +#: ../lLyrics.py:366 ../lLyrics.py:404 ../lLyrics.py:839 +msgid "From cache file" +msgstr "" + +#: ../lLyrics.py:371 ../Config.py:302 +msgid "Sources" +msgstr "Źródła" + +#: ../lLyrics.py:375 +msgid "Scan next source" +msgstr "Sprawdź następne źródło" + +#: ../lLyrics.py:376 +msgid "Scan all sources" +msgstr "Sprawdź wszystkie źródła" + +#: ../lLyrics.py:378 +msgid "Search online" +msgstr "Wyszukaj online" + +#: ../lLyrics.py:380 +msgid "Mark as instrumental" +msgstr "Oznacz jako utwór instrumentalny" + +#: ../lLyrics.py:382 +msgid "Clear lyrics" +msgstr "Wyczyść treść" + +#: ../lLyrics.py:383 +msgid "Edit lyrics" +msgstr "Edytuj tekst" + +#: ../lLyrics.py:387 +msgid "Preferences" +msgstr "Ustawienia" + +#: ../lLyrics.py:603 +msgid "lLyrics Preferences" +msgstr "Ustawienia" + +#: ../lLyrics.py:660 ../lLyrics.py:683 ../lLyrics.py:713 ../lLyrics.py:737 +msgid "searching lyrics..." +msgstr "Wyszukiwanie tekstu utworu" + +#: ../lLyrics.py:845 +msgid "No lyrics found" +msgstr "Nie znaleziono treści utworu" + +#: ../Config.py:146 +msgid "Show sidebar on first playback" +msgstr "Wyświetl panel przy odtwarzaniu muzyki" + +#: ../Config.py:159 +msgid "Save lyrics " +msgstr "Przechowuj teksty utworów" + +#: ../Config.py:163 +msgid "" +"Whether to automatically save retrieved lyrics in the folder specified below" +msgstr "" +"Zapisywanie pobranych tekstów w poniższym folderze aby mieć do nich dostęp " +"szybciej i bez połączenia z internetem" + +#: ../Config.py:183 +msgid "default" +msgstr "" + +#: ../Config.py:186 +msgid "Folder for lyrics" +msgstr "Katalog dla tekstów" + +#: ../Config.py:200 +msgid "Always ignore parentheses in song title" +msgstr "Zawsze ignoruj nawiasy w tytułach utworów" + +#: ../Config.py:203 +msgid "" +"When turned off, only parentheses containing specific strings (e.g. 'remix', " +"'live', 'edit', etc) are filtered" +msgstr "" +"Kiedy wyłączone, tylko nawiasy zawierające konkretne słowa (np. 'remix', " +"'live', 'edit' itp.) są filtrowane" + +#. check buttons for lyric sources +#: ../Config.py:222 +msgid "Sources:" +msgstr "Lista źródeł:" + +#: ../Config.py:267 +msgid "Hide sidebar label" +msgstr "Ukryj nagłówek panelu" + +#: ../Config.py:281 +msgid "Show lyrics in left sidebar instead of right one" +msgstr "Pokazuj treść utworu w lewym panelu, a nie w prawym" + +#: ../Config.py:284 +msgid "" +"You have to disable and re-enable this plugin or restart Rhythmbox to apply " +"changes here" +msgstr "" +"Musisz wyłączyć i jeszcze raz włączyć tę wtyczkę albo ponownie uruchomić " +"Rhythmboxa żeby zmiany odniosły efekt" + +#: ../Config.py:301 +msgid "General" +msgstr "Ogólne" + +#: ../Config.py:303 +msgid "Appearance" +msgstr "Wygląd" diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/POTFILES.in rhythmbox-plugin-llyrics-1.1/lLyrics/locale/POTFILES.in --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/POTFILES.in 1970-01-01 00:00:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/locale/POTFILES.in 2016-02-05 21:35:45.000000000 +0000 @@ -0,0 +1,2 @@ +lLyrics.py +Config.py diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/TRANSLATIONS rhythmbox-plugin-llyrics-1.1/lLyrics/locale/TRANSLATIONS --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/locale/TRANSLATIONS 1970-01-01 00:00:00.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/locale/TRANSLATIONS 2016-02-05 21:35:45.000000000 +0000 @@ -0,0 +1,13 @@ +Help with translation is appreciated! + +If you want to provide locales for your language, start like this: + +1) Run "intltool-update -p -g messages". + This will recreate the messages.pot file so that is up to date with the latest lLyrics source files. + +2) Run "msginit --locale=YOUR_LANGUAGE_CODE". + Replace YOUR_LANGUAGE_CODE with your appropriate language short cut, e.g. "fr" for French or "ru" for Russian. + This will create a new .po file with your language code. + +Now you can translate all messages in the .po file into your language. The original string is given by "msgid", your translation should go to "msgstr". + diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/LyricsmaniaParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/LyricsmaniaParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/LyricsmaniaParser.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/LyricsmaniaParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -18,23 +18,23 @@ import Util + class Parser(object): - def __init__(self, artist, title): self.artist = artist self.title = title self.lyrics = "" - + def parse(self): # remove unwanted characters from artist and title strings - clean_artist = self.artist + clean_artist = self.artist.replace("+", "and") clean_artist = Util.remove_punctuation(clean_artist) clean_artist = clean_artist.replace(" ", "_") - + clean_title = self.title clean_title = Util.remove_punctuation(clean_title) clean_title = clean_title.replace(" ", "_") - + # create lyrics Url url = "http://www.lyricsmania.com/" + clean_title + "_lyrics_" + clean_artist + ".html" print("lyricsmania Url " + url) @@ -43,29 +43,33 @@ except: print("could not connect to lyricsmania.com") return "" - + resp = Util.bytes_to_string(resp) self.lyrics = self.get_lyrics(resp) self.lyrics = string.capwords(self.lyrics, "\n").strip() - + return self.lyrics - + def get_lyrics(self, resp): # cut HTML source to relevant part - start_string = """
""" - start = resp.find(start_string) + start = resp.find("") if start == -1: print("lyrics start not found") return "" - resp = resp[(start+len(start_string)+1):] + resp = resp[(start + 9):] end = resp.find("
") if end == -1: print("lyrics end not found ") return "" - resp = resp[:(end)] - + resp = resp[:end] + # replace unwanted parts + resp = resp.replace("
\n", "\n") + resp = resp.replace("\n
", "\n") + resp = resp.replace("
", "\n") resp = resp.replace("
", "") - + resp = resp.replace("
\n", "") + + resp = "\n".join(line.strip() for line in resp.split("\n")) + return resp - diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/LyricsNMusicParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/LyricsNMusicParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/LyricsNMusicParser.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/LyricsNMusicParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -21,71 +21,72 @@ API_KEY = "5ad5728ee39ebc05de6b8a7a154202" -class Parser(): - + +class Parser(object): def __init__(self, artist, title): self.artist = artist self.title = title self.lyrics = "" - + def parse(self): # remove punctuation from artist/title clean_artist = Util.remove_punctuation(self.artist) clean_title = Util.remove_punctuation(self.title) - + # API request - url = "http://api.lyricsnmusic.com/songs?api_key=" + API_KEY + "&artist=" + clean_artist.replace(" ", "+") + "&track=" + clean_title.replace(" ", "+") + url = "http://api.lyricsnmusic.com/songs?api_key=" + API_KEY + "&artist=" + clean_artist.replace(" ", "+") \ + + "&track=" + clean_title.replace(" ", "+") print("call lyricsnmusic API: " + url) try: - resp = urllib.request.urlopen(url, None, 3).read() + resp = urllib.request.urlopen(Util.add_request_header(url), None, 3).read() except: print("could not connect to lyricsnmusic.com API") return "" - + resp = Util.bytes_to_string(resp) if resp == "": return "" - + resp = json.loads(resp) - + if len(resp) == 0: return "" - + resp = self.verify(resp) if resp is None: return "" - + lyrics_url = resp["url"] print("url: " + lyrics_url) - + # open lyrics-URL try: - resp = urllib.request.urlopen(lyrics_url, None, 3).read() + resp = urllib.request.urlopen(Util.add_request_header(lyrics_url), None, 3).read() except: - print("could not open lyricwiki url") + print("could not open lyricsnmusic.com lyrics url") return "" - + resp = Util.bytes_to_string(resp) self.lyrics = self.get_lyrics(resp) self.lyrics = string.capwords(self.lyrics, "\n").strip() - + return self.lyrics - + def get_lyrics(self, resp): # cut HTML source to relevant part start = resp.find("
")
         if start == -1:
             print("lyrics start not found")
             return ""
-        resp = resp[(start+28):]
+        resp = resp[(start + 28):]
         end = resp.find("
") if end == -1: print("lyrics end not found") return "" - resp = resp[:(end)] - + resp = resp[:end] + return resp - + def verify(self, resp): for entry in resp: title = entry["title"].lower() @@ -93,6 +94,5 @@ if self.artist == artist and self.title == title: return entry print("wrong artist/title! " + artist + " - " + title) - + return None - \ No newline at end of file diff -Nru rhythmbox-plugin-llyrics-0.5.4/lLyrics/LyricwikiParser.py rhythmbox-plugin-llyrics-1.1/lLyrics/LyricwikiParser.py --- rhythmbox-plugin-llyrics-0.5.4/lLyrics/LyricwikiParser.py 2014-04-07 17:10:27.000000000 +0000 +++ rhythmbox-plugin-llyrics-1.1/lLyrics/LyricwikiParser.py 2016-02-05 21:35:45.000000000 +0000 @@ -19,77 +19,79 @@ import Util -class Parser(): - + +class Parser(object): def __init__(self, artist, title): self.artist = artist self.title = title self.lyrics = "" - + def parse(self): # API getSong request - url = "http://lyrics.wikia.com/api.php?func=getSong&artist=" + urllib.parse.quote(self.artist) + "&song=" + urllib.parse.quote(self.title) + "&fmt=realjson" + url = "http://lyrics.wikia.com/api.php?func=getSong&artist=" + urllib.parse.quote(self.artist) \ + + "&song=" + urllib.parse.quote(self.title) + "&fmt=realjson" print("call lyrikwiki API: " + url) try: resp = urllib.request.urlopen(url, None, 3).read() except: print("could not connect to lyricwiki.org API") return "" - + resp = Util.bytes_to_string(resp) if resp == "": return "" - + resp = json.loads(resp) - - if resp["lyrics"] == "Not found": + + print(resp) + if resp["lyrics"] == "Not found" or resp["isOnTakedownList"] == '1': return "" - + lyrics_url = resp["url"] print("url: " + lyrics_url) - + # open lyrics-URL try: resp = urllib.request.urlopen(lyrics_url, None, 3).read() except: print("could not open lyricwiki url") return "" - + resp = Util.bytes_to_string(resp) self.lyrics = self.get_lyrics(resp) self.lyrics = string.capwords(self.lyrics, "\n").strip() - + return self.lyrics - + def get_lyrics(self, resp): # cut HTML source to relevant part - start = resp.find("
&") + start = resp.find("
") if start == -1: - start = resp.find("
&") - if start == -1: - print("lyrics start not found") - return "" - resp = resp[(start+13):] + print("lyrics start not found") + return "" + resp = resp[start:] + + start = resp.find("") + if start == -1: + print("lyrics start not found") + return "" + resp = resp[(start + 9):] + end = resp.find("