mirror of
https://github.com/beetbox/beets.git
synced 2025-12-23 09:03:49 +01:00
Add a query class for years with support for ranges.
This commit is contained in:
parent
bf904187e2
commit
fe41bba380
2 changed files with 74 additions and 0 deletions
|
|
@ -549,6 +549,31 @@ class BooleanQuery(MatchQuery):
|
|||
self.pattern = util.str2bool(pattern)
|
||||
self.pattern = int(self.pattern)
|
||||
|
||||
class YearQuery(FieldQuery):
|
||||
"""Matches a year or years against a year field.
|
||||
"""
|
||||
@classmethod
|
||||
def applies_to(cls, field):
|
||||
return field in ['year', 'original_year']
|
||||
|
||||
@classmethod
|
||||
def value_match(cls, pattern, value):
|
||||
"""Determine whether the value matches the pattern. Both
|
||||
arguments are strings.
|
||||
"""
|
||||
return value in cls._expanded_years(pattern)
|
||||
|
||||
def clause(self):
|
||||
years = YearQuery._expanded_years(self.pattern)
|
||||
return self.field + " IN (" + ",".join(years) + ")", ()
|
||||
|
||||
@classmethod
|
||||
def _expanded_years(self, pattern):
|
||||
ranges = [[int(y) for y in se.split('-')] for se in pattern.split(',')]
|
||||
years = [range(r[0], r[1] + 1) if len(r) > 1 else [r[0]] for r in ranges]
|
||||
return [str(y) for yrs in years for y in yrs]
|
||||
|
||||
|
||||
class SingletonQuery(Query):
|
||||
"""Matches either singleton or non-singleton items."""
|
||||
def __init__(self, sense):
|
||||
|
|
@ -750,6 +775,8 @@ def parse_query_part(part):
|
|||
for pre, query_class in prefixes.items():
|
||||
if term.startswith(pre):
|
||||
return key, term[len(pre):], query_class
|
||||
if YearQuery.applies_to(key):
|
||||
return key, term, YearQuery
|
||||
return key, term, SubstringQuery # The default query type.
|
||||
|
||||
def construct_query_part(query_part, default_fields, all_keys):
|
||||
|
|
|
|||
|
|
@ -60,6 +60,22 @@ class QueryParseTest(unittest.TestCase):
|
|||
r = (None, 'test:regexp', beets.library.RegexpQuery)
|
||||
self.assertEqual(pqp(q), r)
|
||||
|
||||
def test_single_year(self):
|
||||
q = 'year:1999'
|
||||
r = ('year', '1999', beets.library.YearQuery)
|
||||
self.assertEqual(pqp(q), r)
|
||||
|
||||
def test_multiple_years(self):
|
||||
q = 'year:1999,2002,2010'
|
||||
r = ('year', '1999,2002,2010', beets.library.YearQuery)
|
||||
self.assertEqual(pqp(q), r)
|
||||
|
||||
def test_year_range(self):
|
||||
q = 'year:1999-2001'
|
||||
r = ('year', '1999-2001', beets.library.YearQuery)
|
||||
self.assertEqual(pqp(q), r)
|
||||
|
||||
|
||||
class AnyFieldQueryTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.lib = beets.library.Library(':memory:')
|
||||
|
|
@ -219,6 +235,29 @@ class GetTest(unittest.TestCase, AssertsMixin):
|
|||
self.assert_matched(results, 'Littlest Things')
|
||||
self.assert_done(results)
|
||||
|
||||
def test_single_year(self):
|
||||
q = 'year:2006'
|
||||
results = self.lib.items(q)
|
||||
self.assert_matched(results, 'Littlest Things')
|
||||
self.assert_matched(results, 'Lovers Who Uncover')
|
||||
self.assert_done(results)
|
||||
|
||||
def test_year_range(self):
|
||||
q = 'year:2000-2010'
|
||||
results = self.lib.items(q)
|
||||
self.assert_matched(results, 'Littlest Things')
|
||||
self.assert_matched(results, 'Take Pills')
|
||||
self.assert_matched(results, 'Lovers Who Uncover')
|
||||
self.assert_done(results)
|
||||
|
||||
def test_multiple_years(self):
|
||||
q = 'year:1987,2004-2006'
|
||||
results = self.lib.items(q)
|
||||
self.assert_matched(results, 'Littlest Things')
|
||||
self.assert_matched(results, 'Lovers Who Uncover')
|
||||
self.assert_matched(results, 'Boracay')
|
||||
self.assert_done(results)
|
||||
|
||||
class MemoryGetTest(unittest.TestCase, AssertsMixin):
|
||||
def setUp(self):
|
||||
self.album_item = _common.item()
|
||||
|
|
@ -312,6 +351,14 @@ class MatchTest(unittest.TestCase):
|
|||
q = beets.library.SubstringQuery('disc', '6')
|
||||
self.assertTrue(q.match(self.item))
|
||||
|
||||
def test_year_match_positive(self):
|
||||
q = beets.library.YearQuery('year', '1')
|
||||
self.assertTrue(q.match(self.item))
|
||||
|
||||
def test_year_match_negative(self):
|
||||
q = beets.library.YearQuery('year', '10')
|
||||
self.assertFalse(q.match(self.item))
|
||||
|
||||
class PathQueryTest(unittest.TestCase, AssertsMixin):
|
||||
def setUp(self):
|
||||
self.lib = beets.library.Library(':memory:')
|
||||
|
|
|
|||
Loading…
Reference in a new issue