Add Item.any_writable_media_field_query method for BPD search

This commit is contained in:
Šarūnas Nejus 2024-06-16 15:22:52 +01:00
parent d22c497dc0
commit 4650f6513b
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
2 changed files with 18 additions and 11 deletions

View file

@ -350,6 +350,10 @@ class LibModel(dbcore.Model["Library"]):
# Config key that specifies how an instance should be formatted. # Config key that specifies how an instance should be formatted.
_format_config_key: str _format_config_key: str
@cached_classproperty
def writable_media_fields(cls) -> set[str]:
return set(MediaFile.fields()) & cls._fields.keys()
def _template_funcs(self): def _template_funcs(self):
funcs = DefaultTemplateFunctions(self, self._db).functions() funcs = DefaultTemplateFunctions(self, self._db).functions()
funcs.update(plugins.template_funcs()) funcs.update(plugins.template_funcs())
@ -401,6 +405,13 @@ class LibModel(dbcore.Model["Library"]):
[cls.field_query(f, *args, **kwargs) for f in cls._search_fields] [cls.field_query(f, *args, **kwargs) for f in cls._search_fields]
) )
@classmethod
def any_writable_media_field_query(cls, *args, **kwargs) -> dbcore.OrQuery:
fields = cls.writable_media_fields
return dbcore.OrQuery(
[cls.field_query(f, *args, **kwargs) for f in fields]
)
def duplicates_query(self, fields: list[str]) -> dbcore.AndQuery: def duplicates_query(self, fields: list[str]) -> dbcore.AndQuery:
"""Return a query for entities with same values in the given fields.""" """Return a query for entities with same values in the given fields."""
return dbcore.AndQuery( return dbcore.AndQuery(

View file

@ -27,8 +27,6 @@ import time
import traceback import traceback
from string import Template from string import Template
from mediafile import MediaFile
import beets import beets
import beets.ui import beets.ui
from beets import dbcore, vfs from beets import dbcore, vfs
@ -91,8 +89,6 @@ SUBSYSTEMS = [
"partition", "partition",
] ]
ITEM_KEYS_WRITABLE = set(MediaFile.fields()).intersection(Item._fields.keys())
# Gstreamer import error. # Gstreamer import error.
class NoGstreamerError(Exception): class NoGstreamerError(Exception):
@ -1399,7 +1395,7 @@ class Server(BaseServer):
return test_tag, key return test_tag, key
raise BPDError(ERROR_UNKNOWN, "no such tagtype") raise BPDError(ERROR_UNKNOWN, "no such tagtype")
def _metadata_query(self, query_type, any_query_type, kv): def _metadata_query(self, query_type, kv, allow_any_query: bool = False):
"""Helper function returns a query object that will find items """Helper function returns a query object that will find items
according to the library query type provided and the key-value according to the library query type provided and the key-value
pairs specified. The any_query_type is used for queries of pairs specified. The any_query_type is used for queries of
@ -1411,10 +1407,10 @@ class Server(BaseServer):
it = iter(kv) it = iter(kv)
for tag, value in zip(it, it): for tag, value in zip(it, it):
if tag.lower() == "any": if tag.lower() == "any":
if any_query_type: if allow_any_query:
queries.append( queries.append(
any_query_type( Item.any_writable_media_field_query(
value, ITEM_KEYS_WRITABLE, query_type query_type, value
) )
) )
else: else:
@ -1429,14 +1425,14 @@ class Server(BaseServer):
def cmd_search(self, conn, *kv): def cmd_search(self, conn, *kv):
"""Perform a substring match for items.""" """Perform a substring match for items."""
query = self._metadata_query( query = self._metadata_query(
dbcore.query.SubstringQuery, dbcore.query.AnyFieldQuery, kv dbcore.query.SubstringQuery, kv, allow_any_query=True
) )
for item in self.lib.items(query): for item in self.lib.items(query):
yield self._item_info(item) yield self._item_info(item)
def cmd_find(self, conn, *kv): def cmd_find(self, conn, *kv):
"""Perform an exact match for items.""" """Perform an exact match for items."""
query = self._metadata_query(dbcore.query.MatchQuery, None, kv) query = self._metadata_query(dbcore.query.MatchQuery, kv)
for item in self.lib.items(query): for item in self.lib.items(query):
yield self._item_info(item) yield self._item_info(item)
@ -1456,7 +1452,7 @@ class Server(BaseServer):
raise BPDError(ERROR_ARG, 'should be "Album" for 3 arguments') raise BPDError(ERROR_ARG, 'should be "Album" for 3 arguments')
elif len(kv) % 2 != 0: elif len(kv) % 2 != 0:
raise BPDError(ERROR_ARG, "Incorrect number of filter arguments") raise BPDError(ERROR_ARG, "Incorrect number of filter arguments")
query = self._metadata_query(dbcore.query.MatchQuery, None, kv) query = self._metadata_query(dbcore.query.MatchQuery, kv)
clause, subvals = query.clause() clause, subvals = query.clause()
statement = ( statement = (