From 55255b00872052244395a011394de31119631bb1 Mon Sep 17 00:00:00 2001 From: Mark Trolley Date: Sun, 19 Feb 2023 16:13:52 -0500 Subject: [PATCH] Deprecate absubmit and update acousticbrainz plugins Fixes #4627. AcousticBrainz is shutting down as of early 2023. Deprecate the absubmit plugin and update the acousticbrainz plugin to require configuration of an AcousticBrainz server instance. --- beets/autotag/hooks.py | 2 +- beetsplug/absubmit.py | 34 +++++++++++++++++++++++++-------- beetsplug/acousticbrainz.py | 25 +++++++++++++++++++----- docs/changelog.rst | 6 ++++++ docs/plugins/absubmit.rst | 19 +++++++++++++++--- docs/plugins/acousticbrainz.rst | 19 +++++++++++++++--- docs/plugins/index.rst | 2 +- 7 files changed, 86 insertions(+), 21 deletions(-) diff --git a/beets/autotag/hooks.py b/beets/autotag/hooks.py index 8d2680e95..5f33cef28 100644 --- a/beets/autotag/hooks.py +++ b/beets/autotag/hooks.py @@ -18,7 +18,7 @@ from __future__ import annotations from collections import namedtuple from functools import total_ordering import re -from typing import Dict, List, Tuple, Iterator, Union, NewType, Any, Optional,\ +from typing import Dict, List, Tuple, Iterator, Union, Any, Optional,\ Iterable, Callable, TypeVar from beets import logging diff --git a/beetsplug/absubmit.py b/beetsplug/absubmit.py index d1ea692f8..a32889440 100644 --- a/beetsplug/absubmit.py +++ b/beetsplug/absubmit.py @@ -56,10 +56,13 @@ class AcousticBrainzSubmitPlugin(plugins.BeetsPlugin): def __init__(self): super().__init__() + self._log.warning("This plugin is deprecated.") + self.config.add({ 'extractor': '', 'force': False, - 'pretend': False + 'pretend': False, + 'base_url': '' }) self.extractor = self.config['extractor'].as_str() @@ -79,7 +82,7 @@ class AcousticBrainzSubmitPlugin(plugins.BeetsPlugin): except OSError: raise ui.UserError( 'No extractor command found: please install the extractor' - ' binary from https://acousticbrainz.org/download' + ' binary from https://essentia.upf.edu/' ) except ABSubmitError: # Extractor found, will exit with an error if not called with @@ -96,7 +99,15 @@ class AcousticBrainzSubmitPlugin(plugins.BeetsPlugin): self.extractor_sha.update(extractor.read()) self.extractor_sha = self.extractor_sha.hexdigest() - base_url = 'https://acousticbrainz.org/api/v1/{mbid}/low-level' + self.url = '' + base_url = self.config['base_url'].as_str() + if base_url: + if not base_url.startswith('http'): + raise ui.UserError('AcousticBrainz server base URL must start ' + 'with an HTTP scheme') + elif base_url[-1] != '/': + base_url = base_url + '/' + self.url = base_url + '{mbid}/low-level' def commands(self): cmd = ui.Subcommand( @@ -118,10 +129,17 @@ only files which would be processed' return [cmd] def command(self, lib, opts, args): - # Get items from arguments - items = lib.items(ui.decargs(args)) - self.opts = opts - util.par_map(self.analyze_submit, items) + if not self.url: + raise ui.UserError( + 'This plugin is deprecated since AcousticBrainz no longer ' + 'accepts new submissions. See the base_url configuration ' + 'option.' + ) + else: + # Get items from arguments + items = lib.items(ui.decargs(args)) + self.opts = opts + util.par_map(self.analyze_submit, items) def analyze_submit(self, item): analysis = self._get_analysis(item) @@ -179,7 +197,7 @@ only files which would be processed' def _submit_data(self, item, data): mbid = item['mb_trackid'] headers = {'Content-Type': 'application/json'} - response = requests.post(self.base_url.format(mbid=mbid), + response = requests.post(self.url.format(mbid=mbid), json=data, headers=headers) # Test that request was successful and raise an error on failure. if response.status_code != 200: diff --git a/beetsplug/acousticbrainz.py b/beetsplug/acousticbrainz.py index 0cfd6e318..cda0012cf 100644 --- a/beetsplug/acousticbrainz.py +++ b/beetsplug/acousticbrainz.py @@ -22,7 +22,6 @@ import requests from beets import plugins, ui from beets.dbcore import types -ACOUSTIC_BASE = "https://acousticbrainz.org/" LEVELS = ["/low-level", "/high-level"] ABSCHEME = { 'highlevel': { @@ -138,12 +137,23 @@ class AcousticPlugin(plugins.BeetsPlugin): def __init__(self): super().__init__() + self._log.warning("This plugin is deprecated.") + self.config.add({ 'auto': True, 'force': False, - 'tags': [] + 'tags': [], + 'base_url': '' }) + self.base_url = self.config['base_url'].as_str() + if self.base_url: + if not self.base_url.startswith('http'): + raise ui.UserError('AcousticBrainz server base URL must start ' + 'with an HTTP scheme') + elif self.base_url[-1] != '/': + self.base_url = self.base_url + '/' + if self.config['auto']: self.register_listener('import_task_files', self.import_task_files) @@ -171,8 +181,13 @@ class AcousticPlugin(plugins.BeetsPlugin): self._fetch_info(task.imported_items(), False, True) def _get_data(self, mbid): + if not self.base_url: + raise ui.UserError( + 'This plugin is deprecated since AcousticBrainz has shut ' + 'down. See the base_url configuration option.' + ) data = {} - for url in _generate_urls(mbid): + for url in _generate_urls(self.base_url, mbid): self._log.debug('fetching URL: {}', url) try: @@ -328,8 +343,8 @@ class AcousticPlugin(plugins.BeetsPlugin): 'because key {} was not found', subdata, v, k) -def _generate_urls(mbid): +def _generate_urls(base_url, mbid): """Generates AcousticBrainz end point urls for given `mbid`. """ for level in LEVELS: - yield ACOUSTIC_BASE + mbid + level + yield base_url + mbid + level diff --git a/docs/changelog.rst b/docs/changelog.rst index 3fe976ee6..921ae7b30 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -155,6 +155,12 @@ For packagers: Other changes: +* :doc:`/plugins/absubmit`: Deprecate the ``absubmit`` plugin since + AcousticBrainz has stopped accepting new submissions. + :bug:`4627` +* :doc:`/plugins/acousticbrainz`: Deprecate the ``acousticbrainz`` plugin + since the AcousticBrainz project has shut down. + :bug:`4627` * :doc:`/plugins/limit`: Limit query results to head or tail (``lslimit`` command only) * :doc:`/plugins/fish`: Add ``--output`` option. diff --git a/docs/plugins/absubmit.rst b/docs/plugins/absubmit.rst index e26032edb..884eac524 100644 --- a/docs/plugins/absubmit.rst +++ b/docs/plugins/absubmit.rst @@ -1,8 +1,17 @@ AcousticBrainz Submit Plugin ============================ -The ``absubmit`` plugin lets you submit acoustic analysis results to the -`AcousticBrainz`_ server. +The ``absubmit`` plugin lets you submit acoustic analysis results to an +`AcousticBrainz`_ server. This plugin is now deprecated since the +AcousicBrainz project has been shut down. + +As an alternative the `beets-xtractor`_ plugin can be used. + +Warning +------- + +The AcousticBrainz project has shut down. To use this plugin you must set the +``base_url`` configuration option to a server offering the AcousticBrainz API. Installation ------------ @@ -57,10 +66,14 @@ file. The available options are: - **pretend**: Do not analyze and submit of AcousticBrainz data but print out the items which would be processed. Default: ``no``. +- **base_url**: The base URL of the AcousticBrainz server. The plugin has no + function if this option is not set. + Default: None -.. _streaming_extractor_music: https://acousticbrainz.org/download +.. _streaming_extractor_music: https://essentia.upf.edu/ .. _FAQ: https://acousticbrainz.org/faq .. _pip: https://pip.pypa.io .. _requests: https://requests.readthedocs.io/en/master/ .. _github: https://github.com/MTG/essentia .. _AcousticBrainz: https://acousticbrainz.org +.. _beets-xtractor: https://github.com/adamjakab/BeetsPluginXtractor diff --git a/docs/plugins/acousticbrainz.rst b/docs/plugins/acousticbrainz.rst index 7d7aed237..3a053e123 100644 --- a/docs/plugins/acousticbrainz.rst +++ b/docs/plugins/acousticbrainz.rst @@ -2,9 +2,13 @@ AcousticBrainz Plugin ===================== The ``acousticbrainz`` plugin gets acoustic-analysis information from the -`AcousticBrainz`_ project. +`AcousticBrainz`_ project. This plugin is now deprecated since the +AcousicBrainz project has been shut down. + +As an alternative the `beets-xtractor`_ plugin can be used. .. _AcousticBrainz: https://acousticbrainz.org/ +.. _beets-xtractor: https://github.com/adamjakab/BeetsPluginXtractor Enable the ``acousticbrainz`` plugin in your configuration (see :ref:`using-plugins`) and run it by typing:: @@ -44,6 +48,12 @@ these fields: * ``tonal`` * ``voice_instrumental`` +Warning +------- + +The AcousticBrainz project has shut down. To use this plugin you must set the +``base_url`` configuration option to a server offering the AcousticBrainz API. + Automatic Tagging ----------------- @@ -56,7 +66,7 @@ Configuration ------------- To configure the plugin, make a ``acousticbrainz:`` section in your -configuration file. There are three options: +configuration file. The available options are: - **auto**: Enable AcousticBrainz during ``beet import``. Default: ``yes``. @@ -64,4 +74,7 @@ configuration file. There are three options: it. Default: ``no``. - **tags**: Which tags from the list above to set on your files. - Default: [] (all) + Default: [] (all). +- **base_url**: The base URL of the AcousticBrainz server. The plugin has no + function if this option is not set. + Default: None diff --git a/docs/plugins/index.rst b/docs/plugins/index.rst index 8404ce716..1c8aaf760 100644 --- a/docs/plugins/index.rst +++ b/docs/plugins/index.rst @@ -156,7 +156,7 @@ Metadata -------- :doc:`absubmit ` - Analyse audio with the `streaming_extractor_music`_ program and submit the metadata to the AcousticBrainz server + Analyse audio with the `streaming_extractor_music`_ program and submit the metadata to an AcousticBrainz server :doc:`acousticbrainz ` Fetch various AcousticBrainz metadata