diff --git a/NEWS b/NEWS index 3c1a36a13..361905d85 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,11 @@ now matches the entire phrase. To match in specified fields, use a construction like this: beet ls "artist:the knife" +* Queries can match items from the library by directory. A 'path:' + prefix is optional; any query containing a path separator (/ on + POSIX systems) is assumed to be a path query. Running + "beet ls path/to/music" will show all the music in your library + under the specified directory. * Album art is now automatically discovered and copied from the imported directories when available. * The release label for albums and tracks is now fetched from diff --git a/beets/library.py b/beets/library.py index fe64d72fe..5777be6b9 100644 --- a/beets/library.py +++ b/beets/library.py @@ -420,8 +420,14 @@ class CollectionQuery(Query): if not res: continue key, pattern = res - if key is None: # no key specified; match any field - subqueries.append(AnySubstringQuery(pattern, default_fields)) + if key is None: # No key specified. + if os.sep in pattern: + # This looks like a path. + subqueries.append(PathQuery(pattern)) + else: + # Match any field. + subqueries.append(AnySubstringQuery(pattern, + default_fields)) elif key.lower() == 'comp': # a boolean field subqueries.append(BooleanQuery(key.lower(), pattern)) elif key.lower() == 'path': diff --git a/test/test_query.py b/test/test_query.py index 5165c9773..f78c14e69 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -258,6 +258,22 @@ class PathQueryTest(unittest.TestCase, AssertsMixin): self.assert_matched(results, 'path item') self.assert_done(results) + def test_slashed_query_matches_path(self): + q = '/a/b' + results = self.lib.items(q) + self.assert_matched(results, 'path item') + self.assert_done(results) + + def test_non_slashed_does_not_match_path(self): + q = 'c.mp3' + results = self.lib.items(q) + self.assert_done(results) + + def test_slashes_in_explicit_field_does_not_match_path(self): + q = 'title:/a/b' + results = self.lib.items(q) + self.assert_done(results) + class BrowseTest(unittest.TestCase, AssertsMixin): def setUp(self): self.lib = beets.library.Library(