file-based genre whitelist & cleanup

--HG--
rename : beetsplug/lastgenre.py => beetsplug/lastgenre/__init__.py
This commit is contained in:
Adrian Sampson 2011-10-07 12:51:38 -07:00
parent 0805e50a13
commit b62b462b1e
6 changed files with 1587 additions and 19 deletions

View file

@ -8,3 +8,6 @@ include LICENSE NEWS README.rst
# Resources for web plugin.
recursive-include beetsplug/web/templates *
recursive-include beetsplug/web/static *
# And for the lastgenre plugin.
include beetsplug/lastgenre/genres.txt

View file

@ -13,16 +13,30 @@
# included in all copies or substantial portions of the Software.
"""Gets genres for imported music based on Last.fm tags.
Uses a provided whitelist file to determine which tags are valid genres.
The genre whitelist can be specified like so in .beetsconfig:
[lastgenre]
whitelist=/path/to/genres.txt
The included (default) genre list was produced by scraping Wikipedia.
The scraper script used is available here:
https://gist.github.com/1241307
"""
from __future__ import with_statement
import logging
import pylast
import os
from beets import plugins, ui
from beets import plugins
from beets import ui
from beets.util import normpath
log = logging.getLogger('beets')
LASTFM = pylast.LastFMNetwork(api_key=plugins.LASTFM_KEY)
WEIGHT_THRESH = 50
DEFAULT_WHITELIST = os.path.join(os.path.dirname(__file__), 'genres.txt')
def _tags_for(obj):
"""Given a pylast entity (album or track), returns a list of
@ -44,30 +58,40 @@ def _tags_for(obj):
return tags
def _tags_to_genre(tags):
"""Given a tag list, returns a genre. Returns the first tag that is present
in genres white list or None if no tag is suitable.
"""Given a tag list, returns a genre. Returns the first tag that is
present in the genre whitelist or None if no tag is suitable.
"""
if not tags:
return None
elif not options['genres_whitelist']:
elif not options['whitelist']:
return tags[0].title()
for tag in tags :
if tag.lower() in options['genres_whitelist'] :
for tag in tags:
if tag.lower() in options['whitelist']:
return tag.title()
return None
options = {
'genres_whitelist': None,
'whitelist': None,
}
class LastGenrePlugin(plugins.BeetsPlugin):
def configure(self, config):
genres_whitelist = ui.config_val(config, 'lastgenre',
'genres_whitelist', None)
if genres_whitelist :
genres_whitelist = genres_whitelist.lower().split(',')
options['genres_whitelist'] = genres_whitelist
wl_filename = ui.config_val(config, 'lastgenre', 'whitelist', None)
if not wl_filename:
# No filename specified. Instead, use the whitelist that's included
# with the plugin (inside the package).
wl_filename = DEFAULT_WHITELIST
wl_filename = normpath(wl_filename)
# Read the whitelist file.
whitelist = set()
with open(wl_filename) as f:
for line in f:
line = line.decode('utf8').strip().lower()
if line:
whitelist.add(line)
options['whitelist'] = whitelist
@LastGenrePlugin.listen('album_imported')
def album_imported(lib, album):

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,10 @@ Changelog
-----------------------
* The new :doc:`/plugins/lastgenre` automatically assigns genres to imported
albums and items based on Last.fm tags.
albums and items based on Last.fm tags and an internal whitelist. (Thanks to
`KraYmer`_.)
.. _KraYmer: https://github.com/KraYmer
1.0b10 (September 22, 2011)
---------------------------

View file

@ -21,10 +21,20 @@ your ``plugins`` line in :doc:`/reference/config`, like so::
[beets]
plugins: lastgenre
For the time being, the genre-selection algorithm is pretty dumb: the most
popular tag is treated as the genre. This could be enhanced by using a "white
list" of known genre names. (This would be a great project for someone looking
to contribute to the beets project!)
The plugin chooses genres based on a *whitelist*, meaning that only certain tags
can be considered genres. This way, tags like "my favorite music" or "seen live"
won't be considered genres. The plugin ships with a fairly extensive internal
whitelist, but you can set your own in the config file using the ``whitelist``
configuration value::
[lastgenre]
whitelist: /path/to/genres.txt
The genre list file should contain one genre per line. Blank lines are ignored.
For the curious, the default genre list is generated by a `script that scrapes
Wikipedia`_.
.. _pip: http://www.pip-installer.org/
.. _pylast: http://code.google.com/p/pylast/
.. _script that scrapes Wikipedia: https://gist.github.com/1241307

View file

@ -31,7 +31,7 @@ setup(name='beets',
platforms='ALL',
long_description=_read('README.rst'),
test_suite='test.testall.suite',
include_package_data=True, # Install web plugin resources.
include_package_data=True, # Install plugin resources.
packages=[
'beets',
@ -41,6 +41,7 @@ setup(name='beets',
'beetsplug',
'beetsplug.bpd',
'beetsplug.web',
'beetsplug.lastgenre',
],
namespace_packages=['beetsplug'],
entry_points={