mirror of
https://github.com/beetbox/beets.git
synced 2026-01-08 00:45:55 +01:00
lyrics: add 'sources' option
This commit is contained in:
parent
0f2f43ca9b
commit
e7a4b92de5
5 changed files with 56 additions and 21 deletions
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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
32
test/test_util.py
Normal 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')
|
||||
Loading…
Reference in a new issue