mirror of
https://github.com/beetbox/beets.git
synced 2025-12-26 02:24:33 +01:00
info: Specify files through library query
This commit is contained in:
parent
8017b062fe
commit
a9f839bbf8
3 changed files with 69 additions and 34 deletions
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue