LastGenre Plugin
****************

The "lastgenre" plugin fetches *tags* from Last.fm and assigns them as
genres to your albums and items.


Installation
============

The plugin requires pylast, which you can install using pip by typing:

   pip install pylast

After you have pylast installed, enable the "lastgenre" plugin in your
configuration (see Using Plugins).


Usage
=====

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 or
forgo a whitelist altogether by setting the option to *false*.

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.


Canonicalization
----------------

The plugin can also *canonicalize* genres, meaning that more obscure
genres can be turned into coarser-grained ones that are present in the
whitelist. This works using a tree of nested genre names, represented
using YAML, where the leaves of the tree represent the most specific
genres.

The most common way to use this would be with a custom whitelist
containing only a desired subset of genres. Consider for a example
this minimal whitelist:

   rock
   heavy metal
   pop

together with the default genre tree. Then an item that has its genre
specified as *viking metal* would actually be tagged as *heavy metal*
because neither *viking metal* nor its parent *black metal* are in the
whitelist. It always tries to use the most specific genre that's
available in the whitelist.

The relevant subtree path in the default tree looks like this:

   - rock:
       - heavy metal:
           - black metal:
               - viking metal

Considering that, it's not very useful to use the default whitelist
(which contains about any genre contained in the tree) with
canonicalization because nothing would ever be matched to a more
generic node since all the specific subgenres are in the whitelist to
begin with.


Genre Source
------------

When looking up genres for albums or individual tracks, you can choose
whether to use Last.fm tags on the album, the artist, or the track.
For example, you might want all the albums for a certain artist to
carry the same genre. The default is "album". When set to "track", the
plugin will fetch *both* album-level and track-level genres for your
music when importing albums.


Multiple Genres
---------------

By default, the plugin chooses the most popular tag on Last.fm as a
genre. If you prefer to use a *list* of popular genre tags, you can
increase the number of the "count" config option.

Lists of up to *count* genres will then be used instead of single
genres. The genres are separated by commas by default, but you can
change this with the "separator" config option.

Last.fm provides a popularity factor, a.k.a. *weight*, for each tag
ranging from 100 for the most popular tag down to 0 for the least
popular. The plugin uses this weight to discard unpopular tags.  The
default is to ignore tags with a weight less then 10. You can change
this by setting the "min_weight" config option.


Specific vs. Popular Genres
---------------------------

By default, the plugin sorts genres by popularity. However, you can
use the "prefer_specific" option to override this behavior and instead
sort genres by specificity, as determined by your whitelist and
canonicalization tree.

For instance, say you have both "folk" and "americana" in your
whitelist and canonicalization tree and "americana" is a leaf within
"folk". If Last.fm returns both of those tags, lastgenre is going to
use the most popular, which is often the most generic (in this case
"folk"). By setting "prefer_specific" to true, lastgenre would use
"americana" instead.


Configuration
=============

To configure the plugin, make a "lastgenre:" section in your
configuration file. The available options are:

* **auto**: Fetch genres automatically during import. Default: "yes".

* **canonical**: Use a canonicalization tree. Setting this to "yes"
  will use a built-in tree. You can also set it to a path, like the
  "whitelist" config value, to use your own tree. Default: "no"
  (disabled).

* **count**: Number of genres to fetch. Default: 1

* **fallback**: A string if to use a fallback genre when no genre is
  found. You can use the empty string "''" to reset the genre.
  Default: None.

* **force**: By default, beets will always fetch new genres, even if
  the files already have one. To instead leave genres in place in when
  they pass the whitelist, set the "force" option to "no". Default:
  "yes".

* **min_weight**: Minimum popularity factor below which genres are
  discarded. Default: 10.

* **prefer_specific**: Sort genres by the most to least specific,
  rather than most to least popular. Default: "no".

* **source**: Which entity to look up in Last.fm. Can be either
  "artist", "album" or "track". Default: "album".

* **separator**: A separator for multiple genres. Default: "', '".

* **whitelist**: The filename of a custom genre list, "yes" to use the
  internal whitelist, or "no" to consider all genres valid. Default:
  "yes".

* **title_case**: Convert the new tags to TitleCase before saving.
  Default: "yes".


Running Manually
================

In addition to running automatically on import, the plugin can also be
run manually from the command line. Use the command "beet lastgenre
[QUERY]" to fetch genres for albums or items matching a certain query.

By default, "beet lastgenre" matches albums. To match individual
tracks or singletons, use the "-A" switch: "beet lastgenre -A
[QUERY]".

To disable automatic genre fetching on import, set the "auto" config
option to false.
