mirror of
https://github.com/beetbox/beets.git
synced 2026-01-05 23:43:31 +01:00
Merge pull request #4845 from Maxr1998/advancedrewrite
This commit is contained in:
commit
91277a1d53
4 changed files with 127 additions and 0 deletions
82
beetsplug/advancedrewrite.py
Normal file
82
beetsplug/advancedrewrite.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# This file is part of beets.
|
||||
# Copyright 2023, Max Rumpf.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Plugin to rewrite fields based on a given query."""
|
||||
|
||||
from collections import defaultdict
|
||||
import shlex
|
||||
|
||||
import confuse
|
||||
from beets import ui
|
||||
from beets.dbcore import AndQuery, query_from_strings
|
||||
from beets.library import Item, Album
|
||||
from beets.plugins import BeetsPlugin
|
||||
|
||||
|
||||
def rewriter(field, rules):
|
||||
"""Template field function factory.
|
||||
|
||||
Create a template field function that rewrites the given field
|
||||
with the given rewriting rules.
|
||||
``rules`` must be a list of (query, replacement) pairs.
|
||||
"""
|
||||
def fieldfunc(item):
|
||||
value = item._values_fixed[field]
|
||||
for query, replacement in rules:
|
||||
if query.match(item):
|
||||
# Rewrite activated.
|
||||
return replacement
|
||||
# Not activated; return original value.
|
||||
return value
|
||||
|
||||
return fieldfunc
|
||||
|
||||
|
||||
class AdvancedRewritePlugin(BeetsPlugin):
|
||||
"""Plugin to rewrite fields based on a given query."""
|
||||
|
||||
def __init__(self):
|
||||
"""Parse configuration and register template fields for rewriting."""
|
||||
super().__init__()
|
||||
|
||||
template = confuse.Sequence({
|
||||
'match': str,
|
||||
'field': str,
|
||||
'replacement': str,
|
||||
})
|
||||
|
||||
# Gather all the rewrite rules for each field.
|
||||
rules = defaultdict(list)
|
||||
for rule in self.config.get(template):
|
||||
query = query_from_strings(AndQuery, Item, prefixes={},
|
||||
query_parts=shlex.split(rule['match']))
|
||||
fieldname = rule['field']
|
||||
replacement = rule['replacement']
|
||||
if fieldname not in Item._fields:
|
||||
raise ui.UserError(
|
||||
"invalid field name (%s) in rewriter" % fieldname)
|
||||
self._log.debug('adding template field {0} → {1}',
|
||||
fieldname, replacement)
|
||||
rules[fieldname].append((query, replacement))
|
||||
if fieldname == 'artist':
|
||||
# Special case for the artist field: apply the same
|
||||
# rewrite for "albumartist" as well.
|
||||
rules['albumartist'].append((query, replacement))
|
||||
|
||||
# Replace each template field with the new rewriter function.
|
||||
for fieldname, fieldrules in rules.items():
|
||||
getter = rewriter(fieldname, fieldrules)
|
||||
self.template_fields[fieldname] = getter
|
||||
if fieldname in Album._fields:
|
||||
self.album_template_fields[fieldname] = getter
|
||||
|
|
@ -137,6 +137,8 @@ New features:
|
|||
* :doc:`/plugins/fetchart`: Fix the error with CoverArtArchive where no cover
|
||||
would be found when the `maxwidth` option matches a pre-sized thumbnail size,
|
||||
but no thumbnail is provided by CAA. We now fallback to the raw image.
|
||||
* :doc:`/plugins/advancedrewrite`: Add an advanced version of the `rewrite`
|
||||
plugin which allows to replace fields based on a given library query.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
|
|
|
|||
39
docs/plugins/advancedrewrite.rst
Normal file
39
docs/plugins/advancedrewrite.rst
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
Advanced Rewrite Plugin
|
||||
=======================
|
||||
|
||||
The ``advancedrewrite`` plugin lets you easily substitute values
|
||||
in your templates and path formats, similarly to the :doc:`/plugins/rewrite`.
|
||||
Please make sure to read the documentation of that plugin first.
|
||||
|
||||
The *advanced* rewrite plugin doesn't match the rewritten field itself,
|
||||
but instead checks if the given item matches a :doc:`query </reference/query>`.
|
||||
Only then, the field is replaced with the given value.
|
||||
|
||||
To use advanced field rewriting, first enable the ``advancedrewrite`` plugin
|
||||
(see :ref:`using-plugins`).
|
||||
Then, make a ``advancedrewrite:`` section in your config file to contain
|
||||
your rewrite rules.
|
||||
|
||||
In contrast to the normal ``rewrite`` plugin, you need to provide a list
|
||||
of replacement rule objects, each consisting of a query, a field name,
|
||||
and the replacement value.
|
||||
|
||||
For example, to credit all songs of ODD EYE CIRCLE before 2023
|
||||
to their original group name, you can use the following rule::
|
||||
|
||||
advancedrewrite:
|
||||
- match: "mb_artistid:dec0f331-cb08-4c8e-9c9f-aeb1f0f6d88c year:..2022"
|
||||
field: artist
|
||||
replacement: "이달의 소녀 오드아이써클"
|
||||
|
||||
As a convenience, the plugin applies patterns for the ``artist`` field to the
|
||||
``albumartist`` field as well. (Otherwise, you would probably want to duplicate
|
||||
every rule for ``artist`` and ``albumartist``.)
|
||||
|
||||
A word of warning: This plugin theoretically only applies to templates and path
|
||||
formats; it initially does not modify files' metadata tags or the values
|
||||
tracked by beets' library database, but since it *rewrites all field lookups*,
|
||||
it modifies the file's metadata anyway. See comments in issue :bug:`2786`.
|
||||
|
||||
As an alternative to this plugin the simpler :doc:`/plugins/rewrite` or
|
||||
similar :doc:`/plugins/substitute` can be used.
|
||||
|
|
@ -61,6 +61,7 @@ following to your configuration::
|
|||
|
||||
absubmit
|
||||
acousticbrainz
|
||||
advancedrewrite
|
||||
albumtypes
|
||||
aura
|
||||
autobpm
|
||||
|
|
@ -246,6 +247,9 @@ Path Formats
|
|||
:doc:`rewrite <rewrite>`
|
||||
Substitute values in path formats.
|
||||
|
||||
:doc:`advancedrewrite <advancedrewrite>`
|
||||
Substitute field values for items matching a query.
|
||||
|
||||
:doc:`substitute <substitute>`
|
||||
As an alternative to :doc:`rewrite <rewrite>`, use this plugin. The main
|
||||
difference between them is that this plugin never modifies the files
|
||||
|
|
|
|||
Loading…
Reference in a new issue