]> git.immae.eu Git - perso/Immae/Projets/Python/MusicSampler.git/blobdiff - music_sampler/helpers.py
Add config key to config.yml to store command line arguments
[perso/Immae/Projets/Python/MusicSampler.git] / music_sampler / helpers.py
index 2199058cf58555b9ce2a3aec67d2da94340d1fb7..943e5a197465143dc2f47e193bfbcc0f3bdf94e2 100644 (file)
@@ -6,6 +6,7 @@ import math
 import sounddevice as sd
 import logging
 import gettext
+import yaml
 gettext.install('music_sampler')
 Logger = logging.getLogger("kivy")
 
@@ -52,6 +53,96 @@ def path():
     else:
         return os.path.dirname(os.path.realpath(__file__))
 
+
+Configs = {
+    'music_path': {
+        'abbr': '-p',
+        'default': '.',
+        'help': _("Folder in which to find the music files"),
+        'type': None
+    },
+    'latency': {
+        'abbr': '-l',
+        'default': 'high',
+        'help': _("Latency: low, high or number of seconds"),
+        'type': None
+    },
+    'language': {
+        'abbr': '-L',
+        'default': "fr",
+        'help': _("Select another language"),
+        'type': None
+    },
+    'device': {
+        'abbr': '-d',
+        'default': None,
+        'help': _("Select this sound device"),
+        'type': None
+    },
+    'blocksize': {
+        'abbr': '-b',
+        'default': 0,
+        'help': _("Blocksize: If not 0, the number of frames to take\
+                    at each step for the mixer"),
+        'type': int
+    },
+    'frame_rate': {
+        'abbr': '-f',
+        'default': 44100,
+        'help': _("Frame rate to play the musics"),
+        'type': int
+    },
+    'channels': {
+        'abbr': '-x',
+        'default': 2,
+        'help': _("Number of channels to use"),
+        'type': int
+    },
+    'sample_width': {
+        'abbr': '-s',
+        'default': 2,
+        'help': _("Sample width (number of bytes for each frame)"),
+        'type': int
+    },
+    'builtin_mixing': {
+        'default': False,
+        'help_yes': _("Make the mixing of sounds manually\
+                    (do it if the system cannot handle it correctly)"),
+        'help_no': _("Don't make the mixing of sounds manually (default)"),
+        'type': 'boolean'
+    },
+    'debug': {
+        'abbr': '-d',
+        'default': False,
+        'help_yes': _("Print messages in console"),
+        'help_no': _("Don't print messages in console (default)"),
+        'type': 'boolean'
+    },
+    'focus_warning': {
+        'default': True,
+        'help_yes': _("Show a warning when focus is lost (default)"),
+        'help_no': _("Don't show warning when focus is lost"),
+        'type': 'boolean'
+    },
+    'list_devices': {
+        'help': _("List available sound devices"),
+        'type': 'action'
+    },
+}
+Configs_order = [
+    'debug',
+    'music_path',
+    'builtin_mixing',
+    'latency',
+    'blocksize',
+    'frame_rate',
+    'channels',
+    'sample_width',
+    'focus_warning',
+    'language',
+    'list_devices',
+    'device',
+]
 def parse_args():
     argv = sys.argv[1 :]
     sys.argv = sys.argv[: 1]
@@ -68,72 +159,34 @@ def parse_args():
     sys.argv.extend(["-c", "kivy:log_name:/tmp/music_sampler_%_.txt"])
 
     parser = argparse.ArgumentParser(
-            description=_("A Music Sampler application."),
-            formatter_class=argparse.ArgumentDefaultsHelpFormatter)
-    parser.add_argument("-c", "--config",
-            default="config.yml",
-            required=False,
-            help=_("Config file to load"))
-    parser.add_argument("-p", "--music-path",
-            default=".",
-            required=False,
-            help=_("Folder in which to find the music files"))
-    parser.add_argument("-d", "--debug",
-            nargs=0,
-            action=DebugModeAction,
-            help=_("Print messages in console"))
-    parser.add_argument("-m", "--builtin-mixing",
-            action="store_true",
-            help=_("Make the mixing of sounds manually\
-                    (do it if the system cannot handle it correctly)"))
-    parser.add_argument("-l", "--latency",
-            default="high",
-            required=False,
-            help=_("Latency: low, high or number of seconds"))
-    parser.add_argument("-b", "--blocksize",
-            default=0,
-            type=int,
-            required=False,
-            help=_("Blocksize: If not 0, the number of frames to take\
-                    at each step for the mixer"))
-    parser.add_argument("-f", "--frame-rate",
-            default=44100,
-            type=int,
-            required=False,
-            help=_("Frame rate to play the musics"))
-    parser.add_argument("-x", "--channels",
-            default=2,
-            type=int,
-            required=False,
-            help=_("Number of channels to use"))
-    parser.add_argument("-s", "--sample-width",
-            default=2,
-            type=int,
-            required=False,
-            help=_("Sample width (number of bytes for each frame)"))
+            argument_default=argparse.SUPPRESS,
+            description=_("A Music Sampler application."))
     parser.add_argument("-V", "--version",
             action="version",
             help=_("Displays the current version and exits. Only use\
                     in bundled package"),
             version=show_version())
