merge fixes from master

This commit is contained in:
Adrian Sampson 2012-09-09 22:33:05 -07:00
commit e8fa086521
5 changed files with 48 additions and 7 deletions

View file

@ -729,6 +729,10 @@ def plugin_stage(func):
continue
func(task)
# Stage may modify DB, so re-load cached item data.
for item in task.imported_items():
config.lib.load(item)
def manipulate_files():
"""A coroutine (pipeline stage) that performs necessary file
manipulations *after* items have been added to the library.
@ -739,7 +743,7 @@ def manipulate_files():
if task.should_skip():
continue
# Move/copy files.
# Move/copy/write files.
items = task.imported_items()
task.old_paths = [item.path for item in items] # For deletion.
for item in items:

View file

@ -166,10 +166,7 @@ def _regexp(expr, val):
"""
if expr is None:
return False
if val is None:
val = u''
if not isinstance(val, basestring):
val = unicode(val)
val = util.as_string(val)
try:
res = re.search(expr, val)
except re.error:
@ -436,7 +433,7 @@ class SubstringQuery(FieldQuery):
return clause, subvals
def match(self, item):
value = getattr(item, self.field) or ''
value = util.as_string(getattr(item, self.field))
return self.pattern.lower() in value.lower()
class RegexpQuery(FieldQuery):
@ -451,7 +448,7 @@ class RegexpQuery(FieldQuery):
return clause, subvals
def match(self, item):
value = getattr(item, self.field) or ''
value = util.as_string(getattr(item, self.field))
return self.regexp.search(value) is not None
class BooleanQuery(MatchQuery):

View file

@ -467,6 +467,15 @@ def str2bool(value):
else:
return False
def as_string(value):
"""Convert a value to a Unicode object for matching with a query.
None becomes the empty string.
"""
if value is None:
return u''
else:
return unicode(value)
def levenshtein(s1, s2):
"""A nice DP edit distance implementation from Wikibooks:
http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/

View file

@ -12,6 +12,7 @@ Changelog
* Fix album queries for ``artpath`` and other non-item fields.
* Null values in the database can now be matched with the empty-string regular
expression, ``^$``.
* Queries now correctly match non-string values in path format predicates.
* :doc:`/plugins/fetchart`: Fix a bug where cover art filenames could lack
a ``.jpg`` extension.
* :doc:`/plugins/lyrics`: Fix an exception with non-ASCII lyrics.
@ -22,6 +23,8 @@ Changelog
* Add the track mapping dictionary to the ``album_distance`` plugin function.
* Fix an assertion failure when the MusicBrainz main database and search server
disagree.
* Fix a bug that caused the :doc:`/plugins/lastgenre` and other plugins not to
modify files' tags even when they successfully change the database.
.. _Tomahawk resolver: http://beets.radbox.org/blog/tomahawk-resolver.html

View file

@ -302,6 +302,34 @@ class MemoryGetTest(unittest.TestCase, AssertsMixin):
self.assert_matched(results, u'caf\xe9')
self.assert_done(results)
class MatchTest(unittest.TestCase):
def setUp(self):
self.item = _common.item()
def test_regex_match_positive(self):
q = beets.library.RegexpQuery('album', '^the album$')
self.assertTrue(q.match(self.item))
def test_regex_match_negative(self):
q = beets.library.RegexpQuery('album', '^album$')
self.assertFalse(q.match(self.item))
def test_regex_match_non_string_value(self):
q = beets.library.RegexpQuery('disc', '^6$')
self.assertTrue(q.match(self.item))
def test_substring_match_positive(self):
q = beets.library.SubstringQuery('album', 'album')
self.assertTrue(q.match(self.item))
def test_substring_match_negative(self):
q = beets.library.SubstringQuery('album', 'ablum')
self.assertFalse(q.match(self.item))
def test_substring_match_non_string_value(self):
q = beets.library.SubstringQuery('disc', '6')
self.assertTrue(q.match(self.item))
class PathQueryTest(unittest.TestCase, AssertsMixin):
def setUp(self):
self.lib = beets.library.Library(':memory:')