mirror of
https://github.com/beetbox/beets.git
synced 2026-01-30 12:02:41 +01:00
Merge pull request #2211 from heylookltsme/better-genre
Proposal: Add specificity option to lastgenre plugin
This commit is contained in:
commit
4ae02e0d27
2 changed files with 42 additions and 1 deletions
|
|
@ -109,6 +109,7 @@ class LastGenrePlugin(plugins.BeetsPlugin):
|
|||
'force': True,
|
||||
'auto': True,
|
||||
'separator': u', ',
|
||||
'prefer_specific': False,
|
||||
})
|
||||
|
||||
self.setup()
|
||||
|
|
@ -158,6 +159,24 @@ class LastGenrePlugin(plugins.BeetsPlugin):
|
|||
elif source == 'artist':
|
||||
return 'artist',
|
||||
|
||||
def _get_depth(self, tag):
|
||||
"""Find the depth of a tag in the genres tree.
|
||||
"""
|
||||
depth = None
|
||||
for key, value in enumerate(self.c14n_branches):
|
||||
if tag in value:
|
||||
depth = value.index(tag)
|
||||
break
|
||||
return depth
|
||||
|
||||
def _sort_by_depth(self, tags):
|
||||
"""Given a list of tags, sort the tags by their depths in the
|
||||
genre tree.
|
||||
"""
|
||||
depth_tag_pairs = [(self._get_depth(t), t) for t in tags]
|
||||
depth_tag_pairs.sort(reverse=True)
|
||||
return [p[1] for p in depth_tag_pairs]
|
||||
|
||||
def _resolve_genres(self, tags):
|
||||
"""Given a list of strings, return a genre by joining them into a
|
||||
single string and (optionally) canonicalizing each.
|
||||
|
|
@ -179,12 +198,19 @@ class LastGenrePlugin(plugins.BeetsPlugin):
|
|||
parents = [find_parents(tag, self.c14n_branches)[-1]]
|
||||
|
||||
tags_all += parents
|
||||
if len(tags_all) >= count:
|
||||
# Stop if we have enough tags already, unless we need to find
|
||||
# the most specific tag (instead of the most popular).
|
||||
if (not self.config['prefer_specific'] and
|
||||
len(tags_all) >= count):
|
||||
break
|
||||
tags = tags_all
|
||||
|
||||
tags = deduplicate(tags)
|
||||
|
||||
# Sort the tags by specificity.
|
||||
if self.config['prefer_specific']:
|
||||
tags = self._sort_by_depth(tags)
|
||||
|
||||
# c14n only adds allowed genres but we may have had forbidden genres in
|
||||
# the original tags list
|
||||
tags = [x.title() for x in tags if self._is_allowed(x)]
|
||||
|
|
|
|||
|
|
@ -103,6 +103,19 @@ 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
|
||||
-------------
|
||||
|
||||
|
|
@ -126,6 +139,8 @@ configuration file. The available options are:
|
|||
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``.
|
||||
|
|
|
|||
Loading…
Reference in a new issue