def parser(): parser = ArgParser(description='DBCache Manager') list_parser = parser.add_subparser( 'action', 'list', help='List items in the given cache file') list_parser.add_argument('path', help='Path to a DBCache file') del_parser = parser.add_subparser( 'action', 'delete', help='Delete items from the given cache file') del_parser.add_argument('path', help='Path to a DBCache file') del_parser.add_argument( 'patterns', nargs='+', help= 'One or more glob/fnmatch patterns to match against keys to be deleted' ) get_parser = parser.add_subparser( 'action', 'get', help='View information about an entry in the given cache file') get_parser.add_argument('path', help='Path to a DBCache file') get_parser.add_argument('key', help='Key to retrieve') parser.include_common_args('verbosity', 'dry_run') return parser
def parser(): parser = ArgParser(description='UEXP Audio Converter') parser.add_argument('path', nargs='+', help='Path to the .uexp file to convert') parser.add_argument( '--output', '-o', metavar='PATH', help='Output directory (default: same as input directory)') parser.add_argument( '--wav_output', '-w', metavar='PATH', help='WAV output directory (default: same as input directory)') parser.add_argument( '--flac_output', '-f', metavar='PATH', help='FLAC output directory (default: same as input directory)') parser.add_argument( '--mp3_output', '-m', metavar='PATH', help='MP3 output directory (default: same as input directory)') parser.add_argument('--mp3', '-M', action='store_true', help='Convert to MP3 in addition to FLAC') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='Nest Thermostat Flask') parser.add_argument('--use_hostname', '-u', action='store_true', help='Use hostname instead of localhost/127.0.0.1') parser.add_argument('--port', '-p', type=int, default=10000, help='Port to use') parser.add_common_arg('--config', '-c', metavar='PATH', default=DEFAULT_CONFIG_PATH, help='Config file location') parser.add_common_arg( '--reauth', '-A', action='store_true', help='Force re-authentication, even if a cached session exists') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser( description= 'Utility to check passwords against the list from haveibeenpwned.com') parser.add_argument( '--pw_list_path', '-p', metavar='PATH', default=LIST_PATH, help= 'Path to the file that contains the hashed password list (default: %(default)s)' ) src_group = parser.add_mutually_exclusive_group() src_group.add_argument('--from_file', '-f', metavar='PATH', help='Path to a KeePass csv file to check') src_group.add_argument( '--non_confidential', '-C', nargs='+', help='One or more non-confidential passwords to test') parser.include_common_args('verbosity', 'dry_run') return parser
def get_dynamic_parser(): parser = ArgParser() find_parser = parser.add_subparser('action', 'find') find_parser.add_argument('obj_type', choices=('a', 'b')) find_parser.add_argument('title', nargs='*', default=None) find_parser.add_argument('query', nargs=REMAINDER) parser.include_common_args('verbosity', 'dry_run') return parser
def parser(): parser = ArgParser( description= 'Utility to control monitors via DDC. Only Windows is currently supported.' ) list_parser = parser.add_subparser('action', 'list', 'List monitors') list_opts = list_parser.add_mutually_exclusive_group() list_opts.add_argument('--capabilities', '-c', action='store_true', help='Show capabilities') list_opts.add_argument( '--feature', '-f', help='Show the value for the given feature for each monitor') get_parser = parser.add_subparser('action', 'get', 'Get a VCP feature value') get_parser.add_argument( 'monitor', help= 'The ID/index of the monitor for which the feature should be retrieved' ) get_parser.add_argument('feature', help='The feature to get') set_parser = parser.add_subparser('action', 'set', 'Set a VCP feature') set_parser.add_argument( 'monitor', help= 'The ID/index of the monitor on which the feature should be set, or ALL to set it for all monitors' ) set_parser.add_argument('feature', help='The feature to set') set_parser.add_argument('value', help='The hex value to use') cap_parser = parser.add_subparser('action', 'capabilities', 'Show monitor capabilities') cap_parser.add_argument( 'monitor', nargs='*', help='The ID/index(es) of the monitor(s) to show (default: all)') cap_parser.add_argument( '--feature', '-f', nargs='*', help='One or more features to display (default: all supported)') off_parser = parser.add_subparser('action', 'turn_off', 'Turn off the specified monitors') off_parser.add_argument( 'monitor', nargs='*', help= 'The ID pattern(s) / index(es) of the monitor(s) to show (default: all)' ) parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='Extract and cleanup album zips') parser.add_argument('path', help='Directory to process') parser.add_argument('--old_mode', '-o', action='store_true', help='Use the old extraction mode') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='Sort TV show episodes') parser.add_argument('src_path', help='Source directory') parser.add_argument('dst_path', help='Target directory') parser.add_argument('--rm', '-r', action='store_true', help='Remove files after copying') parser.add_argument('--no-refresh', '-F', dest='refresh', action='store_false', help='Do not check for newly added files in src_path after copying existing files') parser.add_argument('--show-dests', '-S', action='store_true', help='Show show destination paths instead of copying any files') parser.add_argument('--buf_size', '-b', type=int, help='Copy buffer size (default: usually ~8MB)') parser.include_common_args('verbosity', 'dry_run') return parser
def parser(): parser = ArgParser(description='Merge 2 or more PDFs') parser.add_argument( 'path', nargs='+', help='Two or more paths of PDF files to merge in the order provided') parser.add_argument('--output', '-o', metavar='PATH', help='Output file name', required=True) parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser( description='Nier Replicant ver.1.22474487139... Save File Watcher') parser.add_argument('--path', '-p', help='Save file path to watch') parser.add_argument( '--backups', '-b', metavar='PATH', help= 'Path to the directory in which backups should be saved (default: same dir as save files)' ) parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='Extract and cleanup album zips') parser.add_argument('--people', '-p', type=int, default=5, help='Number of people to simulate') parser.add_argument('--slices', '-s', type=int, default=8, help='Number of slices per pizza') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='File Backup Tool') parser.add_argument('source', metavar='PATH', help='The file to backup') parser.add_argument('dest_dir', metavar='PATH', help='The directory in which backups should be stored') opt_group = parser.add_argument_group('Behavior Options') opt_group.add_argument( '--always', '-a', action='store_true', help='Always make a backup, even if the source file has not changed') parser.include_common_args('verbosity', 'dry_run') return parser
def parser(): parser = ArgParser(description='View hex data as unpacked structs') parser.add_argument('data', nargs='+', help='A hex string') parser.add_argument( '--offset', '-o', type=int, default=0, help= 'Offset from the beginning of the data in bytes to start struct matching' ) parser.add_argument('--endian', '-e', choices=('big', 'little', 'native'), help='Interpret values with the given endianness') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser( description='Download and merge split videos in a M3U8 playlist') parser.add_argument( 'source', help='URL that provides stream info or path to a .m3u8 file') parser.add_argument( '--name', '-n', help='The name of the video being downloaded (without extension)', required=True) parser.add_argument('--save_dir', '-d', default='~/Downloads/m3u8/', help='Directory to store downloads') parser.add_argument( '--local', '-l', action='store_true', help='Specify if the target ts part files already exist') parser.add_argument('--format', '-f', default='mp4', choices=('mp4', 'mkv'), help='Video format (default: %(default)s)') parser.add_argument('--goplay', '-g', action='store_true', help='The info url is a goplay.anontpp.com dl code') parser.add_argument( '--ffmpeg_dl', '-F', action='store_true', help= 'Have ffmpeg process the m3u8 and download the video parts instead (slower & more error prone)' ) parser.add_common_arg('--debug', '-D', action='store_true', help='Enable HTTP debugging') parser.include_common_args('verbosity', parallel=4) return parser
def parser(): # fmt: off parser = ArgParser(description='Music Manager GUI') with parser.add_subparser('action', 'open', help='Open directly to the Album view for the given path') as open_parser: open_parser.add_argument('album_path', help='The path to the album to open') with parser.add_subparser('action', 'clean', help='Open directly to the Clean view for the given path') as clean_parser: clean_parser.add_argument('path', nargs='+', help='The directory containing files to clean') wait_group = clean_parser.add_argument_group('Wait Options').add_mutually_exclusive_group() wait_group.add_argument('--multi_instance_wait', '-w', type=int, default=1, help='Seconds to wait for multiple instances started at the same time to collaborate on paths') wait_group.add_argument('--no_wait', '-W', action='store_true', help='Do not wait for other instances') with parser.add_subparser('action', 'configure', help='Configure registry entries for right-click actions') as config_parser: config_parser.include_common_args('dry_run') parser.include_common_args('verbosity') parser.add_common_arg('--match_log', action='store_true', help='Enable debug logging for the album match processing logger') # fmt: on return parser
def get_exclusive_set_parser(subparser=False): parser = ArgParser() _parser = parser.add_subparser('action', 'test') if subparser else parser group_1 = _parser.add_argument_group('Group 1') group_1.add_argument('--one', '-o') group_1.add_argument('--two', '-t') group_2 = _parser.add_argument_group('Group 2') group_2.add_argument('--three', '-T', type=int, default=3) group_2.add_argument('--four', '-f', action='store_true') # group_3 = _parser.add_argument_group('Group 3') # group_3.add_argument('--five', '-F', required=True) # If another group is chosen, then this will cause an issue # group_3.add_argument('--six', '-s', action='store_true') parser.add_mutually_exclusive_arg_sets(group_1, group_2) # parser.add_mutually_exclusive_arg_sets(group_1, group_2, group_3) parser.include_common_args('verbosity') return parser
def parser(): # fmt: off parser = ArgParser(description='Compare images') parser.add_argument('path_a', help='Path to an image file') parser.add_argument('path_b', help='Path to an image file') parser.add_argument( '--no_gray', '-G', dest='gray', action='store_false', help='Do not normalize images to grayscale before comparisons') parser.add_argument( '--no_normalize', '-N', dest='normalize', action='store_false', help= 'Do not normalize images for exposure differences before comparisons') parser.add_argument( '--max_width', '-W', type=int, help='Resize images that have a width greater than this value') parser.add_argument( '--max_height', '-H', type=int, help='Resize images that have a height greater than this value') parser.add_argument('--compare_as', '-c', choices=('jpeg', 'png'), default='jpeg', help='The image format to use for the comparison') parser.add_argument( '--same', '-s', action='store_true', help='Include comparisons intended for images that are the same') parser.include_common_args('verbosity') # fmt: on return parser
def parser(): parser = ArgParser(description='Download YouTube videos') dl_parser = parser.add_subparser('action', 'dl', 'Download a video from YouTube') dl_parser.add_argument('url', metavar='URL', help='The name URL of the video to download') dl_parser.add_argument('--save_dir', '-d', metavar='PATH', default='~/Downloads/youtube/', help='Directory to store downloads') # dl_parser.add_argument('--resolution', '-r', default='1080p', help='Video resolution (default: %(default)s)') dl_parser.add_argument('--extension', '-e', default='mp4', help='Video extension') list_parser = parser.add_subparser( 'action', 'list', 'List available parts for the given YouTube video') list_parser.add_argument('url', help='The name URL of the video to download') audio_parser = parser.add_subparser('action', 'audio', 'Download audio from YouTube') audio_parser.add_argument('url', help='The name URL of the video to download') audio_parser.add_argument('--save_dir', '-d', default='~/Downloads/youtube/', help='Directory to store downloads') audio_parser.add_argument( '--extension', '-e', help='File extension (default: based on mime type)') parser.include_common_args('verbosity') return parser
def main(): parser = ArgParser('Lyric Fetcher Flask Server') parser.add_argument('--use_hostname', '-u', action='store_true', help='Use hostname instead of localhost/127.0.0.1') parser.add_argument('--port', '-p', type=int, default=10000, help='Port to use') parser.include_common_args('verbosity') args = parser.parse_args() init_logging(None, args.verbose or 2) host = socket.gethostname() if args.use_hostname else None if platform.system() == 'Windows': from ds_tools.flasks.socketio_server import SocketIOServer as Server else: from ds_tools.flasks.gunicorn_server import GunicornServer as Server server = Server(app, args.port, host, blueprints=[blueprint]) server.start_server()
def parser(): parser = ArgParser(description='Tool for managing Windows scheduled tasks') with parser.add_subparser('action', 'list', help='List all scheduled tasks') as list_parser: list_parser.add_argument('path', nargs='?', help='The location of the tasks to list') list_parser.add_argument('--format', '-f', choices=Printer.formats, default='pseudo-json', help='') list_parser.add_argument('--recursive', '-r', action='store_true', help='Recursively iterate through sub-paths') list_transform_opts = list_parser.add_argument_group( 'Transform Options').add_mutually_exclusive_group() list_transform_opts.add_argument('--summarize', '-s', action='store_true', help='Summarize task info') list_transform_opts.add_argument('--triggers', '-t', action='store_true', help='Only show tasks\' triggers') list_transform_opts.add_argument( '--raw_xml', '-X', action='store_true', help= 'Show task\'s raw XML data instead of processing COM properties') with parser.add_subparser( 'action', 'table', help='Show a table of scheduled tasks and their actions' ) as table_parser: table_parser.add_argument('path', nargs='?', help='The location of the tasks to list') table_parser.add_argument('--recursive', '-r', action='store_true', help='Recursively iterate through sub-paths') table_parser.add_argument('--times', '-t', action='store_true', help='Show the last and next run times') table_parser.add_argument('--hide_actions', '-A', action='store_true', help='Hide actions') table_parser.add_argument( '--with_trigger', '-T', action='store_true', help='Only include tasks with active (enabled) triggers') with parser.add_subparser('action', 'create', help='Create a new task') as create_parser: create_parser.add_argument('path', help='The location + name for the new task') create_parser.add_argument('--schedule', '-s', help='Cron schedule to use', required=True) create_parser.add_argument('--command', '-c', help='The command to run', required=True) create_parser.add_argument('--args', '-a', help='Arguments to pass to the command') create_parser.add_argument( '--update', '-u', action='store_true', help='Allow an existing scheduled task to be updated') parser.include_common_args('verbosity') return parser
def parser(): # fmt: off parser = ArgParser(description='Music Manager') # region File Actions with parser.add_subparser('action', 'show', help='Show song/tag information') as show_parser: for name, help_text in SHOW_ARGS.items(): with show_parser.add_subparser('sub_action', name, help=help_text) as _parser: _parser.add_argument( 'path', nargs='*', default=['.'], help= 'Paths for music files or directories containing music files' ) if name in ('info', 'unique', 'table'): _parser.add_argument('--tags', '-t', nargs='+', help='The tags to display', required=(name == 'unique')) if name == 'info': _parser.add_argument('--no_trim', '-T', action='store_true', help='Do not trim tag IDs') if name == 'processed': _parser.add_argument( '--expand', '-x', action='count', default=0, help= 'Expand entities with a lot of nested info (may be specified multiple times to increase expansion level)' ) _parser.add_argument( '--only_errors', '-E', action='store_true', help='Only print entries with processing errors') with parser.add_subparser( 'action', 'path2tag', help='Update tags based on the path to each file') as p2t_parser: p2t_parser.add_argument( 'path', nargs='+', help= 'One or more paths of music files or directories containing music files' ) p2t_parser.add_argument('--title', '-t', action='store_true', help='Update title based on filename') p2t_parser.add_argument('--yes', '-y', action='store_true', help='Skip confirmation prompts') with parser.add_subparser( 'action', 'update', help= 'Set the value of the given tag on all music files in the given path' ) as set_parser: set_parser.add_argument( 'path', nargs='+', help= 'One or more paths of music files or directories containing music files' ) set_parser.add_argument( '--no_album_move', '-M', action='store_true', help='Do not rename the album directory (only applies to --load/-L)' ) set_parser.add_argument( '--replace_genre', '-G', action='store_true', help='Replace genre instead of combining genres') set_from_file = set_parser.add_argument_group( 'Load File Options', 'Options for loading updates from a file - may notbe combined with arguments from other option groups' ) set_from_file.add_argument( '--load', '-L', metavar='PATH', help= 'Load updates from a json file (may not be combined with other options)' ) set_from_file.add_argument( '--destination', '-d', metavar='PATH', help= f'Destination base directory for sorted files (default: {DEFAULT_DEST_DIR})' ) set_from_args = set_parser.add_argument_group('Tag Update Options') set_from_args.add_argument('--tag', '-t', nargs='+', help='Tag ID(s) to modify (required)') set_from_args.add_argument( '--value', '-V', help='Value to replace existing values with (required)') set_from_args.add_argument( '--replace', '-r', nargs='+', help= 'If specified, only replace tag values that match the given patterns(s)' ) set_from_args.add_argument( '--partial', '-p', action='store_true', help= 'Update only parts of tags that match a pattern specified via --replace/-r' ) set_parser.add_mutually_exclusive_arg_sets(set_from_file, set_from_args) with parser.add_subparser( 'action', 'clean', help='Clean undesirable tags from the specified files' ) as clean_parser: clean_parser.add_argument( 'path', nargs='+', help= 'One or more paths of music files or directories containing music files' ) bpm_group = clean_parser.add_mutually_exclusive_group() bpm_group.add_argument( '--bpm', '-b', action='store_true', default=None, help= 'Add a BPM tag if it is not already present (default: True if aubio is installed)' ) bpm_group.add_argument( '--no_bpm', '-B', dest='bpm', action='store_false', help='Do not add a BPM tag if it is not already present') with parser.add_subparser( 'action', 'remove', help='Remove the specified tags from the specified files' ) as rm_parser: rm_parser.add_argument( 'path', nargs='+', help= 'One or more paths of music files or directories containing music files' ) rm_group = rm_parser.add_mutually_exclusive_group() rm_group.add_argument('--tag', '-t', nargs='+', help='Tag ID(s) to remove') rm_group.add_argument('--all', '-A', action='store_true', help='Remove ALL tags') with parser.add_subparser( 'action', 'bpm', help='Add BPM info to the specified files') as bpm_parser: bpm_parser.add_argument( 'path', nargs='+', help= 'One or more paths of music files or directories containing music files' ) bpm_parser.include_common_args(parallel=4) # bpm_parser.add_argument('--parallel', '-P', type=int, default=1, help='Maximum number of workers to use in parallel (default: %(default)s)')) with parser.add_subparser( 'action', 'dump', help='Dump tag info about the specified files to json' ) as dump_parser: dump_parser.add_argument( 'path', help='A path for a music file or a directory containing music files' ) dump_parser.add_argument('output', help='The destination file path') dump_parser.add_argument( '--title_case', '-T', action='store_true', help= 'Fix track and album names to use Title Case when they are all caps' ) with parser.add_subparser('action', 'cover', help='Extract or add cover art') as cover_parser: cover_parser.add_argument( 'path', help='A path for a music file or a directory containing music files' ) dump_cover_group = cover_parser.add_argument_group( 'Save Cover Options') dump_cover_group.add_argument( '--save', '-s', metavar='PATH', help='Path to save the cover images from the specified file(s)') load_cover_group = cover_parser.add_argument_group( 'Load Cover Options') load_cover_group.add_argument('--load', '-L', metavar='PATH', help='Path to an image file') load_cover_group.add_argument( '--max_width', '-w', type=int, default=1200, help='Resize the provided image if it is larger than this value') del_cover_group = cover_parser.add_argument_group('Save Cover Options') del_cover_group.add_argument('--remove', '-R', action='store_true', help='Remove all cover images') cover_parser.add_mutually_exclusive_arg_sets(dump_cover_group, load_cover_group, del_cover_group) # endregion with parser.add_subparser( 'action', 'wiki', help='Wiki matching / informational functions') as wiki_parser: with wiki_parser.add_subparser( 'sub_action', 'pprint', help='Pretty-print the parsed page content') as pp_parser: pp_parser.add_argument('url', help='A wiki entity URL') pp_parser.add_argument('--mode', '-m', choices=('content', 'processed', 'reprs', 'headers', 'raw'), default='content', help='Pprint mode (default: %(default)s)') with wiki_parser.add_subparser( 'sub_action', 'raw', help='Print the raw page content') as ppr_parser: ppr_parser.add_argument('url', help='A wiki entity URL') with wiki_parser.add_subparser( 'sub_action', 'show', help='Show info about the entity with the given URL' ) as ws_parser: ws_parser.add_argument('identifier', help='A wiki URL or title/name') ws_parser.add_argument( '--expand', '-x', action='count', default=0, help= 'Expand entities with a lot of nested info (may be specified multiple times to increase expansion level)' ) ws_parser.add_argument( '--limit', '-L', type=int, default=0, help= 'Maximum number of discography entry parts to show for a given album (default: unlimited)' ) ws_parser.add_argument( '--types', '-t', nargs='+', help= 'Filter albums to only those that match the specified types') ws_parser.add_argument( '--type', '-T', help= 'An EntertainmentEntity subclass to require that the given page matches' ) with wiki_parser.add_subparser( 'sub_action', 'update', help='Update tracks in the given path(s) based on wiki info' ) as upd_parser: upd_parser.add_argument( 'path', nargs='+', help= 'One or more paths of music files or directories containing music files' ) upd_parser.add_argument( '--destination', '-d', metavar='PATH', default=DEFAULT_DEST_DIR, help= 'Destination base directory for sorted files (default: %(default)s)' ) upd_parser.add_argument( '--url', '-u', help= 'A wiki URL (can only specify one file/directory when providing a URL)' ) upd_parser.add_argument( '--soloist', '-S', action='store_true', help= 'For solo artists, use only their name instead of including their group, and do not sort them with their group' ) upd_parser.add_argument( '--collab_mode', '-c', choices=('title', 'artist', 'both'), default='artist', help= 'List collaborators in the artist tag, the title tag, or both (default: %(default)s)' ) upd_parser.add_argument( '--hide_edition', '-E', action='store_true', help= 'Exclude the edition from the album title, if present (default: include it)' ) upd_parser.add_argument( '--title_case', '-T', action='store_true', help= 'Fix track and album names to use Title Case when they are all caps' ) upd_parser.add_argument( '--artist', '-a', metavar='URL', help= 'Force the use of the given artist instead of an automatically discovered one' ) upd_parser.add_argument( '--update_cover', '-C', action='store_true', help= 'Update the cover art for the album if it does not match an image in the matched wiki page' ) upd_parser.add_argument('--no_album_move', '-M', action='store_true', help='Do not rename the album directory') upd_parser.add_argument( '--artist_only', '-I', action='store_true', help= 'Only match the artist / only use the artist URL if provided') upd_parser.add_argument( '--replace_genre', '-G', action='store_true', help='Replace genre instead of combining genres') upd_sites = upd_parser.add_argument_group( 'Site Options').add_mutually_exclusive_group() upd_sites.add_argument('--sites', '-s', nargs='+', default=None, help='The wiki sites to search') upd_sites.add_argument('--all', '-A', action='store_const', const=ALL_SITES, dest='sites', help='Search all sites') upd_sites.add_argument('--ost', '-O', action='store_const', const=['wiki.d-addicts.com'], dest='sites', help='Search only wiki.d-addicts.com') bpm_group = upd_parser.add_argument_group( 'BPM Options').add_mutually_exclusive_group() bpm_group.add_argument( '--bpm', '-b', action='store_true', default=None, help= 'Add a BPM tag if it is not already present (default: True if aubio is installed)' ) bpm_group.add_argument( '--no_bpm', '-B', dest='bpm', action='store_false', help='Do not add a BPM tag if it is not already present') upd_data = upd_parser.add_argument_group( 'Track Data Options').add_mutually_exclusive_group() upd_data.add_argument( '--dump', '-P', metavar='PATH', help= 'Dump track updates to a json file instead of updating the tracks' ) upd_data.add_argument( '--load', '-L', metavar='PATH', help= 'Load track updates from a json file instead of from a wiki') with wiki_parser.add_subparser( 'sub_action', 'match', help='Match tracks in the given path(s) with wiki info' ) as match_parser: match_parser.add_argument( 'path', nargs='+', help= 'One or more paths of music files or directories containing music files' ) with wiki_parser.add_subparser( 'sub_action', 'test', help= 'Test matching of tracks in a given path with a given wiki URL' ) as test_parser: test_parser.add_argument( 'path', help= 'One path of music files or directories containing music files' ) test_parser.add_argument( 'url', help= 'A wiki URL for a page to test whether it matches the given files' ) parser.include_common_args('verbosity', 'dry_run') parser.add_common_sp_arg( '--match_log', action='store_true', help='Enable debug logging for the album match processing logger') # fmt: on return parser
def parser(): parser = ArgParser(description='Nest Thermostat Manager') status_parser = parser.add_subparser('action', 'status', 'Show current status') status_parser.add_argument('--format', '-f', default='yaml', choices=Printer.formats, help='Output format') status_parser.add_argument('--celsius', '-C', action='store_true', help='Output temperatures in Celsius (default: Fahrenheit)') status_parser.add_argument('--details', '-d', action='store_true', help='Show more detailed information') temp_parser = parser.add_subparser('action', 'temp', 'Set a new temperature') temp_parser.add_argument('temp', type=float, help='The temperature to set') temp_parser.add_argument('unit', nargs='?', default='f', choices=('f', 'c'), help='Unit (Celsius or Fahrenheit)') temp_parser.add_argument('--only_set', '-s', action='store_true', help='Only set the temperature - do not force it to run if the delta is < 0.5 degrees') range_parser = parser.add_subparser('action', 'range', 'Set a new temperature range') range_parser.add_argument('low', type=float, help='The low temperature to set') range_parser.add_argument('high', type=float, help='The high temperature to set') range_parser.add_argument('unit', nargs='?', default='f', choices=('f', 'c'), help='Unit (Celsius or Fahrenheit)') mode_parser = parser.add_subparser('action', 'mode', 'Change the current mode') mode_parser.add_argument('mode', choices=('cool', 'heat', 'range', 'off'), help='The mode to set') fan_parser = parser.add_subparser('action', 'fan', 'Turn the fan on or off') fan_parser.add_argument('state', choices=('on', 'off'), help='The fan state to change to') fan_parser.add_argument('--duration', '-d', type=int, default=1800, help='Time (in seconds) for the fan to run (ignored if setting state to off)') show_parser = parser.add_subparser('action', 'show', 'Show information') show_parser.add_argument('item', choices=SHOW_ITEMS, help='The information to show') show_parser.add_argument('buckets', nargs='*', help='The buckets to show (only applies to item=buckets)') show_parser.add_argument('--format', '-f', choices=Printer.formats, help='Output format') show_parser.add_argument('--unit', '-u', default='f', choices=('f', 'c'), help='Unit (Celsius or Fahrenheit) for functions that support it') show_parser.add_argument('--raw', '-r', action='store_true', help='Show the full raw response instead of the processed response (only applies to item=buckets)') with parser.add_subparser('action', 'schedule', 'Update the schedule') as schd_parser: schd_add = schd_parser.add_subparser('sub_action', 'add', 'Add entries with the specified schedule') schd_add.add_argument('cron', help='Cron-format schedule to use') schd_add.add_argument('temp', type=float, help='The temperature to set at the specified time') schd_add.add_argument('unit', nargs='?', default='f', choices=('f', 'c'), help='Unit (Celsius or Fahrenheit)') schd_rem = schd_parser.add_subparser('sub_action', 'remove', 'Remove entries with the specified schedule') schd_rem.add_argument('cron', help='Cron-format schedule to use') schd_rem.add_constant('temp', None) schd_rem.add_constant('unit', None) schd_save = schd_parser.add_subparser('sub_action', 'save', 'Save the current schedule to a file') schd_save.add_argument('path', help='The path to a file in which the current schedule should be saved') schd_save.add_argument('--overwrite', '-W', action='store_true', help='Overwrite the file if it already exists') schd_save.add_argument('--unit', '-u', default='f', choices=('f', 'c'), help='Unit (Celsius or Fahrenheit)') schd_load = schd_parser.add_subparser('sub_action', 'load', 'Load a schedule from a file') schd_load.add_argument('path', help='The path to a file containing the schedule that should be loaded') schd_show = schd_parser.add_subparser('sub_action', 'show', 'Show the current schedule') schd_show.add_argument('--format', '-f', choices=Printer.formats, help='Output format') schd_show.add_argument('--unit', '-u', default='f', choices=('f', 'c'), help='Unit (Celsius or Fahrenheit)') schd_parser.add_common_arg('--dry_run', '-D', action='store_true', help='Print actions that would be taken instead of taking them') full_status_parser = parser.add_subparser('action', 'full_status', 'Show/save the full device+shared status') full_status_parser.add_argument('--path', '-p', help='Location to store status info') full_status_parser.add_argument('--diff', '-d', action='store_true', help='Print a diff of the current status compared to the previous most recent status') parser.add_common_arg('--config', '-c', metavar='PATH', default='~/.config/nest.cfg', help='Config file location') parser.add_common_arg('--reauth', '-A', action='store_true', help='Force re-authentication, even if a cached session exists') parser.include_common_args('verbosity') return parser
def parser(): description = ( 'Plex Manager\n\nYou will be securely prompted for your password for the first login, after which a session' ' token will be cached') parser = ArgParser(description=description) with parser.add_subparser('action', 'sync', help='Sync Plex information') as sync_parser: ratings_parser = sync_parser.add_subparser( 'sync_action', 'ratings', help='Sync song rating information between Plex and files') ratings_parser.add_argument('direction', choices=('to_files', 'from_files'), help='Direction to sync information') ratings_parser.add_argument( '--path_filter', '-f', help= 'If specified, paths that will be synced must contain the given text (not case sensitive)' ) playlists_parser = sync_parser.add_subparser( 'sync_action', 'playlists', help='Sync playlists with custom filters') obj_types = ('track', 'artist', 'album', 'tracks', 'artists', 'albums') ops = ( 'contains, endswith, exact, exists, gt, gte, icontains, iendswith, iexact, in, iregex, istartswith, like, lt, ' 'lte, ne, regex, startswith') with parser.add_subparser('action', 'find', help='Find Plex information') as find_parser: find_parser.add_argument('obj_type', choices=obj_types, help='Object type') find_parser.add_argument('title', nargs='*', default=None, help='Object title (optional)') find_parser.add_argument( '--escape', '-e', default='()', help= 'Escape the provided regex special characters (default: %(default)r)' ) find_parser.add_argument( '--allow_inst', '-I', action='store_true', help= 'Allow search results that include instrumental versions of songs') find_parser.add_argument( '--full_info', '-F', action='store_true', help='Print all available info about the discovered objects') find_parser.add_argument( '--format', '-f', choices=PRINTER_FORMATS, default='yaml', help='Output format to use for --full_info (default: %(default)s)') find_parser.add_argument( 'query', nargs=argparse.REMAINDER, help= f'Query in the format --field[__operation] value; valid operations: {ops}' ) with parser.add_subparser('action', 'rate', help='Update ratings in Plex') as rate_parser: rate_parser.add_argument('obj_type', choices=obj_types, help='Object type') rate_parser.add_argument('rating', type=int, help='Rating out of 10') rate_parser.add_argument('title', nargs='*', default=None, help='Object title (optional)') rate_parser.add_argument( '--escape', '-e', default='()', help= 'Escape the provided regex special characters (default: %(default)r)' ) rate_parser.add_argument( '--allow_inst', '-I', action='store_true', help= 'Allow search results that include instrumental versions of songs') rate_parser.add_argument( 'query', nargs=argparse.REMAINDER, help= f'Query in the format --field[__operation] value; valid operations: {ops}' ) with parser.add_subparser( 'action', 'rate_offset', help='Update all track ratings in Plex with an offset' ) as rate_offset_parser: rate_offset_parser.add_argument( '--min_rating', '-min', type=int, default=2, help='Minimum rating for which a change will be made') rate_offset_parser.add_argument( '--max_rating', '-max', type=int, default=10, help='Maximum rating for which a change will be made') rate_offset_parser.add_argument('--offset', '-o', type=int, default=-1, help='Adjustment to make') with parser.add_subparser( 'action', 'playlist', help='Save or compare playlists') as playlist_parser: with playlist_parser.add_subparser( 'sub_action', 'dump', help='Save playlists') as playlist_dump: playlist_dump.add_argument( 'path', help='Location to write the playlist dump') playlist_dump.add_argument( '--playlist', '-p', help='Dump the specified playlist (default: all)') with playlist_parser.add_subparser( 'sub_action', 'compare', help='Compare playlists') as playlist_cmp: playlist_cmp.add_argument( 'path', help='Location of the playlist dump to compare') playlist_cmp.add_argument( '--playlist', '-p', help='Compare the specified playlist (default: all)') playlist_cmp.add_argument( '--strict', '-s', action='store_true', help= 'Perform a strict comparison (default: by artist/album/title)') with playlist_parser.add_subparser( 'sub_action', 'list', help='List playlists in a dump') as playlist_list: playlist_list.add_argument( 'path', help='Location of the playlist dump to read') parser.add_common_sp_arg( '--server_path_root', '-r', metavar='PATH', help= 'The root of the path to use from this computer to generate paths to files from the path used by Plex. When you click on the "..." for a song in Plex and click "Get Info", there will be a path in the "Files" box - for example, "/media/Music/a_song.mp3". If you were to access that file from this computer, and the path to that same file is "//my_nas/media/Music/a_song.mp3", then the server_path_root would be "//my_nas/" (only needed when not already cached)' ) parser.add_common_sp_arg( '--server_url', '-u', metavar='URL', help= 'The proto://host:port to use to connect to your local Plex server - for example: "https://10.0.0.100:12000" (only needed when not already cached)' ) parser.add_common_sp_arg( '--username', '-n', help='Plex username (only needed when a token is not already cached)') parser.add_common_sp_arg( '--config_path', '-c', metavar='PATH', default='~/.config/plexapi/config.ini', help= 'Config file in which your token and server_path_root / server_url are stored (default: %(default)s)' ) parser.add_common_sp_arg( '--music_library', '-m', default=None, help='Name of the Music library to use (default: Music)') parser.include_common_args('verbosity', 'dry_run') return parser
def parser(): site_names = sorted(SITE_CLASS_MAPPING.keys()) parser = ArgParser(description='Lyric Fetcher') list_parser = parser.add_subparser('action', 'list', 'List available sites') get_parser = parser.add_subparser( 'action', 'get', 'Retrieve lyrics from a particular page from a single site') get_parser.add_argument( 'song', nargs='+', help='One or more endpoints that contain lyrics for particular songs') get_parser.add_argument( '--title', '-t', help='Page title to use (default: extracted from lyric page)') get_parser.add_argument('--size', '-z', type=int, default=12, help='Font size to use for output') get_parser.add_argument('--ignore_len', '-i', action='store_true', help='Ignore stanza length match') get_parser.add_argument('--output', '-o', help='Output directory to store the lyrics') get_parser.add_argument( '--linebreaks', '-lb', nargs='+', help='Additional linebreaks to use to split stanzas') get_parser.add_argument('--replace_lb', '-R', action='store_true', help='Replace existing linebreaks') search_parser = parser.add_subparser('action', 'search', 'Search for lyric pages') search_parser.add_argument('query', help='Query to run') search_parser.add_argument('--sub_query', '-q', help='Sub-query to run') index_parser = parser.add_subparser( 'action', 'index', 'View lyric page endpoints from an artist\'s index page') index_parser.add_argument('index', help='Name of the index to view') index_parser.add_argument('--album_filter', '-af', help='Filter for albums to be displayed') index_parser.add_argument( '--list', '-L', action='store_true', help='List albums instead of song links (default: %(default)s)') cmp_parser = parser.add_subparser( 'action', 'compare', 'Compare lyrics from separate songs for common phrases, etc') cmp_parser.add_argument( 'song_1', help='One or more endpoints that contain lyrics for particular songs') cmp_parser.add_argument( 'song_2', help='One or more endpoints that contain lyrics for particular songs') for _parser in (get_parser, search_parser, index_parser, cmp_parser): _parser.add_argument('--site', '-s', choices=site_names, default=DEFAULT_SITE, help='Site to use (default: %(default)s)') hybrid_parser = parser.add_subparser( 'action', 'hybrid_get', 'Retrieve lyrics from two separate sites and merge them') hybrid_parser.add_argument( '--korean_site', '-ks', choices=site_names, help='Site from which Korean lyrics should be retrieved', required=True) hybrid_parser.add_argument( '--english_site', '-es', choices=site_names, help='Site from which the English translation should be retrieved', required=True) hybrid_parser.add_argument( '--korean_endpoint', '-ke', help='Site from which Korean lyrics should be retrieved', required=True) hybrid_parser.add_argument( '--english_endpoint', '-ee', help='Site from which the English translation should be retrieved', required=True) hybrid_parser.add_argument( '--title', '-t', help='Page title to use (default: last part of song endpoint)') hybrid_parser.add_argument('--size', '-z', type=int, default=12, help='Font size to use for output') hybrid_parser.add_argument('--ignore_len', '-i', action='store_true', help='Ignore stanza length match') hybrid_parser.add_argument('--output', '-o', help='Output directory to store the lyrics') hybrid_parser.add_argument( '--english_lb', '-el', nargs='+', help='Additional linebreaks to use to split English stanzas') hybrid_parser.add_argument( '--korean_lb', '-kl', nargs='+', help='Additional linebreaks to use to split Korean stanzas') hybrid_parser.add_argument( '--english_extra', '-ex', nargs='+', help='Additional lines to add to the English stanzas at the end') hybrid_parser.add_argument( '--korean_extra', '-kx', nargs='+', help='Additional lines to add to the Korean stanzas at the end') file_parser = parser.add_subparser( 'action', 'file_get', 'Retrieve lyrics from two separate text files and merge them') file_parser.add_argument( '--korean', '-k', metavar='PATH', help='Path to a text file containing Korean lyrics') file_parser.add_argument( '--english', '-e', metavar='PATH', help='Path to a text file containing the English translation') file_parser.add_argument('--title', '-t', help='Page title to use', required=True) file_parser.add_argument('--size', '-z', type=int, default=12, help='Font size to use for output') file_parser.add_argument( '--output', '-o', help='Output directory to store the processed lyrics') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='Alternate F3 Write/Read Test') write_parser = parser.add_subparser( 'action', 'write', 'Equivalent of f3write, with more options') write_parser.add_argument( 'path', help='The directory in which files should be written') write_parser.add_argument( '--start', '-s', type=int, default=1, help='The number for the first file to be written') write_parser.add_argument( '--end', '-e', type=int, help='The number for the last file to be written (default: fill disk)') write_parser.add_argument( '--size', '-S', metavar='BYTES', type=parse_bytes, default=GB_BYTES, help='File size to use (this is for testing purposes only)') write_parser.add_argument('--chunk_size', '-c', metavar='BYTES', type=parse_bytes, default=DEFAULT_CHUNK_SIZE, help='Chunk size to use (default: %(default)s)') write_parser.add_argument( '--mode', '-m', choices=[e.value for e in F3Mode], default='iter', help='Buffer population mode (default: %(default)s)') write_parser.add_argument( '--rewrite', '-r', action='store_true', help= 'If a file already exists for a given number, rewrite it (default: skip unless size is incorrect)' ) write_parser.add_argument('--buffering', '-b', choices=(-1, 0, 1), default=-1, type=int, help='Whether to enable buffering or not') read_parser = parser.add_subparser('action', 'read', 'Simplified version of f3read') read_parser.add_argument( 'path', help='The directory from which files should be read') read_parser.add_argument('--chunk_size', '-c', metavar='BYTES', type=parse_bytes, default=DEFAULT_CHUNK_SIZE, help='Chunk size to use (default: %(default)s)') read_parser.add_constant('mode', 'iter') read_parser.add_constant('size', GB_BYTES) parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='Sort TV show parts') parser.add_argument('path', help='Directory to process') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='Incremental Backup Tool') with parser.add_subparser('action', 'backup', 'Create an incremental backup') as bkp_parser: bkp_parser.add_argument('source', metavar='PATH', help='The file to backup') bkp_parser.add_argument( 'dest_dir', metavar='PATH', help='The directory in which backups should be stored') bkp_parser.add_argument('--last_dirs', nargs='+', metavar='PATH', help='One or more previous backup directories') bkp_options = bkp_parser.add_argument_group('Behavior Options') bkp_options.add_argument( '--ignore_files', nargs='+', help='Add additional file names to be ignored') bkp_options.add_argument( '--ignore_dirs', nargs='+', help='Add additional directory names to be ignored') bkp_options.add_argument('--follow_links', '-L', action='store_true', help='Follow directory symlinks') # with parser.add_subparser('action', 'restore', 'Restore files from a set of incremental backups') as rst_parser: # rst_parser.add_argument('destination', metavar='PATH', help='The destination directory') # rst_parser.add_argument('sources', metavar='PATH', nargs='+') with parser.add_subparser( 'action', 'rebuild', 'Rebuild a remote tree from local incremental backups' ) as bld_parser: bld_parser.add_argument('remote', help='A remote directory') bld_parser.add_argument('destination', help='The local destination directory') bld_parser.add_argument('sources', nargs='+', help='Local incremental backup directories') bld_options = bld_parser.add_argument_group('Behavior Options') bld_options.add_argument( '--ignore_files', nargs='+', help='Add additional file names to be ignored') bld_options.add_argument( '--ignore_dirs', nargs='+', help='Add additional directory names to be ignored') bld_options.add_argument('--follow_links', '-L', action='store_true', help='Follow directory symlinks') parser.include_common_args('verbosity', 'dry_run') return parser
def parser(): parser = ArgParser(description='Utility for working with animated GIFs') alpha_parser = parser.add_subparser( 'action', 'c2a', help='Convert the specified color to alpha') alpha_parser.add_argument('path', help='Path to the input file') alpha_parser.add_argument('output', help='Path for the output file') alpha_parser.add_argument( '--color', '-c', metavar='RGB', help='Color to convert to alpha as an RGB hex code', required=True) alpha_parser.add_argument( '--disposal', '-d', type=int, nargs='+', help= 'Way to treat the graphic after displaying it. Specify 1 value to apply to all, or per-frame values. 1: Do not dispose; 2: Restore to bg color; 3: Restore to prev content' ) # alpha_parser.add_argument('--threshold', '-t', type=float, default=0.95, help='Threshold to convert to alpha') split_parser = parser.add_subparser( 'action', 'split', help='Save each frame of an animated gif as a separate file') split_parser.add_argument('path', help='Path to the input file') split_parser.add_argument('output_dir', help='Path to the input file') split_parser.add_argument('--prefix', '-p', default='frame_', help='Frame filename prefix') split_parser.add_argument('--format', '-f', default='PNG', help='Image format for output files') combine_parser = parser.add_subparser( 'action', 'combine', help='Combine multiple images into a single animated gif') combine_parser.add_argument('paths', nargs='+', help='Input file paths') combine_parser.add_argument('--output', '-o', metavar='PATH', help='Output file path', required=True) combine_parser.add_argument( '--disposal', type=int, nargs='+', help= 'Way to treat the graphic after displaying it. Specify 1 value to apply to all, or per-frame values. 1: Do not dispose; 2: Restore to bg color; 3: Restore to prev content' ) combine_parser.add_argument( '--duration', '-d', type=int, nargs='+', help= 'Duration between frames in milliseconds. Specify 1 value to apply to all, or per-frame values' ) info_parser = parser.add_subparser( 'action', 'info', help='Display information about the given image') info_parser.add_argument('path', help='Path to the input file') mgroup = info_parser.add_mutually_exclusive_group() mgroup.add_argument('--all', '-a', action='store_true', help='Show information about all frames') mgroup.add_argument( '--frames', '-f', type=int, help='Show information about up to the specified number of frames') parser.include_common_args('verbosity') return parser
def parser(): parser = ArgParser(description='EXIF Sorter') parser.add_argument('source', help='Path of the directory to sort from') parser.add_argument('target', help='Path of the directory to sort to') parser.include_common_args('verbosity', 'dry_run') return parser