mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
Merge branch 'master' into smartplaylist-attr-url-encoding
This commit is contained in:
commit
2286511ebe
11 changed files with 63 additions and 70 deletions
|
|
@ -675,7 +675,7 @@ class ImportSessionFixture(ImportSession):
|
|||
>>> importer.run()
|
||||
|
||||
This imports ``/path/to/import`` into `lib`. It skips the first
|
||||
album and imports thesecond one with metadata from the tags. For the
|
||||
album and imports the second one with metadata from the tags. For the
|
||||
remaining albums, the metadata from the autotagger will be applied.
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -1130,7 +1130,10 @@ def get_temp_filename(
|
|||
tempdir = get_module_tempdir(module)
|
||||
tempdir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
_, filename = tempfile.mkstemp(dir=tempdir, prefix=prefix, suffix=suffix)
|
||||
descriptor, filename = tempfile.mkstemp(
|
||||
dir=tempdir, prefix=prefix, suffix=suffix
|
||||
)
|
||||
os.close(descriptor)
|
||||
return bytestring_path(filename)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
# This file is part of beets.
|
||||
# Copyright 2016, Adrian Sampson.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""A namespace package for beets plugins."""
|
||||
|
||||
# Make this a namespace package.
|
||||
from pkgutil import extend_path
|
||||
|
||||
__path__ = extend_path(__path__, __name__)
|
||||
|
|
@ -22,6 +22,9 @@ New features:
|
|||
|
||||
Bug fixes:
|
||||
|
||||
* :doc:`plugins/fetchart`: Fix fetchart bug where a tempfile could not be deleted due to never being
|
||||
properly closed.
|
||||
:bug:`5521`
|
||||
* :doc:`plugins/lyrics`: LRCLib will fallback to plain lyrics if synced lyrics
|
||||
are not found and `synced` flag is set to `yes`.
|
||||
* Synchronise files included in the source distribution with what we used to
|
||||
|
|
@ -74,6 +77,8 @@ Bug fixes:
|
|||
For packagers:
|
||||
|
||||
* The minimum supported Python version is now 3.9.
|
||||
* External plugin developers: ``beetsplug/__init__.py`` file can be removed
|
||||
from your plugin as beets now uses native/implicit namespace package setup.
|
||||
|
||||
Other changes:
|
||||
|
||||
|
|
|
|||
|
|
@ -3,47 +3,57 @@
|
|||
Writing Plugins
|
||||
---------------
|
||||
|
||||
A beets plugin is just a Python module inside the ``beetsplug`` namespace
|
||||
package. (Check out this `Stack Overflow question about namespace packages`_ if
|
||||
you haven't heard of them.) So, to make one, create a directory called
|
||||
``beetsplug`` and put two files in it: one called ``__init__.py`` and one called
|
||||
``myawesomeplugin.py`` (but don't actually call it that). Your directory
|
||||
structure should look like this::
|
||||
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/
|
||||
__init__.py
|
||||
myawesomeplugin.py
|
||||
|
||||
.. _Stack Overflow question about namespace packages:
|
||||
https://stackoverflow.com/questions/1675734/how-do-i-create-a-namespace-package-in-python/1676069#1676069
|
||||
or your plugin subpackage::
|
||||
|
||||
Then, you'll need to put this stuff in ``__init__.py`` to make ``beetsplug`` a
|
||||
namespace package::
|
||||
beetsplug/
|
||||
myawesomeplugin/
|
||||
__init__.py
|
||||
myawesomeplugin.py
|
||||
|
||||
from pkgutil import extend_path
|
||||
__path__ = extend_path(__path__, __name__)
|
||||
.. attention::
|
||||
|
||||
That's all for ``__init__.py``; you can can leave it alone. The meat of your
|
||||
plugin goes in ``myawesomeplugin.py``. There, you'll have to import the
|
||||
``beets.plugins`` module and define a subclass of the ``BeetsPlugin`` class
|
||||
found therein. Here's a skeleton of a plugin file::
|
||||
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.
|
||||
|
||||
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 MyPlugin(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, make sure the directory that contains your
|
||||
``beetsplug`` directory is in the Python
|
||||
path (using ``PYTHONPATH`` or by installing in a `virtualenv`_, for example).
|
||||
Then, as described above, edit your ``config.yaml`` to include
|
||||
``plugins: myawesomeplugin`` (substituting the name of the Python module
|
||||
containing your plugin).
|
||||
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
|
||||
|
||||
.. _virtualenv: https://pypi.org/project/virtualenv
|
||||
.. code-block:: yaml
|
||||
|
||||
# config.yaml
|
||||
plugins:
|
||||
- myawesomeplugin
|
||||
|
||||
and you're good to go!
|
||||
|
||||
.. _this article: https://realpython.com/python-namespace-package/#setting-up-some-namespace-packages
|
||||
.. _this Stack Overflow question: https://stackoverflow.com/a/27586272/9582674
|
||||
.. _poetry: https://python-poetry.org/docs/pyproject/#packages
|
||||
.. _setuptools: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#finding-simple-packages
|
||||
|
||||
.. _add_subcommands:
|
||||
|
||||
|
|
@ -249,13 +259,13 @@ The events currently available are:
|
|||
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.
|
||||
field. Fields already present on the track are overwritten.
|
||||
Parameter: ``data``
|
||||
|
||||
* `mb_album_extract`: Like `mb_track_extract`, but for album tags. Overwrites
|
||||
|
|
|
|||
18
docs/faq.rst
18
docs/faq.rst
|
|
@ -174,9 +174,8 @@ pages.
|
|||
…report a bug in beets?
|
||||
-----------------------
|
||||
|
||||
We use the `issue tracker <https://github.com/beetbox/beets/issues>`__
|
||||
on GitHub. `Enter a new issue <https://github.com/beetbox/beets/issues/new>`__
|
||||
there to report a bug. Please follow these guidelines when reporting an issue:
|
||||
We use the `issue tracker`_ on GitHub where you can `open a new ticket`_.
|
||||
Please follow these guidelines when reporting an issue:
|
||||
|
||||
- Most importantly: if beets is crashing, please `include the
|
||||
traceback <https://imgur.com/jacoj>`__. Tracebacks can be more
|
||||
|
|
@ -206,6 +205,7 @@ If you've never reported a bug before, Mozilla has some well-written
|
|||
`general guidelines for good bug
|
||||
reports`_.
|
||||
|
||||
.. _issue tracker: https://github.com/beetbox/beets/issues
|
||||
.. _general guidelines for good bug reports: https://developer.mozilla.org/en-US/docs/Mozilla/QA/Bug_writing_guidelines
|
||||
|
||||
|
||||
|
|
@ -343,11 +343,11 @@ read the file. You can also use specialized programs for checking file
|
|||
integrity---for example, type ``metaflac --list music.flac`` to check
|
||||
FLAC files.
|
||||
|
||||
If beets still complains about a file that seems to be valid, `file a
|
||||
bug <https://github.com/beetbox/beets/issues/new>`__ and we'll look into
|
||||
it. There's always a possibility that there's a bug "upstream" in the
|
||||
`Mutagen <https://github.com/quodlibet/mutagen>`__ library used by beets,
|
||||
in which case we'll forward the bug to that project's tracker.
|
||||
If beets still complains about a file that seems to be valid, `open a new
|
||||
ticket`_ and we'll look into it. There's always a possibility that there's
|
||||
a bug "upstream" in the `Mutagen <https://github.com/quodlibet/mutagen>`__
|
||||
library used by beets, in which case we'll forward the bug to that project's
|
||||
tracker.
|
||||
|
||||
|
||||
.. _importhang:
|
||||
|
|
@ -398,3 +398,5 @@ try `this Super User answer`_.
|
|||
|
||||
.. _this Super User answer: https://superuser.com/a/284361/4569
|
||||
.. _pip: https://pip.pypa.io/en/stable/
|
||||
.. _open a new ticket:
|
||||
https://github.com/beetbox/beets/issues/new?template=bug-report.md
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ all of these limitations.
|
|||
Musepack, Windows Media, Opus, and AIFF files are supported. (Do you use
|
||||
some other format? Please `file a feature request`_!)
|
||||
|
||||
.. _file a feature request: https://github.com/beetbox/beets/issues/new
|
||||
.. _file a feature request:
|
||||
https://github.com/beetbox/beets/issues/new?template=feature-request.md
|
||||
|
||||
Now that that's out of the way, let's tag some music.
|
||||
|
||||
|
|
|
|||
|
|
@ -37,3 +37,5 @@ allow_any_generics = false
|
|||
# FIXME: Would be better to actually type the libraries (if under our control),
|
||||
# or write our own stubs. For now, silence errors
|
||||
ignore_missing_imports = true
|
||||
namespace_packages = true
|
||||
explicit_package_bases = true
|
||||
|
|
|
|||
|
|
@ -456,16 +456,6 @@ lyrics_pages = [
|
|||
LyricsPage.make(
|
||||
"https://www.musica.com/letras.asp?letra=59862",
|
||||
"""
|
||||
Lady Madonna, children at your feet
|
||||
Wonder how you manage to make ends meet
|
||||
Who finds the money when you pay the rent?
|
||||
Did you think that money was heaven sent?
|
||||
|
||||
Friday night arrives without a suitcase
|
||||
Sunday morning creeping like a nun
|
||||
Monday's child has learned to tie his bootlace
|
||||
See how they run
|
||||
|
||||
Lady Madonna, baby at your breast
|
||||
Wonders how you manage to feed the rest
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class ImportAddedTest(PluginMixin, ImportTestCase):
|
|||
os.path.getmtime(mfile.path) for mfile in self.import_media
|
||||
)
|
||||
self.matcher = AutotagStub().install()
|
||||
self.matcher.macthin = AutotagStub.GOOD
|
||||
self.matcher.matching = AutotagStub.IDENT
|
||||
self.importer = self.setup_importer()
|
||||
self.importer.add_choice(importer.action.APPLY)
|
||||
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ class ImportTest(ImportTestCase):
|
|||
self.prepare_album_for_import(1)
|
||||
self.setup_importer()
|
||||
self.matcher = AutotagStub().install()
|
||||
self.matcher.macthin = AutotagStub.GOOD
|
||||
self.matcher.matching = AutotagStub.IDENT
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
|
|
|
|||
Loading…
Reference in a new issue