updates to digiserver app server

This commit is contained in:
2026-09-10 21:03:16 +03:00
parent 046f5e5efd
commit 1c5186463a
129 changed files with 33014 additions and 17 deletions
+178
View File
@@ -0,0 +1,178 @@
# 04 · Application Core
Covers the application factory, configuration, extensions, middleware, CLI commands, context processors, and template layer. This is **Community 4** in the Graphify knowledge graph.
---
## 1. Application Factory — `app/app.py`
The entire app is constructed by `create_app(config_name=None)`:
```mermaid
flowchart TD
A["create_app()"] --> B["Set instance_path"]
B --> C["Load config: Dev / Prod / Test"]
C --> D["ProxyFix middleware"]
D --> E["ScriptNameFix middleware"]
E --> F["init extensions: db bcrypt login migrate cache cors"]
F --> G["configure_login_manager()"]
G --> H["register_blueprints()"]
H --> I["register_error_handlers()"]
I --> J["register_commands()"]
J --> K["register_context_processors()"]
K --> L["register_template_filters()"]
L --> M["init_portal_sso(app)"]
M --> N["db.create_all() (idempotent)"]
N --> O["return app"]
```
### Blueprint registration
```python
def register_blueprints(app):
from app.blueprints.main import main_bp
from app.blueprints.auth import auth_bp
from app.blueprints.admin import admin_bp
from app.blueprints.players import players_bp
from app.blueprints.content import content_bp
from app.blueprints.playlist import playlist_bp
from app.blueprints.api import api_bp
...
```
> Note: `app.blueprints.content_old` is **not** imported — it is dead/legacy code.
---
## 2. Configuration — `app/config.py`
Four classes: `Config` (base) → `DevelopmentConfig`, `ProductionConfig`, `TestingConfig`.
| Setting | Value | Notes |
|---|---|---|
| `MAX_CONTENT_LENGTH` | 2 GB | upload cap |
| `UPLOAD_FOLDER` | `app/static/uploads` | media |
| `UPLOAD_FOLDERLOGO` | `app/static/resurse` | logos |
| `ALLOWED_EXTENSIONS` | png jpg jpeg gif bmp mp4 avi mkv mov webm pdf ppt pptx | |
| `PERMANENT_SESSION_LIFETIME` | 30 min | |
| `SESSION_COOKIE_SECURE` | False (True in prod) | |
| `ITEMS_PER_PAGE` | 20 | |
| `SERVER_VERSION` | 2.0.0 | shown in UI footer |
| `PLAYER_CODE_DIR` | `/app/data/player` | staged player source |
| `PLAYER_REPO_URL` | env `PLAYER_REPO_URL` | Kiwy-Signage repo |
| DB (dev) | `instance/dev.db` | |
| DB (prod) | `instance/dashboard.db` | |
| DB (test) | in-memory | |
---
## 3. Extensions — `app/extensions.py`
Centralizes shared singletons:
```python
db = SQLAlchemy()
bcrypt = Bcrypt()
login_manager = LoginManager() # login_view='auth.login'
migrate = Migrate()
cache = Cache()
cors = CORS()
```
CORS is configured in `create_app` for `/api/*`: all origins, GET/POST/OPTIONS/PUT/DELETE, supports credentials.
---
## 4. Middleware
### ProxyFix (Werkzeug)
`app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1)` — trusts one reverse-proxy hop (Caddy / umbrella nginx).
### ScriptNameFix — `app/utils/script_name_fix.py`
`ScriptNameFix` WSGI middleware sets `SCRIPT_NAME` from `HTTP_X_SCRIPT_NAME` so `url_for()` generates correct paths when the app is mounted under a sub-path (e.g. `/digiserver`).
---
## 5. Login Manager
```python
login_manager.login_view = 'auth.login'
login_manager.login_message = 'Please log in to access this page.'
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
```
---
## 6. Error Handlers
| Code | Template | Behaviour |
|---|---|---|
| 404 | `errors/404.html` | Not found |
| 403 | `errors/403.html` | Forbidden |
| 500 | `errors/500.html` | Rolls back DB session |
| 413 | `errors/413.html` | Payload too large |
| 408 | `errors/408.html` | Request timeout |
The `/api` blueprint registers its own **JSON** 404/405/500 handlers.
---
## 7. CLI Commands
| Command | Purpose |
|---|---|
| `flask init-db` | `db.create_all()` |
| `flask create-admin --username X` | Create admin user (prompts for password) |
| `flask seed-db` | Seed sample data (blocked in production) |
---
## 8. Context Processors
- **`inject_config`** — exposes `server_version`, `build_date`, `logo_exists` to all templates.
- **`inject_user_theme`** — exposes the authenticated user's `theme` (`light`/`dark`) for the UI toggle.
---
## 9. Template Filters
- **`localtime`** — converts naive/UTC datetimes to local time with a configurable `strftime` format (default `%Y-%m-%d %H:%M`).
---
## 10. Template & Static Layout
```
app/templates/
├── base.html ← main layout (theme, logos, nav)
├── dashboard.html
├── auth/ login.html, register.html, change_password.html
├── admin/ admin.html, user_management.html, leftover_media.html,
│ dependencies.html, customize_logos.html, editing_users.html,
│ https_config.html, build_player.html
├── content/ content_list.html (legacy), content_list_new.html (modern),
│ media_library.html, upload_content.html (legacy),
│ upload_media.html, manage_playlist_content.html, edit_content.html
├── players/ players_list.html, add_player.html, edit_player.html,
│ manage_player.html, player_page.html, player_fullscreen.html,
│ edited_media.html, edited_media_report.html, _deploy_badge.html
└── errors/ 403.html, 404.html, 500.html (+413/408)
app/static/
├── icons/ edit, home, info, monitor, moon, playlist, sun, trash, upload, warning (SVG)
├── uploads/ uploaded media + edited_media/<content_id>/ (versioned edits)
└── (resurse/ logo storage — referenced by config)
```
---
## 11. Portal SSO — `app/utils/portal_sso.py`
`init_portal_sso(app)` registers a `before_request` hook that reads `X-Auth-Username` / `X-Auth-Role` headers (set by the umbrella nginx gateway). If present, it auto-creates and logs in the local `User` (`_get_or_create_user`). This lets the app sit behind an existing corporate SSO portal.
---
> Next: [05 · Blueprints & API](05-blueprints-api.md)