diff --git a/beetsplug/lyrics.py b/beetsplug/lyrics.py index 0762cd3d1..91fc157a5 100644 --- a/beetsplug/lyrics.py +++ b/beetsplug/lyrics.py @@ -465,7 +465,13 @@ class Tekstowo(Backend): except HTMLParseError: return None - href = html.find("div", class_="content").find_all("div", class_="box-przeboje")[0].find('a').get('href') + song_row = html.find("div", class_="content"). \ + find_all("div", class_="box-przeboje")[0] + + if not song_row: + return None + + href = song_row.find('a').get('href') return self.BASE_URL + href def extract_lyrics(self, html): @@ -672,6 +678,7 @@ class Google(Backend): class LyricsPlugin(plugins.BeetsPlugin): SOURCES = ['google', 'lyricwiki', 'musixmatch', 'genius', 'tekstowo'] + SOURCES_USING_BEAUTIFUL_SOUP = ['google', 'genius', 'tekstowo'] SOURCE_BACKENDS = { 'google': Google, 'lyricwiki': LyricsWiki, @@ -716,6 +723,9 @@ class LyricsPlugin(plugins.BeetsPlugin): sources = plugins.sanitize_choices( self.config['sources'].as_str_seq(), available_sources) + if not HAS_BEAUTIFUL_SOUP: + sources = self.sanitize_beautiful_soup_sources(sources) + if 'google' in sources: if not self.config['google_API_key'].get(): # We log a *debug* message here because the default @@ -725,25 +735,6 @@ class LyricsPlugin(plugins.BeetsPlugin): self._log.debug(u'Disabling google source: ' u'no API key configured.') sources.remove('google') - elif not HAS_BEAUTIFUL_SOUP: - self._log.warning(u'To use the google lyrics source, you must ' - u'install the beautifulsoup4 module. See ' - u'the documentation for further details.') - sources.remove('google') - - if 'genius' in sources and not HAS_BEAUTIFUL_SOUP: - self._log.debug( - u'The Genius backend requires BeautifulSoup, which is not ' - u'installed, so the source is disabled.' - ) - sources.remove('genius') - - if 'tekstowo' in sources and not HAS_BEAUTIFUL_SOUP: - self._log.debug( - u'The Tekstowo.pl backend requires BeautifulSoup, which is not ' - u'installed, so the source is disabled.' - ) - sources.remove('tekstowo') self.config['bing_lang_from'] = [ x.lower() for x in self.config['bing_lang_from'].as_str_seq()] @@ -757,6 +748,17 @@ class LyricsPlugin(plugins.BeetsPlugin): self.backends = [self.SOURCE_BACKENDS[source](self.config, self._log) for source in sources] + def sanitize_beautiful_soup_sources(self, sources): + for source in self.SOURCES_USING_BEAUTIFUL_SOUP: + if source in sources: + self._log.warning(u'To use the %s lyrics source, you must ' + u'install the beautifulsoup4 module. See ' + u'the documentation for further details.' + % source) + sources.remove(source) + + return sources + def get_bing_access_token(self): params = { 'client_id': 'beets', diff --git a/docs/changelog.rst b/docs/changelog.rst index a51c85cad..981b2f89a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -19,7 +19,7 @@ New features: * :doc:`plugins/discogs` now adds two extra fields: `discogs_labelid` and `discogs_artistid` :bug: `3413` -* :doc:`/plugins/export`: Added new ``-f`` (``--format``) flag; +* :doc:`/plugins/export`: Added new ``-f`` (``--format``) flag; which allows for the ability to export in json, csv and xml. Thanks to :user:`austinmm`. :bug:`3402` @@ -114,7 +114,7 @@ New features: Fixes: -* :doc:`/plugins/fetchart`: Fixed a bug that caused fetchart to not take +* :doc:`/plugins/fetchart`: Fixed a bug that caused fetchart to not take environment variables such as proxy servers into account when making requests :bug:`3450` * :doc:`/plugins/inline`: In function-style field definitions that refer to @@ -174,6 +174,8 @@ Fixes: * Removed ``@classmethod`` decorator from dbcore.query.NoneQuery.match method failing with AttributeError when called. It is now an instance method. :bug:`3516` :bug:`3517` +* :doc:`/plugins/lyrics`: Added Tekstowo.pl lyrics provider + :bug:`3344` For plugin developers: diff --git a/docs/plugins/lyrics.rst b/docs/plugins/lyrics.rst index fac07ad87..72a664319 100644 --- a/docs/plugins/lyrics.rst +++ b/docs/plugins/lyrics.rst @@ -3,11 +3,12 @@ Lyrics Plugin The ``lyrics`` plugin fetches and stores song lyrics from databases on the Web. Namely, the current version of the plugin uses `Lyric Wiki`_, -`Musixmatch`_, `Genius.com`_, and, optionally, the Google custom search API. +`Musixmatch`_, `Genius.com`_, `Tekstowo.pl`_, and, optionally, the Google custom search API. .. _Lyric Wiki: https://lyrics.wikia.com/ .. _Musixmatch: https://www.musixmatch.com/ .. _Genius.com: https://genius.com/ +.. _Tekstowo.pl: https://www.tekstowo.pl/ Fetch Lyrics During Import @@ -59,11 +60,10 @@ configuration file. The available options are: sources known to be scrapeable. - **sources**: List of sources to search for lyrics. An asterisk ``*`` expands to all available sources. - Default: ``google lyricwiki musixmatch genius``, i.e., all the + Default: ``google lyricwiki musixmatch genius tekstowo``, i.e., all the available sources. The ``google`` source will be automatically deactivated if no ``google_API_key`` is setup. - Both it and the ``genius`` source will only be enabled if BeautifulSoup is - installed. + The following sources will only be enabled if BeatifulSoup is installed: ``[google, genius, tekstowo]`` Here's an example of ``config.yaml``:: @@ -166,6 +166,16 @@ library. Install it by typing:: The backend is enabled by default. +Activate Tekstowo.pl Lyrics +---------------------- + +Like the Google backend, the Tekstowo.pl backend requires the `BeautifulSoup`_ +library. Install it by typing:: + + pip install beautifulsoup4 + +The backend is enabled by default. + .. _lyrics-translation: Activate On-the-Fly Translation diff --git a/test/test_lyrics.py b/test/test_lyrics.py index f7ea538e2..9a5e9e893 100644 --- a/test/test_lyrics.py +++ b/test/test_lyrics.py @@ -251,6 +251,8 @@ class LyricsPluginSourcesTest(LyricsGoogleBaseTest): dict(artist=u'Santana', title=u'Black magic woman', backend=lyrics.MusiXmatch), dict(DEFAULT_SONG, backend=lyrics.Genius), + dict(artist=u'Boy In Space', title=u'u n eye', + backend=lyrics.Tekstowo), ] GOOGLE_SOURCES = [