Model._parse() class method

This commit is contained in:
Adrian Sampson 2014-02-13 21:29:17 -08:00
parent b1d70eee39
commit be31ac683a
4 changed files with 50 additions and 16 deletions

View file

@ -346,17 +346,13 @@ class Model(object):
# Formatting and templating.
def _get_formatted(self, key, for_path=False):
"""Get a field value formatted as a string (`unicode` object)
for display to the user. If `for_path` is true, then the value
will be sanitized for inclusion in a pathname (i.e., path
separators will be removed from the value).
@classmethod
def _format(cls, key, value, for_path=False):
"""Format a value as the given field for this model.
"""
value = self.get(key)
# Format the value as a string according to its type, if any.
if key in self._fields:
value = self._fields[key].format(value)
if key in cls._fields:
value = cls._fields[key].format(value)
# Formatting must result in a string. To deal with
# Python2isms, implicitly convert ASCII strings.
assert isinstance(value, basestring), \
@ -382,6 +378,14 @@ class Model(object):
return value
def _get_formatted(self, key, for_path=False):
"""Get a field value formatted as a string (`unicode` object)
for display to the user. If `for_path` is true, then the value
will be sanitized for inclusion in a pathname (i.e., path
separators will be removed from the value).
"""
return self._format(key, self.get(key), for_path)
def _formatted_mapping(self, for_path=False):
"""Get a mapping containing all values on this object formatted
as human-readable strings.
@ -410,6 +414,23 @@ class Model(object):
return template.substitute(mapping, funcs)
# Parsing.
@classmethod
def _parse(cls, key, string):
"""Parse a string as a value for the given key.
"""
if not isinstance(string, basestring):
raise TypeError("_parse() argument must be a string")
typ = cls._fields.get(key)
if typ:
return typ.parse(string)
else:
# Fall back to unparsed string.
return string
# Database controller and supporting interfaces.

View file

@ -86,11 +86,17 @@ class DateType(types.Type):
time.localtime(value or 0))
def parse(self, string):
# FIXME Real date parsing.
try:
return float(string)
# Try a formatted date string.
return time.mktime(
time.strptime(string, beets.config['time_format'].get(unicode))
)
except ValueError:
return 0.0
# Fall back to a plain timestamp number.
try:
return float(string)
except ValueError:
return 0.0
class PathType(types.Type):

View file

@ -1113,10 +1113,7 @@ def modify_items(lib, mods, query, write, move, album, confirm):
fsets = {}
for mod in mods:
key, value = mod.split('=', 1)
typ = model_cls._fields.get(key)
if typ:
value = typ.parse(value)
fsets[key] = value
fsets[key] = model_cls._parse(key, value)
# Get the items to modify.
items, albums = _do_query(lib, query, album, False)

View file

@ -246,6 +246,16 @@ class FormatTest(_common.TestCase):
self.assertEqual(value, u'')
class ParseTest(_common.TestCase):
def test_parse_fixed_field(self):
value = TestModel1._parse('field_one', u'2')
self.assertEqual(value, 2)
def test_parse_untyped_field(self):
value = TestModel1._parse('field_nine', u'2')
self.assertEqual(value, u'2')
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)