]> kaliko git repositories - mpd-sima.git/blob - sima/utils/startopt.py
a1824ee8ca61b31346c83cb0c77065a291cd5b14
[mpd-sima.git] / sima / utils / startopt.py
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009-2015, 2021 kaliko <kaliko@azylum.org>
4 #
5 #  This file is part of sima
6 #
7 #  sima is free software: you can redistribute it and/or modify
8 #  it under the terms of the GNU General Public License as published by
9 #  the Free Software Foundation, either version 3 of the License, or
10 #  (at your option) any later version.
11 #
12 #  sima is distributed in the hope that it will be useful,
13 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #  GNU General Public License for more details.
16 #
17 #  You should have received a copy of the GNU General Public License
18 #  along with sima.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 #
21
22 from argparse import ArgumentParser, RawDescriptionHelpFormatter, SUPPRESS
23
24
25 from .utils import Wfile, Rfile, Wdir
26
27 DESCRIPTION = """
28 MPD_sima automagicaly queue new tracks in MPD playlist.
29
30 Command line options override their equivalent in configuration file.
31 If a positional arguments is provided MPD_sima execute the command and returns.
32 Commands available:
33 {}
34 """
35
36
37 def clean_dict(to_clean):
38     """Remove items which values are set to None/False"""
39     for k in list(to_clean.keys()):
40         if not to_clean.get(k):
41             to_clean.pop(k)
42
43 # COMMANDS LIST
44 CMDS = {'config-test': 'Test configuration (MPD connection and Tags plugin only)',
45         'create-db': 'Create the database',
46         'generate-config': 'Generate a configuration file to stdout',
47         }
48 # OPTIONS LIST
49 # pop out 'sw' value before creating Parser object.
50 # PAY ATTENTION:
51 #   If an option has to override its dual in conf file, the destination
52 #   identifier "dest" is to be named after that option in the conf file.
53 #   The supersedes_config_with_cmd_line_options method in ConfMan() (config.py)
54 #   is looking for command line option names identical to config file option
55 #   name it is meant to override.
56 OPTS = [
57     {
58         'sw': ['-l', '--log'],
59         'type': str,
60         'dest': 'logfile',
61         'action': Wfile,
62         'help': 'file to log message to, default is stdout/stderr'},
63     {
64         'sw': ['-v', '--log-level'],
65         'type': str,
66         'dest': 'verbosity',
67         'choices': ['debug', 'info', 'warning', 'error'],
68         'help': 'Log messages verbosity, default is info'},
69     {
70         'sw': ['-p', '--pid'],
71         'dest': 'pidfile',
72         'action': Wfile,
73         'help': 'file to save PID to, default is not to store pid'},
74     {
75         'sw': ['-d', '--daemon'],
76         'dest': 'daemon',
77         'action': 'store_true',
78         'help': 'Daemonize process.'},
79     {
80         'sw': ['-S', '--host'],
81         'dest': 'host',
82         'help': 'Host MPD in running on (IP or FQDN)'},
83     {
84         'sw': ['-P', '--port'],
85         'type': int,
86         'dest': 'port',
87         'help': 'Port MPD in listening on'},
88     {
89         'sw': ['-c', '--config'],
90         'dest': 'conf_file',
91         'action': Rfile,
92         'help': 'Configuration file to load'},
93     {  # TODO: To remove eventually in next major realese v0.18
94         'sw': ['--generate-config'],
95         'dest': 'generate_config',
96         'action': 'store_true',
97         'help': SUPPRESS},
98     {
99         'sw': ['--var-dir', '--var_dir'],
100         'dest': 'var_dir',
101         'action': Wdir,
102         'help': 'Directory to store var content (ie. database, cache)'},
103     {  # TODO: To remove eventually in next major realese v0.18
104         'sw': ['--create-db'],
105         'action': 'store_true',
106         'dest': 'create_db',
107         'help': SUPPRESS},
108     {
109         'sw': ['command'],
110         'nargs': '?',
111         'choices': CMDS.keys(),
112         'help': 'Command to run (cf. description or unix manual for more)'},
113 ]
114
115
116 class StartOpt:
117     """Command line management.
118     """
119
120     def __init__(self, script_info,):
121         self.parser = None
122         self.info = dict(script_info)
123         self.options = dict()
124         self.main()
125
126     def declare_opts(self):
127         """
128         Declare options in ArgumentParser object.
129         """
130         cmds = '\n'.join([f'    * {k}: {v}' for k, v in CMDS.items()])
131         self.parser = ArgumentParser(description=DESCRIPTION.format(cmds),
132                                      prog=self.info.get('prog'),
133                                      epilog='Happy Listening',
134                                      formatter_class=RawDescriptionHelpFormatter,
135                                      )
136         self.parser.add_argument('--version', action='version',
137                         version='%(prog)s {version}'.format(**self.info))
138         # Add all options declare in OPTS
139         for opt in OPTS:
140             opt_names = opt.pop('sw')
141             self.parser.add_argument(*opt_names, **opt)
142
143     def main(self):
144         """
145         Look for env. var and parse command line.
146         """
147         self.declare_opts()
148         options = vars(self.parser.parse_args())
149         # Set log file to os.devnull in daemon mode to avoid logging to
150         # std(out|err).
151         # TODO: Probably useless. To be checked
152         #if options.__dict__.get('daemon', False) and \
153         #        not options.__dict__.get('logfile', False):
154         #    options.__dict__['logfile'] = devnull
155         self.options.update(options)
156         clean_dict(self.options)
157
158
159 # VIM MODLINE
160 # vim: ai ts=4 sw=4 sts=4 expandtab