From 78f21a834e772642d9f657b9c5f46b24c6bc73d9 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Wed, 26 Mar 2025 09:27:26 +0100 Subject: [PATCH] Watch directory --- .gitignore | 1 + foucault/__pycache__/__init__.cpython-313.pyc | Bin 196 -> 0 bytes foucault/__pycache__/gui.cpython-313.pyc | Bin 24130 -> 0 bytes foucault/gui.py | 33 ++++++++++++++++-- main.py | 14 +------- 5 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 .gitignore delete mode 100644 foucault/__pycache__/__init__.cpython-313.pyc delete mode 100644 foucault/__pycache__/gui.cpython-313.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/foucault/__pycache__/__init__.cpython-313.pyc b/foucault/__pycache__/__init__.cpython-313.pyc deleted file mode 100644 index 8513b21b1b824857c80a217dea4d1c9b880b85a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmey&%ge<81koRErGx0lAOZ#$p^VQgK*m&tbOudEzm*I{OhDdekkqYY{fzwFRQ;mT zq|`ipm;B_?+|<01V*P-k{H)aE5}=rofsuiJaB6aCQD#Y{LRe;TW`3T2VqSi3Vos%Q zN@@vEReq6vT7GGAVrfnZf)O8|nU`4-AFo$Xd5gm)H$SB`C)KWq6=)~OO~oL_M`lJw J#v*1Q3jjQnHLd^v diff --git a/foucault/__pycache__/gui.cpython-313.pyc b/foucault/__pycache__/gui.cpython-313.pyc deleted file mode 100644 index 51e83fa1f159b9c572a860110d58a188885cf65b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24130 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 QqIc5toAg79JV;0X9~+9JZvX%Q diff --git a/foucault/gui.py b/foucault/gui.py index c890b3b..18d06a5 100644 --- a/foucault/gui.py +++ b/foucault/gui.py @@ -86,6 +86,7 @@ class SubprocessController(): @classmethod def from_toml(cls, filename: os.PathLike): + logger.info(f"Load from TOML {filename}") path = pathlib.Path(filename) name = path.stem args = [] @@ -93,7 +94,7 @@ class SubprocessController(): data = tomllib.load(fp) print(data) - for arg in data['arguments']: + for arg in data.get('arguments', []): args.append(Argument.from_dict(arg)) sc = cls( @@ -198,10 +199,34 @@ class Foucault(): def __init__(self): self.processes: list[SubprocessController] = [] self.uis: list[SubprocessUI] = [] + self.directories: list[pathlib.Path] = [] def add_process(self, sc: SubprocessController): + logger.info(f"add process {sc.as_bash_string()}") self.processes.append(sc) self.uis.append(SubprocessUI(sc)) + self.ui.refresh() + + def watch(self, path: os.PathLike): + path = pathlib.Path(path).resolve() + if path.is_dir(): + if path in self.directories: + logger.warning(f"Path already watched {path}") + self.directories.append(path) + self.update_watched() + elif path.suffix == 'toml': + self.add_process(SubprocessController.from_toml(path)) + else: + raise RuntimeError(f"Not a valid path {path}") + + def update_watched(self): + # TODO)) It would be great to use e.g. Watchdog + fns = [scu.sc.filename for scu in self.uis] + for d in self.directories: + config_files = d.glob("**/*.toml") + for path in config_files: + if path not in fns: + self.add_process(SubprocessController.from_toml(path)) def run_all(self): for p in self.processes: @@ -217,6 +242,7 @@ class Foucault(): self.stop_all() self.run_all() + @ui.refreshable_method def ui(self): with ui.row(): ui.button('▶', on_click=self.run_all) @@ -248,6 +274,7 @@ class Foucault(): i+=1 # if we're only interested in running, we can use os.waitpid(), but we also check config changes time.sleep(.3) + self.update_watched() for proc_ui in self.uis: state = proc_ui.sc.state() if state != states[proc_ui.sc]: @@ -262,7 +289,7 @@ class SubprocessUI: @ui.refreshable_method def ui(self): - card_class = "bg-teal" if self.sc.is_running() else ("bg-warning" if self.sc.return_code() else "bg-gray") + card_class = "bg-teal" if self.sc.is_running() else ("bg-warning" if self.sc.return_code() and math.abs(self.sc.return_code()) != 15 else "bg-gray") with ui.card().classes(card_class): with ui.row(align_items="stretch").classes('w-full'): if self.sc.return_code(): @@ -276,7 +303,7 @@ class SubprocessUI: ui.button('↺', on_click=self.sc.restart, color='red' if self.sc.is_stale() else "primary") - ui.label(f'Running: {self.sc.is_running()}') + ui.label(f'Running: {self.sc.is_running()}' + f"({self.sc.return_code()})") ui.code(f'{" ".join(self.sc.cmd)}') ui.code(self.sc.as_bash_string()) ui.separator() diff --git a/main.py b/main.py index 2e24fb4..ab8c673 100644 --- a/main.py +++ b/main.py @@ -2,21 +2,9 @@ from pathlib import Path from foucault.gui import * -# print(sc) - logging.basicConfig(level=logging.INFO) conductofconduct = Foucault() -sc = SubprocessController.from_toml(Path('processes/tail.toml')) -sc2 = SubprocessController.from_toml(Path('processes/tail2.toml')) -sc3 = SubprocessController.from_toml(Path('processes/tail.toml')) -conductofconduct.add_process(sc) -conductofconduct.add_process(sc2) -conductofconduct.add_process(sc3) -# conductofconduct.add_process(SubprocessController("test1" , ["tail"], ['-f', "gui.py"])) -# conductofconduct.add_process(SubprocessController("test2" , ["tail"], ['-f', "gui.py"])) -# conductofconduct.add_process(SubprocessController("test3 broken" , ["tail"], ['-f', "nonexistent.py"])) -# conductofconduct.add_process(SubprocessController("system status" , ["uv run status.py"], ['-f', "nonexistent.py"])) - +conductofconduct.watch("processes") conductofconduct.run()