From e161a0c1f9a90a336cdabac83780f2de87b4b38a Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Mon, 27 Oct 2025 07:08:10 +1100 Subject: [PATCH] started working on getting plugins working --- main.py | 3 ++ plugin_loader.py | 74 +++++++++++++++++++++++++++++++++ plugins/test-plugin/plugin.json | 6 +++ 3 files changed, 83 insertions(+) create mode 100644 plugin_loader.py create mode 100644 plugins/test-plugin/plugin.json diff --git a/main.py b/main.py index 7f1bcc6..641226c 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,8 @@ from assets.theme_mappings import theme_mappings from textual_fspicker import FileOpen, FileSave +from plugin_loader import PluginLoader + import subprocess import os @@ -54,6 +56,7 @@ class Berry(App): # yield Terminal(command="bash", id="terminal") yield Footer() + yield PluginLoader() def on_input_submitted(self, event: Input.Submitted): if event.input.id != "console-input": diff --git a/plugin_loader.py b/plugin_loader.py new file mode 100644 index 0000000..86d4e7e --- /dev/null +++ b/plugin_loader.py @@ -0,0 +1,74 @@ +from textual_window import Window +from textual.widgets import RichLog + +import os, json + + +class PluginLoader(Window): + def __init__(self): + super().__init__( + id="Plugin Loader", + mode="permanent", + icon="⚙️", + starting_horizontal="centerright", + starting_vertical="lowermiddle", + start_open=True + ) + + def on_mount(self): + log = self.query_one(RichLog) + log.write("[b]Finding plugins...[/]") + + # Find all plugins (they're just in the plugins folder for now) + folders = [ + os.path.join(os.path.dirname(__file__), "plugins") + ] + # path to the folder of all correctly formatted plugins + plugin_paths = [] + + for folder in folders: + log.write(f"Searching {folder}...") + plugin_folders = os.listdir(folder) + + for plugin_folder in plugin_folders: + plugin_folder = os.path.join(folder, plugin_folder) + + if not os.path.isdir(plugin_folder): + log.write(f"[d]Ignoring {plugin_folder} because it is not a folder.[/]") + continue + + if not os.path.isdir(os.path.join(plugin_folder, "lua")): + log.write(f"[d]Ignoring {plugin_folder} because it has no \"lua\" folder.[/]") + continue + + if not os.path.isfile(os.path.join(plugin_folder, "plugin.json")): + log.write(f"[d]Ignoring {plugin_folder} because it has no plugin.json file.[/]") + continue + + with open(os.path.join(plugin_folder, "plugin.json"), "r") as f: + try: + plugin_json = json.loads(f.read()) + plugin_json["name"] + plugin_json["version"] + plugin_json["author"] + plugin_json["dependencies"] + except UnicodeDecodeError: + log.write(f"[d]Ignoring {plugin_folder} because its plugin.json file is unreadable.[/]") + continue + except json.JSONDecodeError: + log.write(f"[d]Ignoring {plugin_folder} because its plugin.json file is malformed.[/]") + continue + except KeyError as e: + log.write(f"[d]Ignoring {plugin_folder} because its plugin.json file is missing the field {e}.") + continue + except Exception as e: + log.write(f"[d]Ignoring {plugin_folder} because of error: {e}.[/]") + continue + + + + log.write(f"[b green]FOUND[/] {plugin_json['name']} ({plugin_json['version']})") + plugin_paths.append(plugin_folder) + + def compose(self): + yield RichLog(markup=True, id="plugins-log") \ No newline at end of file diff --git a/plugins/test-plugin/plugin.json b/plugins/test-plugin/plugin.json new file mode 100644 index 0000000..1b3fc6e --- /dev/null +++ b/plugins/test-plugin/plugin.json @@ -0,0 +1,6 @@ +{ + "version": "0.0.1", + "name": "Test Plugin", + "author": "SpookyDervish", + "dependencies": [] +} \ No newline at end of file