inline: allow album field definitions

Under the album_field heading.
This commit is contained in:
Adrian Sampson 2013-05-28 23:10:47 -07:00
parent a0cb31956d
commit 0176e10ccf
3 changed files with 48 additions and 9 deletions

View file

@ -46,7 +46,7 @@ def _compile_func(body):
eval(code, env)
return env[FUNC_NAME]
def compile_inline(python_code):
def compile_inline(python_code, album):
"""Given a Python expression or function body, compile it as a path
field function. The returned function takes a single argument, an
Item, and returns a Unicode string. If the expression cannot be
@ -68,10 +68,18 @@ def compile_inline(python_code):
else:
is_expr = True
def _dict_for(obj):
if album:
out = dict(obj._record)
out['items'] = list(obj.items())
return out
else:
return dict(obj.record)
if is_expr:
# For expressions, just evaluate and return the result.
def _expr_func(item):
values = dict(item.record)
def _expr_func(obj):
values = _dict_for(obj)
try:
return eval(code, values)
except Exception as exc:
@ -80,8 +88,8 @@ def compile_inline(python_code):
else:
# For function bodies, invoke the function with values as global
# variables.
def _func_func(item):
func.__globals__.update(item.record)
def _func_func(obj):
func.__globals__.update(_dict_for(obj))
try:
return func()
except Exception as exc:
@ -94,11 +102,18 @@ class InlinePlugin(BeetsPlugin):
config.add({
'pathfields': {},
'album_fields': {},
})
# Add field expressions.
for key, view in config['pathfields'].items():
log.debug(u'adding template field %s' % key)
func = compile_inline(view.get(unicode))
log.debug(u'inline: adding item field %s' % key)
func = compile_inline(view.get(unicode), False)
if func is not None:
self.template_fields[key] = func
for key, view in config['album_fields'].items():
log.debug(u'inline: adding album field %s' % key)
func = compile_inline(view.get(unicode), True)
if func is not None:
self.album_template_fields[key] = func

View file

@ -31,8 +31,9 @@ Changelog
Thanks to jayme on GitHub.
* :doc:`/plugins/lyrics`: Lyrics searches should now turn up more results due
to some fixes in dealing with special characters.
* Plugins can now provide fields for both Album and Item templates. Thanks
to Pedro Silva.
* Plugins can now provide fields for both Album and Item templates, thanks
to Pedro Silva. Accordingly, the :doc:`/plugins/inline` can also now define
album fields.
* The :ref:`fields-cmd` command shows template fields provided by plugins.
Thanks again to Pedro Silva.
* Album art filenames now respect the :ref:`replace` configuration.

View file

@ -31,6 +31,10 @@ referenced in path templates like so::
paths:
default: $initial/$artist/$album%aunique{}/$disc_and_track $title
Function Fields
---------------
If you need to use statements like ``import``, you can write a Python function
body instead of a single expression. In this case, you'll need to ``return``
a result for the value of the path field, like so::
@ -43,3 +47,22 @@ a result for the value of the path field, like so::
You might want to use the YAML syntax for "block literals," in which a leading
``|`` character indicates a multi-line block of text.
Album Fields
------------
The above examples define fields for *item* templates, but you can also define
fields for *album* templates. Use the ``album_fields`` configuration section.
In this context, all existing album fields are available as variables along
with ``items``, which is a list of items in the album.
This example defines a ``$bitrate`` field for albums as the average of the
tracks' fields::
album_fields:
bitrate: |
total = 0
for item in items:
total += item.bitrate
return total / len(items)