mirror of
https://github.com/beetbox/beets.git
synced 2026-01-15 20:51:38 +01:00
fix crash when using an item-only field in an album query
This commit is contained in:
parent
ac9147928a
commit
efa704f61e
3 changed files with 37 additions and 10 deletions
1
NEWS
1
NEWS
|
|
@ -43,6 +43,7 @@
|
|||
* Fix a "broken pipe" error when piping beets' standard output.
|
||||
* A better error message is given when the database file is unopenable.
|
||||
* Suppress errors due to timeouts and bad responses from MusicBrainz.
|
||||
* Fix a crash on album queries with item-only field names.
|
||||
|
||||
1.0b8
|
||||
-----
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ class CollectionQuery(Query):
|
|||
return out
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, query_string, default_fields=None):
|
||||
def from_string(cls, query_string, default_fields=None, all_keys=ITEM_KEYS):
|
||||
"""Creates a query from a string in the format used by
|
||||
_parse_query. If default_fields are specified, they are the
|
||||
fields to be searched by unqualified search terms. Otherwise,
|
||||
|
|
@ -423,7 +423,7 @@ class CollectionQuery(Query):
|
|||
subqueries.append(AnySubstringQuery(pattern, default_fields))
|
||||
elif key.lower() == 'comp': # a boolean field
|
||||
subqueries.append(BooleanQuery(key.lower(), pattern))
|
||||
elif key.lower() in ITEM_KEYS: # ignore unrecognized keys
|
||||
elif key.lower() in all_keys: # ignore unrecognized keys
|
||||
subqueries.append(SubstringQuery(key.lower(), pattern))
|
||||
elif key.lower() == 'singleton':
|
||||
subqueries.append(SingletonQuery(util.str2bool(pattern)))
|
||||
|
|
@ -522,16 +522,22 @@ class BaseLibrary(object):
|
|||
# Helpers.
|
||||
|
||||
@classmethod
|
||||
def _get_query(cls, val=None, default_fields=None):
|
||||
def _get_query(cls, val=None, album=False):
|
||||
"""Takes a value which may be None, a query string, or a Query
|
||||
object, and returns a suitable Query object. If default_fields
|
||||
is specified, then it restricts the list of fields to search
|
||||
for unqualified terms in query strings.
|
||||
object, and returns a suitable Query object. album determines
|
||||
whether the query is to match items or albums.
|
||||
"""
|
||||
if album:
|
||||
default_fields = ALBUM_DEFAULT_FIELDS
|
||||
all_keys = ALBUM_KEYS
|
||||
else:
|
||||
default_fields = ITEM_DEFAULT_FIELDS
|
||||
all_keys = ITEM_KEYS
|
||||
|
||||
if val is None:
|
||||
return TrueQuery()
|
||||
elif isinstance(val, basestring):
|
||||
return AndQuery.from_string(val, default_fields)
|
||||
return AndQuery.from_string(val, default_fields, all_keys)
|
||||
elif isinstance(val, Query):
|
||||
return val
|
||||
elif not isinstance(val, Query):
|
||||
|
|
@ -919,7 +925,7 @@ class Library(BaseLibrary):
|
|||
# Querying.
|
||||
|
||||
def albums(self, query=None, artist=None):
|
||||
query = self._get_query(query, ALBUM_DEFAULT_FIELDS)
|
||||
query = self._get_query(query, True)
|
||||
if artist is not None:
|
||||
# "Add" the artist to the query.
|
||||
query = AndQuery((query, MatchQuery('albumartist', artist)))
|
||||
|
|
@ -931,7 +937,7 @@ class Library(BaseLibrary):
|
|||
return [Album(self, dict(res)) for res in c.fetchall()]
|
||||
|
||||
def items(self, query=None, artist=None, album=None, title=None):
|
||||
queries = [self._get_query(query, ITEM_DEFAULT_FIELDS)]
|
||||
queries = [self._get_query(query, False)]
|
||||
if artist is not None:
|
||||
queries.append(MatchQuery('artist', artist))
|
||||
if album is not None:
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ class MemoryGetTest(unittest.TestCase, AssertsMixin):
|
|||
|
||||
self.lib = beets.library.Library(':memory:')
|
||||
self.lib.add(self.single_item)
|
||||
self.lib.add_album([self.album_item])
|
||||
self.album = self.lib.add_album([self.album_item])
|
||||
|
||||
def test_singleton_true(self):
|
||||
q = 'singleton:true'
|
||||
|
|
@ -206,6 +206,26 @@ class MemoryGetTest(unittest.TestCase, AssertsMixin):
|
|||
self.assert_matched(results, 'singleton item')
|
||||
self.assert_done(results)
|
||||
|
||||
def test_unknown_field_name_ignored(self):
|
||||
q = 'xyzzy:nonsense'
|
||||
results = self.lib.items(q)
|
||||
titles = [i.title for i in results]
|
||||
self.assertTrue('singleton item' in titles)
|
||||
self.assertTrue('album item' in titles)
|
||||
self.assertEqual(len(titles), 2)
|
||||
|
||||
def test_unknown_field_name_ignored_in_album_query(self):
|
||||
q = 'xyzzy:nonsense'
|
||||
results = self.lib.albums(q)
|
||||
names = [a.album for a in results]
|
||||
self.assertEqual(names, ['the album'])
|
||||
|
||||
def test_item_field_name_ignored_in_album_query(self):
|
||||
q = 'format:nonsense'
|
||||
results = self.lib.albums(q)
|
||||
names = [a.album for a in results]
|
||||
self.assertEqual(names, ['the album'])
|
||||
|
||||
class BrowseTest(unittest.TestCase, AssertsMixin):
|
||||
def setUp(self):
|
||||
self.lib = beets.library.Library(
|
||||
|
|
|
|||
Loading…
Reference in a new issue