diff --git a/docs/conf.py b/docs/conf.py index 840c55a3b..1e53fe427 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -75,6 +75,17 @@ man_pages = [ ), ] +# Global substitutions that can be used anywhere in the documentation. +rst_epilog = """ +.. |Album| replace:: :class:`~beets.library.models.Album` +.. |AlbumInfo| replace:: :class:`beets.autotag.hooks.AlbumInfo` +.. |ImportSession| replace:: :class:`~beets.importer.session.ImportSession` +.. |ImportTask| replace:: :class:`~beets.importer.tasks.ImportTask` +.. |Item| replace:: :class:`~beets.library.models.Item` +.. |Library| replace:: :class:`~beets.library.library.Library` +.. |Model| replace:: :class:`~beets.dbcore.db.Model` +.. |TrackInfo| replace:: :class:`beets.autotag.hooks.TrackInfo` +""" # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output diff --git a/docs/dev/library.rst b/docs/dev/library.rst index 0f7554aac..8b854937d 100644 --- a/docs/dev/library.rst +++ b/docs/dev/library.rst @@ -7,18 +7,18 @@ This page describes the internal API of beets' core database features. It doesn't exhaustively document the API, but is aimed at giving an overview of the architecture to orient anyone who wants to dive into the code. -The :class:`Library` object is the central repository for data in beets. It -represents a database containing songs, which are :class:`Item` instances, and -groups of items, which are :class:`Album` instances. +The |Library| object is the central repository for data in beets. It represents +a database containing songs, which are |Item| instances, and groups of items, +which are |Album| instances. The Library Class ----------------- -The :class:`Library` is typically instantiated as a singleton. A single -invocation of beets usually has only one :class:`Library`. It's powered by -:class:`dbcore.Database` under the hood, which handles the SQLite_ abstraction, -something like a very minimal ORM_. The library is also responsible for handling -queries to retrieve stored objects. +The |Library| is typically instantiated as a singleton. A single invocation of +beets usually has only one |Library|. It's powered by :class:`dbcore.Database` +under the hood, which handles the SQLite_ abstraction, something like a very +minimal ORM_. The library is also responsible for handling queries to retrieve +stored objects. Overview ~~~~~~~~ @@ -40,10 +40,9 @@ which you can get using the :py:meth:`Library.transaction` context manager. Model Classes ------------- -The two model entities in beets libraries, :class:`Item` and :class:`Album`, -share a base class, :class:`LibModel`, that provides common functionality. That -class itself specialises :class:`beets.dbcore.Model` which provides an ORM-like -abstraction. +The two model entities in beets libraries, |Item| and |Album|, share a base +class, :class:`LibModel`, that provides common functionality. That class itself +specialises :class:`beets.dbcore.Model` which provides an ORM-like abstraction. To get or change the metadata of a model (an item or album), either access its attributes (e.g., ``print(album.year)`` or ``album.year = 2012``) or use the @@ -56,8 +55,7 @@ Models use dirty-flags to track when the object's metadata goes out of sync with the database. The dirty dictionary maps field names to booleans indicating whether the field has been written since the object was last synchronized (via load or store) with the database. This logic is implemented in the model base -class :class:`LibModel` and is inherited by both :class:`Item` and -:class:`Album`. +class :class:`LibModel` and is inherited by both |Item| and |Album|. We provide CRUD-like methods for interacting with the database: @@ -77,10 +75,10 @@ normal the normal mapping API is supported: Item ~~~~ -Each :class:`Item` object represents a song or track. (We use the more generic -term item because, one day, beets might support non-music media.) An item can -either be purely abstract, in which case it's just a bag of metadata fields, or -it can have an associated file (indicated by ``item.path``). +Each |Item| object represents a song or track. (We use the more generic term +item because, one day, beets might support non-music media.) An item can either +be purely abstract, in which case it's just a bag of metadata fields, or it can +have an associated file (indicated by ``item.path``). In terms of the underlying SQLite database, items are backed by a single table called items with one column per metadata fields. The metadata fields currently @@ -97,12 +95,12 @@ become out of sync with on-disk metadata, mainly to speed up the :ref:`update-cmd` (which needs to check whether the database is in sync with the filesystem). This feature turns out to be sort of complicated. -For any :class:`Item`, there are two mtimes: the on-disk mtime (maintained by -the OS) and the database mtime (maintained by beets). Correspondingly, there is -on-disk metadata (ID3 tags, for example) and DB metadata. The goal with the -mtime is to ensure that the on-disk and DB mtimes match when the on-disk and DB -metadata are in sync; this lets beets do a quick mtime check and avoid rereading -files in some circumstances. +For any |Item|, there are two mtimes: the on-disk mtime (maintained by the OS) +and the database mtime (maintained by beets). Correspondingly, there is on-disk +metadata (ID3 tags, for example) and DB metadata. The goal with the mtime is to +ensure that the on-disk and DB mtimes match when the on-disk and DB metadata are +in sync; this lets beets do a quick mtime check and avoid rereading files in +some circumstances. Specifically, beets attempts to maintain the following invariant: @@ -126,14 +124,14 @@ This leads to the following implementation policy: Album ~~~~~ -An :class:`Album` is a collection of Items in the database. Every item in the -database has either zero or one associated albums (accessible via -``item.album_id``). An item that has no associated album is called a singleton. -Changing fields on an album (e.g. ``album.year = 2012``) updates the album -itself and also changes the same field in all associated items. +An |Album| is a collection of Items in the database. Every item in the database +has either zero or one associated albums (accessible via ``item.album_id``). An +item that has no associated album is called a singleton. Changing fields on an +album (e.g. ``album.year = 2012``) updates the album itself and also changes the +same field in all associated items. -An :class:`Album` object keeps track of album-level metadata, which is (mostly) -a subset of the track-level metadata. The album-level metadata fields are listed +An |Album| object keeps track of album-level metadata, which is (mostly) a +subset of the track-level metadata. The album-level metadata fields are listed in ``Album._fields``. For those fields that are both item-level and album-level (e.g., ``year`` or ``albumartist``), every item in an album should share the same value. Albums use an SQLite table called ``albums``, in which each column @@ -147,7 +145,7 @@ is an album metadata field. Transactions ~~~~~~~~~~~~ -The :class:`Library` class provides the basic methods necessary to access and +The |Library| class provides the basic methods necessary to access and manipulate its contents. To perform more complicated operations atomically, or to interact directly with the underlying SQLite database, you must use a *transaction* (see this `blog post`_ for motivation). For example @@ -181,8 +179,8 @@ matching items/albums. The ``clause()`` method should return an SQLite ``WHERE`` clause that matches appropriate albums/items. This allows for efficient batch queries. -Correspondingly, the ``match(item)`` method should take an :class:`Item` object -and return a boolean, indicating whether or not a specific item matches the +Correspondingly, the ``match(item)`` method should take an |Item| object and +return a boolean, indicating whether or not a specific item matches the criterion. This alternate implementation allows clients to determine whether items that have already been fetched from the database match the query. @@ -194,4 +192,4 @@ together, matching only albums/items that match all constituent queries. Beets has a human-writable plain-text query syntax that can be parsed into :class:`Query` objects. Calling ``AndQuery.from_strings`` parses a list of query -parts into a query object that can then be used with :class:`Library` objects. +parts into a query object that can then be used with |Library| objects. diff --git a/docs/dev/plugins/events.rst b/docs/dev/plugins/events.rst index 325b01b33..68773db3b 100644 --- a/docs/dev/plugins/events.rst +++ b/docs/dev/plugins/events.rst @@ -52,166 +52,146 @@ registration process in this case: command starts. ``import`` - :Parameters: :py:class:`lib `, ``paths`` (list of - path strings) + :Parameters: ``lib`` (|Library|), ``paths`` (list of path strings) :Description: Called after the ``import`` command finishes. ``album_imported`` - :Parameters: :py:class:`lib `, :py:class:`album - ` + :Parameters: ``lib`` (|Library|), ``album`` (|Album|) :Description: Called every time the importer finishes adding an album to the library. ``album_removed`` - :Parameters: :py:class:`lib `, :py:class:`album - ` + :Parameters: ``lib`` (|Library|), ``album`` (|Album|) :Description: Called every time an album is removed from the library (even when its files are not deleted from disk). ``item_copied`` - :Parameters: :py:class:`item `, ``source`` (path), - ``destination`` (path) + :Parameters: ``item`` (|Item|), ``source`` (path), ``destination`` (path) :Description: Called whenever an item file is copied. ``item_imported`` - :Parameters: :py:class:`lib `, :py:class:`item - ` + :Parameters: ``lib`` (|Library|), ``item`` (|Item|) :Description: Called every time the importer adds a singleton to the library (not called for full-album imports). ``before_item_imported`` - :Parameters: :py:class:`item `, ``source`` (path), - ``destination`` (path) + :Parameters: ``item`` (|Item|), ``source`` (path), ``destination`` (path) :Description: Called with an ``Item`` object immediately before it is imported. ``before_item_moved`` - :Parameters: :py:class:`item `, ``source`` (path), - ``destination`` (path) + :Parameters: ``item`` (|Item|), ``source`` (path), ``destination`` (path) :Description: Called with an ``Item`` object immediately before its file is moved. ``item_moved`` - :Parameters: :py:class:`item `, ``source`` (path), - ``destination`` (path) + :Parameters: ``item`` (|Item|), ``source`` (path), ``destination`` (path) :Description: Called with an ``Item`` object whenever its file is moved. ``item_linked`` - :Parameters: :py:class:`item `, ``source`` (path), - ``destination`` (path) + :Parameters: ``item`` (|Item|), ``source`` (path), ``destination`` (path) :Description: Called with an ``Item`` object whenever a symlink is created for a file. ``item_hardlinked`` - :Parameters: :py:class:`item `, ``source`` (path), - ``destination`` (path) + :Parameters: ``item`` (|Item|), ``source`` (path), ``destination`` (path) :Description: Called with an ``Item`` object whenever a hardlink is created for a file. ``item_reflinked`` - :Parameters: :py:class:`item `, ``source`` (path), - ``destination`` (path) + :Parameters: ``item`` (|Item|), ``source`` (path), ``destination`` (path) :Description: Called with an ``Item`` object whenever a reflink is created for a file. ``item_removed`` - :Parameters: :py:class:`item ` + :Parameters: ``item`` (|Item|) :Description: Called with an ``Item`` object every time an item (singleton or part of an album) is removed from the library (even when its file is not deleted from disk). ``write`` - :Parameters: :py:class:`item `, ``path`` (path), - ``tags`` (dict) + :Parameters: ``item`` (|Item|), ``path`` (path), ``tags`` (dict) :Description: Called just before a file's metadata is written to disk. Handlers may modify ``tags`` or raise ``library.FileOperationError`` to abort. ``after_write`` - :Parameters: :py:class:`item ` + :Parameters: ``item`` (|Item|) :Description: Called after a file's metadata is written to disk. ``import_task_created`` - :Parameters: :py:class:`task `, - :py:class:`session ` + :Parameters: ``task`` (|ImportTask|), ``session`` (|ImportSession|) :Description: Called immediately after an import task is initialized. May return a list (possibly empty) of replacement tasks. ``import_task_start`` - :Parameters: :py:class:`task `, - :py:class:`session ` + :Parameters: ``task`` (|ImportTask|), ``session`` (|ImportSession|) :Description: Called before an import task begins processing. ``import_task_apply`` - :Parameters: :py:class:`task `, - :py:class:`session ` + :Parameters: ``task`` (|ImportTask|), ``session`` (|ImportSession|) :Description: Called after metadata changes have been applied in an import task (on the UI thread; keep fast). Prefer a pipeline stage otherwise (see :ref:`plugin-stage`). ``import_task_before_choice`` - :Parameters: :py:class:`task `, - :py:class:`session ` + :Parameters: ``task`` (|ImportTask|), ``session`` (|ImportSession|) :Description: Called after candidate search and before deciding how to import. May return an importer action (only one handler may return non-None). ``import_task_choice`` - :Parameters: :py:class:`task `, - :py:class:`session ` + :Parameters: ``task`` (|ImportTask|), ``session`` (|ImportSession|) :Description: Called after a decision has been made about an import task. Use ``task.choice_flag`` to inspect or change the action. ``import_task_files`` - :Parameters: :py:class:`task `, - :py:class:`session ` + :Parameters: ``task`` (|ImportTask|), ``session`` (|ImportSession|) :Description: Called after filesystem manipulation (copy/move/write) for an import task. ``library_opened`` - :Parameters: :py:class:`lib ` + :Parameters: ``lib`` (|Library|) :Description: Called after beets starts and initializes the main Library object. ``database_change`` - :Parameters: :py:class:`lib `, :py:class:`model - ` + :Parameters: ``lib`` (|Library|), ``model`` (|Model|) :Description: A modification has been made to the library database (may not yet be committed). ``cli_exit`` - :Parameters: :py:class:`lib ` + :Parameters: ``lib`` (|Library|) :Description: Called just before the ``beet`` command-line program exits. ``import_begin`` - :Parameters: :py:class:`session ` + :Parameters: ``session`` (|ImportSession|) :Description: Called just before a ``beet import`` session starts. ``trackinfo_received`` - :Parameters: :py:class:`info ` + :Parameters: ``info`` (|TrackInfo|) :Description: Called after metadata for a track is fetched (e.g., from MusicBrainz). Handlers can modify the tags seen by later pipeline stages or adjustments (e.g., ``mbsync``). ``albuminfo_received`` - :Parameters: :py:class:`info ` + :Parameters: ``info`` (|AlbumInfo|) :Description: Like ``trackinfo_received`` but for album-level metadata. ``before_choose_candidate`` - :Parameters: :py:class:`task `, - :py:class:`session ` + :Parameters: ``task`` (|ImportTask|), ``session`` (|ImportSession|) :Description: Called before prompting the user during interactive import. May return a list of ``PromptChoices`` to append to the prompt (see :ref:`append_prompt_choices`). ``mb_track_extract`` - :Parameters: :py:class:`data ` + :Parameters: ``data`` (dict) :Description: Called after metadata is obtained from MusicBrainz for a track. Must return a (possibly empty) dict of additional ``field: value`` pairs to apply (overwriting existing fields). ``mb_album_extract`` - :Parameters: :py:class:`data ` + :Parameters: ``data`` (dict) :Description: Like ``mb_track_extract`` but for album tags. Overwrites tags set at the track level with the same field.