from abc import ABC, abstractmethod from owrx.jsons import Encoder import json class Converter(ABC): @abstractmethod def convert_to_form(self, value): pass @abstractmethod def convert_from_form(self, value): pass class NullConverter(Converter): def convert_to_form(self, value): return value def convert_from_form(self, value): return value class OptionalConverter(Converter): """ Transforms a special form value to None The default is look for an empty string, but this can be used to adopt to other types. If the default is not found, the actual value is passed to the sub_converter for further transformation. useful for optional fields since None is not stored in the configuration """ def __init__(self, sub_converter: Converter = None, defaultFormValue=""): self.sub_converter = NullConverter() if sub_converter is None else sub_converter self.defaultFormValue = defaultFormValue def convert_to_form(self, value): return self.defaultFormValue if value is None else self.sub_converter.convert_to_form(value) def convert_from_form(self, value): return None if value == self.defaultFormValue else self.sub_converter.convert_from_form(value) class IntConverter(Converter): def convert_to_form(self, value): return str(value) def convert_from_form(self, value): return int(value) class FloatConverter(Converter): def convert_to_form(self, value): return str(value) def convert_from_form(self, value): return float(value) class EnumConverter(Converter): def __init__(self, enumCls): self.enumCls = enumCls def convert_to_form(self, value): return None if value is None else self.enumCls(value).name def convert_from_form(self, value): return self.enumCls[value].value class JsonConverter(Converter): def convert_to_form(self, value): return json.dumps(value, cls=Encoder) def convert_from_form(self, value): return json.loads(value) class WaterfallColorsConverter(Converter): def convert_to_form(self, value): if value is None: return "" return "\n".join("#{:06x}".format(v) for v in value) def convert_from_form(self, value): def parseString(s): try: if s.startswith("#"): return int(s[1:], 16) # int() with base 0 can accept "0x" prefixed hex strings, or int numbers return int(s, 0) except ValueError: return None # \r\n or \n? this should work with both. values = [parseString(v.strip("\r ")) for v in value.split("\n")] return [v for v in values if v is not None]