local: Move find_exact and search out of tag cache.
This commit is contained in:
parent
4161c2bf27
commit
ca358e05db
179
mopidy/backends/local/search.py
Normal file
179
mopidy/backends/local/search.py
Normal file
@ -0,0 +1,179 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from mopidy.models import Album, SearchResult
|
||||
|
||||
|
||||
def find_exact(tracks, query=None, uris=None):
|
||||
# TODO Only return results within URI roots given by ``uris``
|
||||
|
||||
if query is None:
|
||||
query = {}
|
||||
|
||||
_validate_query(query)
|
||||
|
||||
for (field, values) in query.iteritems():
|
||||
if not hasattr(values, '__iter__'):
|
||||
values = [values]
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
for value in values:
|
||||
if field == 'track_no':
|
||||
q = _convert_to_int(value)
|
||||
else:
|
||||
q = value.strip()
|
||||
|
||||
uri_filter = lambda t: q == t.uri
|
||||
track_name_filter = lambda t: q == t.name
|
||||
album_filter = lambda t: q == getattr(t, 'album', Album()).name
|
||||
artist_filter = lambda t: filter(
|
||||
lambda a: q == a.name, t.artists)
|
||||
albumartist_filter = lambda t: any([
|
||||
q == a.name
|
||||
for a in getattr(t.album, 'artists', [])])
|
||||
composer_filter = lambda t: any([
|
||||
q == a.name
|
||||
for a in getattr(t, 'composers', [])])
|
||||
performer_filter = lambda t: any([
|
||||
q == a.name
|
||||
for a in getattr(t, 'performers', [])])
|
||||
track_no_filter = lambda t: q == t.track_no
|
||||
genre_filter = lambda t: t.genre and q == t.genre
|
||||
date_filter = lambda t: q == t.date
|
||||
comment_filter = lambda t: q == t.comment
|
||||
any_filter = lambda t: (
|
||||
uri_filter(t) or
|
||||
track_name_filter(t) or
|
||||
album_filter(t) or
|
||||
artist_filter(t) or
|
||||
albumartist_filter(t) or
|
||||
composer_filter(t) or
|
||||
performer_filter(t) or
|
||||
track_no_filter(t) or
|
||||
genre_filter(t) or
|
||||
date_filter(t) or
|
||||
comment_filter(t))
|
||||
|
||||
if field == 'uri':
|
||||
tracks = filter(uri_filter, tracks)
|
||||
elif field == 'track_name':
|
||||
tracks = filter(track_name_filter, tracks)
|
||||
elif field == 'album':
|
||||
tracks = filter(album_filter, tracks)
|
||||
elif field == 'artist':
|
||||
tracks = filter(artist_filter, tracks)
|
||||
elif field == 'albumartist':
|
||||
tracks = filter(albumartist_filter, tracks)
|
||||
elif field == 'composer':
|
||||
tracks = filter(composer_filter, tracks)
|
||||
elif field == 'performer':
|
||||
tracks = filter(performer_filter, tracks)
|
||||
elif field == 'track_no':
|
||||
tracks = filter(track_no_filter, tracks)
|
||||
elif field == 'genre':
|
||||
tracks = filter(genre_filter, tracks)
|
||||
elif field == 'date':
|
||||
tracks = filter(date_filter, tracks)
|
||||
elif field == 'comment':
|
||||
tracks = filter(comment_filter, tracks)
|
||||
elif field == 'any':
|
||||
tracks = filter(any_filter, tracks)
|
||||
else:
|
||||
raise LookupError('Invalid lookup field: %s' % field)
|
||||
|
||||
# TODO: add local:search:<query>
|
||||
return SearchResult(uri='local:search', tracks=tracks)
|
||||
|
||||
|
||||
def search(tracks, query=None, uris=None):
|
||||
# TODO Only return results within URI roots given by ``uris``
|
||||
|
||||
if query is None:
|
||||
query = {}
|
||||
|
||||
_validate_query(query)
|
||||
|
||||
for (field, values) in query.iteritems():
|
||||
if not hasattr(values, '__iter__'):
|
||||
values = [values]
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
for value in values:
|
||||
if field == 'track_no':
|
||||
q = _convert_to_int(value)
|
||||
else:
|
||||
q = value.strip().lower()
|
||||
|
||||
uri_filter = lambda t: q in t.uri.lower()
|
||||
track_name_filter = lambda t: q in t.name.lower()
|
||||
album_filter = lambda t: q in getattr(
|
||||
t, 'album', Album()).name.lower()
|
||||
artist_filter = lambda t: filter(
|
||||
lambda a: q in a.name.lower(), t.artists)
|
||||
albumartist_filter = lambda t: any([
|
||||
q in a.name.lower()
|
||||
for a in getattr(t.album, 'artists', [])])
|
||||
composer_filter = lambda t: any([
|
||||
q in a.name.lower()
|
||||
for a in getattr(t, 'composers', [])])
|
||||
performer_filter = lambda t: any([
|
||||
q in a.name.lower()
|
||||
for a in getattr(t, 'performers', [])])
|
||||
track_no_filter = lambda t: q == t.track_no
|
||||
genre_filter = lambda t: t.genre and q in t.genre.lower()
|
||||
date_filter = lambda t: t.date and t.date.startswith(q)
|
||||
comment_filter = lambda t: t.comment and q in t.comment.lower()
|
||||
any_filter = lambda t: (
|
||||
uri_filter(t) or
|
||||
track_name_filter(t) or
|
||||
album_filter(t) or
|
||||
artist_filter(t) or
|
||||
albumartist_filter(t) or
|
||||
composer_filter(t) or
|
||||
performer_filter(t) or
|
||||
track_no_filter(t) or
|
||||
genre_filter(t) or
|
||||
date_filter(t) or
|
||||
comment_filter(t))
|
||||
|
||||
if field == 'uri':
|
||||
tracks = filter(uri_filter, tracks)
|
||||
elif field == 'track_name':
|
||||
tracks = filter(track_name_filter, tracks)
|
||||
elif field == 'album':
|
||||
tracks = filter(album_filter, tracks)
|
||||
elif field == 'artist':
|
||||
tracks = filter(artist_filter, tracks)
|
||||
elif field == 'albumartist':
|
||||
tracks = filter(albumartist_filter, tracks)
|
||||
elif field == 'composer':
|
||||
tracks = filter(composer_filter, tracks)
|
||||
elif field == 'performer':
|
||||
tracks = filter(performer_filter, tracks)
|
||||
elif field == 'track_no':
|
||||
tracks = filter(track_no_filter, tracks)
|
||||
elif field == 'genre':
|
||||
tracks = filter(genre_filter, tracks)
|
||||
elif field == 'date':
|
||||
tracks = filter(date_filter, tracks)
|
||||
elif field == 'comment':
|
||||
tracks = filter(comment_filter, tracks)
|
||||
elif field == 'any':
|
||||
tracks = filter(any_filter, tracks)
|
||||
else:
|
||||
raise LookupError('Invalid lookup field: %s' % field)
|
||||
# TODO: add local:search:<query>
|
||||
return SearchResult(uri='local:search', tracks=tracks)
|
||||
|
||||
|
||||
def _validate_query(query):
|
||||
for (_, values) in query.iteritems():
|
||||
if not values:
|
||||
raise LookupError('Missing query')
|
||||
for value in values:
|
||||
if not value:
|
||||
raise LookupError('Missing query')
|
||||
|
||||
|
||||
def _convert_to_int(string):
|
||||
try:
|
||||
return int(string)
|
||||
except ValueError:
|
||||
return object()
|
||||
@ -6,7 +6,7 @@ import tempfile
|
||||
|
||||
from mopidy.backends import base
|
||||
from mopidy.backends.local.translator import local_to_file_uri
|
||||
from mopidy.models import Album, SearchResult
|
||||
from mopidy.backends.local import search
|
||||
|
||||
from .translator import parse_mpd_tag_cache, tracks_to_tag_cache_format
|
||||
|
||||
@ -21,12 +21,6 @@ class LocalTagcacheLibraryProvider(base.BaseLibraryProvider):
|
||||
self._tag_cache_file = self.backend.config['local']['tag_cache_file']
|
||||
self.refresh()
|
||||
|
||||
def _convert_to_int(self, string):
|
||||
try:
|
||||
return int(string)
|
||||
except ValueError:
|
||||
return object()
|
||||
|
||||
def refresh(self, uri=None):
|
||||
logger.debug(
|
||||
'Loading local tracks from %s using %s',
|
||||
@ -54,169 +48,12 @@ class LocalTagcacheLibraryProvider(base.BaseLibraryProvider):
|
||||
return []
|
||||
|
||||
def find_exact(self, query=None, uris=None):
|
||||
# TODO Only return results within URI roots given by ``uris``
|
||||
|
||||
if query is None:
|
||||
query = {}
|
||||
self._validate_query(query)
|
||||
result_tracks = self._uri_mapping.values()
|
||||
|
||||
for (field, values) in query.iteritems():
|
||||
if not hasattr(values, '__iter__'):
|
||||
values = [values]
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
for value in values:
|
||||
if field == 'track_no':
|
||||
q = self._convert_to_int(value)
|
||||
else:
|
||||
q = value.strip()
|
||||
|
||||
uri_filter = lambda t: q == t.uri
|
||||
track_name_filter = lambda t: q == t.name
|
||||
album_filter = lambda t: q == getattr(t, 'album', Album()).name
|
||||
artist_filter = lambda t: filter(
|
||||
lambda a: q == a.name, t.artists)
|
||||
albumartist_filter = lambda t: any([
|
||||
q == a.name
|
||||
for a in getattr(t.album, 'artists', [])])
|
||||
composer_filter = lambda t: any([
|
||||
q == a.name
|
||||
for a in getattr(t, 'composers', [])])
|
||||
performer_filter = lambda t: any([
|
||||
q == a.name
|
||||
for a in getattr(t, 'performers', [])])
|
||||
track_no_filter = lambda t: q == t.track_no
|
||||
genre_filter = lambda t: t.genre and q == t.genre
|
||||
date_filter = lambda t: q == t.date
|
||||
comment_filter = lambda t: q == t.comment
|
||||
any_filter = lambda t: (
|
||||
uri_filter(t) or
|
||||
track_name_filter(t) or
|
||||
album_filter(t) or
|
||||
artist_filter(t) or
|
||||
albumartist_filter(t) or
|
||||
composer_filter(t) or
|
||||
performer_filter(t) or
|
||||
track_no_filter(t) or
|
||||
genre_filter(t) or
|
||||
date_filter(t) or
|
||||
comment_filter(t))
|
||||
|
||||
if field == 'uri':
|
||||
result_tracks = filter(uri_filter, result_tracks)
|
||||
elif field == 'track_name':
|
||||
result_tracks = filter(track_name_filter, result_tracks)
|
||||
elif field == 'album':
|
||||
result_tracks = filter(album_filter, result_tracks)
|
||||
elif field == 'artist':
|
||||
result_tracks = filter(artist_filter, result_tracks)
|
||||
elif field == 'albumartist':
|
||||
result_tracks = filter(albumartist_filter, result_tracks)
|
||||
elif field == 'composer':
|
||||
result_tracks = filter(composer_filter, result_tracks)
|
||||
elif field == 'performer':
|
||||
result_tracks = filter(performer_filter, result_tracks)
|
||||
elif field == 'track_no':
|
||||
result_tracks = filter(track_no_filter, result_tracks)
|
||||
elif field == 'genre':
|
||||
result_tracks = filter(genre_filter, result_tracks)
|
||||
elif field == 'date':
|
||||
result_tracks = filter(date_filter, result_tracks)
|
||||
elif field == 'comment':
|
||||
result_tracks = filter(comment_filter, result_tracks)
|
||||
elif field == 'any':
|
||||
result_tracks = filter(any_filter, result_tracks)
|
||||
else:
|
||||
raise LookupError('Invalid lookup field: %s' % field)
|
||||
# TODO: add local:search:<query>
|
||||
return SearchResult(uri='local:search', tracks=result_tracks)
|
||||
tracks = self._uri_mapping.values()
|
||||
return search.find_exact(tracks, query=query, uris=uris)
|
||||
|
||||
def search(self, query=None, uris=None):
|
||||
# TODO Only return results within URI roots given by ``uris``
|
||||
|
||||
if query is None:
|
||||
query = {}
|
||||
self._validate_query(query)
|
||||
result_tracks = self._uri_mapping.values()
|
||||
|
||||
for (field, values) in query.iteritems():
|
||||
if not hasattr(values, '__iter__'):
|
||||
values = [values]
|
||||
# FIXME this is bound to be slow for large libraries
|
||||
for value in values:
|
||||
if field == 'track_no':
|
||||
q = self._convert_to_int(value)
|
||||
else:
|
||||
q = value.strip().lower()
|
||||
|
||||
uri_filter = lambda t: q in t.uri.lower()
|
||||
track_name_filter = lambda t: q in t.name.lower()
|
||||
album_filter = lambda t: q in getattr(
|
||||
t, 'album', Album()).name.lower()
|
||||
artist_filter = lambda t: filter(
|
||||
lambda a: q in a.name.lower(), t.artists)
|
||||
albumartist_filter = lambda t: any([
|
||||
q in a.name.lower()
|
||||
for a in getattr(t.album, 'artists', [])])
|
||||
composer_filter = lambda t: any([
|
||||
q in a.name.lower()
|
||||
for a in getattr(t, 'composers', [])])
|
||||
performer_filter = lambda t: any([
|
||||
q in a.name.lower()
|
||||
for a in getattr(t, 'performers', [])])
|
||||
track_no_filter = lambda t: q == t.track_no
|
||||
genre_filter = lambda t: t.genre and q in t.genre.lower()
|
||||
date_filter = lambda t: t.date and t.date.startswith(q)
|
||||
comment_filter = lambda t: t.comment and q in t.comment.lower()
|
||||
any_filter = lambda t: (
|
||||
uri_filter(t) or
|
||||
track_name_filter(t) or
|
||||
album_filter(t) or
|
||||
artist_filter(t) or
|
||||
albumartist_filter(t) or
|
||||
composer_filter(t) or
|
||||
performer_filter(t) or
|
||||
track_no_filter(t) or
|
||||
genre_filter(t) or
|
||||
date_filter(t) or
|
||||
comment_filter(t))
|
||||
|
||||
if field == 'uri':
|
||||
result_tracks = filter(uri_filter, result_tracks)
|
||||
elif field == 'track_name':
|
||||
result_tracks = filter(track_name_filter, result_tracks)
|
||||
elif field == 'album':
|
||||
result_tracks = filter(album_filter, result_tracks)
|
||||
elif field == 'artist':
|
||||
result_tracks = filter(artist_filter, result_tracks)
|
||||
elif field == 'albumartist':
|
||||
result_tracks = filter(albumartist_filter, result_tracks)
|
||||
elif field == 'composer':
|
||||
result_tracks = filter(composer_filter, result_tracks)
|
||||
elif field == 'performer':
|
||||
result_tracks = filter(performer_filter, result_tracks)
|
||||
elif field == 'track_no':
|
||||
result_tracks = filter(track_no_filter, result_tracks)
|
||||
elif field == 'genre':
|
||||
result_tracks = filter(genre_filter, result_tracks)
|
||||
elif field == 'date':
|
||||
result_tracks = filter(date_filter, result_tracks)
|
||||
elif field == 'comment':
|
||||
result_tracks = filter(comment_filter, result_tracks)
|
||||
elif field == 'any':
|
||||
result_tracks = filter(any_filter, result_tracks)
|
||||
else:
|
||||
raise LookupError('Invalid lookup field: %s' % field)
|
||||
# TODO: add local:search:<query>
|
||||
return SearchResult(uri='local:search', tracks=result_tracks)
|
||||
|
||||
def _validate_query(self, query):
|
||||
for (_, values) in query.iteritems():
|
||||
if not values:
|
||||
raise LookupError('Missing query')
|
||||
for value in values:
|
||||
if not value:
|
||||
raise LookupError('Missing query')
|
||||
tracks = self._uri_mapping.values()
|
||||
return search.search(tracks, query=query, uris=uris)
|
||||
|
||||
|
||||
class LocalTagcacheLibraryUpdateProvider(base.BaseLibraryProvider):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user