add a small set of default path functions (#231)

This commit is contained in:
Adrian Sampson 2011-12-15 14:27:59 -08:00
parent 9005420920
commit 255fbf6c41
2 changed files with 100 additions and 1 deletions

View file

@ -817,7 +817,7 @@ class Library(BaseLibrary):
mapping['albumartist'] = mapping['artist']
# Perform substitution.
subpath = subpath_tmpl.substitute(mapping)
subpath = subpath_tmpl.substitute(mapping, TEMPLATE_FUNCTIONS)
# Encode for the filesystem, dropping unencodable characters.
if isinstance(subpath, unicode) and not fragment:
@ -1260,3 +1260,48 @@ class Album(BaseAlbum):
util.soft_remove(oldart)
util.copy(path, artdest)
self.artpath = artdest
# Default path template resources.
def _int_arg(s):
"""Convert a string argument to an integer for use in a template
function. May raise a ValueError.
"""
return int(s.strip())
def _tmpl_lower(s):
"""Convert a string to lower case."""
return s.lower()
def _tmpl_upper(s):
"""Covert a string to upper case."""
return s.upper()
def _tmpl_title(s):
"""Convert a string to title case."""
return s.title()
def _tmpl_left(s, chars):
"""Get the leftmost characters of a string."""
return s[0:_int_arg(chars)]
def _tmpl_right(s, chars):
"""Get the rightmost characters of a string."""
return s[-_int_arg(chars):]
def _tmpl_if(condition, trueval, falseval=u''):
"""If ``condition`` is nonempty and nonzero, emit ``trueval``;
otherwise, emit ``falseval`` (if provided).
"""
try:
condition = _int_arg(condition)
except ValueError:
condition = condition.strip()
if condition:
return trueval
else:
return falseval
TEMPLATE_FUNCTIONS = {
'lower': _tmpl_lower,
'upper': _tmpl_upper,
'title': _tmpl_title,
'left': _tmpl_left,
'right': _tmpl_right,
'if': _tmpl_if,
}

View file

@ -363,6 +363,60 @@ class DestinationTest(unittest.TestCase):
p = util.sanitize_path('', posixpath)
self.assertEqual(p, '')
class DestinationFunctionTest(unittest.TestCase):
def setUp(self):
self.lib = beets.library.Library(':memory:')
self.lib.directory = '/base'
self.lib.path_formats = {'default': u'path'}
self.i = item()
def tearDown(self):
self.lib.conn.close()
def _setf(self, fmt):
self.lib.path_formats['default'] = fmt
def _assert_dest(self, dest):
self.assertEqual(self.lib.destination(self.i), dest)
def test_upper_case_literal(self):
self._setf(u'%upper{foo}')
self._assert_dest('/base/FOO')
def test_upper_case_variable(self):
self._setf(u'%upper{$title}')
self._assert_dest('/base/THE TITLE')
def test_title_case_variable(self):
self._setf(u'%title{$title}')
self._assert_dest('/base/The Title')
def test_left_variable(self):
self._setf(u'%left{$title, 3}')
self._assert_dest('/base/the')
def test_right_variable(self):
self._setf(u'%right{$title,3}')
self._assert_dest('/base/tle')
def test_if_false(self):
self._setf(u'%if{,foo}')
self._assert_dest('/base/')
def test_if_true(self):
self._setf(u'%if{bar,foo}')
self._assert_dest('/base/foo')
def test_if_else_false(self):
self._setf(u'%if{,foo,baz}')
self._assert_dest('/base/baz')
def test_if_int_value(self):
self._setf(u'%if{0,foo,baz}')
self._assert_dest('/base/baz')
def test_nonexistent_function(self):
self._setf(u'%foo{bar}')
self._assert_dest('/base/%foo{bar}')
class MigrationTest(unittest.TestCase):
"""Tests the ability to change the database schema between
versions.