mirror of
https://github.com/beetbox/beets.git
synced 2025-12-07 00:53:08 +01:00
Moved plugin docs into folder.
This commit is contained in:
parent
c60f0ceb3c
commit
07549ed896
4 changed files with 264 additions and 263 deletions
50
docs/dev/plugins/commands.rst
Normal file
50
docs/dev/plugins/commands.rst
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
.. _add_subcommands:
|
||||||
|
|
||||||
|
Add Commands to the CLI
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Plugins can add new subcommands to the ``beet`` command-line interface. Define
|
||||||
|
the plugin class' ``commands()`` method to return a list of ``Subcommand``
|
||||||
|
objects. (The ``Subcommand`` class is defined in the ``beets.ui`` module.)
|
||||||
|
Here's an example plugin that adds a simple command:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from beets.plugins import BeetsPlugin
|
||||||
|
from beets.ui import Subcommand
|
||||||
|
|
||||||
|
my_super_command = Subcommand('super', help='do something super')
|
||||||
|
def say_hi(lib, opts, args):
|
||||||
|
print("Hello everybody! I'm a plugin!")
|
||||||
|
my_super_command.func = say_hi
|
||||||
|
|
||||||
|
class SuperPlug(BeetsPlugin):
|
||||||
|
def commands(self):
|
||||||
|
return [my_super_command]
|
||||||
|
|
||||||
|
To make a subcommand, invoke the constructor like so: ``Subcommand(name, parser,
|
||||||
|
help, aliases)``. The ``name`` parameter is the only required one and should
|
||||||
|
just be the name of your command. ``parser`` can be an `OptionParser instance`_,
|
||||||
|
but it defaults to an empty parser (you can extend it later). ``help`` is a
|
||||||
|
description of your command, and ``aliases`` is a list of shorthand versions of
|
||||||
|
your command name.
|
||||||
|
|
||||||
|
.. _optionparser instance: https://docs.python.org/library/optparse.html
|
||||||
|
|
||||||
|
You'll need to add a function to your command by saying ``mycommand.func =
|
||||||
|
myfunction``. This function should take the following parameters: ``lib`` (a
|
||||||
|
beets ``Library`` object) and ``opts`` and ``args`` (command-line options and
|
||||||
|
arguments as returned by OptionParser.parse_args_).
|
||||||
|
|
||||||
|
.. _optionparser.parse_args: https://docs.python.org/library/optparse.html#parsing-arguments
|
||||||
|
|
||||||
|
The function should use any of the utility functions defined in ``beets.ui``.
|
||||||
|
Try running ``pydoc beets.ui`` to see what's available.
|
||||||
|
|
||||||
|
You can add command-line options to your new command using the ``parser`` member
|
||||||
|
of the ``Subcommand`` class, which is a ``CommonOptionsParser`` instance. Just
|
||||||
|
use it like you would a normal ``OptionParser`` in an independent script. Note
|
||||||
|
that it offers several methods to add common options: ``--album``, ``--path``
|
||||||
|
and ``--format``. This feature is versatile and extensively documented, try
|
||||||
|
``pydoc beets.ui.CommonOptionsParser`` for more information.
|
||||||
|
|
||||||
142
docs/dev/plugins/events.rst
Normal file
142
docs/dev/plugins/events.rst
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
.. _plugin_events:
|
||||||
|
|
||||||
|
Listen for Events
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Event handlers allow plugins to run code whenever something happens in beets'
|
||||||
|
operation. For instance, a plugin could write a log message every time an album
|
||||||
|
is successfully autotagged or update MPD's index whenever the database is
|
||||||
|
changed.
|
||||||
|
|
||||||
|
You can "listen" for events using ``BeetsPlugin.register_listener``. Here's an
|
||||||
|
example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from beets.plugins import BeetsPlugin
|
||||||
|
|
||||||
|
def loaded():
|
||||||
|
print 'Plugin loaded!'
|
||||||
|
|
||||||
|
class SomePlugin(BeetsPlugin):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.register_listener('pluginload', loaded)
|
||||||
|
|
||||||
|
Note that if you want to access an attribute of your plugin (e.g. ``config`` or
|
||||||
|
``log``) you'll have to define a method and not a function. Here is the usual
|
||||||
|
registration process in this case:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from beets.plugins import BeetsPlugin
|
||||||
|
|
||||||
|
class SomePlugin(BeetsPlugin):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.register_listener('pluginload', self.loaded)
|
||||||
|
|
||||||
|
def loaded(self):
|
||||||
|
self._log.info('Plugin loaded!')
|
||||||
|
|
||||||
|
The events currently available are:
|
||||||
|
|
||||||
|
- ``pluginload``: called after all the plugins have been loaded after the
|
||||||
|
``beet`` command starts
|
||||||
|
- ``import``: called after a ``beet import`` command finishes (the ``lib``
|
||||||
|
keyword argument is a Library object; ``paths`` is a list of paths (strings)
|
||||||
|
that were imported)
|
||||||
|
- ``album_imported``: called with an ``Album`` object every time the ``import``
|
||||||
|
command finishes adding an album to the library. Parameters: ``lib``,
|
||||||
|
``album``
|
||||||
|
- ``album_removed``: called with an ``Album`` object every time an album is
|
||||||
|
removed from the library (even when its file is not deleted from disk).
|
||||||
|
- ``item_copied``: called with an ``Item`` object whenever its file is copied.
|
||||||
|
Parameters: ``item``, ``source`` path, ``destination`` path
|
||||||
|
- ``item_imported``: called with an ``Item`` object every time the importer adds
|
||||||
|
a singleton to the library (not called for full-album imports). Parameters:
|
||||||
|
``lib``, ``item``
|
||||||
|
- ``before_item_moved``: called with an ``Item`` object immediately before its
|
||||||
|
file is moved. Parameters: ``item``, ``source`` path, ``destination`` path
|
||||||
|
- ``item_moved``: called with an ``Item`` object whenever its file is moved.
|
||||||
|
Parameters: ``item``, ``source`` path, ``destination`` path
|
||||||
|
- ``item_linked``: called with an ``Item`` object whenever a symlink is created
|
||||||
|
for a file. Parameters: ``item``, ``source`` path, ``destination`` path
|
||||||
|
- ``item_hardlinked``: called with an ``Item`` object whenever a hardlink is
|
||||||
|
created for a file. Parameters: ``item``, ``source`` path, ``destination``
|
||||||
|
path
|
||||||
|
- ``item_reflinked``: called with an ``Item`` object whenever a reflink is
|
||||||
|
created for a file. Parameters: ``item``, ``source`` path, ``destination``
|
||||||
|
path
|
||||||
|
- ``item_removed``: called with an ``Item`` object every time an item (singleton
|
||||||
|
or album's part) is removed from the library (even when its file is not
|
||||||
|
deleted from disk).
|
||||||
|
- ``write``: called with an ``Item`` object, a ``path``, and a ``tags``
|
||||||
|
dictionary just before a file's metadata is written to disk (i.e., just before
|
||||||
|
the file on disk is opened). Event handlers may change the ``tags`` dictionary
|
||||||
|
to customize the tags that are written to the media file. Event handlers may
|
||||||
|
also raise a ``library.FileOperationError`` exception to abort the write
|
||||||
|
operation. Beets will catch that exception, print an error message and
|
||||||
|
continue.
|
||||||
|
- ``after_write``: called with an ``Item`` object after a file's metadata is
|
||||||
|
written to disk (i.e., just after the file on disk is closed).
|
||||||
|
- ``import_task_created``: called immediately after an import task is
|
||||||
|
initialized. Plugins can use this to, for example, change imported files of a
|
||||||
|
task before anything else happens. It's also possible to replace the task with
|
||||||
|
another task by returning a list of tasks. This list can contain zero or more
|
||||||
|
``ImportTask``. Returning an empty list will stop the task. Parameters:
|
||||||
|
``task`` (an ``ImportTask``) and ``session`` (an ``ImportSession``).
|
||||||
|
- ``import_task_start``: called when before an import task begins processing.
|
||||||
|
Parameters: ``task`` and ``session``.
|
||||||
|
- ``import_task_apply``: called after metadata changes have been applied in an
|
||||||
|
import task. This is called on the same thread as the UI, so use this
|
||||||
|
sparingly and only for tasks that can be done quickly. For most plugins, an
|
||||||
|
import pipeline stage is a better choice (see :ref:`plugin-stage`).
|
||||||
|
Parameters: ``task`` and ``session``.
|
||||||
|
- ``import_task_before_choice``: called after candidate search for an import
|
||||||
|
task before any decision is made about how/if to import or tag. Can be used to
|
||||||
|
present information about the task or initiate interaction with the user
|
||||||
|
before importing occurs. Return an importer action to take a specific action.
|
||||||
|
Only one handler may return a non-None result. Parameters: ``task`` and
|
||||||
|
``session``
|
||||||
|
- ``import_task_choice``: called after a decision has been made about an import
|
||||||
|
task. This event can be used to initiate further interaction with the user.
|
||||||
|
Use ``task.choice_flag`` to determine or change the action to be taken.
|
||||||
|
Parameters: ``task`` and ``session``.
|
||||||
|
- ``import_task_files``: called after an import task finishes manipulating the
|
||||||
|
filesystem (copying and moving files, writing metadata tags). Parameters:
|
||||||
|
``task`` and ``session``.
|
||||||
|
- ``library_opened``: called after beets starts up and initializes the main
|
||||||
|
Library object. Parameter: ``lib``.
|
||||||
|
- ``database_change``: a modification has been made to the library database. The
|
||||||
|
change might not be committed yet. Parameters: ``lib`` and ``model``.
|
||||||
|
- ``cli_exit``: called just before the ``beet`` command-line program exits.
|
||||||
|
Parameter: ``lib``.
|
||||||
|
- ``import_begin``: called just before a ``beet import`` session starts up.
|
||||||
|
Parameter: ``session``.
|
||||||
|
- ``trackinfo_received``: called after metadata for a track item has been
|
||||||
|
fetched from a data source, such as MusicBrainz. You can modify the tags that
|
||||||
|
the rest of the pipeline sees on a ``beet import`` operation or during later
|
||||||
|
adjustments, such as ``mbsync``. Slow handlers of the event can impact the
|
||||||
|
operation, since the event is fired for any fetched possible match ``before``
|
||||||
|
the user (or the autotagger machinery) gets to see the match. Parameter:
|
||||||
|
``info``.
|
||||||
|
- ``albuminfo_received``: like ``trackinfo_received``, the event indicates new
|
||||||
|
metadata for album items. The parameter is an ``AlbumInfo`` object instead of
|
||||||
|
a ``TrackInfo``. Parameter: ``info``.
|
||||||
|
- ``before_choose_candidate``: called before the user is prompted for a decision
|
||||||
|
during a ``beet import`` interactive session. Plugins can use this event for
|
||||||
|
:ref:`appending choices to the prompt <append_prompt_choices>` by returning a
|
||||||
|
list of ``PromptChoices``. Parameters: ``task`` and ``session``.
|
||||||
|
- ``mb_track_extract``: called after the metadata is obtained from MusicBrainz.
|
||||||
|
The parameter is a ``dict`` containing the tags retrieved from MusicBrainz for
|
||||||
|
a track. Plugins must return a new (potentially empty) ``dict`` with
|
||||||
|
additional ``field: value`` pairs, which the autotagger will apply to the
|
||||||
|
item, as flexible attributes if ``field`` is not a hardcoded field. Fields
|
||||||
|
already present on the track are overwritten. Parameter: ``data``
|
||||||
|
- ``mb_album_extract``: Like ``mb_track_extract``, but for album tags.
|
||||||
|
Overwrites tags set at the track level, if they have the same ``field``.
|
||||||
|
Parameter: ``data``
|
||||||
|
|
||||||
|
The included ``mpdupdate`` plugin provides an example use case for event
|
||||||
|
listeners.
|
||||||
72
docs/dev/plugins/index.rst
Normal file
72
docs/dev/plugins/index.rst
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
Plugin Development Guide
|
||||||
|
========================
|
||||||
|
|
||||||
|
Beets plugins are Python modules or packages that extend the core functionality
|
||||||
|
of beets. The plugin system is designed to be flexible, allowing developers to
|
||||||
|
add virtually any type of features.
|
||||||
|
|
||||||
|
.. _writing-plugins:
|
||||||
|
|
||||||
|
Writing Plugins
|
||||||
|
---------------
|
||||||
|
|
||||||
|
A beets plugin is just a Python module or package inside the ``beetsplug``
|
||||||
|
namespace package. (Check out `this article`_ and `this Stack Overflow
|
||||||
|
question`_ if you haven't heard about namespace packages.) So, to make one,
|
||||||
|
create a directory called ``beetsplug`` and add either your plugin module:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
beetsplug/
|
||||||
|
myawesomeplugin.py
|
||||||
|
|
||||||
|
or your plugin subpackage:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
beetsplug/
|
||||||
|
myawesomeplugin/
|
||||||
|
__init__.py
|
||||||
|
myawesomeplugin.py
|
||||||
|
|
||||||
|
.. attention::
|
||||||
|
|
||||||
|
You do not anymore need to add a ``__init__.py`` file to the ``beetsplug``
|
||||||
|
directory. Python treats your plugin as a namespace package automatically,
|
||||||
|
thus we do not depend on ``pkgutil``-based setup in the ``__init__.py`` file
|
||||||
|
anymore.
|
||||||
|
|
||||||
|
.. _this article: https://realpython.com/python-namespace-package/#setting-up-some-namespace-packages
|
||||||
|
|
||||||
|
.. _this stack overflow question: https://stackoverflow.com/a/27586272/9582674
|
||||||
|
|
||||||
|
The meat of your plugin goes in ``myawesomeplugin.py``. There, you'll have to
|
||||||
|
import ``BeetsPlugin`` from ``beets.plugins`` and subclass it, for example
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from beets.plugins import BeetsPlugin
|
||||||
|
|
||||||
|
|
||||||
|
class MyAwesomePlugin(BeetsPlugin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
Once you have your ``BeetsPlugin`` subclass, there's a variety of things your
|
||||||
|
plugin can do. (Read on!)
|
||||||
|
|
||||||
|
To use your new plugin, package your plugin (see how to do this with poetry_ or
|
||||||
|
setuptools_, for example) and install it into your ``beets`` virtual
|
||||||
|
environment. Then, add your plugin to beets configuration
|
||||||
|
|
||||||
|
.. _poetry: https://python-poetry.org/docs/pyproject/#packages
|
||||||
|
|
||||||
|
.. _setuptools: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#finding-simple-packages
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
# config.yaml
|
||||||
|
plugins:
|
||||||
|
- myawesomeplugin
|
||||||
|
|
||||||
|
and you're good to go!
|
||||||
|
|
||||||
|
|
@ -1,267 +1,4 @@
|
||||||
Plugin Development Guide
|
|
||||||
========================
|
|
||||||
|
|
||||||
Beets plugins are Python modules or packages that extend the core functionality
|
|
||||||
of beets. The plugin system is designed to be flexible, allowing developers to
|
|
||||||
add virtually any type of features.
|
|
||||||
|
|
||||||
.. _writing-plugins:
|
|
||||||
|
|
||||||
Writing Plugins
|
|
||||||
---------------
|
|
||||||
|
|
||||||
A beets plugin is just a Python module or package inside the ``beetsplug``
|
|
||||||
namespace package. (Check out `this article`_ and `this Stack Overflow
|
|
||||||
question`_ if you haven't heard about namespace packages.) So, to make one,
|
|
||||||
create a directory called ``beetsplug`` and add either your plugin module:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
beetsplug/
|
|
||||||
myawesomeplugin.py
|
|
||||||
|
|
||||||
or your plugin subpackage:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
beetsplug/
|
|
||||||
myawesomeplugin/
|
|
||||||
__init__.py
|
|
||||||
myawesomeplugin.py
|
|
||||||
|
|
||||||
.. attention::
|
|
||||||
|
|
||||||
You do not anymore need to add a ``__init__.py`` file to the ``beetsplug``
|
|
||||||
directory. Python treats your plugin as a namespace package automatically,
|
|
||||||
thus we do not depend on ``pkgutil``-based setup in the ``__init__.py`` file
|
|
||||||
anymore.
|
|
||||||
|
|
||||||
.. _this article: https://realpython.com/python-namespace-package/#setting-up-some-namespace-packages
|
|
||||||
|
|
||||||
.. _this stack overflow question: https://stackoverflow.com/a/27586272/9582674
|
|
||||||
|
|
||||||
The meat of your plugin goes in ``myawesomeplugin.py``. There, you'll have to
|
|
||||||
import ``BeetsPlugin`` from ``beets.plugins`` and subclass it, for example
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from beets.plugins import BeetsPlugin
|
|
||||||
|
|
||||||
|
|
||||||
class MyAwesomePlugin(BeetsPlugin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
Once you have your ``BeetsPlugin`` subclass, there's a variety of things your
|
|
||||||
plugin can do. (Read on!)
|
|
||||||
|
|
||||||
To use your new plugin, package your plugin (see how to do this with poetry_ or
|
|
||||||
setuptools_, for example) and install it into your ``beets`` virtual
|
|
||||||
environment. Then, add your plugin to beets configuration
|
|
||||||
|
|
||||||
.. _poetry: https://python-poetry.org/docs/pyproject/#packages
|
|
||||||
|
|
||||||
.. _setuptools: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#finding-simple-packages
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
# config.yaml
|
|
||||||
plugins:
|
|
||||||
- myawesomeplugin
|
|
||||||
|
|
||||||
and you're good to go!
|
|
||||||
|
|
||||||
.. _add_subcommands:
|
|
||||||
|
|
||||||
Add Commands to the CLI
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Plugins can add new subcommands to the ``beet`` command-line interface. Define
|
|
||||||
the plugin class' ``commands()`` method to return a list of ``Subcommand``
|
|
||||||
objects. (The ``Subcommand`` class is defined in the ``beets.ui`` module.)
|
|
||||||
Here's an example plugin that adds a simple command:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
from beets.plugins import BeetsPlugin
|
|
||||||
from beets.ui import Subcommand
|
|
||||||
|
|
||||||
my_super_command = Subcommand('super', help='do something super')
|
|
||||||
def say_hi(lib, opts, args):
|
|
||||||
print("Hello everybody! I'm a plugin!")
|
|
||||||
my_super_command.func = say_hi
|
|
||||||
|
|
||||||
class SuperPlug(BeetsPlugin):
|
|
||||||
def commands(self):
|
|
||||||
return [my_super_command]
|
|
||||||
|
|
||||||
To make a subcommand, invoke the constructor like so: ``Subcommand(name, parser,
|
|
||||||
help, aliases)``. The ``name`` parameter is the only required one and should
|
|
||||||
just be the name of your command. ``parser`` can be an `OptionParser instance`_,
|
|
||||||
but it defaults to an empty parser (you can extend it later). ``help`` is a
|
|
||||||
description of your command, and ``aliases`` is a list of shorthand versions of
|
|
||||||
your command name.
|
|
||||||
|
|
||||||
.. _optionparser instance: https://docs.python.org/library/optparse.html
|
|
||||||
|
|
||||||
You'll need to add a function to your command by saying ``mycommand.func =
|
|
||||||
myfunction``. This function should take the following parameters: ``lib`` (a
|
|
||||||
beets ``Library`` object) and ``opts`` and ``args`` (command-line options and
|
|
||||||
arguments as returned by OptionParser.parse_args_).
|
|
||||||
|
|
||||||
.. _optionparser.parse_args: https://docs.python.org/library/optparse.html#parsing-arguments
|
|
||||||
|
|
||||||
The function should use any of the utility functions defined in ``beets.ui``.
|
|
||||||
Try running ``pydoc beets.ui`` to see what's available.
|
|
||||||
|
|
||||||
You can add command-line options to your new command using the ``parser`` member
|
|
||||||
of the ``Subcommand`` class, which is a ``CommonOptionsParser`` instance. Just
|
|
||||||
use it like you would a normal ``OptionParser`` in an independent script. Note
|
|
||||||
that it offers several methods to add common options: ``--album``, ``--path``
|
|
||||||
and ``--format``. This feature is versatile and extensively documented, try
|
|
||||||
``pydoc beets.ui.CommonOptionsParser`` for more information.
|
|
||||||
|
|
||||||
.. _plugin_events:
|
|
||||||
|
|
||||||
Listen for Events
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Event handlers allow plugins to run code whenever something happens in beets'
|
|
||||||
operation. For instance, a plugin could write a log message every time an album
|
|
||||||
is successfully autotagged or update MPD's index whenever the database is
|
|
||||||
changed.
|
|
||||||
|
|
||||||
You can "listen" for events using ``BeetsPlugin.register_listener``. Here's an
|
|
||||||
example:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
from beets.plugins import BeetsPlugin
|
|
||||||
|
|
||||||
def loaded():
|
|
||||||
print 'Plugin loaded!'
|
|
||||||
|
|
||||||
class SomePlugin(BeetsPlugin):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self.register_listener('pluginload', loaded)
|
|
||||||
|
|
||||||
Note that if you want to access an attribute of your plugin (e.g. ``config`` or
|
|
||||||
``log``) you'll have to define a method and not a function. Here is the usual
|
|
||||||
registration process in this case:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
from beets.plugins import BeetsPlugin
|
|
||||||
|
|
||||||
class SomePlugin(BeetsPlugin):
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self.register_listener('pluginload', self.loaded)
|
|
||||||
|
|
||||||
def loaded(self):
|
|
||||||
self._log.info('Plugin loaded!')
|
|
||||||
|
|
||||||
The events currently available are:
|
|
||||||
|
|
||||||
- ``pluginload``: called after all the plugins have been loaded after the
|
|
||||||
``beet`` command starts
|
|
||||||
- ``import``: called after a ``beet import`` command finishes (the ``lib``
|
|
||||||
keyword argument is a Library object; ``paths`` is a list of paths (strings)
|
|
||||||
that were imported)
|
|
||||||
- ``album_imported``: called with an ``Album`` object every time the ``import``
|
|
||||||
command finishes adding an album to the library. Parameters: ``lib``,
|
|
||||||
``album``
|
|
||||||
- ``album_removed``: called with an ``Album`` object every time an album is
|
|
||||||
removed from the library (even when its file is not deleted from disk).
|
|
||||||
- ``item_copied``: called with an ``Item`` object whenever its file is copied.
|
|
||||||
Parameters: ``item``, ``source`` path, ``destination`` path
|
|
||||||
- ``item_imported``: called with an ``Item`` object every time the importer adds
|
|
||||||
a singleton to the library (not called for full-album imports). Parameters:
|
|
||||||
``lib``, ``item``
|
|
||||||
- ``before_item_moved``: called with an ``Item`` object immediately before its
|
|
||||||
file is moved. Parameters: ``item``, ``source`` path, ``destination`` path
|
|
||||||
- ``item_moved``: called with an ``Item`` object whenever its file is moved.
|
|
||||||
Parameters: ``item``, ``source`` path, ``destination`` path
|
|
||||||
- ``item_linked``: called with an ``Item`` object whenever a symlink is created
|
|
||||||
for a file. Parameters: ``item``, ``source`` path, ``destination`` path
|
|
||||||
- ``item_hardlinked``: called with an ``Item`` object whenever a hardlink is
|
|
||||||
created for a file. Parameters: ``item``, ``source`` path, ``destination``
|
|
||||||
path
|
|
||||||
- ``item_reflinked``: called with an ``Item`` object whenever a reflink is
|
|
||||||
created for a file. Parameters: ``item``, ``source`` path, ``destination``
|
|
||||||
path
|
|
||||||
- ``item_removed``: called with an ``Item`` object every time an item (singleton
|
|
||||||
or album's part) is removed from the library (even when its file is not
|
|
||||||
deleted from disk).
|
|
||||||
- ``write``: called with an ``Item`` object, a ``path``, and a ``tags``
|
|
||||||
dictionary just before a file's metadata is written to disk (i.e., just before
|
|
||||||
the file on disk is opened). Event handlers may change the ``tags`` dictionary
|
|
||||||
to customize the tags that are written to the media file. Event handlers may
|
|
||||||
also raise a ``library.FileOperationError`` exception to abort the write
|
|
||||||
operation. Beets will catch that exception, print an error message and
|
|
||||||
continue.
|
|
||||||
- ``after_write``: called with an ``Item`` object after a file's metadata is
|
|
||||||
written to disk (i.e., just after the file on disk is closed).
|
|
||||||
- ``import_task_created``: called immediately after an import task is
|
|
||||||
initialized. Plugins can use this to, for example, change imported files of a
|
|
||||||
task before anything else happens. It's also possible to replace the task with
|
|
||||||
another task by returning a list of tasks. This list can contain zero or more
|
|
||||||
``ImportTask``. Returning an empty list will stop the task. Parameters:
|
|
||||||
``task`` (an ``ImportTask``) and ``session`` (an ``ImportSession``).
|
|
||||||
- ``import_task_start``: called when before an import task begins processing.
|
|
||||||
Parameters: ``task`` and ``session``.
|
|
||||||
- ``import_task_apply``: called after metadata changes have been applied in an
|
|
||||||
import task. This is called on the same thread as the UI, so use this
|
|
||||||
sparingly and only for tasks that can be done quickly. For most plugins, an
|
|
||||||
import pipeline stage is a better choice (see :ref:`plugin-stage`).
|
|
||||||
Parameters: ``task`` and ``session``.
|
|
||||||
- ``import_task_before_choice``: called after candidate search for an import
|
|
||||||
task before any decision is made about how/if to import or tag. Can be used to
|
|
||||||
present information about the task or initiate interaction with the user
|
|
||||||
before importing occurs. Return an importer action to take a specific action.
|
|
||||||
Only one handler may return a non-None result. Parameters: ``task`` and
|
|
||||||
``session``
|
|
||||||
- ``import_task_choice``: called after a decision has been made about an import
|
|
||||||
task. This event can be used to initiate further interaction with the user.
|
|
||||||
Use ``task.choice_flag`` to determine or change the action to be taken.
|
|
||||||
Parameters: ``task`` and ``session``.
|
|
||||||
- ``import_task_files``: called after an import task finishes manipulating the
|
|
||||||
filesystem (copying and moving files, writing metadata tags). Parameters:
|
|
||||||
``task`` and ``session``.
|
|
||||||
- ``library_opened``: called after beets starts up and initializes the main
|
|
||||||
Library object. Parameter: ``lib``.
|
|
||||||
- ``database_change``: a modification has been made to the library database. The
|
|
||||||
change might not be committed yet. Parameters: ``lib`` and ``model``.
|
|
||||||
- ``cli_exit``: called just before the ``beet`` command-line program exits.
|
|
||||||
Parameter: ``lib``.
|
|
||||||
- ``import_begin``: called just before a ``beet import`` session starts up.
|
|
||||||
Parameter: ``session``.
|
|
||||||
- ``trackinfo_received``: called after metadata for a track item has been
|
|
||||||
fetched from a data source, such as MusicBrainz. You can modify the tags that
|
|
||||||
the rest of the pipeline sees on a ``beet import`` operation or during later
|
|
||||||
adjustments, such as ``mbsync``. Slow handlers of the event can impact the
|
|
||||||
operation, since the event is fired for any fetched possible match ``before``
|
|
||||||
the user (or the autotagger machinery) gets to see the match. Parameter:
|
|
||||||
``info``.
|
|
||||||
- ``albuminfo_received``: like ``trackinfo_received``, the event indicates new
|
|
||||||
metadata for album items. The parameter is an ``AlbumInfo`` object instead of
|
|
||||||
a ``TrackInfo``. Parameter: ``info``.
|
|
||||||
- ``before_choose_candidate``: called before the user is prompted for a decision
|
|
||||||
during a ``beet import`` interactive session. Plugins can use this event for
|
|
||||||
:ref:`appending choices to the prompt <append_prompt_choices>` by returning a
|
|
||||||
list of ``PromptChoices``. Parameters: ``task`` and ``session``.
|
|
||||||
- ``mb_track_extract``: called after the metadata is obtained from MusicBrainz.
|
|
||||||
The parameter is a ``dict`` containing the tags retrieved from MusicBrainz for
|
|
||||||
a track. Plugins must return a new (potentially empty) ``dict`` with
|
|
||||||
additional ``field: value`` pairs, which the autotagger will apply to the
|
|
||||||
item, as flexible attributes if ``field`` is not a hardcoded field. Fields
|
|
||||||
already present on the track are overwritten. Parameter: ``data``
|
|
||||||
- ``mb_album_extract``: Like ``mb_track_extract``, but for album tags.
|
|
||||||
Overwrites tags set at the track level, if they have the same ``field``.
|
|
||||||
Parameter: ``data``
|
|
||||||
|
|
||||||
The included ``mpdupdate`` plugin provides an example use case for event
|
|
||||||
listeners.
|
|
||||||
|
|
||||||
Extend the Autotagger
|
Extend the Autotagger
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
Loading…
Reference in a new issue