Skip to content

Commit d9d4227

Browse files
committed
config editor from cli
1 parent 11077de commit d9d4227

File tree

2 files changed

+122
-1
lines changed

2 files changed

+122
-1
lines changed

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ progressbar33
1212
scikit_learn
1313
face_recognition
1414
pyzm>=0.3.48
15-
bjoern
15+
bjoern
16+
configupdater

tools/config_edit.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/usr/bin/python3
2+
3+
# argparse k,v handling: https://stackoverflow.com/a/52014520/1361529
4+
import sys
5+
from configupdater import ConfigUpdater
6+
import argparse
7+
import logging
8+
9+
def parse_var(s):
10+
items = s.split('=',1)
11+
sk = items[0].split(':',1)
12+
if len(sk) == 1:
13+
key = sk[0]
14+
section = '_global_'
15+
else:
16+
key=sk[1]
17+
section=sk[0]
18+
19+
key = key.strip() # we remove blanks around keys, as is logical
20+
section = section.strip() # we remove blanks around keys, as is logical
21+
22+
if len(items) > 1:
23+
# rejoin the rest:
24+
value = '='.join(items[1:])
25+
return (section, key, value)
26+
27+
28+
def parse_vars(items):
29+
d = {}
30+
if items:
31+
for item in items:
32+
section, key, value = parse_var(item)
33+
#logger.debug ('Updating section:{} key:{} to value:{}'.format(section,key,value))
34+
if not d.get(section):
35+
d[section]={}
36+
d[section][key] = value
37+
return d
38+
39+
40+
# main
41+
logger = logging.getLogger()
42+
handler = logging.StreamHandler()
43+
formatter = logging.Formatter('[%(asctime)s] [%(filename)s:%(lineno)d] %(levelname)s - %(message)s','%m-%d %H:%M:%S')
44+
45+
handler.setFormatter(formatter)
46+
logger.addHandler(handler)
47+
48+
49+
ap = argparse.ArgumentParser(
50+
description='config editing script',
51+
epilog='''
52+
Example:
53+
%(prog)s --config /etc/zm/zmeventnotification.ini --set network:address=comment_out general:restart_interval=60 network:port=9999 general:base_data_path='/my new/path with/spaces'
54+
55+
'''
56+
)
57+
ap.add_argument('-c', '--config', help='input ini file with path', required=True)
58+
ap.add_argument('-o', '--output', help='output file with path')
59+
ap.add_argument('--nologs', action='store_true', help='disable logs')
60+
ap.add_argument('--set',
61+
metavar='[SECTION:]KEY=VALUE',
62+
nargs='+',
63+
help='''
64+
Set a number of key-value pairs.
65+
(do not put spaces before or after the = sign).
66+
If a value contains spaces, you should define
67+
it witin quotes. If you omit the SECTION:, all keys in all
68+
sections that match your key will be updated.
69+
If you do specify a section, remember to add the : after it
70+
Finally, use the special keyword of 'comment_out' if you want
71+
to comment out a key. There is no way to 'uncomment' as once it is
72+
a comment, it won't be found as a key.
73+
''')
74+
75+
args, u = ap.parse_known_args()
76+
args = vars(args)
77+
78+
if args.get('nologs'):
79+
logger.setLevel(logging.CRITICAL + 1)
80+
else:
81+
logger.setLevel(logging.DEBUG)
82+
83+
values = parse_vars(args['set'])
84+
85+
86+
input_file = args['config']
87+
updater = ConfigUpdater(space_around_delimiters=False)
88+
updater.read(input_file)
89+
90+
91+
for sec in values:
92+
if sec == '_global_':
93+
continue
94+
for key in values[sec]:
95+
if values[sec][key]=='comment_out' and updater[sec].get(key):
96+
logger.debug ('commenting out [{}]->{}={}'.format(sec,key,updater[sec][key].value))
97+
updater[sec][key].key = '#{}'.format(key)
98+
99+
else:
100+
logger.debug ('setting [{}]->{}={}'.format(sec,key,values[sec][key]))
101+
updater[sec][key] = values[sec][key]
102+
103+
if values.get('_global_'):
104+
for key in values.get('_global_'):
105+
for secname in updater.sections():
106+
if updater.has_option(secname,key):
107+
if values['_global_'][key]=='comment_out' and updater[secname].get(key):
108+
logger.debug ('commenting out [{}]->{}={}'.format(secname,key,updater[secname][key].value))
109+
updater[secname][key].key = '#{}'.format(key)
110+
else:
111+
updater[secname][key] = values['_global_'][key]
112+
logger.debug ('{} found in [{}] setting to {}'.format(key,secname,values['_global_'][key]))
113+
114+
115+
116+
output_file_handle = open(args['output'],'w') if args.get('output') else sys.stdout
117+
updater.write(output_file_handle)
118+
if output_file_handle is not sys.stdout:
119+
output_file_handle.close()
120+

0 commit comments

Comments
 (0)