#62: simplify list (and random) code

With the new centralized print_obj function, we can greatly simplify the code
for the list command. This necessitated a couple of additional tweaks:

- For performance reasons, print_obj can now take a compiled template. (There's
  still an issue with using the default/configured template, but we can cross
  that bridge later).
- When listing albums, $path now expands to the album's item dir. So the format
  string '$path' now exactly corresponds to passing the -p switch.

As an added bonus, we can now also reduce copypasta in the random plugin (which
behaves almost exactly the same as list).
This commit is contained in:
Adrian Sampson 2012-10-20 21:10:39 -07:00
parent 2770b7d6fc
commit 91ad913399
5 changed files with 26 additions and 38 deletions

View file

@ -1600,6 +1600,7 @@ class Album(BaseAlbum):
mapping[key] = getattr(self, key)
mapping['artpath'] = displayable_path(mapping['artpath'])
mapping['path'] = displayable_path(self.item_dir())
# Get template functions.
funcs = DefaultTemplateFunctions().functions()

View file

@ -539,7 +539,10 @@ def print_obj(obj, lib, config, fmt=None):
album = isinstance(obj, library.Album)
if not fmt:
fmt = _pick_format(config, album=album)
template = Template(fmt)
if isinstance(fmt, Template):
template = fmt
else:
template = Template(fmt)
if album:
print_(obj.evaluate_template(template))
else:

View file

@ -810,25 +810,17 @@ default_commands.append(import_cmd)
# list: Query and show library contents.
def list_items(lib, query, album, path, fmt):
def list_items(lib, query, album, fmt, config):
"""Print out items in lib matching query. If album, then search for
albums instead of single items. If path, print the matched objects'
paths instead of human-readable information about them.
albums instead of single items.
"""
template = Template(fmt)
tmpl = Template(fmt) if fmt else None
if album:
for album in lib.albums(query):
if path:
print_(album.item_dir())
elif fmt is not None:
print_(album.evaluate_template(template))
ui.print_obj(album, lib, config, tmpl)
else:
for item in lib.items(query):
if path:
print_(item.path)
elif fmt is not None:
print_(item.evaluate_template(template, lib))
ui.print_obj(item, lib, config, tmpl)
list_cmd = ui.Subcommand('list', help='query the library', aliases=('ls',))
list_cmd.parser.add_option('-a', '--album', action='store_true',
@ -838,8 +830,11 @@ list_cmd.parser.add_option('-p', '--path', action='store_true',
list_cmd.parser.add_option('-f', '--format', action='store',
help='print with custom format', default=None)
def list_func(lib, config, opts, args):
fmt = ui._pick_format(config, opts.album, opts.format)
list_items(lib, decargs(args), opts.album, opts.path, fmt)
if opts.path:
fmt = '$path'
else:
fmt = opts.format
list_items(lib, decargs(args), opts.album, fmt, config)
list_cmd.func = list_func
default_commands.append(list_cmd)

View file

@ -15,22 +15,17 @@
"""Get a random song or album from the library.
"""
from beets.plugins import BeetsPlugin
from beets.ui import Subcommand, decargs, print_
from beets.ui import Subcommand, decargs, print_obj
from beets.util.functemplate import Template
import random
def random_item(lib, config, opts, args):
query = decargs(args)
path = opts.path
fmt = opts.format
if fmt is None:
# If no specific template is supplied, use a default
if opts.album:
fmt = u'$albumartist - $album'
else:
fmt = u'$artist - $album - $title'
template = Template(fmt)
if opts.path:
fmt = '$path'
else:
fmt = opts.format
template = Template(fmt) if fmt else None
if opts.album:
objs = list(lib.albums(query=query))
@ -41,16 +36,10 @@ def random_item(lib, config, opts, args):
if opts.album:
for album in objs:
if path:
print_(album.item_dir())
else:
print_(album.evaluate_template(template))
print_obj(album, lib, config, template)
else:
for item in objs:
if path:
print_(item.path)
else:
print_(item.evaluate_template(template, lib))
for item in objs:
print_obj(item, lib, config, template)
random_cmd = Subcommand('random',
help='chose a random track or album')

View file

@ -25,8 +25,8 @@ Changelog
tags and ID3 tags, the ID3 tags are now also removed.
* :ref:`stats-cmd` command: New ``--exact`` switch to make the file size
calculation more accurate (thanks to Jakob Schnitzer).
* :ref:`list-cmd` command: Templates given with ``-f`` can now show items' paths
(using ``$path``).
* :ref:`list-cmd` command: Templates given with ``-f`` can now show items' and
albums' paths (using ``$path``).
* The output of the :ref:`update-cmd`, :ref:`remove-cmd`, and :ref:`modify-cmd`
commands now respects the :ref:`list_format_album` and
:ref:`list_format_item` config options. Thanks to Mike Kazantsev.