Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Substitute plugin #4668

Merged
merged 12 commits into from
Sep 8, 2023
54 changes: 54 additions & 0 deletions beetsplug/substitute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# This file is part of beets.
# Copyright 2023, Daniele Ferone.
#
# 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.

"""The substitute plugin module.

Uses user-specified substitution rules to canonicalize names for path formats.
"""

import re
from beets.plugins import BeetsPlugin


class Substitute(BeetsPlugin):
"""The substitute plugin class.

Create a template field function that subsitute the given field with the
given substitution rules. ``rules`` must be a list of (pattern,
replacement) pairs.
"""
def tmpl_substitute(self, text):
"""Do the actual replacing."""
if text:
for pattern, replacement in self.substitute_rules:
if pattern.match(text.lower()):
return replacement
return text
else:
return u''

def __init__(self):
"""Initialize the substitute plugin.

Get the configuration, register template function and create list of
substitute rules.
"""
super(Substitute, self).__init__()
self.substitute_rules = []
self.template_funcs['substitute'] = self.tmpl_substitute

for key, view in self.config.items():
value = view.as_str()
pattern = re.compile(key.lower())
self.substitute_rules.append((pattern, value))
4 changes: 4 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ New features:
* :doc:`/plugins/embyupdate`: Add handling for private users by adding
``userid`` config option.
:bug:`4402`
* :doc:`/plugins/substitute`: Add the new plugin `substitute` as an alternative
to the `rewrite` plugin. The main difference between them being that
`rewrite` modifies files' metadata and `substitute` does not.
:bug:`2786`

Bug fixes:

Expand Down
6 changes: 6 additions & 0 deletions docs/plugins/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ following to your configuration::
spotify
subsonicplaylist
subsonicupdate
substitute
the
thumbnails
types
Expand Down Expand Up @@ -240,6 +241,11 @@ Path Formats
:doc:`rewrite <rewrite>`
Substitute values in path formats.

: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
metadata.

:doc:`the <the>`
Move patterns in path formats (i.e., move "a" and "the" to the
end).
Expand Down
8 changes: 6 additions & 2 deletions docs/plugins/rewrite.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@ 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``.)

Note that this plugin only applies to templating; it does not modify files'
metadata tags or the values tracked by beets' library database.
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 :doc:`/plugins/substitute` could be used.
23 changes: 23 additions & 0 deletions docs/plugins/substitute.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Substitute Plugin
=================

The ``substitute`` plugin lets you easily substitute values in your templates and
fdaniele85 marked this conversation as resolved.
Show resolved Hide resolved
path formats. Specifically, it is intended to let you *canonicalize* names
such as artists: For example, perhaps you want albums from The Jimi Hendrix
Experience to be sorted into the same folder as solo Hendrix albums.

This plugin is intented as a replacement for the ``rewrite`` plugin. While
the ``rewrite`` plugin modifies the metadata, this plugin does not.

Enable the ``substitute`` plugin (see :ref:`using-plugins`), then make a ``substitute:`` section in your config file to contain your rules.
Each rule consists of a case-insensitive regular expression pattern, and a
replacement value. For example, you might use:

substitute:
.*jimi hendrix.*: Jimi Hendrix


To apply the substitution, you have to call the function ``%substitute{}`` in the paths section. For example:

paths:
default: %substitute{$albumartist}/$year - $album%aunique{}/$track - $title
Loading