[WIP] improvements overview/test

This commit is contained in:
zolliker 2023-10-06 17:24:05 +02:00
parent 92d44f5c94
commit 7ac25158eb
2 changed files with 79 additions and 37 deletions

View File

@ -25,7 +25,7 @@ import os
import re
import builtins
from glob import glob
from collections import defaultdict
from itertools import zip_longest
from os.path import join, isdir, basename, expanduser, exists
from configparser import ConfigParser
from .base import ServiceManager, ServiceDown, UsageError
@ -62,7 +62,14 @@ class Namespace(dict):
__builtins__ = builtins
def make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict=False):
SEAEXT = {'main': '.config', 'stick': '.stick'}
def get_service(key):
return key if key in ('main', 'stick') else 'addons'
def make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict=False, giventitle='nicos'):
overview = {}
for service in 'main', 'stick':
given = givencfgs.get(service)
@ -80,43 +87,67 @@ def make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict=False):
if addon:
overview.setdefault(addon, {})['frappy'] = addon
seacfgfiles = [(c or '') + SEAEXT.get(s, '.addon')
for c, s in zip_longest(seacfgs, FrappyManager.services)]
seacfgset = set(seacfgfiles)
inverted_sea_info = {k: [] for k in seacfgfiles}
for cfg, seacfg in sea_info.items():
if seacfg in seacfgset:
inverted_sea_info[seacfg].append(cfg)
error = False
result = {}
addons = set()
for i, seacfg in enumerate(seacfgs):
if i == 0:
key, ext = 'main', '.config'
elif i == 1:
key, ext = 'stick', '.stick'
else:
key, ext = None, '.addon'
available = sea_info.get(seacfg + ext, ())
for seacfg, seacfgfile, key in zip_longest(seacfgs, seacfgfiles, ('main', 'stick')):
service = key or 'addons'
if not seacfg:
continue
available = inverted_sea_info[seacfgfile]
if available:
proposed = list(available)[0] if len(available) == 1 else None
proposed = available[0] if len(available) == 1 else None
if not proposed:
running = None
for item in available:
if item == overview.get(key or item, {}).get('given'):
proposed = item
if item == overview.get(key or item, {}).get('frappy'):
frappy = item
if frappy and not proposed:
proposed = frappy
running = item
if running and not proposed:
proposed = running
if proposed:
itemdict = overview.setdefault(key or proposed, {})
given = itemdict.get('given')
itemdict.update(name=(key or 'addon'), sea=seacfg,
remark='ok' if given == proposed else f'change to {proposed}')
if key:
result[key] = given
running = overview.get(key or proposed, {}).get('frappy')
if running == proposed:
remark = '' if given == running else 'reconnect'
else:
addons.add(given)
remark = f'restart'
itemdict.update(name=service, sea=seacfg, remark=remark)
if key:
result[key] = proposed
else:
addons.add(proposed)
else:
for item in available:
overview.setdefault(item, {}).update(name=item, remark='ambiguous', sea=seacfg)
overview.setdefault(item, {}).update(name=service, frappy=item, remark='ambiguous', sea=seacfg)
error = True
else:
overview.setdefault(key or seacfg, {}).update(name=key or '', sea=seacfg, remark='missing frappy config')
overview.setdefault(key or seacfg, {}).update(name=service, sea=seacfg,
remark='missing frappy config')
error = True
restart = set()
for key, itemdict in overview.items():
running = itemdict.get('frappy')
if running:
service = get_service(key)
if service == 'addons':
addons.add(running)
if not itemdict.get('sea'):
if sea_info.get(running):
restart.add(service)
itemdict['remark'] = f'restart to start sea'
elif itemdict.get('given') != running:
itemdict['remark'] = f'reconnect'
if addons:
result['addons'] = ','.join(addons)
@ -125,18 +156,17 @@ def make_proposed(givencfgs, ourcfgs, seacfgs, sea_info, strict=False):
result = {}
else:
for service, cfg in ourcfgs.items():
key = cfg if service is 'addons' else service
if cfg:
prop = result.get(service, '')
if prop == cfg:
if prop == cfg and service not in restart:
result[service] = True
columns = ['name', 'given', 'frappy', 'sea', 'remark']
rows = [columns[:-1] + [' ']] + [[d.get(c) or '' for c in columns] for d in overview.values()]
rows = [['', giventitle, 'frappy', 'sea', '']] + [[d.get(c) or '' for c in columns] for d in overview.values()]
wid = [max(len(v) for v in column) for column in zip(*rows)]
# insert title lines
rows.insert(1, ['-' * w for w in wid])
return result, [' '.join(v.ljust(w) for w, v in zip(wid, row)) for row in rows]
rows.insert(1, [''] + ['-' * w for w in wid[1:-1]] + [''])
return result, [' '.join(v.ljust(w) for w, v in zip(wid, row)) for row in rows]
class FrappyManager(ServiceManager):
@ -284,7 +314,8 @@ class FrappyManager(ServiceManager):
:param service: service nor None for all services
:param list_info: None or a dict to collect info in the form
dict <cfgdir> of <cfg> of <description>
:param sea_info: None or a dict <sea config> of set() to be populated
:param sea_info: None or a dict <frappycfg> of <seacfg> with info about sea configs
in frappy cfgs to be populated
:return: set of available config
"""
all_cfg = set()
@ -305,6 +336,7 @@ class FrappyManager(ServiceManager):
if cfg not in all_cfg:
if sea_cfg and sea_info is not None:
sea_info.setdefault(sea_cfg, set()).add(cfg)
sea_info[cfg] = sea_cfg
all_cfg.add(cfg)
if list_info is not None:
list_info.setdefault(cfgdir, {})[cfg] = desc.split('\n', 1)[0]
@ -320,11 +352,10 @@ class FrappyManager(ServiceManager):
else:
for service in self.services:
self.all_cfg(ins, service, list_info, sea_info)
sea_ambig = {} # collect info about ambiguous sea info
seacfgpat = re.compile(r'(.*)(\.config|\.stick|\.addon)')
for seacfg, cfgset in sea_info.items():
name, ext = seacfgpat.match(seacfg).groups()
sea_ambig.update({k: (name, ext, len(cfgset)) for k in cfgset})
sea_ambig = {} # collect info about ambiguous sea info
for cfg, seacfg in sea_info.items():
sea_ambig.setdefault(seacfg, set()).add(cfg)
ambiguous = 0
keylen = max(max(len(k) for k in cfgs) for cfgs in list_info.values())
for cfgdir, cfgs in list_info.items():
@ -332,12 +363,14 @@ class FrappyManager(ServiceManager):
prt('')
prt('--- %s:' % cfgdir)
for cfg, desc in cfgs.items():
if cfg in sea_ambig:
name, ext, n = sea_ambig[cfg]
seacfg = sea_info.get(cfg)
if seacfg:
name, ext = seacfgpat.match(seacfg).groups()
if name == cfg or name + 'stick' == cfg:
prefix = '* '
else:
prefix = f'* ({name}{ext}) '
n = len(sea_ambig.get(seacfg))
if n > 1:
prefix = '!' + prefix[1:]
ambiguous += 1

View File

@ -2,10 +2,13 @@ import pytest
from servicemanager.frappyman import make_proposed
sea_info = {
'ma10.config': {'ma10'},
'ma10.stick': {'ma10stick', 'ma10'},
'rt.addon': {'rt', 'roomt'},
'befilter.addon': {'befilter'},
'ma10': 'ma10.config',
'ma10stick': 'ma10.stick',
'ma11': 'ma11.config',
'ma11stick': 'ma11.stick',
'roomt': 'rt.addon',
'rt': 'rt.addon',
'befilter': 'befilter.addon',
}
given = dict(main='ma10', stick='ma10stick')
@ -22,3 +25,9 @@ def test_proposed(given, current, seacfg, output, proposed, proposedstrict):
props, overview = make_proposed(given, current, seacfg, sea_info, True)
assert overview == output
assert props == proposedstrict
def do():
prop, tab = make_proposed(given, cfgs, seacfg, sea_info)
print(prop)
print('\n'.join(tab))