0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-24 02:31:55 +00:00
bird/python/BIRD/Config.py
2023-05-23 13:44:48 +02:00

100 lines
3.0 KiB
Python

from datetime import datetime
from weakref import WeakKeyDictionary
import itertools
class ConfigObject:
def __init__(self, comment=None):
self.symbols = {}
self.config = WeakKeyDictionary()
self.comment = comment
def isp(self, indent):
return " " * indent
def append(self):
return "" if self.comment is None else f" # {self.comment}"
def lines(self, indent):
return [] if self.comment is None else [ f"{self.isp(indent)}# {self.comment}" ]
def writelines(self, f):
f.writelines([ x + "\n" for x in self.lines(0) ])
class Timestamp(ConfigObject):
def __init__(self, comment):
super().__init__(comment=f"{comment} at {datetime.now()}")
class BlockOption(ConfigObject):
def __init__(self, config_text, _type, value, **kwargs):
super().__init__(**kwargs)
if not isinstance(value, _type):
raise Exception("BlockOption value doesn't match declared type")
self.config_text = config_text
self._type = _type
self.value = value
def set(self, value, **kwargs):
if value == self.value and len(kwargs) == 0:
return self
else:
return type(self)(self.config_text, self._type, value, **kwargs)
def lines(self, indent):
return [ f"{self.isp(indent)}{self.config_text} {self.value};{self.append()}" ]
class ConfigBlock(ConfigObject):
def __init__(self, **kwargs):
super().__init__(**{ k:v for k,v in kwargs.items() if k not in self.options })
self.options_set = {}
for k,v in kwargs.items():
if k in self.options:
self.options_set[k] = self.options[k].set(v)
def set(self, arg, val, **kwargs):
if arg not in self.options:
raise NotImplementedError
self.options_set[arg] = self.options[arg].set(val, **kwargs)
def lines(self, indent):
inside = [
(opt.lines(indent+1))
for k,opt in self.options_set.items()
if opt != self.options[k]
]
header = self.block_header()
isp = " " * indent
if len(inside) == 0:
return [ header + " {}" + self.append() ]
else:
return [ *super().lines(indent), isp + header + " {", *itertools.chain(*inside), isp + "}" ]
class ProtocolConfig(ConfigBlock):
options = {
"disabled": BlockOption("disabled", bool, False),
}
def __init__(self, name=None, template=None, **kwargs):
super().__init__(**kwargs)
self.name = name
if template is not None:
raise NotImplementedError()
def block_header(self):
return f"protocol {self.protocol_type}{'' if self.name is None else ' ' + self.name }"
class DeviceProtocolConfig(ProtocolConfig):
name_prefix = "device"
protocol_type = "device"
options = ProtocolConfig.options | {
"scan_time": BlockOption("scan time", int, 60),
}