Use configuration file for commands defaults
This commit is contained in:
		
							parent
							
								
									58e4e42b30
								
							
						
					
					
						commit
						261c8b6275
					
				| 
						 | 
				
			
			@ -1,11 +1,17 @@
 | 
			
		|||
import argparse
 | 
			
		||||
import configparser
 | 
			
		||||
import traceback
 | 
			
		||||
import sys
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
try:
 | 
			
		||||
    from importlib import metadata
 | 
			
		||||
except ImportError:  # Python <3.8
 | 
			
		||||
    import importlib_metadata as metadata
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CONFIG_FILE = '~/.negromate/config.ini'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    """
 | 
			
		||||
        Build parser for all the commands and launch appropiate command.
 | 
			
		||||
| 
						 | 
				
			
			@ -15,25 +21,31 @@ def main():
 | 
			
		|||
            * name: String with the command name. Will be used for
 | 
			
		||||
              argparse subcommand.
 | 
			
		||||
            * help_text: String with the help text.
 | 
			
		||||
            * initial_config: Dict for initial configuration of commands.
 | 
			
		||||
            * options: Function to build the parser of the command. Takes
 | 
			
		||||
              one parametter, the argparser parser instance for this
 | 
			
		||||
              subcommand.
 | 
			
		||||
            * run: Function that runs the actual command. Takes one
 | 
			
		||||
              parametter, the Namespace with the arguments.
 | 
			
		||||
              two parametters, the argparser parser instance for this
 | 
			
		||||
              subcommand and the ConfigParser instance with all the
 | 
			
		||||
              configuration.
 | 
			
		||||
            * run: Function that runs the actual command. Takes two
 | 
			
		||||
              parametters, the argparse Namespace with the arguments and
 | 
			
		||||
              the ConfigParser with all the configuration.
 | 
			
		||||
 | 
			
		||||
        Minimal module example:
 | 
			
		||||
 | 
			
		||||
            # hello_world.py
 | 
			
		||||
            name = 'hello'
 | 
			
		||||
            help_text = 'Sample command'
 | 
			
		||||
            initial_config = {
 | 
			
		||||
                'who': 'World',
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            def options(parser):
 | 
			
		||||
            def options(parser, config, **kwargs):
 | 
			
		||||
                parser.add_argument(
 | 
			
		||||
                    '-w', '--who', default='World'
 | 
			
		||||
                    help="Who to say hello, defaults to 'World'"
 | 
			
		||||
                    '-w', '--who', default=config['hello']['who'],
 | 
			
		||||
                    help="Who to say hello, defaults to '{}'".format(config['hello']['who'])
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            def run(args):
 | 
			
		||||
            def run(args, **kwargs):
 | 
			
		||||
                print("Hello {}".format(args.who))
 | 
			
		||||
 | 
			
		||||
        To add more commands to negromate register 'negromate.commands'
 | 
			
		||||
| 
						 | 
				
			
			@ -50,22 +62,47 @@ def main():
 | 
			
		|||
    args = sys.argv.copy()
 | 
			
		||||
    sys.argv = args[:1]
 | 
			
		||||
 | 
			
		||||
    # Load commands from entry_point
 | 
			
		||||
    entry_points = metadata.entry_points().get('negromate.commands', [])
 | 
			
		||||
    for entry_point in entry_points:
 | 
			
		||||
        commands.append(entry_point.load())
 | 
			
		||||
        try:
 | 
			
		||||
            command = entry_point.load()
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            traceback.print_exc()
 | 
			
		||||
            print(e)
 | 
			
		||||
            continue
 | 
			
		||||
        commands.append(command)
 | 
			
		||||
 | 
			
		||||
    # Load initial configuration for commands
 | 
			
		||||
    initial_config = {
 | 
			
		||||
        'global': {
 | 
			
		||||
            'song_folder': '~/negro_mate/bideoak/',
 | 
			
		||||
            'lyrics_file': '~/negro_mate/libreto/libreto.pdf',
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    for command in commands:
 | 
			
		||||
        if hasattr(command, 'initial_config'):
 | 
			
		||||
            initial_config[command.name] = command.initial_config
 | 
			
		||||
 | 
			
		||||
    # Load configuration
 | 
			
		||||
    config = configparser.ConfigParser()
 | 
			
		||||
    config.read_dict(initial_config)
 | 
			
		||||
    config.read(Path(CONFIG_FILE).expanduser())
 | 
			
		||||
 | 
			
		||||
    # Build parser
 | 
			
		||||
    parser = argparse.ArgumentParser()
 | 
			
		||||
    parser.set_defaults(command=None)
 | 
			
		||||
    subparsers = parser.add_subparsers()
 | 
			
		||||
    for command in commands:
 | 
			
		||||
        command_parser = subparsers.add_parser(command.name, help=command.help_text)
 | 
			
		||||
        command_parser.set_defaults(command=command.name)
 | 
			
		||||
        command.options(command_parser)
 | 
			
		||||
        command.options(parser=command_parser, config=config)
 | 
			
		||||
 | 
			
		||||
    # Run command
 | 
			
		||||
    args = parser.parse_args(args[1:])
 | 
			
		||||
    if args.command is None:
 | 
			
		||||
        parser.print_usage()
 | 
			
		||||
    else:
 | 
			
		||||
        for command in commands:
 | 
			
		||||
            if args.command == command.name:
 | 
			
		||||
                command.run(args)
 | 
			
		||||
                command.run(args=args, config=config)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
import sys
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
 | 
			
		||||
name = 'config'
 | 
			
		||||
help_text = 'Write the configuration'
 | 
			
		||||
initial_config = {
 | 
			
		||||
    'file': '~/.negromate/config.ini',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def options(parser, config, **kwargs):
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '-f', '--file', type=Path,
 | 
			
		||||
        default=config['config']['file'],
 | 
			
		||||
        help="Configuration file, defaults to {}".format(
 | 
			
		||||
            config['config']['file']))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run(args, config, **kwargs):
 | 
			
		||||
    with args.file.expanduser().open('w') as f:
 | 
			
		||||
        config.write(f)
 | 
			
		||||
| 
						 | 
				
			
			@ -7,14 +7,16 @@ name = 'songs'
 | 
			
		|||
help_text = 'Update song database'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def options(parser):
 | 
			
		||||
def options(parser, config, **kwargs):
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        'song_folder', type=Path,
 | 
			
		||||
        help="Folder with the song database.")
 | 
			
		||||
        '-s', '--song_folder', type=Path,
 | 
			
		||||
        default=config['global']['song_folder'],
 | 
			
		||||
        help="Folder with the song database, defaults to {}".format(
 | 
			
		||||
            config['global']['song_folder']))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run(args):
 | 
			
		||||
    songs, pending_songs = load_songs(args.song_folder)
 | 
			
		||||
def run(args, **kwargs):
 | 
			
		||||
    songs, pending_songs = load_songs(args.song_folder.expanduser())
 | 
			
		||||
    print(
 | 
			
		||||
        "#######\n"
 | 
			
		||||
        " Songs\n"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ name = 'thumbnail'
 | 
			
		|||
help_text = 'Generate cover and thumbnail for a video.'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def options(parser):
 | 
			
		||||
def options(parser, config, **kwargs):
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        'video', help="Video of the song.", type=Path)
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ def options(parser):
 | 
			
		|||
        help='Take snapshot at this second.')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run(args):
 | 
			
		||||
def run(args, **kwargs):
 | 
			
		||||
    video = args.video
 | 
			
		||||
    cover = video.parent / 'cover.jpg'
 | 
			
		||||
    thumbnail = video.parent / 'thumb.jpg'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue