import argparse import re import typing import symuid def _walk_track_attrs(path, path_ignore_regex) -> typing.Iterator[dict]: for track in symuid.Track.walk(path, path_ignore_regex): yield { "path": track.path, "comment": track.comment, "play_count": track.get_play_count_sum(), } def _init_argparser(): argparser = argparse.ArgumentParser(description="filter & sort tracks") argparser.add_argument("path") argparser.add_argument( "--path-ignore-regex", default=symuid.Track.PATH_DEFAULT_IGNORE_REGEX, dest="path_ignore_regex", nargs=1, type=re.compile, metavar="pattern", help="(default: %(default)s)", ) argparser.add_argument( "--filter", metavar="expression", dest="filter_expression", help="(example: {!r} or {!r})".format( "play_count > 16 and path.endswith('.mp3')", "comment is None or len(comment) < 16", ), ) argparser.add_argument( "--sort", metavar="expression", dest="sort_expression", help="(example: {!r} or {!r})".format( "play_count * -1", "(play_count, len(path))", ), ) argparser.add_argument( "--limit", type=int, help="(default: none)", ) argparser.add_argument( "--prefix", type=str, default="", help="add prefix to each resulting path (default: %(default)r)", ) return argparser def _main(): args = _init_argparser().parse_args() # use generators until sort is required track_attrs = _walk_track_attrs( path=args.path, path_ignore_regex=args.path_ignore_regex ) # pylint: disable=eval-used if args.filter_expression: track_attrs = filter(lambda a: eval(args.filter_expression, a), track_attrs) if args.sort_expression: track_attrs = sorted(track_attrs, key=lambda a: eval(args.sort_expression, a)) for track_index, attr in enumerate(track_attrs): if args.limit and track_index == args.limit: break print(args.prefix + attr["path"])