diff --git a/beets/library.py b/beets/library.py index 322c158c7..b352acece 100644 --- a/beets/library.py +++ b/beets/library.py @@ -858,7 +858,10 @@ class Library(BaseLibrary): break else: assert False, "no default path format" - subpath_tmpl = Template(path_format) + if isinstance(path_format, Template): + subpath_tmpl = path_format + else: + subpath_tmpl = Template(path_format) # Get the item's Album if it has one. album = self.get_album(item) diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index 195440f53..e2eebb738 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -31,6 +31,7 @@ import re from beets import library from beets import plugins from beets import util +from beets.util.functemplate import Template # On Windows platforms, use colorama to support "ANSI" terminal colors. @@ -56,9 +57,12 @@ PF_KEY_QUERIES = { 'singleton': 'singleton:true', } DEFAULT_PATH_FORMATS = [ - (library.PF_KEY_DEFAULT, '$albumartist/$album%aunique{}/$track $title'), - (PF_KEY_QUERIES['singleton'], 'Non-Album/$artist/$title'), - (PF_KEY_QUERIES['comp'], 'Compilations/$album%aunique{}/$track $title'), + (library.PF_KEY_DEFAULT, + Template('$albumartist/$album%aunique{}/$track $title')), + (PF_KEY_QUERIES['singleton'], + Template('Non-Album/$artist/$title')), + (PF_KEY_QUERIES['comp'], + Template('Compilations/$album%aunique{}/$track $title')), ] DEFAULT_ART_FILENAME = 'cover' DEFAULT_TIMEOUT = 5.0 @@ -465,10 +469,12 @@ def _get_path_formats(config): legacy_path_format = config_val(config, 'beets', 'path_format', None) if legacy_path_format: # Old path formats override the default values. - path_formats = [(library.PF_KEY_DEFAULT, legacy_path_format)] + path_formats = [(library.PF_KEY_DEFAULT, + Template(legacy_path_format))] else: # If no legacy path format, use the defaults instead. path_formats = DEFAULT_PATH_FORMATS + if config.has_section('paths'): custom_path_formats = [] for key, value in config.items('paths', True): @@ -479,8 +485,9 @@ def _get_path_formats(config): # For non-special keys (literal queries), the _ # character denotes a :. key = key.replace('_', ':') - custom_path_formats.append((key, value)) + custom_path_formats.append((key, Template(value))) path_formats = custom_path_formats + path_formats + return path_formats diff --git a/beetsplug/bench.py b/beetsplug/bench.py new file mode 100644 index 000000000..779d9e015 --- /dev/null +++ b/beetsplug/bench.py @@ -0,0 +1,51 @@ +# This file is part of beets. +# Copyright 2012, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +from beets.plugins import BeetsPlugin +from beets import ui +from beets import vfs +from beets import library +from beets.util.functemplate import Template +import time + +def benchmark(lib): + # Measure path generation performance with %aunique{} included. + lib.path_formats = [ + (library.PF_KEY_DEFAULT, + Template('$albumartist/$album%aunique{}/$track $title')), + ] + start_time = time.time() + vfs.libtree(lib) + end_time = time.time() + print 'With %aunique:', end_time - start_time + + # And with %aunique replaceed with a "cheap" no-op function. + lib.path_formats = [ + (library.PF_KEY_DEFAULT, + Template('$albumartist/$album%lower{}/$track $title')), + ] + start_time = time.time() + vfs.libtree(lib) + end_time = time.time() + print 'Without %aunique:', end_time - start_time + +class BenchmarkPlugin(BeetsPlugin): + """A plugin for performing some simple performance benchmarks. + """ + def commands(self): + def bench_func(lib, config, opts, args): + benchmark(lib) + cmd = ui.Subcommand('bench', help='benchmark') + cmd.func = bench_func + return [cmd] diff --git a/test/test_ui.py b/test/test_ui.py index 13d82c030..970c27e56 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -503,7 +503,9 @@ class ConfigTest(unittest.TestCase): def test_paths_section_respected(self): def func(lib, config, opts, args): - self.assertEqual(lib.path_formats[0], ('x', 'y')) + key, template = lib.path_formats[0] + self.assertEqual(key, 'x') + self.assertEqual(template.original, 'y') self._run_main([], textwrap.dedent(""" [paths] x=y"""), func) @@ -753,7 +755,9 @@ class PathFormatTest(unittest.TestCase): pf = self._paths_for(""" foo: bar """) - self.assertEqual(pf[0], ('foo', 'bar')) + key, tmpl = pf[0] + self.assertEqual(key, 'foo') + self.assertEqual(tmpl.original, 'bar') self.assertEqual(pf[1:], ui.DEFAULT_PATH_FORMATS) def suite():