mirror of
https://github.com/beetbox/beets.git
synced 2026-02-04 06:24:13 +01:00
pre-parse path format templates
Instead of parsing the template at each call to destination(), it's now possible to parse them *once*, a priori, and re-use the resulting template object. This is analogous to the re module's compiled expressions.
This commit is contained in:
parent
c4f9b452da
commit
d042bed27c
4 changed files with 73 additions and 8 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
51
beetsplug/bench.py
Normal file
51
beetsplug/bench.py
Normal file
|
|
@ -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]
|
||||
|
|
@ -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():
|
||||
|
|
|
|||
Loading…
Reference in a new issue