generated from MoeMusic/plugin_template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
4,971 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,73 +1,6 @@ | ||
############### | ||
Plugin Template | ||
############### | ||
This repository serves as a template that can be used to quickly get a plugin published to PyPI as well as establish a consistent development environment with the rest of Moe. | ||
########### | ||
Musicbrainz | ||
########### | ||
This is a plugin for Moe utilizing the musicbrainz metadata source. | ||
|
||
By following the instructions of this template repository, you will setup a plugin that has the following features: | ||
|
||
#. Automatic release process initiated by a manual trigger. | ||
|
||
* Changelog generation as well as releasing to PyPI and github are all initiated by running the ``Create Release PR`` github action. Once run, it will create a pull request for the new release which will allow you to edit the generated changelog prior to rebasing the PR onto the main branch. Once rebased into main, the ``Release`` github action will automatically run, publishing your new release. | ||
|
||
.. important:: | ||
The automatic changelog generation is dependent on you adhering to the specific commit conventions of Moe. | ||
|
||
#. Plugin documentation hosted on `Read the Docs <https://readthedocs.org/>`_. | ||
|
||
* As well as creating a consistent documentation interface with the rest of Moe, the main benefit of this is to use the auto-documentation feature of Sphinx for any API functions your plugin may provide. | ||
|
||
#. Project and dependency management using `Poetry <https://python-poetry.org/>`_. | ||
#. A CI suite that will run tests, lint your code, and build the documentation of any PR. | ||
|
||
Instructions | ||
============ | ||
#. Create a new repository from this template repository. | ||
|
||
* Name your repository ``moe_{plugin name}``. This will be the name of your package on PyPI as well. | ||
|
||
#. Edit ``pyproject.toml``. | ||
|
||
* Edit any information in the ``tool.poetry`` and ``tool.poetry.plugins."moe.plugins"`` sections. | ||
|
||
#. Edit github scripts and files. | ||
|
||
* ``.github/ISSUE TEMPLATE`` contains default issue templates that Moe uses. At a minimum, you need to change the url in ``config.yml`` to link to your repository's discussions. | ||
|
||
* You must also enable 'Discussions' in your repository settings in order for the referenced link to work. | ||
|
||
* Edit the ``SLUG`` constant in ``.github/scripts/prep_release.py`` to be your repository. | ||
|
||
#. Setup documentation on `Read the Docs <https://readthedocs.org/>`_. | ||
|
||
* Edit ``docs/conf.py`` project information. | ||
|
||
* `Import your repository into Read the Docs <https://readthedocs.org/dashboard/import/?>`_. | ||
|
||
* This is the site used to host your documentation. | ||
|
||
.. note:: | ||
This step is optional if you are not providing any new API functions with your plugin. In that case, you may remove the ``docs`` directory as well as the ``.readthedocs.yml`` file. | ||
|
||
#. Setup repository settings. | ||
|
||
* Add ``PYPI_USERNAME`` and ``PYPI PASSWORD`` secrets to the repository with your PyPI username and password. These will be used by the CI for the release process. | ||
|
||
#. Edit plugin information. | ||
|
||
* Edit the repository "About" section on github | ||
|
||
* Ensure to add your documentation link to the ``Website`` section. | ||
|
||
* Edit ``README.rst`` | ||
|
||
* Edit ``docs/index.rst`` | ||
|
||
#. Edit repository "About" information. | ||
|
||
* Ensure to add your documentation link to the ``Website`` section. | ||
|
||
#. Once finished, commit your changes and create a ``v0.1.0`` tag. Then, push your changes with the new tag. | ||
|
||
Contributing | ||
============ | ||
If you find any steps missing, confusing, outdated, etc, please don't hesitate to create an issue, discussion, or PR. I'd like this repository to be a central truth for any shared project files such as linter settings, CI scripts, test helper functions, and anything else contained here. | ||
Check out the `full documentation <https://moe-musicbrainz.readthedocs.io/en/latest/>`_ for more info. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,90 @@ | ||
############### | ||
Plugin Template | ||
############### | ||
########### | ||
Musicbrainz | ||
########### | ||
This is a plugin for Moe utilizing the musicbrainz metadata source and provides the following features: | ||
|
||
* Musicbrainz as an import souce. | ||
* Update musicbrainz collections automatically on import or manually. | ||
* Various API functions. | ||
|
||
Configuration | ||
============= | ||
``username`` | ||
Musicbrainz username. | ||
``password`` | ||
Musicbrainz password. | ||
|
||
Collections | ||
~~~~~~~~~~~ | ||
The following options involve auto updating a specific collection on musicbrainz, and should be specified under a ``musicbrainz.collection`` block as shown: | ||
|
||
.. code-block:: toml | ||
[musicbrainz.collection] | ||
collection_id = "123" | ||
.. important:: | ||
|
||
Utilizing any of the collections functionality requires setting your musicbrainz username and password as described above. | ||
|
||
``collection_id`` | ||
Musicbrainz collection to automatically update. | ||
|
||
``auto_add = False`` | ||
Whether to automatically add new releases in the library to the collection defined in ``collection_id``. | ||
|
||
``auto_remove = False`` | ||
Whether to automatically remove releases from ``collection_id`` when removed from the library. | ||
|
||
Custom Fields | ||
============= | ||
This plugin adds the following custom fields: | ||
|
||
Track Fields | ||
~~~~~~~~~~~~ | ||
* ``mb_track_id`` - musicbrainz track id | ||
|
||
Album Fields | ||
~~~~~~~~~~~~ | ||
* ``mb_album_id`` - musicbrainz album aka release id | ||
|
||
Command-line Iterface | ||
===================== | ||
This plugin adds the following commands: | ||
|
||
mbcol | ||
~~~~~ | ||
Used to sync a musicbrainz collection with musicbrainz releases in the library. The collection synced is the one specified under ``collection_id`` in the user config. | ||
|
||
.. code-block:: bash | ||
moe mbcol [-h] [-a | -e] [--add | --remove] query | ||
By default, the musicbrainz collection will be set to the releases found in the queried items. If tracks or extras are queried, their associated album releases will be synced with the collection. | ||
|
||
Positional Arguments | ||
~~~~~~~~~~~~~~~~~~~~ | ||
``query`` | ||
Query your library for items to sync your collection with. See the Moe query docs for more info. | ||
|
||
Optional Arguments | ||
~~~~~~~~~~~~~~~~~~ | ||
``-h, --help`` | ||
Display the help message. | ||
``-a, --album`` | ||
Query for matching albums instead of tracks. | ||
``-e, --extra`` | ||
Query for matching extras instead of tracks. | ||
``--add`` | ||
Add releases to the collection. | ||
``--remove`` | ||
Remove releases from the collection. | ||
|
||
*** | ||
API | ||
*** | ||
``moe_musicbrainz`` | ||
|
||
.. automodule:: moe_musicbrainz.mb_core | ||
:members: | ||
:show-inheritance: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
"""Musicbrainz integration plugin. | ||
See Also: | ||
* https://musicbrainz.org/doc/MusicBrainz_API/ | ||
* https://python-musicbrainzngs.readthedocs.io/en/latest/api/ | ||
""" | ||
|
||
import moe | ||
import pluggy | ||
from moe import config | ||
|
||
from . import mb_cli, mb_core | ||
from .mb_core import * | ||
|
||
__all__ = [] | ||
__all__.extend(mb_core.__all__) | ||
|
||
|
||
@moe.hookimpl | ||
def plugin_registration(): | ||
"""Only register the cli sub-plugin if the cli is enabled.""" | ||
config.CONFIG.pm.register(mb_core, "musicbrainz_core") | ||
if config.CONFIG.pm.has_plugin("cli"): | ||
config.CONFIG.pm.register(mb_cli, "musicbrainz_cli") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
"""Integrates musicbrainz with the import prompt. | ||
The ``musicbrainz`` cli plugin provides the following functionality: | ||
* Ability to search for a specific musicbrainz ID when importing an item. | ||
* `mbcol` command to sync a musicbrainz collection with items in the library. | ||
""" | ||
|
||
|
||
import argparse | ||
import logging | ||
from typing import Optional | ||
|
||
import moe | ||
import moe.cli | ||
import questionary | ||
from moe import moe_import | ||
from moe.library import Album, Extra, Track | ||
from moe.util.cli import PromptChoice, cli_query, query_parser | ||
from sqlalchemy.orm.session import Session | ||
|
||
import moe_musicbrainz | ||
|
||
__all__: list[str] = [] | ||
|
||
log = logging.getLogger("moe.cli.mb") | ||
|
||
|
||
@moe.hookimpl | ||
def add_command(cmd_parsers: argparse._SubParsersAction): | ||
"""Adds the ``mbcol`` command to Moe's CLI.""" | ||
mbcol_parser = cmd_parsers.add_parser( | ||
"mbcol", | ||
description="Set a musicbrainz collection to a query.", | ||
help="sync a musicbrainz collection", | ||
parents=[query_parser], | ||
) | ||
col_option_group = mbcol_parser.add_mutually_exclusive_group() | ||
col_option_group.add_argument( | ||
"--add", | ||
action="store_true", | ||
help="add items to a collection", | ||
) | ||
col_option_group.add_argument( | ||
"--remove", | ||
action="store_true", | ||
help="remove items from a collection", | ||
) | ||
mbcol_parser.set_defaults(func=_parse_args) | ||
|
||
|
||
def _parse_args(session: Session, args: argparse.Namespace): | ||
"""Parses the given commandline arguments. | ||
Args: | ||
session: Library db session. | ||
args: Commandline arguments to parse. | ||
Raises: | ||
SystemExit: Invalid query given, or no items to remove. | ||
""" | ||
items = cli_query(session, args.query, query_type=args.query_type) | ||
|
||
releases = set() | ||
for item in items: | ||
release_id: Optional[str] = None | ||
if isinstance(item, (Extra, Track)): | ||
release_id = item.album.custom.get("mb_album_id") | ||
elif isinstance(item, Album): | ||
release_id = item.custom.get("mb_album_id") | ||
|
||
if release_id: | ||
releases.add(release_id) | ||
|
||
if not releases: | ||
log.error("Queried items don't contain any musicbrainz releases to sync.") | ||
raise SystemExit(1) | ||
|
||
if args.add: | ||
moe_musicbrainz.add_releases_to_collection(releases) | ||
elif args.remove: | ||
moe_musicbrainz.rm_releases_from_collection(releases) | ||
else: | ||
moe_musicbrainz.set_collection(releases) | ||
|
||
|
||
@moe.hookimpl | ||
def add_candidate_prompt_choice(prompt_choices: list[PromptChoice]): | ||
"""Adds a choice to the import prompt to allow specifying a mb id.""" | ||
prompt_choices.append( | ||
PromptChoice(title="Enter Musicbrainz ID", shortcut_key="m", func=_enter_id) | ||
) | ||
|
||
|
||
def _enter_id(new_album: Album, candidate: moe_import.CandidateAlbum): | ||
"""Re-run the add prompt with the inputted Musibrainz release.""" | ||
mb_id = questionary.text("Enter Musicbrainz ID: ").ask() | ||
|
||
log.debug(f"Running import prompt for a selected musicbrainz release. [{mb_id=!r}]") | ||
|
||
candidate = moe_musicbrainz.get_candidate_by_id(new_album, mb_id) | ||
moe_import.import_prompt(new_album, candidate) |
Oops, something went wrong.