From 54e070d06bdf609ee29e9de360a5de973f9af2a6 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sun, 3 Mar 2013 16:29:31 -0800 Subject: [PATCH] mbsync: use SingletonQuery for item updates --- beets/library.py | 62 +++++++++++++++++++++------------------------ beetsplug/mbsync.py | 13 +++++----- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/beets/library.py b/beets/library.py index f07ea7a53..390d4e1dd 100644 --- a/beets/library.py +++ b/beets/library.py @@ -798,6 +798,33 @@ class ResultIterator(object): row = self.rowiter.next() # May raise StopIteration. return Item(row) +def get_query(val, album=False): + """Takes a value which may be None, a query string, a query string + list, or a Query 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 + + # Convert a single string into a list of space-separated + # criteria. + if isinstance(val, basestring): + val = val.split() + + if val is None: + return TrueQuery() + elif isinstance(val, list) or isinstance(val, tuple): + return AndQuery.from_strings(val, default_fields, all_keys) + elif isinstance(val, Query): + return val + else: + raise ValueError('query must be None or have type Query or str') + + # An abstract library. @@ -809,37 +836,6 @@ class BaseLibrary(object): raise NotImplementedError - # Helpers. - - @classmethod - def _get_query(cls, val=None, album=False): - """Takes a value which may be None, a query string, a query - string list, or a Query 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 - - # Convert a single string into a list of space-separated - # criteria. - if isinstance(val, basestring): - val = val.split() - - if val is None: - return TrueQuery() - elif isinstance(val, list) or isinstance(val, tuple): - return AndQuery.from_strings(val, default_fields, all_keys) - elif isinstance(val, Query): - return val - elif not isinstance(val, Query): - raise ValueError('query must be None or have type Query or str') - - # Basic operations. def add(self, item, copy=False): @@ -1358,7 +1354,7 @@ class Library(BaseLibrary): # Querying. def albums(self, query=None, artist=None): - query = self._get_query(query, True) + query = get_query(query, True) if artist is not None: # "Add" the artist to the query. query = AndQuery((query, MatchQuery('albumartist', artist))) @@ -1372,7 +1368,7 @@ class Library(BaseLibrary): return [Album(self, dict(res)) for res in rows] def items(self, query=None, artist=None, album=None, title=None): - queries = [self._get_query(query, False)] + queries = [get_query(query, False)] if artist is not None: queries.append(MatchQuery('artist', artist)) if album is not None: diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index a751d4d27..44a1a8771 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -12,7 +12,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -"""Update local library from MusicBrainz +"""Update library's tags using MusicBrainz. """ import logging @@ -52,10 +52,10 @@ def mbsync_func(lib, opts, args): write = opts.write with lib.transaction(): - singletons = lib.items(ui.decargs(args + ['singleton'])) - albums = lib.albums(ui.decargs(args)) - - for s in singletons: + # Process matching singletons. + singletons_query = library.get_query(ui.decargs(args), False) + singletons_query.subqueries.append(library.SingletonQuery(True)) + for s in lib.items(singletons_query): if not s.mb_trackid: log.info(u'Skipping singleton {0}: has no mb_trackid' .format(s.title)) @@ -67,7 +67,8 @@ def mbsync_func(lib, opts, args): autotag.apply_item_metadata(s, match.info) _print_and_apply_changes(lib, s, move, pretend, write) - for a in albums: + # Process matching albums. + for a in lib.albums(ui.decargs(args)): if not a.mb_albumid: log.info(u'Skipping album {0}: has no mb_albumid'.format(a.id)) continue