mirror of
https://github.com/beetbox/beets.git
synced 2025-12-24 01:25:47 +01:00
lastgenre plugin (#139)
This commit is contained in:
parent
55c72f678e
commit
d6431b992e
4 changed files with 111 additions and 0 deletions
74
beetsplug/lastgenre.py
Normal file
74
beetsplug/lastgenre.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# This file is part of beets.
|
||||
# Copyright 2011, 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.
|
||||
|
||||
"""Gets genres for imported music based on Last.fm tags.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import pylast
|
||||
|
||||
from beets.plugins import BeetsPlugin
|
||||
|
||||
log = logging.getLogger('beets')
|
||||
LASTFM = pylast.LastFMNetwork(api_key='2dc3914abf35f0d9c92d97d8f8e42b43')
|
||||
WEIGHT_THRESH = 50
|
||||
|
||||
def _tags_for(obj):
|
||||
"""Given a pylast entity (album or track), returns a list of
|
||||
tag names for that entity. Returns an empty list if the entity is
|
||||
not found or another error occurs.
|
||||
"""
|
||||
try:
|
||||
res = obj.get_top_tags()
|
||||
except pylast.WSError, exc:
|
||||
log.debug(u'last.fm error: %s' % unicode(exc))
|
||||
return []
|
||||
|
||||
tags = []
|
||||
for el in res:
|
||||
if isinstance(el, pylast.TopItem):
|
||||
el = el.item
|
||||
tags.append(el.get_name())
|
||||
log.debug(u'last.fm tags: %s' % unicode(tags))
|
||||
return tags
|
||||
|
||||
def _tags_to_genre(tags):
|
||||
"""Given a tag list, returns a genre. Returns None if no tag is
|
||||
suitable. This should be smarter, but at the moment it just takes
|
||||
the top tag and puts it in Title Case.
|
||||
"""
|
||||
if not tags:
|
||||
return None
|
||||
return tags[0].title()
|
||||
|
||||
class LastGenrePlugin(BeetsPlugin):
|
||||
pass
|
||||
|
||||
@LastGenrePlugin.listen('album_imported')
|
||||
def album_imported(lib, album):
|
||||
tags = _tags_for(LASTFM.get_album(album.albumartist, album.album))
|
||||
genre = _tags_to_genre(tags)
|
||||
if genre:
|
||||
log.debug(u'adding last.fm album genre: %s' % genre)
|
||||
album.genre = genre
|
||||
lib.save()
|
||||
|
||||
@LastGenrePlugin.listen('item_imported')
|
||||
def item_imported(lib, item):
|
||||
tags = _tags_for(LASTFM.get_track(item.artist, item.title))
|
||||
genre = _tags_to_genre(tags)
|
||||
if genre:
|
||||
log.debug(u'adding last.fm item genre: %s' % genre)
|
||||
item.genre = genre
|
||||
lib.save()
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
1.0b11 (In Development)
|
||||
-----------------------
|
||||
|
||||
* The new :doc:`/plugins/lastgenre` automatically assigns genres to imported
|
||||
albums and items based on Last.fm tags.
|
||||
|
||||
1.0b10 (September 22, 2011)
|
||||
---------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ disabled by default, but you can turn them on as described above:
|
|||
mpdupdate
|
||||
embedart
|
||||
web
|
||||
lastgenre
|
||||
|
||||
.. _other-plugins:
|
||||
|
||||
|
|
|
|||
30
docs/plugins/lastgenre.rst
Normal file
30
docs/plugins/lastgenre.rst
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
LastGenre Plugin
|
||||
================
|
||||
|
||||
The MusicBrainz database `does not contain genre information`_. Therefore, when
|
||||
importing and autotagging music, beets does not assign a genre. The
|
||||
``lastgenre`` plugin fetches *tags* from `Last.fm`_ and assigns them as genres
|
||||
to your albums and items. The plugin is included with beets as of version
|
||||
1.0b11.
|
||||
|
||||
.. _does not contain genre information:
|
||||
http://musicbrainz.org/doc/General_FAQ#Why_does_MusicBrainz_not_support_genre_information.3F
|
||||
.. _Last.fm: http://last.fm/
|
||||
|
||||
The plugin requires `pylast`_, which you can install using `pip`_ by typing::
|
||||
|
||||
pip install pylast
|
||||
|
||||
After you have pylast installed, enable the plugin by putting ``lastgenre`` on
|
||||
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!)
|
||||
|
||||
.. _pip: http://www.pip-installer.org/
|
||||
.. _pylast: http://code.google.com/p/pylast/
|
||||
Loading…
Reference in a new issue