diff --git a/beets/plugins.py b/beets/plugins.py index 6dec7ef2a..f10dc5849 100644 --- a/beets/plugins.py +++ b/beets/plugins.py @@ -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. diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index 1abce2e67..327db6b04 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -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 diff --git a/docs/dev/plugins.rst b/docs/dev/plugins.rst index bab0e604d..c9018c394 100644 --- a/docs/dev/plugins.rst +++ b/docs/dev/plugins.rst @@ -443,15 +443,24 @@ Extend the Query Syntax ^^^^^^^^^^^^^^^^^^^^^^^ You can add new kinds of queries to beets' :doc:`query syntax -` indicated by a prefix. As an example, beets already +`. 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