Support plugin-provided named queries

This commit is contained in:
Adrian Sampson 2019-02-17 13:49:54 -05:00
parent d8e167637e
commit 22c8289269
3 changed files with 28 additions and 5 deletions

View file

@ -344,6 +344,16 @@ def types(model_cls):
return types
def named_queries(model_cls):
# Gather `item_queries` and `album_queries` from the plugins.
attr_name = '{0}_queries'.format(model_cls.__name__.lower())
queries = {}
for plugin in find_plugins():
plugin_queries = getattr(plugin, attr_name, {})
queries.update(plugin_queries)
return queries
def track_distance(item, info):
"""Gets the track distance calculated by all loaded plugins.
Returns a Distance object.

View file

@ -1143,8 +1143,12 @@ def _setup(options, lib=None):
if lib is None:
lib = _open_library(config)
plugins.send("library_opened", lib=lib)
# Add types and queries defined by plugins.
library.Item._types.update(plugins.types(library.Item))
library.Album._types.update(plugins.types(library.Album))
library.Item._queries.update(plugins.named_queries(library.Item))
library.Album._queries.update(plugins.named_queries(library.Album))
return subcommands, plugins, lib

View file

@ -443,15 +443,24 @@ Extend the Query Syntax
^^^^^^^^^^^^^^^^^^^^^^^
You can add new kinds of queries to beets' :doc:`query syntax
</reference/query>` indicated by a prefix. As an example, beets already
</reference/query>`. There are two ways to add custom queries: using a prefix
and using a name. Prefix-based query extension can apply to *any* field, while
named queries are not associated with any field. For example, beets already
supports regular expression queries, which are indicated by a colon
prefix---plugins can do the same.
To do so, define a subclass of the ``Query`` type from the
``beets.dbcore.query`` module. Then, in the ``queries`` method of your plugin
class, return a dictionary mapping prefix strings to query classes.
For either kind of query extension, define a subclass of the ``Query`` type
from the ``beets.dbcore.query`` module. Then:
One simple kind of query you can extend is the ``FieldQuery``, which
- To define a prefix-based query, define a ``queries`` method in your plugin
class. Return from this method a dictionary mapping prefix strings to query
classes.
- To define a named query, defined dictionaries named either ``item_queries``
or ``album_queries``. These should map names to query types. So if you
use ``{ "foo": FooQuery }``, then the query ``foo:bar`` will construct a
query like ``FooQuery("bar")``.
For prefix-based queries, you will want to extend ``FieldQuery``, which
implements string comparisons on fields. To use it, create a subclass
inheriting from that class and override the ``value_match`` class method.
(Remember the ``@classmethod`` decorator!) The following example plugin