-    parser.add_argument("--device",
-            action=SelectDeviceAction,
-            help=_("Select this sound device")
-            )
-    parser.add_argument("--list-devices",
-            nargs=0,
-            action=ListDevicesAction,
-            help=_("List available sound devices")
-            )
-    parser.add_argument("--no-focus-warning",
-            action='store_true',
-            help=_("Don't show warning when focus is lost")
-            )
-    parser.add_argument("-L", "--language",
+    parser.add_argument("-c", "--config",
+            default="config.yml",
             required=False,
-            default="fr",
-            help=_("Select another language")
-            )
+            help=_("Config file to load (default: config.yml)"))
+    for argument in Configs_order:
+        arg = Configs[argument]
+        if arg['type'] != 'boolean' and arg['type'] != 'action':
+            parser.add_argument(arg['abbr'], '--' + argument.replace('_', '-'),
+                    type=arg['type'],
+                    help=arg['help']+_(" (default: {})").format(arg['default']))
+        elif arg['type'] == 'boolean':
+            parser.add_argument('--' + argument.replace('_', '-'),
+                    action='store_const', const=True,
+                    help=arg['help_yes'])
+            parser.add_argument('--no-' + argument.replace('_', '-'),
+                    action='store_const', const=True,
+                    help=arg['help_no'])
+        else:
+            parser.add_argument('--' + argument.replace('_', '-'),
+                    action='store_const', const=True,
+                    help=arg['help'])
     parser.add_argument('--',
             dest="args",
             help=_("Kivy arguments. All arguments after this are interpreted\
@@ -142,36 +195,58 @@ def parse_args():
     args = parser.parse_args(argv)
 
     Config.yml_file = args.config
+    build_config(args)
 
-    Config.latency = args.latency
-    Config.blocksize = args.blocksize
-    Config.frame_rate = args.frame_rate
-    Config.channels = args.channels
-    Config.sample_width = args.sample_width
-    Config.builtin_mixing = args.builtin_mixing
-    Config.no_focus_warning = args.no_focus_warning
-    if args.language != 'en':
+    if Config.device is not None:
+        sd.default.device = Config.device
+
+    if Config.list_devices:
+        print(sd.query_devices())
+        sys.exit()
+
+    if Config.debug:
+        sys.argv.extend(["-c", "kivy:log_level:debug"])
+
+    if Config.language != 'en':
         gettext.translation("music_sampler",
                 localedir=path() + '/locales',
-                languages=[args.language]).install()
-    if args.music_path.endswith("/"):
-        Config.music_path = args.music_path
-    else:
-        Config.music_path = args.music_path + "/"
+                languages=[Config.language]).install()
+    if not Config.music_path.endswith("/"):
+        Config.music_path = Config.music_path + "/"
 
-class DebugModeAction(argparse.Action):
-    def __call__(self, parser, namespace, values, option_string=None):
-        sys.argv.extend(["-c", "kivy:log_level:debug"])
+def build_config(args):
+    stream = open(Config.yml_file, "r")
+    try:
+        config = yaml.safe_load(stream)
+    except Exception as e:
+        error_print("Error while loading config file: {}".format(e))
+        config = {}
+    stream.close()
+    if 'config' in config:
+        config = config['config']
+    else:
+        config = {}
 
-class SelectDeviceAction(argparse.Action):
-    def __call__(self, parser, namespace, values, option_string=None):
-        sd.default.device = values
+    for config_item in Configs_order:
+        if Configs[config_item]['type'] != 'boolean' and \
+                Configs[config_item]['type'] != 'action':
+            t = Configs[config_item]['type'] or str
+            if hasattr(args, config_item):
+                setattr(Config, config_item, getattr(args, config_item))
+            elif config_item in config:
+                setattr(Config, config_item, t(config[config_item]))
+            else:
+                setattr(Config, config_item, Configs[config_item]['default'])
+        elif Configs[config_item]['type'] == 'boolean':
+            if hasattr(args, 'no_' + config_item) or hasattr(args, config_item):
+                setattr(Config, config_item, hasattr(args, config_item))
+            elif config_item in config:
+                setattr(Config, config_item, config[config_item])
+            else:
+                setattr(Config, config_item, Configs[config_item]['default'])
+        else:
+            setattr(Config, config_item, hasattr(args, config_item))
 
-class ListDevicesAction(argparse.Action):
-    nargs = 0
-    def __call__(self, parser, namespace, values, option_string=None):
-        print(sd.query_devices())
-        sys.exit()
 
 def show_version():
     if getattr(sys, 'frozen', False):