diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py index 8889a2534..c88fe38c5 100644 --- a/beetsplug/smartplaylist.py +++ b/beetsplug/smartplaylist.py @@ -23,7 +23,7 @@ from beets import ui from beets.util import mkdirall, normpath, syspath from beets.library import Item, Album, parse_query_string from beets.dbcore import OrQuery -from beets.dbcore.query import MultipleSort +from beets.dbcore.query import MultipleSort, ParsingError import os @@ -93,36 +93,46 @@ class SmartPlaylistPlugin(BeetsPlugin): self._matched_playlists = set() for playlist in self.config['playlists'].get(list): - playlist_data = (playlist['name'],) - for key, Model in (('query', Item), ('album_query', Album)): - qs = playlist.get(key) - if qs is None: - query_and_sort = None, None - elif isinstance(qs, basestring): - query_and_sort = parse_query_string(qs, Model) - elif len(qs) == 1: - query_and_sort = parse_query_string(qs[0], Model) - else: - # multiple queries and sorts - queries, sorts = zip(*(parse_query_string(q, Model) - for q in qs)) - query = OrQuery(queries) - final_sorts = [] - for s in sorts: - if s: - if isinstance(s, MultipleSort): - final_sorts += s.sorts - else: - final_sorts.append(s) - if not final_sorts: - sort = None - elif len(final_sorts) == 1: - sort, = final_sorts - else: - sort = MultipleSort(final_sorts) - query_and_sort = query, sort + if 'name' not in playlist: + self._log.warn("playlist configuration is missing name") + continue - playlist_data += (query_and_sort,) + playlist_data = (playlist['name'],) + try: + for key, Model in (('query', Item), ('album_query', Album)): + qs = playlist.get(key) + if qs is None: + query_and_sort = None, None + elif isinstance(qs, basestring): + query_and_sort = parse_query_string(qs, Model) + elif len(qs) == 1: + query_and_sort = parse_query_string(qs[0], Model) + else: + # multiple queries and sorts + queries, sorts = zip(*(parse_query_string(q, Model) + for q in qs)) + query = OrQuery(queries) + final_sorts = [] + for s in sorts: + if s: + if isinstance(s, MultipleSort): + final_sorts += s.sorts + else: + final_sorts.append(s) + if not final_sorts: + sort = None + elif len(final_sorts) == 1: + sort, = final_sorts + else: + sort = MultipleSort(final_sorts) + query_and_sort = query, sort + + playlist_data += (query_and_sort,) + + except ParsingError as exc: + self._log.warn("invalid query in playlist {}: {}", + playlist['name'], exc) + continue self._unmatched_playlists.add(playlist_data) diff --git a/docs/changelog.rst b/docs/changelog.rst index 247e0efda..d86137b0e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -53,6 +53,8 @@ Fixes: * :doc:`/plugins/metasync`: Fix a crash when syncing with recent versions of iTunes. :bug:`1700` * :doc:`/plugins/duplicates`: Fix a crash when merging items. :bug:`1699` +* :doc:`/plugins/smartplaylist`: More gracefully handle malformed queries and + missing configuration. 1.3.15 (October 17, 2015)