From aeb7626194264dbdc008fac0ce3a8ca634df900c Mon Sep 17 00:00:00 2001 From: jonnybravo Date: Mon, 20 Jul 2026 16:20:15 +0200 Subject: [PATCH] 2 --- Caddyfile | 1 + app/app.py | 180 ++++++++++++++---- app/sicherung_1.py | 9 +- certs/localhost.crt | 19 ++ certs/localhost.key | 28 +++ certs/new-cert.crt | 19 ++ certs/new-key.key | 28 +++ docker-compose.yml | 1 + outputs/20260720_105453_hello_world.txt | 21 ++ outputs/20260720_105837_hello_world.txt | 21 ++ outputs/20260720_110257_hello_world.txt | 21 ++ outputs/20260720_110328_hello_world.txt | 21 ++ outputs/20260720_110442_hello_world.txt | 21 ++ outputs/20260720_111002_test.txt | 21 ++ outputs/20260720_111257_test.txt | 21 ++ outputs/20260720_111305_hello_world.txt | 21 ++ outputs/20260720_111310_hello_world.txt | 21 ++ outputs/20260720_111315_test.txt | 21 ++ outputs/20260720_111328_test.txt | 21 ++ outputs/20260720_161802_test.txt | 21 ++ outputs/20260720_161812_hello_world.txt | 21 ++ .../20260717_144254_hello_world.txt | 0 .../20260717_144306_hello_world.txt | 0 .../20260717_150244_hello_world.txt | 0 .../hello_world.yml => playbooks/test.yml | 0 reflex.lock/bun.lock | 53 ++++++ reflex.lock/package.json | 1 + rxconfig.py | 22 ++- rxconfig___ | 38 ---- weg | 11 -- 30 files changed, 585 insertions(+), 98 deletions(-) create mode 100644 Caddyfile create mode 100644 certs/localhost.crt create mode 100644 certs/localhost.key create mode 100644 certs/new-cert.crt create mode 100644 certs/new-key.key create mode 100644 docker-compose.yml create mode 100644 outputs/20260720_105453_hello_world.txt create mode 100644 outputs/20260720_105837_hello_world.txt create mode 100644 outputs/20260720_110257_hello_world.txt create mode 100644 outputs/20260720_110328_hello_world.txt create mode 100644 outputs/20260720_110442_hello_world.txt create mode 100644 outputs/20260720_111002_test.txt create mode 100644 outputs/20260720_111257_test.txt create mode 100644 outputs/20260720_111305_hello_world.txt create mode 100644 outputs/20260720_111310_hello_world.txt create mode 100644 outputs/20260720_111315_test.txt create mode 100644 outputs/20260720_111328_test.txt create mode 100644 outputs/20260720_161802_test.txt create mode 100644 outputs/20260720_161812_hello_world.txt rename outputs/{ => archiv}/20260717_144254_hello_world.txt (100%) rename outputs/{ => archiv}/20260717_144306_hello_world.txt (100%) rename outputs/{ => archiv}/20260717_150244_hello_world.txt (100%) rename app/playbooks/hello_world.yml => playbooks/test.yml (100%) delete mode 100644 rxconfig___ delete mode 100644 weg diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..852688b --- /dev/null +++ b/Caddyfile @@ -0,0 +1 @@ +# Diese Datei wird für den direkten Host‑Betrieb ohne Caddy nicht benötigt. diff --git a/app/app.py b/app/app.py index e5440a9..210d50a 100644 --- a/app/app.py +++ b/app/app.py @@ -4,12 +4,15 @@ import os import glob import datetime import asyncio +import traceback # --- PFADE ABSOLUT DEFINIEREN --- APP_DIR = os.path.dirname(os.path.abspath(__file__)) BASE_DIR = os.path.dirname(APP_DIR) -PLAYBOOK_DIR = os.path.join(BASE_DIR, "playbooks") +# Expliziter Pfad zum playbooks/ Ordner +PLAYBOOK_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "playbooks")) +print(f"Playbook directory: {PLAYBOOK_DIR}") OUTPUT_DIR = os.path.join(BASE_DIR, "outputs") # Sichere Ordner-Erstellung @@ -26,13 +29,34 @@ class AppState(rx.State): output: str = "" is_running: bool = False error: str = "" + show_preview: bool = False + preview_content: str = "" + + def toggle_preview(self): + """Schaltet die Vorschau um.""" + self.show_preview = not self.show_preview + if self.show_preview and self.selected_playbook: + self.load_preview() + + def load_preview(self): + """Lädt den Inhalt des ausgewählten Playbooks für die Vorschau.""" + if not self.selected_playbook: + self.preview_content = "Wählen Sie ein Playbook" + return + try: + playbook_path = os.path.join(PLAYBOOK_DIR, self.selected_playbook) + with open(playbook_path, "r", encoding="utf-8") as f: + self.preview_content = f.read() + except Exception as e: + self.preview_content = f"Fehler beim Laden: {str(e)}" - # --- NEU: Für die Historie --- past_runs: list[str] = [] selected_run: str = "" def set_selected_playbook(self, val: str): self.selected_playbook = val + if self.show_preview: + self.load_preview() def set_selected_run(self, val: str): """Setzt den ausgewählten alten Durchlauf und lädt dessen Inhalt.""" @@ -53,23 +77,58 @@ class AppState(rx.State): async def load_playbooks(self): """Lädt alle Playbooks aus dem konfigurierten Ordner.""" try: - playbook_files = glob.glob(os.path.join(PLAYBOOK_DIR, "*.yml")) + \ - glob.glob(os.path.join(PLAYBOOK_DIR, "*.yaml")) - self.playbooks = [os.path.basename(p) for p in playbook_files] - if self.playbooks and not self.selected_playbook: - self.selected_playbook = self.playbooks[0] - self.error = "" + self.playbooks = [] + print(f"Searching for playbooks in: {PLAYBOOK_DIR}") + + if not os.path.exists(PLAYBOOK_DIR): + self.error = f"Playbook directory not found: {PLAYBOOK_DIR}" + print(self.error) + return + + playbook_files = [] + for ext in ("*.yml", "*.yaml"): + playbook_files.extend(glob.glob(os.path.join(PLAYBOOK_DIR, ext))) + + print(f"Found playbook files: {playbook_files}") + + self.playbooks = sorted([os.path.basename(p) for p in playbook_files]) + + if self.playbooks: + if not self.selected_playbook or self.selected_playbook not in self.playbooks: + self.selected_playbook = self.playbooks[0] + else: + self.selected_playbook = "" + self.error = "Keine Playbooks gefunden. Bitte legen Sie welche im playbooks/ Ordner ab." + + print(f"Playbooks: {self.playbooks}") + print(f"Selected: {self.selected_playbook}") except Exception as e: self.error = f"Fehler beim Laden der Playbooks: {str(e)}" + print(f"Fehler in load_playbooks: {str(e)}") + print(f"Traceback: {traceback.format_exc()}") async def load_past_runs(self): - """Scannt den outputs/ Ordner nach alten Logs und sortiert sie (neueste zuerst).""" + """Scannt den outputs/ Ordner nach alten Logs, zeigt nur die 20 neuesten an und archiviert den Rest.""" try: + archive_dir = os.path.join(OUTPUT_DIR, "archiv") + os.makedirs(archive_dir, exist_ok=True) + log_files = glob.glob(os.path.join(OUTPUT_DIR, "*.txt")) - # Sortiert nach Dateiname absteigend (da Zeitstempel vorne steht, ist das neueste oben) - self.past_runs = sorted([os.path.basename(l) for l in log_files], reverse=True) + sorted_files = sorted(log_files, key=os.path.getmtime, reverse=True) + + for file in sorted_files[20:]: + try: + dest = os.path.join(archive_dir, os.path.basename(file)) + os.rename(file, dest) + except Exception as e: + print(f"Fehler beim Archivieren von {file}: {str(e)}") + + remaining_files = glob.glob(os.path.join(OUTPUT_DIR, "*.txt")) + self.past_runs = sorted([os.path.basename(l) for l in remaining_files], + key=lambda x: x.split("_")[0:2], reverse=True)[:20] except Exception as e: self.error = f"Fehler beim Laden der Historie: {str(e)}" + print(f"Fehler in load_past_runs: {str(e)}") async def run_playbook(self): """Führt das ausgewählte Playbook asynchron aus und speichert den Output.""" @@ -79,10 +138,13 @@ class AppState(rx.State): self.is_running = True self.error = "" - self.output = "Wird ausgeführt..." + self.output = f"Starte Ausführung von {self.selected_playbook}..." + print(f"Starte Playbook: {self.selected_playbook}") yield playbook_path = os.path.join(PLAYBOOK_DIR, self.selected_playbook) + print(f"Playbook Pfad: {playbook_path}") + timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") output_filename = f"{timestamp}_{self.selected_playbook.replace('.yml', '').replace('.yaml', '')}.txt" output_path = os.path.join(OUTPUT_DIR, output_filename) @@ -104,11 +166,9 @@ class AppState(rx.State): output_text = stdout.decode() + stderr.decode() self.output = output_text - # Output speichern try: with open(output_path, "w", encoding="utf-8") as f: f.write(output_text) - # Direkt die Historie aktualisieren, damit das neue Log auftaucht await self.load_past_runs() except Exception as e: self.error = f"Fehler beim Speichern des Outputs: {str(e)}" @@ -116,7 +176,8 @@ class AppState(rx.State): if proc.returncode != 0: self.error = f"Playbook wurde mit Fehlercode {proc.returncode} beendet." else: - self.error = "Playbook erfolgreich ausgeführt." + self.error = "" + self.error = f"{self.selected_playbook} wurde erfolgreich ausgeführt!" except asyncio.TimeoutError as e: self.error = str(e) @@ -132,30 +193,58 @@ class AppState(rx.State): def index(): return rx.container( rx.heading("Ansible Playbook Runner", size="6"), - - # Ein Grid layout: Links Steuerung & Historie, rechts das große Log-Fenster rx.grid( - # Linke Spalte (Bedienung) rx.vstack( rx.text("Playbook auswählen:", font_weight="bold"), - rx.select( - AppState.playbooks, - placeholder="Wählen Sie ein Playbook...", - value=AppState.selected_playbook, - on_change=AppState.set_selected_playbook, - width="100%", + rx.vstack( + rx.cond( + AppState.playbooks, + rx.select( + AppState.playbooks, + placeholder="Wählen Sie ein Playbook...", + value=AppState.selected_playbook, + on_change=AppState.set_selected_playbook, + width="100%", + ), + rx.text("Keine Playbooks gefunden!", color="red") + ), + rx.cond( + AppState.error, + rx.text(AppState.error, color="red"), + ), + spacing="2" ), rx.button( - "Ausführen", + rx.cond( + AppState.is_running, + rx.hstack(rx.spinner(), "Wird ausgeführt..."), + "Ausführen" + ), on_click=AppState.run_playbook, disabled=AppState.is_running, color_scheme="blue", width="100%", ), - rx.divider(margin_y="1em"), - - # --- NEU: Historie Dropdown --- + rx.vstack( + rx.button( + "Playbook-Vorschau anzeigen", + on_click=AppState.toggle_preview, + width="100%", + font_weight="bold" + ), + rx.cond( + AppState.show_preview, + rx.code_block( + AppState.preview_content, + language="yaml", + width="100%", + max_height="300px", + ) + ), + width="100%", + spacing="2" + ), rx.text("Alte Durchläufe ansehen:", font_weight="bold"), rx.select( AppState.past_runs, @@ -164,17 +253,18 @@ def index(): on_change=AppState.set_selected_run, width="100%", ), - - rx.text( + rx.cond( AppState.error, - color=rx.cond(AppState.error, "red", "transparent"), - margin_top="1em", + rx.text( + AppState.error, + color="red", + margin_top="1em", + font_weight="bold" + ), ), align_items="stretch", spacing="3", ), - - # Rechte Spalte (Textausgabe) rx.vstack( rx.text("Ausgabe / Log-Inhalt:", font_weight="bold"), rx.text_area( @@ -186,22 +276,34 @@ def index(): ), width="100%", ), - columns="2", + columns="1", + sm_columns="1", + md_columns="2", spacing="5", margin_top="2em", + width="100%", ), padding="2em", - max_width="1200px", # Etwas breiter gemacht fürs Grid-Layout + max_width="1200px", margin="auto", ) app = rx.App() -# Wichtig: Wir rufen beim Laden jetzt "load_data" auf, um beides zu laden -app.add_page(index, route="/", on_load=AppState.load_data) +app.add_page( + index, + route="/", + on_load=AppState.load_data, + meta=[] +) if __name__ == "__main__": try: - app.run(debug=True) + # Nur die benötigten Argumente übergeben; Ports/Hosts kommen aus rxconfig.py + app.run( + host="0.0.0.0", + reload=True, + log_level="debug", + ) except Exception as e: print(f"Fehler bei der Ausführung: {str(e)}") diff --git a/app/sicherung_1.py b/app/sicherung_1.py index 029ed58..c16e176 100644 --- a/app/sicherung_1.py +++ b/app/sicherung_1.py @@ -102,7 +102,14 @@ class AppState(rx.State): if proc.returncode != 0: self.error = f"Playbook wurde mit Fehlercode {proc.returncode} beendet." else: - self.error = "Playbook erfolgreich ausgeführt." + duration = (datetime.datetime.now() - start_time).total_seconds() + self.error = "" + rx.notify( + title="Erfolgreich ausgeführt", + description=f"{self.selected_playbook} in {duration:.2f} Sekunden abgeschlossen", + status="success", + duration=3000 + ) except asyncio.TimeoutError as e: self.error = str(e) diff --git a/certs/localhost.crt b/certs/localhost.crt new file mode 100644 index 0000000..4d122b5 --- /dev/null +++ b/certs/localhost.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJTCCAg2gAwIBAgIUYAf7j9oARluWbEpoJCJtFHvb0aYwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDcyMDA4NDkzM1oXDTI3MDcy +MDA4NDkzM1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAwq+iVe568a/EVtsSIJOwkhHdRYDFwzyPoIkHzcZmFGS/ +XK3E8K62DbcLNipU5kjY1s5S+HXU1Ac0lsWj5HBp43G4sOns8ugZvvhsHXqo8T5V +zQW/SGyxkPF2cACSHcdu7lgZ7+whoWl78fbpyOVd7QAKAk20sWg1MmvLSoyJI9f2 +TRjp+pvB7jYkaIniKepE20ZWPIGeanbDz4M4JIkrRE/TE9TyZZeG1fJ4dKmcUU/F +lyOmj73a5Lao2co61ShjPqAAT2lysTYHFdntH7VgnmSCbge+Vna57zjGcBRBLPeO +P+QaFdGtQHNRocQoW+/vABIwXVbt5HsPGmqLY4c0WwIDAQABo28wbTAdBgNVHQ4E +FgQUkR8RYdiJVdQBSZrcUxhYVQ5yp0AwHwYDVR0jBBgwFoAUkR8RYdiJVdQBSZrc +UxhYVQ5yp0AwDwYDVR0TAQH/BAUwAwEB/zAaBgNVHREEEzARgglsb2NhbGhvc3SH +BH8AAAEwDQYJKoZIhvcNAQELBQADggEBALBYL7slIr90e3O3KA4BAssn4SkVeHkb ++bntJGJBX6AU658iStD43nJYY2lHtOlFESYdUUz/Pyb7ZUdPAjkFA0iLqlPs8cRa +eH9sxbdX7XIVh8Ro04d1OhOiyYzn4SNFL4WGMT6jEpnklSWElZIfluIjsAgYIxMJ +lWFN6xm6qOXfxqaEpnMHvwb5lqhDP03/lOhiPAtoP187H9uh/Q3/1S2bK5nO5DnP +y44KLl2q8V0csHEJGvkWr/2KVdKpg7wOfq8wLJKNbRAYT0htHywciJO8KTCb+g/J +SGBkGsqdLRMcWaAjXXQ2V4MxGDZeeRKJhnJynUowOABcoKnqJF/xOWA= +-----END CERTIFICATE----- diff --git a/certs/localhost.key b/certs/localhost.key new file mode 100644 index 0000000..b2694b6 --- /dev/null +++ b/certs/localhost.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDCr6JV7nrxr8RW +2xIgk7CSEd1FgMXDPI+giQfNxmYUZL9crcTwrrYNtws2KlTmSNjWzlL4ddTUBzSW +xaPkcGnjcbiw6ezy6Bm++GwdeqjxPlXNBb9IbLGQ8XZwAJIdx27uWBnv7CGhaXvx +9unI5V3tAAoCTbSxaDUya8tKjIkj1/ZNGOn6m8HuNiRoieIp6kTbRlY8gZ5qdsPP +gzgkiStET9MT1PJll4bV8nh0qZxRT8WXI6aPvdrktqjZyjrVKGM+oABPaXKxNgcV +2e0ftWCeZIJuB75WdrnvOMZwFEEs944/5BoV0a1Ac1GhxChb7+8AEjBdVu3kew8a +aotjhzRbAgMBAAECggEADUDipsHw6bIjBhysy73yJ8eCjkA5dlSRnIanmtkWSu4e +3uLPhOkH6MAcycew9upfpKPwHwz6e6Kv8FGtGhiTBNJRle2e3VxyoD8OMSWQCbhK +JAZvorEPl4PwoahQSimxAhXKUjx7f58MOokqGiyPK9q0U7rRgcBL2s5ezQjrLx7e +tXZGc7RmYJ061s1Fyy5raGZW9rpxZCGVjz87f4isDZgFyT2G6wCIxYv5bj6SRyR9 +dHeKLOiUc1EJP38YYWxPu0+6gP9ltib7McLfoMlz5NgPlhHQJfY8stpgNtQlTQkQ +i+UAsK70MdsCgXNR01V4Flz344l1DiWphnEDPR9C3QKBgQDjQAFAQDHGELwWIuXp +4WSgXY7KVRvrB0o211MsBkR+vndFPpllHh2hqyMkW4Sfr8CdnF6cM1CC9HEz4Yx2 +8RoV4uP/b0XUy99LzRlDq6DTuo2ZEJ8cD8QED/qvAHiloMn99RExhcheFZSZW+2R +DJ6BSMXr/wiSSIcJztMpOnIF9wKBgQDbUPlBsyKgmgyimNW2cU6NhVWUDETmvPI2 +kK+7ZfRdqvAHfeHxuIu5fx2J2b1bjb9viN7/JXFPkSpBU3SZQbBOIDvbMVZUGkK2 +/tfvj/ZUWpbv5hCDw1Vm04EMx8BSwDqrlCcFusaraptzMJbMLTBaiDbvnjxr3tEf +tnWE3hZbvQKBgB82BjX12yAx4jNEHcGuhCyGTPs7DzeLa8T2c+TjA3tI24a2H0lF +BprSr2Pp8eAgulqrRE89uPwTaIzQmIMpgASrgdbuSG/+hC+b/rFNnCwYPiRcpQ2s +mKZaL3rjnK5a1AM+Kltb3XYWjq81cf5u9kIZZZ2RDHNS5METF+tcrJZnAoGAV+Xa +IETFSgyzp68NaDN9QicAJ3fLXZa4lLnkVH0GNUw/KyF+nrxR86RImGkWBU2IPhFj +HmtJQJRzlP73qjyzhnxQwQbDDK4BswnsTW0rUp+EAt34HHb7EV0PSan9IK0+Vmno +QdmbqjPt3XrJ1Ub/LCmPqvWGTc1djxI3g2rnFxkCgYB4y7dxwx5QJ3fqaWlRLz12 +EORm3BcqYbKAUdGgYAG2NnC1cDcNV2EGwA2Rx5hvuKcKxU9jwuv+nUtkzP7cTy+b +f/Tk5+pNIAks6bXWdPk0umCacbKu84bTjOlq1QUFBB6w6eQRO47fJ/csaUoWJgaT +MAE5zpu85O93rjEazmwDhQ== +-----END PRIVATE KEY----- diff --git a/certs/new-cert.crt b/certs/new-cert.crt new file mode 100644 index 0000000..0e82325 --- /dev/null +++ b/certs/new-cert.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIUfnlGzePBRgG7jMsbfT6tBSsvdI0wDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDcyMDA4NDYzMVoXDTI3MDcy +MDA4NDYzMVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAjzXH+Lzr0YsfceomsiTzkpczSjFs/n1mLt4L8dQWIBQ5 +9K0+FCaRgNMx+SPHO7I2GPHRA4hoCUkD12PjzA9ZBpAj2+ojFYQ++nKdCp1bY9m/ +4k5d/hK35Zf+lW+35KHTieUHXFSAK+5ialvUhVeyZcv/6GNRbNb2wWp+W2CMobNv +UldSrnDiYLSG+T3yiN//+aqJYQ+tjMqDYe2EiFR0ttYF4SUOVPfVr3ghXHMjaIHB +nq++BGVgWrL4y5hJTTPYN4f9OlmlkJq+hmGGnpNw8QcVVo6TPe2cLWIv7NHpDxfk +Nm2pm0iByneYX9vIrIExAv6Ntliy6+IC38YUbqicnwIDAQABo1MwUTAdBgNVHQ4E +FgQUUMOwmGMrursTKZdT94A69biQaOgwHwYDVR0jBBgwFoAUUMOwmGMrursTKZdT +94A69biQaOgwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXa6e +GcNSHYjSIBpMRP7qcWEBsM1Bm5N882cBSQpEwT2r0MSAcrE5eywfpPry2a89nRM1 +/cCmH+od3dssw4Y95MGULbMl9KOTWKTL6UsUux8gdNwhW55sQFwSNcMsXRE5SxwH +CBYRAqucfHmunVtHKRt4txdYgMJNpU0gtNuThp8Mp7jpsvC832n8rAFrWZHuKU02 +lvUNw2oSWg+ffWWO2Ahp0FOrNlC6yjGqJxy5gm+7QJ3L+T71L/CgXSSLPpKU2IH8 +a37iJyxEiQOckYmte96FVLidSXopR7KvJ9Vw/k//Z22+jmXVEUuqGjV1IfmTcCXG +GZbLdArIrfq4LiNrpQ== +-----END CERTIFICATE----- diff --git a/certs/new-key.key b/certs/new-key.key new file mode 100644 index 0000000..8dc5c98 --- /dev/null +++ b/certs/new-key.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCPNcf4vOvRix9x +6iayJPOSlzNKMWz+fWYu3gvx1BYgFDn0rT4UJpGA0zH5I8c7sjYY8dEDiGgJSQPX +Y+PMD1kGkCPb6iMVhD76cp0KnVtj2b/iTl3+Erfll/6Vb7fkodOJ5QdcVIAr7mJq +W9SFV7Jly//oY1Fs1vbBan5bYIyhs29SV1KucOJgtIb5PfKI3//5qolhD62MyoNh +7YSIVHS21gXhJQ5U99WveCFccyNogcGer74EZWBasvjLmElNM9g3h/06WaWQmr6G +YYaek3DxBxVWjpM97ZwtYi/s0ekPF+Q2bambSIHKd5hf28isgTEC/o22WLLr4gLf +xhRuqJyfAgMBAAECggEAJAseqeFunr4bq3GJzLNVJHNuosE+0+xev/P94J8G9Iry +rTy/D5ZHb7t36+MP3Vv0lqGh//ggaxnX4CmRZ0YDm43CoLJUozE2IpWfJdFF86MV +0tDzgiNW6m+vURAdoesC0UV17UyNN8FXPrqfCfJxAYLvBR+eGj0ePL7fT4NE0dt1 +hu5A5fhmQYfNKe/Hn68slYMJ6Hr9eZ6TaFgXLEQvS28Ok/H+roX5pcfwKQ7FFCSF +xzLk84tUG80U+FKmiqKOtkdvz6K9YFPI7IR25CmOLhAagDF59WQtqShDJVC7Nhuk +EFxzIAtP+rFnWGqjYFyTsJ7bBWoNY99sRZto0P6YgQKBgQDC7gvrpdcB+ZfBKFjD +5snENpxgh+VXe7/UDKYddJqxIP+lBgsdwSMOGxrPeI1IDi0T1Zh/5bNp/uwIHeem +PJTV8u5uNvpD705pmW1uUaNqs8LXhWtttlylxNI01M19IA8Uhd9I2h8rPw1rgBHK +0ltnTB1gwqdFF2Llk8J2U4elgQKBgQC8E6eCr/W66CHIY4BImWYK5K+abP2Doe5S +MmefYRbCxsKBH2HCEg43ubZ+KXoBBaR+TDIw/Zv3uOdjkbR4/CH8vM1tGaK9SMiD +g07xzuPd3IIqpQ1ajI3Np5V6Y+vcO8jjXpHgxCpmnaUq3fkxL4ST2Rfr3P5T16pj +/9JxUNiSHwKBgQC86CT1QcqUR2Yh8w/TCh4O4T267vf7SBonTfrOIOqpLemR68Fq +HHn0eaAJ4DJK2jIlPqKDj//HgR0M4K5WE+/JR5x5gx4WKBw9ikra1pMgHQV+B/aM +ZGZ038E3IePilucGZJZ266u5JWnD/GFBxYp/GOx/kSS5eGiHRCL4uQqEAQKBgQCr +/GUgEvxo0MGj16mFuhEgQQN7+dLSPpAKxmEP097Wep9/KE1jBNPPjZoeQJt6t8g2 +XkM/nYq0u3eNC763LAmAbr6D1/+DjD0gVkEoyoKBbZXynUBa31EFEQyWAS28FUec +8+v+WCRV9i8FxjqMCeH4uXswisRfs0XzcArm6IFDDQKBgGs+OOUIs8pyaH1/Jy82 +w3W5c0h8xWj+fCIn3Yb6A0IaudH3OyTwDoVsd1u9nSTakFtJAxD/Sym0yo0WG5hm +Sbs/b+rNlSh9G9BEmB7eH/mrJ3DgFUnUC/7XbYbQGNWVHK5uiU1IPcgvD8HW77hE +g7C2WtSeC0v73kW/QA8EKYBZ +-----END PRIVATE KEY----- diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b8a7b74 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1 @@ +# Diese Datei wird für den direkten Host‑Betrieb ohne Docker nicht benötigt. diff --git a/outputs/20260720_105453_hello_world.txt b/outputs/20260720_105453_hello_world.txt new file mode 100644 index 0000000..cf79423 --- /dev/null +++ b/outputs/20260720_105453_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T08:54:54Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T08:54:54Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_105837_hello_world.txt b/outputs/20260720_105837_hello_world.txt new file mode 100644 index 0000000..d2367b4 --- /dev/null +++ b/outputs/20260720_105837_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T08:58:37Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T08:58:37Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_110257_hello_world.txt b/outputs/20260720_110257_hello_world.txt new file mode 100644 index 0000000..1c45eae --- /dev/null +++ b/outputs/20260720_110257_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:02:57Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:02:57Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_110328_hello_world.txt b/outputs/20260720_110328_hello_world.txt new file mode 100644 index 0000000..88905d5 --- /dev/null +++ b/outputs/20260720_110328_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:03:32Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:03:32Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_110442_hello_world.txt b/outputs/20260720_110442_hello_world.txt new file mode 100644 index 0000000..6ba1892 --- /dev/null +++ b/outputs/20260720_110442_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:04:46Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:04:46Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_111002_test.txt b/outputs/20260720_111002_test.txt new file mode 100644 index 0000000..3f1b3a0 --- /dev/null +++ b/outputs/20260720_111002_test.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:10:03Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:10:03Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_111257_test.txt b/outputs/20260720_111257_test.txt new file mode 100644 index 0000000..6d57740 --- /dev/null +++ b/outputs/20260720_111257_test.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:12:59Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:12:59Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_111305_hello_world.txt b/outputs/20260720_111305_hello_world.txt new file mode 100644 index 0000000..642049a --- /dev/null +++ b/outputs/20260720_111305_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:13:08Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:13:08Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_111310_hello_world.txt b/outputs/20260720_111310_hello_world.txt new file mode 100644 index 0000000..7d46dee --- /dev/null +++ b/outputs/20260720_111310_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:13:11Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:13:11Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_111315_test.txt b/outputs/20260720_111315_test.txt new file mode 100644 index 0000000..2d1c033 --- /dev/null +++ b/outputs/20260720_111315_test.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:13:16Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:13:16Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_111328_test.txt b/outputs/20260720_111328_test.txt new file mode 100644 index 0000000..b0b7064 --- /dev/null +++ b/outputs/20260720_111328_test.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T09:13:29Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T09:13:29Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_161802_test.txt b/outputs/20260720_161802_test.txt new file mode 100644 index 0000000..faef5f6 --- /dev/null +++ b/outputs/20260720_161802_test.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T14:18:02Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T14:18:02Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260720_161812_hello_world.txt b/outputs/20260720_161812_hello_world.txt new file mode 100644 index 0000000..98b5113 --- /dev/null +++ b/outputs/20260720_161812_hello_world.txt @@ -0,0 +1,21 @@ + +PLAY [Hallo Welt ausgeben] ***************************************************** + +TASK [Gathering Facts] ********************************************************* +ok: [localhost] + +TASK [Hallo Welt ausgeben] ***************************************************** +ok: [localhost] => { + "msg": "Hallo man-dan-05! Die Uhrzeit ist 2026-07-20T14:18:12Z" +} + +TASK [Uhrzeit ausgeben] ******************************************************** +ok: [localhost] => { + "msg": "Die Uhrzeit ist 2026-07-20T14:18:12Z" +} + +PLAY RECAP ********************************************************************* +localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +[WARNING]: No inventory was parsed, only implicit localhost is available +[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' diff --git a/outputs/20260717_144254_hello_world.txt b/outputs/archiv/20260717_144254_hello_world.txt similarity index 100% rename from outputs/20260717_144254_hello_world.txt rename to outputs/archiv/20260717_144254_hello_world.txt diff --git a/outputs/20260717_144306_hello_world.txt b/outputs/archiv/20260717_144306_hello_world.txt similarity index 100% rename from outputs/20260717_144306_hello_world.txt rename to outputs/archiv/20260717_144306_hello_world.txt diff --git a/outputs/20260717_150244_hello_world.txt b/outputs/archiv/20260717_150244_hello_world.txt similarity index 100% rename from outputs/20260717_150244_hello_world.txt rename to outputs/archiv/20260717_150244_hello_world.txt diff --git a/app/playbooks/hello_world.yml b/playbooks/test.yml similarity index 100% rename from app/playbooks/hello_world.yml rename to playbooks/test.yml diff --git a/reflex.lock/bun.lock b/reflex.lock/bun.lock index f8f55d6..32bf267 100644 --- a/reflex.lock/bun.lock +++ b/reflex.lock/bun.lock @@ -15,6 +15,7 @@ "react-helmet": "6.1.0", "react-router": "7.15.0", "react-router-dom": "7.15.0", + "react-syntax-highlighter": "16.1.1", "socket.io-client": "4.8.3", "sonner": "2.0.7", "universal-cookie": "7.2.2", @@ -418,8 +419,14 @@ "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + "@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="], + "@types/parse-json": ["@types/parse-json@4.0.2", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="], + "@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], @@ -444,10 +451,18 @@ "caniuse-lite": ["caniuse-lite@1.0.30001806", "", {}, "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw=="], + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "classnames": ["classnames@2.5.1", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="], + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + "confbox": ["confbox@0.2.4", "", {}, "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ=="], "convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="], @@ -460,6 +475,8 @@ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + "dedent": ["dedent@1.7.2", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA=="], "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], @@ -488,10 +505,14 @@ "exsolve": ["exsolve@1.1.0", "", {}, "sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw=="], + "fault": ["fault@1.0.4", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "find-root": ["find-root@1.1.0", "", {}, "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="], + "format": ["format@0.2.2", "", {}, "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="], + "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -504,14 +525,30 @@ "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], + "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], + + "hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="], + + "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], + + "highlightjs-vue": ["highlightjs-vue@1.0.0", "", {}, "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA=="], + "hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], + + "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], "is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "^2.0.3" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="], + "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], + + "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + "isbot": ["isbot@5.1.40", "", {}, "sha512-yNeeynhhtIVRBk12tBV4eHNxwB42HzR4Q3Ea7vCOiJhImGaAIdIMrbJtacQlBizGLjUPw+akkFI5Dn9T70XoVQ=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -552,6 +589,8 @@ "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + "lowlight": ["lowlight@1.20.0", "", { "dependencies": { "fault": "^1.0.0", "highlight.js": "~10.7.0" } }, "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw=="], + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "lucide-react": ["lucide-react@1.14.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-+1mdWcfSJVUsaTIjN9zoezmUhfXo5l0vP7ekBMPo3jcS/aIkxHnXqAPsByszMZx/Y8oQBRJxJx5xg+RH3urzxA=="], @@ -570,6 +609,8 @@ "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], + "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], @@ -594,8 +635,12 @@ "prettier": ["prettier@3.9.5", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg=="], + "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], + "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], + "radix-ui": ["radix-ui@1.6.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-accessible-icon": "1.1.11", "@radix-ui/react-accordion": "1.2.16", "@radix-ui/react-alert-dialog": "1.1.19", "@radix-ui/react-arrow": "1.1.11", "@radix-ui/react-aspect-ratio": "1.1.11", "@radix-ui/react-avatar": "1.2.2", "@radix-ui/react-checkbox": "1.3.7", "@radix-ui/react-collapsible": "1.1.16", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-context-menu": "2.3.3", "@radix-ui/react-dialog": "1.1.19", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-dropdown-menu": "2.1.20", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.12", "@radix-ui/react-form": "0.1.12", "@radix-ui/react-hover-card": "1.1.19", "@radix-ui/react-label": "2.1.11", "@radix-ui/react-menu": "2.1.20", "@radix-ui/react-menubar": "1.1.20", "@radix-ui/react-navigation-menu": "1.2.18", "@radix-ui/react-one-time-password-field": "0.1.12", "@radix-ui/react-password-toggle-field": "0.1.7", "@radix-ui/react-popover": "1.1.19", "@radix-ui/react-popper": "1.3.3", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-progress": "1.1.12", "@radix-ui/react-radio-group": "1.4.3", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-scroll-area": "1.2.14", "@radix-ui/react-select": "2.3.3", "@radix-ui/react-separator": "1.1.11", "@radix-ui/react-slider": "1.4.3", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-switch": "1.3.3", "@radix-ui/react-tabs": "1.1.17", "@radix-ui/react-toast": "1.2.19", "@radix-ui/react-toggle": "1.1.14", "@radix-ui/react-toggle-group": "1.1.15", "@radix-ui/react-toolbar": "1.1.15", "@radix-ui/react-tooltip": "1.2.12", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-escape-keydown": "1.1.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-OwYUjzMwiInCUxgAWpPsavXC3Kh4iyi/49uU1/qZTG3RQDlvegyk1GOMiGvSkjua1RDb3JD3fo3eroL9FV4GQw=="], "react": ["react@19.2.6", "", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="], @@ -624,10 +669,14 @@ "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + "react-syntax-highlighter": ["react-syntax-highlighter@16.1.1", "", { "dependencies": { "@babel/runtime": "^7.28.4", "highlight.js": "^10.4.1", "highlightjs-vue": "^1.0.0", "lowlight": "^1.17.0", "prismjs": "^1.30.0", "refractor": "^5.0.0" }, "peerDependencies": { "react": ">= 0.14.0" } }, "sha512-PjVawBGy80C6YbC5DDZJeUjBmC7skaoEUdvfFQediQHgCL7aKyVHe57SaJGfQsloGDac+gCpTfRdtxzWWKmCXA=="], + "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + "refractor": ["refractor@5.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/prismjs": "^1.0.0", "hastscript": "^9.0.0", "parse-entities": "^4.0.0" } }, "sha512-QXOrHQF5jOpjjLfiNk5GFnWhRXvxjUVnlFxkeDmewR5sXkr3iM46Zo+CnRR8B+MDVqkULW4EcLVcRBNOPXHosw=="], + "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], @@ -652,6 +701,8 @@ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + "stylis": ["stylis@4.2.0", "", {}, "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], @@ -692,6 +743,8 @@ "@react-router/dev/isbot": ["isbot@5.2.1", "", {}, "sha512-dJ+LpKyClQZ7NG+j3OensC/mAZkGpukE9YUrgPYvAZj2doVL0edfDgywTUh5CXa0o+nW9a1V9e5+CJTX8+SxRw=="], + "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + "pkg-types/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "vite/postcss": ["postcss@8.5.19", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ=="], diff --git a/reflex.lock/package.json b/reflex.lock/package.json index 3873926..b5702c3 100644 --- a/reflex.lock/package.json +++ b/reflex.lock/package.json @@ -16,6 +16,7 @@ "react-helmet": "6.1.0", "react-router": "7.15.0", "react-router-dom": "7.15.0", + "react-syntax-highlighter": "16.1.1", "socket.io-client": "4.8.3", "sonner": "2.0.7", "universal-cookie": "7.2.2" diff --git a/rxconfig.py b/rxconfig.py index d74237d..c272e08 100644 --- a/rxconfig.py +++ b/rxconfig.py @@ -1,16 +1,20 @@ import reflex as rx from reflex.plugins import SitemapPlugin +from reflex_components_radix.plugin import RadixThemesPlugin config = rx.Config( + appearance="dark", app_name="app", - frontend_port=8080, - backend_port=8081, - # Wichtig: Hier jetzt http:// statt https:// - api_url="http://man-dan-05:8081", - - # Sitemap-Warnung deaktivieren + frontend_port=3000, + backend_port=3001, + api_url="http://localhost:3001", + backend_host="0.0.0.0", + frontend_host="0.0.0.0", + backend_ws_url="ws://localhost:3001/ws", + cors_allowed_origins=["http://localhost:3000"], + cors_credentials=True, + plugins=[RadixThemesPlugin()], disable_plugins=[SitemapPlugin], - - # Vite anweisen, den Hostnamen im Netzwerk zu akzeptieren - vite_allowed_hosts=["man-dan-05", "localhost", "127.0.0.1"] + vite_allowed_hosts=["localhost", "127.0.0.1"], + env=rx.Env.DEV, ) diff --git a/rxconfig___ b/rxconfig___ deleted file mode 100644 index 5d0da92..0000000 --- a/rxconfig___ +++ /dev/null @@ -1,38 +0,0 @@ -import reflex as rx -from reflex.plugins import SitemapPlugin -import os - -# --- AUTOMATISCHER VITE-PATCH FÜR LINUX --- -# Sucht die von Reflex generierte Vite-Konfiguration -VITE_CONFIG_PATH = os.path.join(os.path.dirname(__file__), ".web", "vite.config.js") - -if os.path.exists(VITE_CONFIG_PATH): - try: - with open(VITE_CONFIG_PATH, "r", encoding="utf-8") as f: - content = f.read() - - # Wenn der Host noch nicht erlaubt ist, patchen wir das 'server'-Objekt - if "allowedHosts" not in content: - # Wir fügen allowedHosts direkt in die Server-Konfiguration von Vite ein - patched_content = content.replace( - "server: {", - "server: {\n allowedHosts: ['man-dan-05', 'localhost', '127.0.0.1']," - ) - with open(VITE_CONFIG_PATH, "w", encoding="utf-8") as f: - f.write(patched_content) - print("[INFO] Vite-Sicherheitsblockade erfolgreich im Code gelöst!") - except Exception as e: - print(f"[WARNUNG] Patch fehlgeschlagen: {str(e)}") - - -config = rx.Config( - app_name="app", - frontend_port=8080, - backend_port=8081, - api_url="http://man-dan-05:8081", - - # ssl_cert="certs/man-dan-05.crt", - #ssl_key="certs/man-dan-05.key", - - disable_plugins=[SitemapPlugin], -) diff --git a/weg b/weg deleted file mode 100644 index 4ee39d0..0000000 --- a/weg +++ /dev/null @@ -1,11 +0,0 @@ -// Konfiguration für Reflex -module.exports = { - // Pfade für die Reflex-Anwendung - paths: { - public: './public', - output: './dist' - }, - // Weitere Konfigurationen... - plugins: [], - theme: {} -};