info: Specify files through library query

This commit is contained in:
Thomas Scholtes 2014-08-25 22:59:38 +02:00
parent 8017b062fe
commit a9f839bbf8
3 changed files with 69 additions and 34 deletions

View file

@ -23,7 +23,51 @@ from beets import mediafile
from beets import util
def info(paths):
def run(lib, opts, args):
"""Print tag info for each file referenced by args.
Main entry point for the `beet info ARGS...` command.
If an argument is a path pointing to an existing file, then the tags
of that file are printed. All other arguments are considered
queries, and for each item matching all those queries the tags from
the file are printed.
"""
paths, query = parse_args(args)
first = True
for path in paths:
if not first:
ui.print_()
print_tags(path)
first = False
if not query:
return
for item in lib.items(*query):
if not first:
ui.print_()
print_tags(item.path)
first = False
def parse_args(args):
"""Split `args` into a tuple of paths and querys.
"""
if not args:
raise ui.UserError('no file specified')
paths = []
query = []
for arg in args:
if os.sep in arg and os.path.exists(arg):
paths.append(util.normpath(arg))
else:
query.append(arg)
return paths, query
def print_tags(path):
# Set up fields to output.
fields = list(mediafile.MediaFile.readable_fields())
fields.remove('art')
@ -34,43 +78,25 @@ def info(paths):
maxwidth = max(len(name) for name in fields + other_fields)
lineformat = u'{{0:>{0}}}: {{1}}'.format(maxwidth)
first = True
for path in paths:
if not first:
ui.print_()
ui.print_(path)
try:
mf = mediafile.MediaFile(path)
except mediafile.UnreadableFileError:
ui.print_('cannot read file: {0}'.format(
util.displayable_path(path)
))
return
path = util.normpath(path)
if not os.path.isfile(path):
ui.print_(u'not a file: {0}'.format(
util.displayable_path(path)
))
continue
ui.print_(path)
try:
mf = mediafile.MediaFile(path)
except mediafile.UnreadableFileError:
ui.print_('cannot read file: {0}'.format(
util.displayable_path(path)
))
continue
# Basic fields.
for name in fields:
ui.print_(lineformat.format(name, getattr(mf, name)))
# Extra stuff.
ui.print_(lineformat.format('album art', mf.art is not None))
first = False
# Basic fields.
for name in fields:
ui.print_(lineformat.format(name, getattr(mf, name)))
# Extra stuff.
ui.print_(lineformat.format('album art', mf.art is not None))
class InfoPlugin(BeetsPlugin):
def commands(self):
cmd = ui.Subcommand('info', help='show file metadata')
def func(lib, opts, args):
if not args:
raise ui.UserError('no file specified')
info(args)
cmd.func = func
cmd.func = run
return [cmd]

View file

@ -6,6 +6,9 @@ Changelog
This release adds **sorting** to beets queries. See :ref:`query-sort`.
Features:
* :doc:`/plugins/info`: Files can be specified through library queries.
Fixes:
* Invalid state files don't crash the importer.

View file

@ -80,12 +80,13 @@ def capture_stdout():
'spam'
"""
org = sys.stdout
sys.stdout = StringIO()
sys.stdout = capture = StringIO()
sys.stdout.encoding = 'utf8'
try:
yield sys.stdout
finally:
sys.stdout = org
print(capture.getvalue())
def has_program(cmd, args=['--version']):
@ -289,6 +290,11 @@ class TestHelper(object):
lib = Library(':memory:')
beets.ui._raw_main(list(args), lib)
def run_with_output(self, *args):
with capture_stdout() as out:
self.run_command(*args)
return out.getvalue()
def create_temp_dir(self):
"""Create a temporary directory and assign it into
`self.temp_dir`. Call `remove_temp_dir` later to delete it.