from yaml import safe_load from schema import And, Optional, Regex, Schema, SchemaError, Or def get_validated_config(filename): config_schema = Schema({ "bar": { Optional("config"): { Optional("geometry"): Regex(r'^[0-9]*x[0-9]*\+[0-9]*\+[0-9]*$'), Optional("bottom"): bool, Optional("force"): bool, Optional("font"): str, Optional("name"): str, Optional("line_thickness"): And(int, lambda n: n > 0), Optional("bg_color", default="#000"): Regex(r'^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$|^#[0-9a-fA-F]{8}$'), Optional("fg_color", default="#FFF"): Regex(r'^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$|^#[0-9a-fA-F]{8}$'), Optional("offset"): int, Optional("line_color"): Regex(r'^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$|^#[0-9a-fA-F]{8}$'), Optional("padding", default=" "): str, Optional("seperator", default="|"): str, Optional("global_padding", default=""): str }, "modules": [ { "name": str, "command": str, "refresh": And(int, lambda n : n >= 0), Optional("prefix"): str, "format": { "align": Or("left", "center", "right"), Optional("bg_color"): Regex(r'^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$|^#[0-9a-fA-F]{8}$'), Optional("fg_color"): Regex(r'^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$|^#[0-9a-fA-F]{8}$'), Optional("font"): And(int, lambda n: 1 <= n <= 5), Optional("offset"): int, Optional("line"): { "type": Or("underline", "overline"), Optional("color"): Regex(r'^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$|^#[0-9a-fA-F]{8}$') }, Optional("button"): { "activator": Or("left", "center", "right", "scrup", "scrdown"), "command": str } } } ] } }) with open(filename, "r", encoding="utf8") as file: config_file = safe_load(file) try: return config_schema.validate(config_file) except SchemaError as se: raise se def get_lemonbar_flags(config): configuration_options = config["bar"]["config"] flags = "" for option in configuration_options: match option: case 'geometry': flags += (" -g '" + configuration_options[option] + "'") case 'bottom': flags += (" -b") case 'force': flags += (" -d") case 'font': flags += (" -f '" + configuration_options[option] + "'") case 'name': flags += (" -n '" + configuration_options[option] + "'") case 'line_thickness': flags += (" -u " + str(configuration_options[option])) case 'bg_color': flags += (" -B '" + configuration_options[option] + "'") case 'fg_color': flags += (" -F '" + configuration_options[option] + "'") case 'offset': flags += (" -o " + str(configuration_options[option])) case 'line_color': flags += (" -U '" + configuration_options[option] + "'") return flags.strip() def parse_module(module): alignment = "" pre = "" name = "" prefix = "" command = "" refresh = 0 post ="" for option in module: match option: case "name": name = module[option] case "command": command = module[option] case "refresh": refresh = module[option] case "prefix": prefix = module[option] format_options = module["format"] for option in format_options: match option: case "align": alignment = format_options[option] case "offset": pre = ("%{O" + str(format_options[option]) + "}") + pre case "bg_color": pre = ("%{B" + format_options[option] + "}") + pre post += "%{B-}" case "fg_color": pre = ("%{F" + format_options[option] + "}") + pre post += "%{F-}" case "font": pre = ("%{T" + format_options[option] + "}") + pre post += "%{T-}" case "line": line_options = format_options[option] for line_option in line_options: match line_option: case "type": if line_options[line_option] == "underline": pre = ("%{+u}") + pre post += ("%{-u}") elif line_options[line_option] == "overline": pre = ("%{+o}") + pre post += ("%{-o}") case "color": pre = ("%{U" + line_options[line_option] + "}") + pre post += "%{U-}" case "button": button_options = format_options[option] button = 1 match button_options["activator"]: case "left": button = 1 case "middle": button = 2 case "right": button = 3 case "scrup": button = 4 case "scrdown": button = 5 pre = ("%{A" + str(button)+ ":" + button_options["command"] + ":}") + pre post += "%{A}" return [alignment, pre, name, prefix, command, post, refresh]