From 8aee497225d1b8394bf3ac0ee494490ac9333431 Mon Sep 17 00:00:00 2001 From: Noah Swerhun Date: Sun, 12 Feb 2023 14:09:01 -0600 Subject: [PATCH] finished new parsing --- __pycache__/config_parsing.cpython-310.pyc | Bin 0 -> 3639 bytes config_parsing.py | 106 ++++++++++++++++----- example_config.yml | 93 +++++++++--------- lemonbar_command.py | 33 +------ main.py | 56 +++++++++++ modules.py | 101 -------------------- 6 files changed, 189 insertions(+), 200 deletions(-) create mode 100644 __pycache__/config_parsing.cpython-310.pyc create mode 100644 main.py delete mode 100644 modules.py diff --git a/__pycache__/config_parsing.cpython-310.pyc b/__pycache__/config_parsing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fda87f63cfb181feed5d32422db9746c66b6583 GIT binary patch literal 3639 zcmZ`+&2t<_6`$_;*x64@vTRxYh}V&9c`dIcCnPqmV8_8xaR9kMaiv(WRio|M)s}W= z);%LTQf4R{r6?{gNEIh4Ma2gWzQc_RN1*rz8j1@Sbff|tl&YBD>)Dkh%h{=Z-Tiy7 zU%&2t?{#ljE*A{^9$(pR{&B)E{z;v^KaS43DA9L7gdteh=&=T4)aG5@GaF{lYFItH zVfUPd)5|q-J-6Y4Zwl)ZqmdW3a8MUSPPnLxBEMwR3fs_T)R@XgUdvzZhMuT7%Dfo} z<=*bcoiOma%Km}h_CHe2QghYsd8(Mz?@Jj<#c#_dBOQaEjrt7Aw^5?cz=>gM%mm*e zYJzfM>9!4O0&@m+4z-28JE-%h?bs0oQT)W%;^34-SyY~IXgCBO6C+}DUw;g!1N<=R zq0G2AqGd?)Q8AIVJ0)>UxUnTBQI6|bPVCNd5~D3~O1u{5#A#6#XST@7(jJ{7d)j0* zS^4_z_@Nb3TTDzt$60YsTR$@#)uFYVM{l5C)Wn4?8*|Qn#yh!=-DVx$VOuO^v6~p; zqNs~YPt0GGQXc0M>|<(vh(ovVZJEpn+{;GvyN7TD`hJMA=_Ks)LSjB;9~w)Lii;b6 zWkza&!xQVLOrZS}>mhq+)aDkIx#CIXG{d0PX)Cwwhdn=*8=I%^{b;`a&AS&q%BmmF z?ysknvl7N}*i&{Zluch*tuTm{6?i>gRl1$PUyfHh&9%UfqJ92BzCy0Ngz|+8f)%ng zYsq-V7bP*D8PAwvfjo@1COdD;t-`3eAoNz}BH5hty=a5%t#|!i7{L6w%=+cNC!H19e&p=~$klXOxvdu(7Zw(j6Si8B zAFG1iDLt3U^*teA{tl}m8vVX6y*QLREK#{$DAv1vq;k!$*YgmYIqA2gAFY1v*2+=Z zzOmsR%JJQn-q)klMV2upsc{TMIeqBtAj)x`Jug-^_Ng5xtLwL7_=g|FzErmCv{&N; zvzkyq2O5zk!4f!~X{@m@FZdc;!g({WYv$rM9q=}#i0pX3&Z^U-iw^CW0R!Mn%8EDo zzRIr$!j~Fw!v}+woo%19vJQU?lpQtYdSB&GiSS`i<0|hpf#Yb6Z3%8X(uX?e=*1hFKCRaV&d14-sJ+@Uwg9J)0d2i@uV z6ajlar6$);!pgfq?@R$}hp8)GB*Tp;xE|L}^% zEmi@-2iO?e4l5A%E61t;x4z>4<6rXU{NK*=k=X(}`J9_2jIo&eh(DJ%FwMT>rO9b$ zbUt6e`BA)1;>wvcQsncLC+wDS_gATzn3f@|H7-vvBjLhMSYl2Z6NYdmj4MXUgU8_K zz@O24S7Q%><$+z+SV3bwU`1dzHC8&H=PvkV@V~G5l>_|mfqw{mPxD7&Ba_%-13SJ2 z{wVnOHGk~D_&WH9!GEmz;|KVsz&`^1r<#BCfc~(NA|((zZ~jEK!h~k_1X~< zm+rspw`1hD!*sl?MM-t^4UiJ~7Cf)Oj-m`dY9A~P8)y8H%jEkQxX%x1^%P^;4_6R; z0{0^dM=?<>6kG7rL7hvCTgKh5ngT00B=22JGA_wev4z&A8bz9)(kh>Hn| zgg-&11R30SqMS+WCcqzagq?{FhA5WVWUyaV9M%CGq+sE)FpT4PRg-z=A6J)98PR{#o>o zp?^+~#cM{)067HYyhh4EYCs%uLH7@f*|aP!;ta}q|LfTQlCX46x->istZPnNbpx@= z6Em?AJIN(ZJBJvZUzG2{<@B>ehn&7YqDh_1g)SCzZ~vQ0Oce3M%GqNDJX7ePqX%^h}alV3|WEws}b)5)P$QBL;y zz%@z_f*u|M%EVhC+Yr4CQ>2D=MOpn2$>bKAjY{^87$%TLNk4T4>7-HI(`!_+t9vM# zt!4N9m)(pddffTTnJsrPLG*JF3%TXR=W@z2FFuFz&Lfv+*@y7sDC1gUFQxmGM$*kX zq?CzhH2<$#axn+pqFE{FJD7A^tg2Gc%Rg;6pvF?ZiCo%lcWA|oyU literal 0 HcmV?d00001 diff --git a/config_parsing.py b/config_parsing.py index 79ad5c4..652a863 100644 --- a/config_parsing.py +++ b/config_parsing.py @@ -1,6 +1,5 @@ -from yaml import dump, safe_load +from yaml import safe_load from schema import And, Optional, Regex, Schema, SchemaError, Or -from json import dumps def get_validated_config(filename): config_schema = Schema({ @@ -21,24 +20,23 @@ def get_validated_config(filename): }, "modules": [ { - 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 - } + "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 } } } @@ -84,7 +82,71 @@ def get_lemonbar_flags(config): flags += (" -U '" + configuration_options[option] + "'") return flags.strip() - -print(get_lemonbar_flags(get_validated_config("./testing_config.yml"))) +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] diff --git a/example_config.yml b/example_config.yml index ea40617..b298382 100644 --- a/example_config.yml +++ b/example_config.yml @@ -47,51 +47,52 @@ bar: modules: # This is an example module. You can name it whatever you want, it doesn't # matter. Notice the `-` before the name. Each module must be a list item! - - example_module: - # This command is run by `sh -c`, and whatever is sent to stdout is the - # text that will be displayed for this module. `date` here is used as an - # example. THIS IS A REQUIRED FIELD. - command: "date" - # How often to re-run the command and display the updated text. THIS IS A - # REQUIRED FIELD. - refresh: 1000 - # Prefix to be printed before the text of the command. - prefix: "DATE: " - # Formatting options. These will only affect the text and padding of this - # module. - format: - # Where the text should be placed on the bar. `left`, `right`, or - # `center`. THIS IS A REQUIRED FIELD. - align: left - # Background color of the bar. - bg_color: "#000" - # Text color - fg_color: "#FFF" - # INDEX of the font for this module to be displayed in (see above). - font: 1 - # Horizontal offset of the module text in pixels (can be negative). - offset: 0 - # Set an underline or overline - line: - # Self-explanatory. `underline` or `overline`. IF you set a line, then - # this is a required field. - type: underline - # Set a custom color for the line. - color: "#000" - # Make this module act like a button. Both of these fields are required - # if you are making a button. You may also define multiple buttons with - # different activators for a single module. - button: - # What mouse click you have to make to activate the button. Can be - # `left`, `center`, or `right`. You can also set it to activate when - # you scroll up or down with `scrup` and `scrdown.` - activator: left - # Command to be executed upon activation. Will be run with `sh -c`. - command: "echo 'hello' > ~/file.txt" + # THIS IS A REQUIRED FIELD. + - name: "time" + # This command is run by `sh -c`, and whatever is sent to stdout is the + # text that will be displayed for this module. `date` here is used as an + # example. THIS IS A REQUIRED FIELD. + command: "date" + # How often to re-run the command and display the updated text. THIS IS A + # REQUIRED FIELD. + refresh: 1000 + # Prefix to be printed before the text of the command. + prefix: "DATE: " + # Formatting options. These will only affect the text and padding of this + # module. + format: + # Where the text should be placed on the bar. `left`, `right`, or + # `center`. THIS IS A REQUIRED FIELD. + align: left + # Background color of the bar. + bg_color: "#000" + # Text color + fg_color: "#FFF" + # INDEX of the font for this module to be displayed in (see above). + font: 1 + # Horizontal offset of the module text in pixels (can be negative). + offset: 0 + # Set an underline or overline + line: + # Self-explanatory. `underline` or `overline`. IF you set a line, then + # this is a required field. + type: underline + # Set a custom color for the line. + color: "#000" + # Make this module act like a button. Both of these fields are required + # if you are making a button. You may also define multiple buttons with + # different activators for a single module. + button: + # What mouse click you have to make to activate the button. Can be + # `left`, `center`, or `right`. You can also set it to activate when + # you scroll up or down with `scrup` and `scrdown.` + activator: left + # Command to be executed upon activation. Will be run with `sh -c`. + command: "echo 'hello' > ~/file.txt" # Here is a simpler example module showing only the required fields. - - bare_minimum: - command: "whoami" - refresh: 1000 - format: - align: right + - name: "bare_minimum" + command: "whoami" + refresh: 1000 + format: + align: right diff --git a/lemonbar_command.py b/lemonbar_command.py index 2939939..4e95cf7 100644 --- a/lemonbar_command.py +++ b/lemonbar_command.py @@ -1,33 +1,4 @@ -import yaml -import io +from config_parsing import get_lemonbar_flags, get_validated_config -with io.open("./testing_config.yml", 'r', encoding='utf8') as file: - config_file = yaml.safe_load(file) -lemonbar_command = "lemonbar" - -lemonbar_cmd_options = config_file['bar']['config'] -for item in lemonbar_cmd_options: - match item: - case 'geometry': - lemonbar_command += (" -g '" + lemonbar_cmd_options['geometry'] + "'") - case 'bottom': - lemonbar_command += (" -b") - case 'force': - lemonbar_command += (" -d") - case 'font': - lemonbar_command += (" -f '" + lemonbar_cmd_options['font'] + "'") - case 'name': - lemonbar_command += (" -n '" + lemonbar_cmd_options['name'] + "'") - case 'line_thickness': - lemonbar_command += (" -u " + str(lemonbar_cmd_options['line_thickness'])) - case 'bg_color': - lemonbar_command += (" -B '" + lemonbar_cmd_options['bg_color'] + "'") - case 'fg_color': - lemonbar_command += (" -F '" + lemonbar_cmd_options['fg_color'] + "'") - case 'offset': - lemonbar_command += (" -o " + str(lemonbar_cmd_options['offset'])) - case 'line_color': - lemonbar_command += (" -U '" + lemonbar_cmd_options['line_color'] + "'") - -print(lemonbar_command) +print(get_lemonbar_flags(get_validated_config("./testing_config.yml"))) diff --git a/main.py b/main.py new file mode 100644 index 0000000..21a2cd8 --- /dev/null +++ b/main.py @@ -0,0 +1,56 @@ +from threading import Thread +from subprocess import run +from time import sleep +from config_parsing import get_validated_config, parse_module + +running_modules_dict = {"left": {}, "center": {}, "right": {}} + +def print_bar(): + for alignment in running_modules_dict: + match alignment: + case "left": + print("%{l}", end="") + case "center": + print("%{c}", end="") + case "right": + print("%{r}", end="") + group = running_modules_dict[alignment] + for index, module in enumerate(group): + print(group[module], end="") + if index != (len(group) - 1): + print(seperator, end="") + + print(flush=True) + +def create_module_string(pre, prefix, command, post): + cmd_output = run(command, shell=True, capture_output=True, text=True).stdout.strip() + return (pre + padding + prefix + cmd_output + padding + post) + + +def new_module_thread(alignment, pre, name, prefix, command, post, refresh): + while True: + module_string = create_module_string(pre, prefix, command, post) + running_modules_dict[alignment][name] = module_string + print_bar() + sleep(refresh/1000) + + +def main(): + global padding + global seperator + + config = get_validated_config("./testing_config.yml") + padding = config["bar"]["config"]["padding"] + seperator = config["bar"]["config"]["seperator"] + + + modules = config["bar"]["modules"] + for module in modules: + parameters = parse_module(module) + # print(parameters) + + x = Thread(target=new_module_thread, args=parameters) + x.start() + +if __name__ == "__main__": + main() diff --git a/modules.py b/modules.py deleted file mode 100644 index 7b9ee29..0000000 --- a/modules.py +++ /dev/null @@ -1,101 +0,0 @@ -from yaml import safe_load -from io import open -from threading import Thread -from subprocess import run -from time import sleep - -running_modules_dict = {"left": {}, "center": {}, "right": {}} - -def print_modules(): - for alignment in running_modules_dict: - match alignment: - case "left": - print("%{l}", end="") - case "center": - print("%{c}", end="") - case "right": - print("%{r}", end="") - for module in running_modules_dict[alignment]: - print(running_modules_dict[alignment][module], end="") - - print(flush=True) - -def new_module_thread(alignment, name, cmd, refresh, pre, post): - while True: - result = pre - result += run(cmd, shell=True, capture_output=True, text=True).stdout.strip() - result += post - running_modules_dict[alignment][name] = result - print_modules() - sleep(refresh/1000) - -def parse_module(module): - cmd = module["command"] - refresh = module["refresh"] - pre = "" - post = "" - - format_options = module["format"] - for option in format_options: - match option: - # Align is handled differently. See below. - # case "align": - case "offset": - pre += ("%{O" + str(format_options[option]) + "}") - case "bg_color": - pre += ("%{B" + format_options[option] + "}") - post += "%{B-}" - case "fg_color": - pre += ("%{F" + format_options[option] + "}") - post += "%{F-}" - case "font": - pre += ("%{T" + format_options[option] + "}") - 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}") - post += ("%{-u}") - elif line_options[line_option] == "overline": - pre += ("%{+o}") - post += ("%{-o}") - case "color": - pre += ("%{U" + line_options[line_option] + "}") - 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"] + ":}") - post += "%{A}" - - return [cmd, refresh, pre, post] - -with open("./testing_config.yml", "r", encoding="utf8") as file: - config_file = safe_load(file) - -modules = config_file["bar"]["modules"] -for module in modules: - parameters = parse_module(modules[module]) - parameters.insert(0, module) - - alignment = modules[module]["format"]["align"] - parameters.insert(0, alignment) - running_modules_dict[alignment][module] = '' - print(parameters) - - x = Thread(target=new_module_thread, args=parameters) - x.start()