From 4b9dd45f059365e3fdcf92245248f1c875a5a916 Mon Sep 17 00:00:00 2001 From: ppfeiffer Date: Fri, 20 Feb 2026 21:37:11 +0100 Subject: [PATCH] refactor(config): Konfigurationsdateien nach config/ verschoben (closes #3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config.yaml, nina.yaml, scheduler.yaml aus Root → config/ verschoben - conf/ (env.example, nina.yaml, scheduler.yaml, config.yaml) gelöscht - meshbot/config.py, nina.py, scheduler.py: Pfade auf config/ aktualisiert - .gitignore: config/.env und .forgejo_token ergänzt Co-Authored-By: Claude Sonnet 4.6 --- .claude/CLAUDE.md | 59 ++++++++++++++++++------- .gitignore | 2 + CHANGELOG.md | 10 +++++ conf/config.yaml | 19 -------- conf/scheduler.yaml | 15 ------- config.yaml => config/config.yaml | 2 +- {conf => config}/env.example | 0 {conf => config}/nina.yaml | 0 scheduler.yaml => config/scheduler.yaml | 0 meshbot/config.py | 4 +- meshbot/nina.py | 2 +- meshbot/scheduler.py | 2 +- nina.yaml | 19 -------- 13 files changed, 61 insertions(+), 73 deletions(-) delete mode 100644 conf/config.yaml delete mode 100644 conf/scheduler.yaml rename config.yaml => config/config.yaml (94%) rename {conf => config}/env.example (100%) rename {conf => config}/nina.yaml (100%) rename scheduler.yaml => config/scheduler.yaml (100%) delete mode 100644 nina.yaml diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index f8c7ceb..b4965f9 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -6,48 +6,77 @@ - Changelog format: `## [x.y.z] - YYYY-MM-DD` with `### Added/Changed/Removed` sections ## Project Structure -- Config: `config.yaml` (live-reloaded via file watcher in `meshbot/config.py`) +- Config: `config/config.yaml` (live-reloaded via file watcher in `meshbot/config.py`) - Bot: `meshbot/bot.py` - Meshtastic TCP, commands use `config.get("bot.command_prefix")` - Auth: `meshbot/auth.py` - Session-Middleware, Passwort-Hashing, Auth-Routen, Admin-API, Email - Web: `meshbot/webserver.py` - aiohttp + WebSocket + Auth-Integration - DB: `meshbot/database.py` - SQLite via aiosqlite (nodes, messages, commands, users, tokens, email_logs) - Scheduler: `meshbot/scheduler.py` - Cron-based job scheduler -- Frontend: `static/` - Bootstrap 5.3 dark/light theme, AdminLTE-style layout +- NINA: `meshbot/nina.py` - NINA-Warnmeldungen (Polling + WebSocket-Broadcast) +- Frontend: `static/` - Tabler CSS + Bootstrap 5.3 dark/light theme +- Shared JS: `static/js/app.js` - `initPage()`, Sidebar-Injection, Navbar, Theme, Auth-Check - Entry: `main.py` ## Pages & Routes -- `/` - Dashboard (`static/index.html`, `static/js/dashboard.js`) +- `/` - Dashboard (`static/index.html`, `static/js/dashboard.js`) - Public - `/scheduler` - Scheduler (`static/scheduler.html`, `static/js/scheduler.js`) - Admin only +- `/nina` - NINA-Warnungen (`static/nina.html`, `static/js/nina.js`) - Admin only (Sidebar) - `/map` - Leaflet map (`static/map.html`, `static/js/map.js`) - Public +- `/packets` - Paket-Log (`static/packets.html`, `static/js/packets.js`) - Public +- `/messages` - Nachrichtenverlauf (`static/messages.html`, `static/js/messages.js`) - Public - `/settings` - Node config (`static/settings.html`, `static/js/settings.js`) - Admin only - `/login` + `/register` - Auth (`static/login.html`, `static/js/login.js`) - `/admin` - User management (`static/admin.html`, `static/js/admin.js`) - Admin only - `/ws` - WebSocket endpoint -- Auth: `/auth/login`, `/auth/register`, `/auth/logout`, `/auth/verify`, `/auth/set-password`, `/auth/forgot-password`, `/auth/reset-password` -- API: `/api/nodes`, `/api/messages`, `/api/stats`, `/api/send` (user), `/api/node/config` (admin), `/api/scheduler/jobs` (admin) -- API Auth: `/api/auth/me`, `/api/admin/users`, `/api/admin/users/{id}/role`, `/api/admin/users/{id}/verify` + +### Auth-Routen +`/auth/login`, `/auth/register`, `/auth/logout`, `/auth/verify`, `/auth/set-password`, `/auth/forgot-password`, `/auth/reset-password` + +### API-Routen +| Endpunkt | Methode | Auth | +|----------|---------|------| +| `/api/nodes` | GET | Public | +| `/api/messages` | GET | Public | +| `/api/packets` | GET | Public | +| `/api/stats` | GET | Public | +| `/api/links` | GET | Public | +| `/api/send` | POST | User | +| `/api/node/config` | GET | Admin | +| `/api/scheduler/jobs` | GET | Public | +| `/api/scheduler/jobs` | POST | Admin | +| `/api/scheduler/jobs/{name}` | PUT/DELETE | Admin | +| `/api/nina/config` | GET/PUT | Admin | +| `/api/nina/alerts` | GET | Admin | +| `/api/auth/me` | GET | - | +| `/api/admin/users` | GET | Admin | +| `/api/admin/users/{id}/role` | PUT | Admin | +| `/api/admin/users/{id}/verify` | PUT | Admin | ## Rollen & Zugriffsrechte | Bereich | Public | User | Admin | |---------|--------|------|-------| -| `/map`, `/` (Nodes, Stats) | Ja | Ja | Ja | -| Dashboard Nachrichten + Senden | Nein | Ja | Ja | -| `/scheduler`, `/settings` | Nein | Nein | Ja | +| `/`, `/map`, `/packets`, `/messages` | Ja | Ja | Ja | +| Dashboard Nachrichten senden (`/api/send`) | Nein | Ja | Ja | +| `/scheduler`, `/settings`, `/nina` | Nein | Nein | Ja | | `/admin` | Nein | Nein | Ja | ## Frontend Layout Pattern -- All pages use consistent AdminLTE-style: top-navbar (46px), sidebar (200px), content-wrapper -- Sidebar nav with active state, 5 entries: Dashboard, Scheduler, Karte, Einstellungen, Benutzer -- Admin-only sidebar entries use class `sidebar-admin` (hidden via JS if not admin) -- Navbar: User-Name + Logout button (logged in) or Login button (not logged in) -- Each JS file has: auth check (`/api/auth/me`), updateNavbar(), updateSidebar(), theme toggle, sidebar toggle +- Alle Seiten: Tabler CSS + Bootstrap 5.3, AdminLTE-Style (top-navbar 46px, sidebar 200px, content-wrapper) +- Sidebar wird per `app.js` (`_injectSidebar()`) dynamisch generiert – 8 Einträge: + Dashboard, Scheduler (admin), NINA (admin), Karte, Pakete, Nachrichten (user), Einstellungen (admin), Benutzer (admin) +- Zugriffsklassen: `.sidebar-admin` (nur Admin), `.sidebar-user` (jeder eingeloggte User) +- Sichtbarkeit wird in `_updateSidebar(user)` per `style.display` gesteuert +- Jede Seite ruft `initPage({ onAuth })` aus `app.js` auf – übernimmt Auth-Check, Navbar, Sidebar, Theme - Shared styles in `static/css/style.css` ## Key Details - Meshtastic host configured in config.yaml, not env vars - Bot start: `/home/peter/meshdd-bot/venv/bin/python main.py` +- Web port: 8081 (konfigurierbar via `web.port`) - Forgejo remote with token in URL -- Current version: 0.5.0 +- Current version: 0.08.15 - Protobuf objects converted via `google.protobuf.json_format.MessageToDict()` - Auth: bcrypt (12 rounds), aiohttp-session EncryptedCookieStorage, aiosmtplib for emails - SMTP fallback: if no smtp.host configured, verification links logged to console +- `web.online_threshold` (Default: 900 s): Online-Schwellwert für Nodes, zentral konfigurierbar +- `links:` in config.yaml: Liste mit `url` + `label`, wird über `/api/links` und Dashboard-Links-Card angezeigt diff --git a/.gitignore b/.gitignore index 687173f..a54422e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ venv/ .venv/ env/ .env +config/.env *.db *.sqlite *.sqlite3 @@ -21,3 +22,4 @@ env/ *~ .DS_Store .claude/settings.local.json +.forgejo_token diff --git a/CHANGELOG.md b/CHANGELOG.md index 3689350..1b8d340 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [0.08.16] - 2026-02-20 + +### Changed +- **Konfigurationsdateien in `config/` verschoben** (closes #3): + `config.yaml`, `nina.yaml`, `scheduler.yaml` und `env.example` liegen jetzt im + Unterverzeichnis `config/` statt im Root-Verzeichnis bzw. `conf/`. +- **`conf/` entfernt**: Das alte Verzeichnis `conf/` wurde vollständig gelöscht. +- **Python-Pfade aktualisiert**: `meshbot/config.py`, `meshbot/nina.py` und + `meshbot/scheduler.py` referenzieren jetzt das neue `config/`-Verzeichnis. + ## [0.08.15] - 2026-02-20 ### Added diff --git a/conf/config.yaml b/conf/config.yaml deleted file mode 100644 index dc008c8..0000000 --- a/conf/config.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: "0.7.0" - -bot: - name: "MeshDD-Bot" - command_prefix: "?" - -meshtastic: - host: "192.168.11.4" - port: 4403 - -web: - host: "0.0.0.0" - port: 8081 - -database: - path: "data/meshdd.db" - -auth: - session_max_age: 86400 diff --git a/conf/scheduler.yaml b/conf/scheduler.yaml deleted file mode 100644 index 472b6eb..0000000 --- a/conf/scheduler.yaml +++ /dev/null @@ -1,15 +0,0 @@ -jobs: -- name: Wetterbericht - enabled: true - cron: 0 6,12,18 * * * - command: /weather - channel: 0 - description: Taeglicher Wetterbericht - type: command -- name: Mesh-Status - enabled: true - cron: 30 18 * * * - command: /mesh - channel: 0 - description: Mesh-Netzwerk Uebersicht - type: command diff --git a/config.yaml b/config/config.yaml similarity index 94% rename from config.yaml rename to config/config.yaml index 399c3e1..4bda76d 100644 --- a/config.yaml +++ b/config/config.yaml @@ -1,4 +1,4 @@ -version: "0.08.15" +version: "0.08.16" bot: name: "MeshDD-Bot" diff --git a/conf/env.example b/config/env.example similarity index 100% rename from conf/env.example rename to config/env.example diff --git a/conf/nina.yaml b/config/nina.yaml similarity index 100% rename from conf/nina.yaml rename to config/nina.yaml diff --git a/scheduler.yaml b/config/scheduler.yaml similarity index 100% rename from scheduler.yaml rename to config/scheduler.yaml diff --git a/meshbot/config.py b/meshbot/config.py index cde629b..790de40 100644 --- a/meshbot/config.py +++ b/meshbot/config.py @@ -6,8 +6,8 @@ import yaml logger = logging.getLogger(__name__) -CONFIG_PATH = os.environ.get("CONFIG_PATH", os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.yaml")) -ENV_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), ".env") +CONFIG_PATH = os.environ.get("CONFIG_PATH", os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "config.yaml")) +ENV_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", ".env") _config = {} _mtime = 0.0 diff --git a/meshbot/nina.py b/meshbot/nina.py index 5f9b937..800aad3 100644 --- a/meshbot/nina.py +++ b/meshbot/nina.py @@ -10,7 +10,7 @@ import yaml logger = logging.getLogger(__name__) NINA_API_BASE = "https://warnung.bund.de/api31" -NINA_CONFIG_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "nina.yaml") +NINA_CONFIG_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "nina.yaml") SEVERITY_ORDER = { "Unknown": -1, diff --git a/meshbot/scheduler.py b/meshbot/scheduler.py index b657af7..4f5c729 100644 --- a/meshbot/scheduler.py +++ b/meshbot/scheduler.py @@ -9,7 +9,7 @@ from meshbot import config logger = logging.getLogger(__name__) -SCHEDULER_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "scheduler.yaml") +SCHEDULER_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "scheduler.yaml") class Scheduler: diff --git a/nina.yaml b/nina.yaml deleted file mode 100644 index 1f66473..0000000 --- a/nina.yaml +++ /dev/null @@ -1,19 +0,0 @@ -enabled: false -send_to_mesh: false # true = ins Mesh senden | false = nur Weboberfläche (Monitor-Modus) -poll_interval: 300 -resend_interval: 3600 # Aktive Warnungen alle N Sekunden erneut ins Mesh senden -channel: 0 -min_severity: Severe -ags_codes: - - "146120000000" # Stadt Dresden - - "146270000000" # Landkreis Meißen - - "146280000000" # LK Sächsische Schweiz-Osterzgebirge - - "146250000000" # Landkreis Bautzen - - "146260000000" # Landkreis Görlitz -sources: - katwarn: true - biwapp: true - mowas: true - dwd: true - lhp: true - police: false