mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 16:42:42 +01:00
Add Item.any_writable_media_field_query method for BPD search
This commit is contained in:
parent
d22c497dc0
commit
4650f6513b
2 changed files with 18 additions and 11 deletions
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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 = (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue