From b278db42be42bb90b43f816dfc5c6390ed13a753 Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Mon, 25 Aug 2014 23:47:16 +0200 Subject: [PATCH] info: print library fields and sort output --- beetsplug/info.py | 105 ++++++++++++++++++++++++++------------------- docs/changelog.rst | 3 +- test/helper.py | 4 +- 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/beetsplug/info.py b/beetsplug/info.py index 3bd1a10fe..b6876a0a1 100644 --- a/beetsplug/info.py +++ b/beetsplug/info.py @@ -21,42 +21,30 @@ from beets.plugins import BeetsPlugin from beets import ui from beets import mediafile from beets import util +from beets.util import displayable_path def run(lib, opts, args): - """Print tag info for each file referenced by args. + """Print tag info or library data for each file referenced by args. Main entry point for the `beet info ARGS...` command. + """ + if opts.library: + print_library_info(lib, args) + else: + print_tag_info(lib, args) + +def print_tag_info(lib, args): + """Print tag info for each file referenced by args. 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: @@ -64,34 +52,63 @@ def parse_args(args): paths.append(util.normpath(arg)) else: query.append(arg) - return paths, query + + if query: + for item in lib.items(query): + paths.append(item.path) + + first = True + for path in paths: + if not first: + ui.print_() + try: + data = tag_data(path) + except mediafile.UnreadableFileError: + ui.print_('cannot read file: {0}'.format( + util.displayable_path(path) + )) + else: + print_data(path, data) + first = False -def print_tags(path): - # Set up fields to output. +def print_library_info(lib, queries): + """Print library data for each item matching all queries + """ + first = True + for item in lib.items(queries): + if not first: + ui.print_() + print_data(item.path, library_data(item)) + first = False + + +def tag_data(path): fields = list(mediafile.MediaFile.readable_fields()) - fields.remove('art') fields.remove('images') + mf = mediafile.MediaFile(path) + tags = {} + for field in fields: + tags[field] = getattr(mf, field) + tags['art'] = mf.art is not None + return tags - # Line format. - other_fields = ['album art'] - maxwidth = max(len(name) for name in fields + other_fields) + +def library_data(item): + return dict(item.formatted()) + + +def print_data(path, data): + maxwidth = max(len(key) for key in data) lineformat = u'{{0:>{0}}}: {{1}}'.format(maxwidth) - ui.print_(path) - try: - mf = mediafile.MediaFile(path) - except mediafile.UnreadableFileError: - ui.print_('cannot read file: {0}'.format( - util.displayable_path(path) - )) - return + ui.print_(displayable_path(path)) - # 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)) + for field in sorted(data): + value = data[field] + if isinstance(value, list): + value = u'; '.join(value) + ui.print_(lineformat.format(field, value)) class InfoPlugin(BeetsPlugin): @@ -99,4 +116,6 @@ class InfoPlugin(BeetsPlugin): def commands(self): cmd = ui.Subcommand('info', help='show file metadata') cmd.func = run + cmd.parser.add_option('-l', '--library', action='store_true', + help='show library fields instead of tags') return [cmd] diff --git a/docs/changelog.rst b/docs/changelog.rst index 5b7802cab..dd0958476 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,7 +7,8 @@ Changelog This release adds **sorting** to beets queries. See :ref:`query-sort`. Features: -* :doc:`/plugins/info`: Files can be specified through library queries. +* :doc:`/plugins/info`: Files can be specified through library queries + and the `--library` option prints library fields instead of tags. Fixes: diff --git a/test/helper.py b/test/helper.py index 2e7732ede..d8b86b8c0 100644 --- a/test/helper.py +++ b/test/helper.py @@ -237,8 +237,8 @@ class TestHelper(object): path = os.path.join(_common.RSRC, 'full.' + ext) for i in range(count): item = Item.from_path(str(path)) - item.album = u'\xc3\xa4lbum {0}'.format(i) # Check unicode paths - item.title = u't\xc3\x8ftle {0}'.format(i) + item.album = u'\u00e4lbum {0}'.format(i) # Check unicode paths + item.title = u't\u00eftle {0}'.format(i) item.add(self.lib) item.move(copy=True) item.store()