class Preset: def __init__(self, data): # Set default values for all preset attributes self.p = "off" self.d = 100 self.b = 127 self.c = [(255, 255, 255)] self.a = True self.n1 = 0 self.n2 = 0 self.n3 = 0 self.n4 = 0 self.n5 = 0 self.n6 = 0 self.bg = (0, 0, 0) # Override defaults with provided data self.edit(data) def edit(self, data=None): if not data: return False aliases = { "pattern": "p", "colors": "c", "delay": "d", "brightness": "b", "auto": "a", "background": "bg", "mode": "n6", } int_fields = {"d", "b", "n1", "n2", "n3", "n4", "n5", "n6"} allowed_fields = {"p", "c", "d", "b", "a", "bg", "n1", "n2", "n3", "n4", "n5", "n6"} for key, value in data.items(): key = aliases.get(key, key) if key not in allowed_fields: continue if key in int_fields: try: parsed = int(value) if key == "b": parsed = max(0, min(255, parsed)) elif key in ("d", "n1", "n2", "n3", "n4", "n5", "n6"): parsed = max(0, parsed) setattr(self, key, parsed) except (TypeError, ValueError): continue elif key == "a": if isinstance(value, bool): self.a = value elif isinstance(value, int): self.a = bool(value) elif isinstance(value, str): lowered = value.lower() if lowered in ("true", "1", "yes", "on"): self.a = True elif lowered in ("false", "0", "no", "off"): self.a = False elif key == "c": if isinstance(value, (list, tuple)): self.c = value elif key == "bg": if isinstance(value, str) and value.startswith("#") and len(value) == 7: try: self.bg = ( int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16), ) except (TypeError, ValueError): continue elif isinstance(value, (list, tuple)) and len(value) == 3: try: self.bg = tuple(max(0, min(255, int(x))) for x in value) except (TypeError, ValueError): continue else: setattr(self, key, value) return True @property def pattern(self): return self.p @pattern.setter def pattern(self, value): self.p = value @property def delay(self): return self.d @delay.setter def delay(self, value): self.d = value @property def brightness(self): return self.b @brightness.setter def brightness(self, value): self.b = value @property def colors(self): return self.c @colors.setter def colors(self, value): self.c = value @property def auto(self): return self.a @auto.setter def auto(self, value): self.a = value def background_or(self, colors=None, default=(0, 0, 0)): bg = getattr(self, "bg", None) if isinstance(bg, (list, tuple)) and len(bg) == 3: try: return tuple(max(0, min(255, int(x))) for x in bg) except (TypeError, ValueError): return default return default def to_dict(self): return { "p": self.p, "d": self.d, "b": self.b, "c": self.c, "a": self.a, "bg": self.bg, "n1": self.n1, "n2": self.n2, "n3": self.n3, "n4": self.n4, "n5": self.n5, "n6": self.n6, }