diff --git a/beets/dbcore/__init__.py b/beets/dbcore/__init__.py index 41d1c1256..b4f80fb98 100644 --- a/beets/dbcore/__init__.py +++ b/beets/dbcore/__init__.py @@ -16,5 +16,5 @@ Library. """ from .db import Model, Database -from .query import Query, FieldQuery, MatchQuery, AndQuery +from .query import Query, FieldQuery, MatchQuery, AndQuery, OrQuery from .types import Type diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index e8495b439..4c888302d 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -307,6 +307,15 @@ class AndQuery(MutableCollectionQuery): return all([q.match(item) for q in self.subqueries]) +class OrQuery(MutableCollectionQuery): + """A conjunction of a list of other queries.""" + def clause(self): + return self.clause_with_joiner('or') + + def match(self, item): + return any([q.match(item) for q in self.subqueries]) + + class TrueQuery(Query): """A query that always matches.""" def clause(self): diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py index 40a5d7305..254671094 100644 --- a/beetsplug/smartplaylist.py +++ b/beetsplug/smartplaylist.py @@ -18,6 +18,7 @@ from __future__ import print_function from beets.plugins import BeetsPlugin from beets import config, ui, library +from beets import dbcore from beets.util import normpath, syspath import os @@ -35,13 +36,13 @@ def update_playlists(lib): relative_to = normpath(relative_to) for playlist in playlists: - # Query attribute could be a single query or a list of queries - queries = playlist['query'] - if not isinstance(queries, (list, tuple)): - queries = [queries] - items = [] - for query in queries: - items.extend(lib.items(library.get_query(query, library.Item))) + # Parse the query. If it's a list, join the queries with OR. + query_strings = playlist['query'] + if not isinstance(query_strings, (list, tuple)): + query_strings = [query_strings] + items = lib.items(dbcore.OrQuery( + [library.get_query(q, library.Item) for q in query_strings] + )) m3us = {} basename = playlist['name'].encode('utf8')