lyrics: add 'sources' option

This commit is contained in:
Fabrice Laporte 2014-12-17 00:42:11 +01:00
parent 0f2f43ca9b
commit e7a4b92de5
5 changed files with 56 additions and 21 deletions

View file

@ -27,8 +27,7 @@ import itertools
from HTMLParser import HTMLParseError
from beets.plugins import BeetsPlugin
from beets import ui
from beets import config
from beets import config, ui, util
from beets.util import feat_tokens
@ -431,6 +430,11 @@ def fetch_google(artist, title):
# Plugin logic.
SOURCES_ALL = {'google': fetch_google,
'lyricwiki': fetch_lyricswiki,
'lyrics.com': fetch_lyricscom,
'musixmatch': fetch_musixmatch}
class LyricsPlugin(BeetsPlugin):
def __init__(self):
@ -441,12 +445,16 @@ class LyricsPlugin(BeetsPlugin):
'google_API_key': None,
'google_engine_ID': u'009217259823014548361:lndtuqkycfu',
'fallback': None,
'sources': SOURCES_ALL
})
self.backends = [fetch_lyricswiki, fetch_lyricscom]
if self.config['google_API_key'].get():
self.backends.insert(0, fetch_google)
if not self.config['google_API_key'].get():
SOURCES_ALL.pop('google', None)
self.config['sources'] = util.sanitize_choices(
self.config['sources'].as_str_seq(), SOURCES_ALL.keys())
self.backends = []
for key in self.config['sources'].as_str_seq():
self.backends.append(SOURCES_ALL[key])
def commands(self):
cmd = ui.Subcommand('lyrics', help='fetch song lyrics')

View file

@ -11,6 +11,8 @@ library by typing ``pip install requests`` or the equivalent for your OS.
New:
* :doc:`/plugins/lyrics`: Add musixmatch source.
* :doc:`/plugins/lyrics`: New ``sources`` config option that lets you choose
exactly where to look for lyrics and in which order.
* :doc:`/plugins/lyrics`: Add brazilian and hispanic sources to Google custom
search engine.
* A new :doc:`/plugins/permissions` makes it easy to fix permissions on music

View file

@ -43,8 +43,13 @@ configuration file. The available options are:
backend).
Default: None.
- **google_engine_ID**: The custom search engine to use.
Default: The beets custom search engine, which gathers a list of sources
Default: The `beets custom search engine`_, which gathers a list of sources
known to be scrapeable.
- **sources**: List of sources to search for lyrics. An asterisk `*` expands
to all available sources.
Default: ``google lyricwiki lyrics.com musixmatch``, i.e., all sources.
*google* source will be automatically deactivated if no `google_engine_ID` is
setup.
Here's an example of ``config.yaml``::
@ -53,6 +58,7 @@ Here's an example of ``config.yaml``::
google_API_key: AZERTYUIOPQSDFGHJKLMWXCVBN1234567890_ab
google_engine_ID: 009217259823014548361:lndtuqkycfu
.. _beets custom search engine: https://www.google.com:443/cse/publicurl?cx=009217259823014548361:lndtuqkycfu
Fetching Lyrics Manually
------------------------
@ -93,7 +99,7 @@ default, beets use a list of sources known to be scrapeable.
.. _define a custom search engine: http://www.google.com/cse/all
Note that the Google custom search API is limited to 100 queries per day.
After that, the lyrics plugin will fall back on its other data sources.
After that, the lyrics plugin will fall back on other declared data sources.
.. _pip: http://www.pip-installer.org/
.. _BeautifulSoup: http://www.crummy.com/software/BeautifulSoup/bs4/doc/

View file

@ -12,8 +12,6 @@
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
from beetsplug import fetchart
import os.path
from _common import unittest
from helper import TestHelper
@ -43,17 +41,6 @@ class FetchartCliTest(unittest.TestCase, TestHelper):
with open(cover_path, 'r') as f:
self.assertEqual(f.read(), 'IMAGE')
def test_sanitize_sources(self):
self.assertEqual(fetchart.sanitize_sources(['google', 'unknown']),
['google'])
self.assertEqual(fetchart.sanitize_sources(['google', 'google']),
['google'])
res = fetchart.sanitize_sources(['google', '*', 'amazon'])
# don't check strict egality on lengths as itunes source may be removed
# by plugin
self.assertTrue(len(res) >= len(fetchart.SOURCES_ALL) - 1 and
res[0] == 'google' and res[-1] == 'amazon')
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

32
test/test_util.py Normal file
View file

@ -0,0 +1,32 @@
# This file is part of beets.
# Copyright 2013, Adrian Sampson.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
from _common import unittest
from beets import util
class UtilTest(unittest.TestCase):
def test_sanitize_choices(self):
self.assertEqual(util.sanitize_choices(['A', 'Z'], ('A', 'B')),
['A'])
self.assertEqual(util.sanitize_choices(['A', 'A'], ('A')), ['A'])
self.assertEqual(util.sanitize_choices(['D', '*', 'A'],
('A', 'B', 'C', 'D')), ['D', 'B', 'C', 'A'])
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)
if __name__ == '__main__':
unittest.main(defaultTest='suite')