print(f'* NEW : {self._count["n"]}') print(f'* DUP : {self._count["d"]}') print(f'* REJECTED : {self._count["r"]}') print(f'* SKIP : {self._count["s"]}') print(f'# DONE : ' + str(self._count['n'] + self._count['d'] + self._count['r'])) print(f'# TOTAL : ' + str(self._count['n'] + self._count['d'] + self._count['r'] + self._count['s'])) class ImageSelectorCommand(Command): name = 'select-images' aliases = ['image-selector'] description = "Select photos - or files collected by 'collect-images' and create a filter file in YAML format. " \ "Use 'dedup-images' for next step." @staticmethod def register_arguments(c: OptionContext): c.add_option( '--filter', '--filter-file', dest='filter_file', required=True, help='File of filters') c.add_option( '--sql', '--sqlite-db', '--db', '-d', dest='db', required=True, help='SQLite database to read') def run(self, ctx: ApplicationContext): sorter = ImageSelector(ctx.args.filter_file, ctx.args.db) sorter.run() ImageSelectorPlugin = CommandPlugin.create(ImageSelectorCommand)
# aliases = [] description = "Streaming HTTP server, /dev/urandom" @staticmethod def register_arguments(c: OptionContext): c.add_option('-p', '--port', type=int, default=8081, help='The port number, default: 8081') c.add_option( '--count', default='40M', help='Amount of bytes. Can be used the K/M/G suffix. Default: 40M') def run(self, ctx: ApplicationContext): if ctx.args.port < 1 or ctx.args.port > 65535: print(f'Invalid port number: {ctx.args.port}') return 1 success, count = Http.convert_count(ctx.args.count) if not success: print('Unable to convert count to a number: ' + ctx.args.count) return 1 p = Http(ctx.args.port, count) return p.run() HttpPlugin = CommandPlugin.create(HttpCommand)
os.makedirs(os.path.dirname(target_path), exist_ok=True) os.rename(entry.orig_path, new_file_name) break else: i += 1 class PhotoSorterCommand(Command): name = 'sortphotos' aliases = ['sort-photos', 'sort-files', 'sortfiles', 'filesort'] description = "Sort photos - or files - by its modification name and detect duplicates." @staticmethod def register_arguments(c: OptionContext): c.add_option( '-s', '--source', '--source-directory', dest='source_dir', required=True, help='Source Directory of files (photos) to be checked and cleaned') c.add_option( '-d', '--destination', '--destination-directory', dest='dest_dir', required=True, help='Target Root Directory - Files will be copied to $TARGET/$YEAR/$YEAR-$MONTH/$YEAR-$MONTH-$DAY') c.add_option( '--pretend', dest='pretend', default=False, is_flag=True, help='Pretend only, but do not move files') def run(self, ctx: ApplicationContext): sorter = PhotoSorter(ctx.args.source_dir, ctx.args.dest_dir, ctx.args.pretend) sorter.run() PhotoSorterPlugin = CommandPlugin.create(PhotoSorterCommand)
description = "Packt stuffs" @staticmethod def register_arguments(c: OptionContext): c.add_option('--wait-for-close', help='Wait a minute before closing Chrome', is_flag=True) driver_grp = c.add_group( 'Browser and WebDriver options', help='Options influences the behaviour of Selenium Web Driver and Google Chrome / Firefox') driver_grp.add_option('--screenshots', '--screenshot-dir', dest='screenshot_dir', default='.', help='The directory to save any screenshot, default: current directory') driver_grp.add_option('--download-directory', '--dl-dir', dest='download_dir', required=True, help='Download directory') driver_grp.add_option('--headless', is_flag=True, help='Start Chrome in headless mode') driver_grp.add_option('--timeout', type=int, default=60, help='Timeout for waiting any element or action, default: 60s') def run(self, ctx: ApplicationContext): config = load_config() config.driver.screenshot_directory = ctx.args.screenshot_dir config.driver.download_directory = ctx.args.download_dir config.driver.headless = ctx.args.headless config.driver.timeout = ctx.args.timeout config.wait_before_close = ctx.args.wait_for_close return run(config) PacktPlugin = CommandPlugin.create(PacktCommand)
if match: result.append(match.group(1)) result.append('+' + match.group(2)) else: result.append(args[0]) elif len(args) > 1: result = ['-p'] + args return result class EditCommand(Command): name = 'edit' aliases = ['ed'] description = 'Calls vim with the file names and line numbers parsed from argument list.' @staticmethod def register_arguments(c: OptionContext): c.add_argument('file_list', nargs=-1, type=click.Path(), help='Files to open') def run(self, ctx: ApplicationContext): args = ['vim'] + convert_to_vim_args(ctx.args.file_list) pipe = subprocess.Popen(args) pipe.communicate() EditPlugin = CommandPlugin.create(EditCommand)
c.add_option('--target-directory', dest='target', required=True, help='Target directory to store unique files') c.add_option('--log-file', dest='log_file', required=True, help='Log file for detailed run') c.add_option('--dry-run', '-n', dest='dry_run', is_flag=True, help='Do change file system, just print what would do') def run(self, ctx: ApplicationContext): config = DeduplicatorConfig() config.filter_filename = ctx.args.filter_file config.sqlite_filename = ctx.args.db config.main_target_dir = ctx.args.target config.dry_run = ctx.args.dry_run config.log_file = ctx.args.log_file sorter = ImageDeduplicator(config) sorter.run() ImageDeduplicatorPlugin = CommandPlugin.create(ImageDeduplicatorCommand)
# Copyright 2021 Laszlo Attila Toth # Distributed under the terms of the Apache License, Version 2.0 from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin from dewi_core.commands.edit.edit import EditCommand from dewi_core.commands.review import ReviewCommand class EditOrReviewCommand(Command): name = 'edit-review' aliases = ['er'] description = 'Example of command with subcommands from other loaded plugins' subcommand_classes = [EditCommand, ReviewCommand] EditReviewPlugin = CommandPlugin.create(EditOrReviewCommand)
from dewi_core.appcontext import ApplicationContext from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin from dewi_core.optioncontext import OptionContext from dewi_utils.lithurgical import print_events_of_year class LithurgicalCommand(Command): name = 'lithurgical' aliases = [] description = "Prints Lutheran liturgical events of a calendar year" @staticmethod def register_arguments(c: OptionContext): c.add_argument('year', type=int, help='The calendar year') def run(self, ctx: ApplicationContext): year: int = ctx.args.year if year < 1600: print('Please specify a year not earlier than 1600') return 1 if year > 2200: print('Please specify a year not later than 2200') return 1 print_events_of_year(year) return LithurgicalPlugin = CommandPlugin.create(LithurgicalCommand)
name = 'hash' description = 'Runs hash-related tasks' @staticmethod def register_arguments(c: OptionContext): c.add_option( '-v', '--verbose', is_flag=True, default=False, dest='verbose', help='Verbose output, prints the details of hashed values') grp = c.add_mutually_exclusive_group(required=True) grp.add_option( '--phash', '--python-hash', dest='phash', metavar='PYTHON-DIR', help= 'Calculate MD5 hex digest of a directory without .git and __pychache__' ) def run(self, ctx: ApplicationContext): if ctx.args.phash: print( python_repo_hash_md5(ctx.args.phash, verbose=ctx.args.verbose)) HashPlugin = CommandPlugin.create(HashCommand)
file=self.log) class SafeEraserCommand(Command): name = 'safe-delete-images' description = "Erase duplicated photos - or files that successfully copied to their target location" @staticmethod def register_arguments(c: OptionContext): c.add_option( '--sql', '--sqlite-db', '--db', '-d', dest='db', required=True, help='SQLite database to read and update') c.add_option('--log-file', dest='log_file', required=True, help='Log file for detailed run') c.add_option('--dry-run', '-n', dest='dry_run', is_flag=True, help='Do change file system, just print what would do') def run(self, ctx: ApplicationContext): config = SafeEraserConfig() config.sqlite_filename = ctx.args.db config.dry_run = ctx.args.dry_run config.log_file = ctx.args.log_file sorter = SafeEraser(config) sorter.run() SafeEraserPlugin = CommandPlugin.create(SafeEraserCommand)
# Distributed under the terms of the GNU Lesser General Public License v3 from dewi_commands.commands.dice.die import Die from dewi_core.appcontext import ApplicationContext from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin from dewi_core.optioncontext import OptionContext class DiceCommand(Command): name = 'dice' aliases = ['d20'] description = "Roll one or more dice" @staticmethod def register_arguments(c: OptionContext): c.add_argument( 'dice', nargs=-1, help= 'The dice (or die) to roll, based on DnD: [count]d{4,6,8,10,12,20,%%}, default=d6' ) def run(self, ctx: ApplicationContext): dice = Die() for d in ctx.args.dice or ['d6']: dice.roll(d) DicePlugin = CommandPlugin.create(DiceCommand)
import os import shlex import subprocess from dewi_core.appcontext import ApplicationContext from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin class SshToUbuntuOnWindows(Command): name = 'ssh_ubuntu_on_windows' aliases = ['cu', 'chroot'] description = "Ssh to localhost, to ubuntu on windows, into current directory" def run(self, ctx: ApplicationContext): path = self._prepare_path(os.getcwd()) res = subprocess.run([ 'ssh', '-oUserKnownHostsFile=/dev/null', '-oStrictHostKeyChecking=no', '127.0.0.1', '-t', 'cd {} && bash'.format(path) ]) return res.returncode def _prepare_path(self, path: str): return shlex.quote('/mnt/' + path[0].lower() + '/'.join(path[2:].split('\\'))) SshToUbuntuOnWindowsPlugin = CommandPlugin.create(SshToUbuntuOnWindows)
# Copyright 2019 Laszlo Attila Toth # Distributed under the terms of the GNU Lesser General Public License v3 from dewi_commands.commands.worktime.subcommands import Import, Login, Logout, Print, Subcommand from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin class WorktimeCommand(Command): name = 'worktime' aliases = ['w', 'wt'] description = "Calculate worktime from a file" subcommand_classes = [ Import, Login, Logout, Print ] WorktimePlugin = CommandPlugin.create(WorktimeCommand)
# Distributed under the terms of the GNU Lesser General Public License v3 from dewi_commands.commands.stocks.stocks import StocksProcessor from dewi_core.appcontext import ApplicationContext from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin from dewi_core.optioncontext import OptionContext class StocksCommand(Command): name = 'stocks' description = "Calculate gain/loss and others based on " \ "DATE;ACTION;SOCK;PRICE;SHARE-PRICE;SHARE-AMOUNT" @staticmethod def register_arguments(c: OptionContext): c.add_option('-i', '--input', required=True, help='The CSV file to process') c.add_option('-o', '--output', required=False, help='The output CSV filename') def run(self, ctx: ApplicationContext): StocksProcessor(ctx.args.input, ctx.args.output).process() StocksPlugin = CommandPlugin.create(StocksCommand)
class SysInfoCommand(Command): name = 'sysinfo' aliases = ['debug-info'] description = "Examine the system and creates a summary in HTML & YAML form" @staticmethod def register_arguments(c: OptionContext): c.add_option('--reprocess', '-f', '--force', is_flag=True, dest='reprocess', default=False, help='Reprocess sysinfo if generated YAML file exists') c.add_option('--output', '-o', dest='output_dir', required=True, help='Output directory for result.yaml and index.html') c.add_option('--munin-dir', '-m', dest='munin_dir', default='/var/lib/munin', help='Munin directory, may not exist, default: /var/lib/munin') c.add_option('--log-dir', '-l', dest='log_dir', default='/var/log', help='Log directory, may not exist, default: /var/log') c.add_option('--no-logs', '-L', is_flag=True, dest='no_log', default=False, help='Skip processing logs') c.add_option('--no-graphs', '-G', is_flag=True, dest='no_graph', default=False, help='Skip generating munin graphs') def run(self, ctx: ApplicationContext): p = Processor(ctx.args.log_dir, ctx.args.munin_dir, ctx.args.output_dir, ctx.args.reprocess, not ctx.args.no_log, not ctx.args.no_graph) return p.process() SysInfoPlugin = CommandPlugin.create(SysInfoCommand)
c.add_option('-s', '--silent', dest='silent', is_flag=True, help='Do not print status, the line numbers') c.add_option( '-D', '-m', '--delimiter', dest='delimiter', default='.' if sys.platform == 'win32' else ':', help= 'Delimiter character used in filename, default: same as in session_id, the colon' ) c.add_argument( 'zorplogfile', nargs=1, default='-', help= 'The original Zorp log file to be splitted. Omit or use - to read from stdin' ) def run(self, ctx: ApplicationContext): splitter = Splitter(ctx.args.zorplogfile, ctx.args.directory, ctx.args.delimiter, ctx.args.reopen, ctx.args.silent) splitter.run() SplitZorpLogPlugin = CommandPlugin.create(SplitZorpLogCommand)
# Copyright 2020 Laszlo Attila Toth # Distributed under the terms of the GNU Lesser General Public License v3 from dewi_core.appcontext import ApplicationContext from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin from dewi_core.optioncontext import OptionContext from .find import Find class FindCommand(Command): name = 'find' description = 'Partial implementation of UNIX "find" tool' @staticmethod def register_arguments(c: OptionContext): c.add_argument( 'directories', nargs=-1, help='The search directories') def run(self, ctx: ApplicationContext): return Find(ctx.args.directories or ['.']).find() FindPlugin = CommandPlugin.create(FindCommand)
# Distributed under the terms of the GNU Lesser General Public License v3 import json from dewi_core.appcontext import ApplicationContext from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin from dewi_core.optioncontext import OptionContext class JsonFormatterCommand(Command): name = 'jsonformatter' aliases = ['json-formatter', 'format-json', 'formatj', 'jsonf'] description = "Read a JSON file and write it with indentation and in UTF-8 encoding" @staticmethod def register_arguments(c: OptionContext): c.add_argument('source', nargs=1, help='The source file') c.add_argument('destination', nargs=1, help='The destination file') def run(self, ctx: ApplicationContext): with open(ctx.args.source) as f: input_json = json.load(f) with open(ctx.args.destination, 'wt', encoding='UTF-8') as f: json.dump(input_json, f, indent=2, ensure_ascii=False) f.write("\n") JSonFormatterPlugin = CommandPlugin.create(JsonFormatterCommand)
name = 'change' @staticmethod def register_arguments(c: OptionContext): licenses = c.add_mutually_exclusive_group('License Types', required=True) for name, text in LicenseChange.LICENSES.items(): licenses.add_option(f'--{name}', dest='license_type', flag_value=name, help=f'Switches to {text}') c.add_argument('targets', nargs=-1, required=True, help='One or more directory or file to be updated') def run(self, ctx: ApplicationContext): LicenseChange(ctx.args.license_type, ctx.args.targets).run() class LicenseCommand(Command): name = 'license' description = "Switches between licenses (Distributed under the terms of X)" subcommand_classes = [ ChangeCommand, ] LicensePlugin = CommandPlugin.create(LicenseCommand)
# Copyright 2021 Laszlo Attila Toth # Distributed under the terms of the Apache License, Version 2.0 from dewi_core.command import Command from dewi_core.commandplugin import CommandPlugin from .commands import GerritChangeReviewer, GerritChangeChainReviewer, register_global_args_in_review_cmd from ...optioncontext import OptionContext class ReviewCommand(Command): name = 'review' aliases = ['r', 'rw'] description = "Example command which could be for Gerrit review" subcommand_classes = [ GerritChangeChainReviewer, GerritChangeReviewer, ] @classmethod def register_arguments(cls, c: OptionContext): register_global_args_in_review_cmd(c) ReviewPlugin = CommandPlugin.create(ReviewCommand)
class PrimesCommand(Command): name = 'primes' aliases = ['prime'] description = "Calculate first N primes" @staticmethod def register_arguments(c: OptionContext): c.add_option('-s', '--smaller-than', dest='smaller_than', type=int, help='Print till the primes are smaller than this value.') c.add_option( '-c', '--count', type=int, help= 'Max number of printed primes (if --smaller-than is not specified, count is 100)' ) def run(self, ctx: ApplicationContext): if ctx.args.smaller_than is None and ctx.args.count is None: ctx.args.count = 100 p = PrimeGenerator(ctx.args.smaller_than, ctx.args.count) return p.run() PrimesPlugin = CommandPlugin.create(PrimesCommand)
c.add_option( '-l', '--login', '-u', '--user', dest='user', required=True, help='The username used on the SSH server' ) c.add_option( '--skip-host-key-check', is_flag=True, default=False, help='Skip check SSH host key - it is insecure, but in trusted environment it is reasonable' ) def run(self, ctx: ApplicationContext) -> typing.Optional[int]: entries = EntryListLoader().load_from_string_list(ctx.args.entry, ctx.args.skip_chmod) app = SyncOverSshApp(ctx.args.directory, ctx.args.target_directory, entries, user=ctx.args.user, host=ctx.args.host, port=ctx.args.port, check_host_key=not ctx.args.skip_host_key_check) return app.run() class FileSyncCommand(Command): name = 'filesync' aliases = ['dirsync'] description = "Sync content of a directory to a remote location controlled by mapping rules" subcommand_classes = [ LocalCommand, RemoteCommand, ] FileSyncPlugin = CommandPlugin.create(FileSyncCommand)