Sanitize codebase, reorganize docs, and add missing deploy files

Remove dead code identified in docs/SANITIZATION-REVIEW.md:
- app/blueprints/content_old.py and app/blueprints/playlist.py
- app/models/group.py, app/utils/nginx_config_reader.py
- orphaned templates (content_list, edit_content, upload_content,
  player_page) and the related group/Template references

Result: 6 blueprints, 82 routes, no dead modules or orphan templates.

Add files that deploy.sh and docker-entrypoint.sh already require but
which were never tracked:
- https_manager.py       (referenced by deploy.sh, migrate_network.sh,
                          docker-entrypoint.sh)
- Caddyfile.example      (seeded by deploy.sh; its absence aborts deploy)

Relocate generated Graphify artifacts from graphify-out/ to
docs/graphify-out/ (110 files, no content change) and archive the
superseded docs under docs/.

Ignore hygiene:
- ignore ad-hoc .env backups (.env.bak*) — they contain live secrets
- keep the pre-sanitization snapshots (docs/legacy code/,
  docs/old_code_documentation/) on disk but out of the repo

Fix .env.example: drop a duplicated config block, genericize the
hardcoded host IP, and document HOSTNAME_INTERNAL.
This commit is contained in:
2026-09-11 12:18:34 +03:00
parent 1c5186463a
commit 46602f1933
226 changed files with 3999 additions and 15737 deletions
+3 -4
View File
@@ -56,7 +56,7 @@ Graphify assigns each node a **level** (0 = entry/global → 3 = utility):
|---|---|---|
| **L0 — Entry / Global** | 0 | `create_app()`, `app.py`, config classes, error handlers, CLI commands |
| **L1 — Strategic / Core** | 1 | Blueprint route handlers (players, content, api, admin), model classes |
| **L2 — Implementation** | 2 | Playlist/group management helpers, processing helpers, model methods |
| **L2 — Implementation** | 2 | Playlist management helpers, processing helpers, model methods |
| **L3 — Utility** | 3 | `logger.py`, `ssh_deploy.py`, `caddy_manager.py`, `uploads.py`, `pptx_converter.py`, migrations |
```mermaid
@@ -81,7 +81,6 @@ flowchart TD
log["log_action()"]
up["uploads.py"]
pptx["pptx_converter.py"]
nginx["NginxConfigReader"]
end
create_app --> bp
create_app --> models
@@ -102,14 +101,14 @@ Graphify clustered the code into **41 communities**. The 12 meaningful ones are
| Community | Domain (derived) | Files | Role |
|---|---|---|---|
| **C0** (90) | **Authentication + legacy groups** | `blueprints/auth.py`, `blueprints/content_old.py`, `models/server_log.py`, `utils/logger.py`, `utils/group_player_management.py`, `old_code_documentation/blueprint_groups.py` | Auth flows + audit logging + (legacy) group features |
| **C0** (90) | **Authentication + audit** | `blueprints/auth.py`, `models/server_log.py`, `utils/logger.py`, `old_code_documentation/blueprint_groups.py` | Auth flows + audit logging |
| **C1** (80) | **Admin + HTTPS + player users** | `blueprints/admin.py`, `models/https_config.py`, `models/player_user.py`, `utils/caddy_manager.py`, `migrations/add_player_user_table.py` | Admin panel, Caddy HTTPS generation, editing-user registry |
| **C2** (68) | **Playlist & content workflows** | `blueprints/content.py`, `blueprints/playlist.py`, `models/playlist.py` | Modern playlist-centric content management + legacy redirects |
| **C3** (62) | **Player API + edits** | `blueprints/api.py`, `models/player_edit.py` | Player-facing REST, edited-media pipeline |
| **C4** (55) | **Application core** | `app.py`, `config.py`, `models/user.py`, `utils/portal_sso.py`, `utils/script_name_fix.py` | App factory, config, auth identity, middleware |
| **C5** (54) | **Content & player models** | `models/content.py`, `models/player.py`, `models/player_feedback.py`, `blueprints/main.py` | Media model, player model, feedback, dashboard |
| **C6** (51) | **Player management UI** | `blueprints/players.py`, `migrations/add_https_config_table.py` | Player CRUD, manage page, deployment polling |
| **C7** (42) | **Groups (legacy)** | `models/group.py`, `utils/nginx_config_reader.py` | Archived groups feature + legacy nginx reader |
| **C7** (42) | ***(removed)*** | — | Groups model + legacy nginx reader were deleted during sanitization |
| **C8** (24) | **Dev tooling** | `old_code_documentation/test_edit_media_api.py`, `Colors`, integrity checker | Test/analysis utilities |
| **C9** (21) | **Upload processing** | `utils/uploads.py` | Upload progress, video/image processing |
| **C10** (20) | **Deployment** | `utils/background_tasks.py`, `utils/ssh_deploy.py` | Background SSH deployment engine |
+1 -1
View File
@@ -84,7 +84,7 @@ These are the most-connected nodes (graph centrality). They are the architectura
Graphify groups related code into communities. See [01-architecture.md §3](01-architecture.md#3-component-map-files--communities) for the full mapping. The largest:
- **C0 · Auth & logging** (90 nodes) — login/logout/register + audit logging + legacy groups
- **C0 · Auth & logging** (90 nodes) — login/logout/register + audit logging
- **C1 · Admin & HTTPS** (80 nodes) — admin panel, Caddy generation, editing users
- **C2 · Playlists & content** (68 nodes) — the modern content/playlist workflow
- **C3 · Player API & edits** (62 nodes) — player-facing REST + edited-media pipeline
+8 -12
View File
@@ -15,7 +15,6 @@ erDiagram
content ||--o{ player_edit : "edited (cascade)"
content ||--o{ player_feedback : "playing"
playlist ||--o{ content : "playlist_content M2M (position,duration,muted,edit_on_player_enabled)"
content }o--o{ group : "group_content M2M (legacy)"
player_user ||--o{ player_edit : "user_code"
https_config ||--o| https_config : "singleton row"
```
@@ -74,8 +73,8 @@ Methods: `is_online` (5-min window), `update_status()`, `set_password()/check_pa
| `description` | Text | nullable |
| `uploaded_at` | DateTime | NOT NULL, indexed |
Relationships: `playlists` (M2M via `playlist_content`), `groups` (M2M via `group_content`).
Properties/methods: `file_size_mb`, `group_count`, `original_display_name`, `original_media_path`, `current_media_path`, `is_image()/is_video()/is_pdf()/is_weblink()`, `has_player_edits`.
Relationships: `playlists` (M2M via `playlist_content`).
Properties/methods: `file_size_mb`, `original_display_name`, `original_media_path`, `current_media_path`, `is_image()/is_video()/is_pdf()/is_weblink()`, `has_player_edits`.
### `playlist` — ordered collections of content
| Column | Type | Notes |
@@ -168,15 +167,13 @@ Classmethods: `log_info`, `log_warning`, `log_error`.
Classmethods: `get_config()` (first row), `create_or_update(...)`. Method: `to_dict()`.
### `group` + `group_content` — **ARCHIVED / LEGACY**
| Column | Type | Notes |
|---|---|---|
| `id` | Integer | PK |
| `name` | String(100) | unique, NOT NULL, indexed |
| `description` | Text | nullable |
| `created_at` / `updated_at` | DateTime | NOT NULL |
### `group` + `group_content` — **REMOVED**
`group_content(group_id, content_id)` composite-PK M2M. The current `Player` model has **no** `group_id` column — group features are archived (see [09 · Legacy](09-legacy-and-migrations.md)).
The `Group` model, the `group_content` association table, `Content.groups` /
`Content.group_count`, and the group-management utility functions were **deleted**
during the code sanitization pass (the feature was archived and the table had no
rows). `Player` never had a `group_id` column. See
[SANITIZATION-REVIEW.md](SANITIZATION-REVIEW.md).
---
@@ -185,7 +182,6 @@ Classmethods: `get_config()` (first row), `create_or_update(...)`. Method: `to_d
| Relationship | Cardinality | FK / Mechanism |
|---|---|---|
| `playlist``content` | M:N | `playlist_content` (positioned, with extras) |
| `group``content` | M:N | `group_content` (legacy) |
| `player``playlist` | N:1 | `player.playlist_id` (ON DELETE SET NULL) |
| `player``player_feedback` | 1:N | `player_feedback.player_id` (cascade) |
| `player``player_edit` | 1:N | `player_edit.player_id` (cascade) |
+5 -4
View File
@@ -40,7 +40,9 @@ def register_blueprints(app):
...
```
> Note: `app.blueprints.content_old` is **not** imported — it is dead/legacy code.
> Note: `content_old.py` (legacy content routes) was **deleted** during the code
> sanitization pass — see [SANITIZATION-REVIEW.md](SANITIZATION-REVIEW.md). The
> legacy `playlist.py` blueprint remains (redirect-only).
---
@@ -153,9 +155,8 @@ app/templates/
├── 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
├── content/ content_list_new.html, media_library.html,
upload_media.html, manage_playlist_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
+2 -2
View File
@@ -1,6 +1,6 @@
# 05 · Blueprints & REST API
DigiServer v2 registers **7 active blueprints** (`content_old.py` is legacy dead code and is not registered).
DigiServer v2 registers **7 active blueprints**.
---
@@ -203,7 +203,7 @@ Redirects/legacy — kept for compatibility:
|---|---|---|---|
| `/player-feedback` | POST | `receive_player_feedback` | Status (playing/paused/error/restarting); infers player; **auto-marks deployment `deployed`** |
| `/player-status/<player_id>` | GET | `get_player_status` | Online (5-min), latest feedback |
| `/system-info` | GET | — | Counts: players online/total, groups, content, 24h logs |
| `/system-info` | GET | — | Counts: players online/total, content, 24h logs |
| `/content` | GET | — | List content with counts |
| `/logs` | GET | `get_logs` | Query logs (`limit`/`level`/`since`) |
+35 -6
View File
@@ -9,7 +9,7 @@ All shared services live in `app/utils/`. This document details each module, its
| Module | Community | Responsibility | Key symbols |
|---|---|---|---|
| `logger.py` | C0 | DB-backed audit logging | `log_action()`, `get_recent_logs()`, `clear_old_logs()` |
| `group_player_management.py` | C0 | Group/player stats (legacy) | `get_player_status_info()`, `assign_player_to_group()`, `get_online_players_count()` |
| `group_player_management.py` | C0 | Player status reporting | `get_player_status_info()` |
| `caddy_manager.py` | C1 | HTTPS Caddyfile generation | `CaddyConfigGenerator`, `write_caddyfile()`, `reload_caddy()` |
| `background_tasks.py` | C10 | Async task execution | `run_background_task()`, `background_player_deployment()` |
| `ssh_deploy.py` | C10 | Remote player provisioning | `deploy_player_to_host()`, `test_ssh_connection()`, `generate_player_config()` |
@@ -18,7 +18,9 @@ All shared services live in `app/utils/`. This document details each module, its
| `uploads.py` | C9 | Upload progress + file ops | `get/set/clear_upload_progress()`, `save_uploaded_file()`, `process_video_file()` |
| `portal_sso.py` | C4 | SSO auto-login | `init_portal_sso()`, `_get_or_create_user()` |
| `script_name_fix.py` | C4 | WSGI sub-path middleware | `ScriptNameFix` |
| `nginx_config_reader.py` | C7 | Legacy nginx status parsing | `NginxConfigReader`, `get_nginx_status()` |
> `nginx_config_reader.py` (C7) was **removed** during the sanitization pass — the
> reverse proxy is Caddy. See [SANITIZATION-REVIEW.md](SANITIZATION-REVIEW.md).
---
@@ -81,11 +83,31 @@ Other helpers:
| Method | Purpose |
|---|---|
| `generate_caddyfile(config)` | Pick template by mode: **HTTP-only** (`:80`), **domain** (Let's Encrypt), or **IP** (internal CA self-signed). Includes `reverse_proxy digiserver-app:5000`, 2 GB body limit, gzip, security headers |
| `generate_caddyfile(config, http_fallback=True)` | Pick template by mode: **HTTP-only** (`:80`), **domain** (Let's Encrypt), or **IP-only** (internal CA `tls internal`). Includes `reverse_proxy digiserver-app:5000`, 2 GB body limit, gzip, security headers. `http_fallback` also serves plain HTTP alongside internal-CA TLS so clients that cannot trust the local CA still work |
| `write_caddyfile(content, path=/etc/caddy/Caddyfile)` | Write to disk |
| `reload_caddy()` | POST to Caddy admin API `http://caddy:2019/load` |
Triggered from `admin.update_https_config` after saving `HTTPSConfig`.
Triggered from `admin.update_https_config` (Admin UI) **or** `https_manager.py` (CLI),
both of which save `HTTPSConfig` first so the two paths stay in sync.
> **Internal CA vs Let's Encrypt:** an intranet name (e.g. `*.harting.intra`) is not
> resolvable publicly, so ACME challenges cannot succeed. Leaving `domain` empty selects
> `tls internal`, which needs no DNS and no external service. See
> [07 · Deployment §6](07-deployment.md#6-https-setup-caddy).
---
## 4b. `https_manager.py` — HTTPS CLI (repo root)
Command-line equivalent of the Admin HTTPS page, used by `deploy.sh`.
| Command | Purpose |
|---|---|
| `enable <hostname> <domain> <email> <ip> [port]` | Persist `HTTPSConfig`, regenerate + write the Caddyfile, hot-reload Caddy. Empty `<domain>` → internal CA. `--redirect-only` to disable the HTTP fallback; `--no-https` for HTTP only |
| `disable` | Turn HTTPS off (HTTP only) |
| `status` | Print the stored configuration and resolved mode |
Exit codes: `0` success · `1` bad args/config · `2` config applied but Caddy did not reload.
---
@@ -131,9 +153,16 @@ Used by the upload pipeline: **PPTX → PDF → PNG slides (Full HD)**.
---
## 9. `nginx_config_reader.py` — Legacy (informational)
## 9. `group_player_management.py` — Player Status
`NginxConfigReader` parses an `nginx.conf` and reports `ssl_enabled`, ports, upstreams, `server_names`, `ssl_protocols`, `client_max_body_size`, `gzip`. **Legacy** — the current reverse proxy is Caddy; retained for reference and the old deployment stack.
Only `get_player_status_info(player_id)` remains: it returns the online flag
(5-minute window), status, last-seen plus a humanised "time ago", and the latest
`PlayerFeedback`. Used by `players.list` and `players.manage_player`.
The group helpers (`get_group_statistics`, `assign_player_to_group`,
`bulk_assign_players_to_group`) and the status-list helpers
(`get_online_players_count`, `get_players_by_status`) were **removed** with the
archived Group subsystem.
---
+217 -23
View File
@@ -63,40 +63,232 @@ flowchart LR
## 4. `docker-entrypoint.sh`
1. Create `/app/instance` and `/app/app/static/uploads`.
2. If `dashboard.db` is missing: create app + `db.create_all()`, then create/update the admin user from `ADMIN_USERNAME` / `ADMIN_PASSWORD`.
3. Start **Gunicorn**: `--bind 0.0.0.0:5000 --workers 4 --timeout 120 app.app:create_app('production')`.
1. **Pin the database**: export `DATABASE_URL` (default `sqlite:////app/instance/dashboard.db`) so migrations and the app resolve to the *same* file. Required because the config classes default to different files (`dev.db` vs `dashboard.db`) and most migration scripts call `create_app()` without an argument (→ development config), while the app runs `create_app('production')`.
2. Create `/app/instance` and `/app/app/static/uploads`.
3. Ensure schema + admin user — runs on **every** start (idempotent): `db.create_all()`, then create the admin from `ADMIN_USERNAME` / `ADMIN_PASSWORD` or refresh its password.
4. Run the **migration chain** (idempotent, ordered — table-creating migrations run before those that alter them):
```
add_https_config_table.py
add_player_user_table.py
add_email_to_https_config.py
migrate_player_user_global.py
add_url_to_content.py
add_original_filename_to_content.py
add_deployment_fields_to_player.py
```
Migrations are **non-fatal**: failures are logged as `⚠️ WARNING` and startup continues, so one bad migration can't strand the container in a restart loop.
5. Start **Gunicorn**: `--bind 0.0.0.0:5000 --workers 4 --timeout 120 app.app:create_app('production')`.
> Because migrations now run automatically on startup, `deploy.sh` step 4 is redundant (harmless — the scripts are idempotent).
### Data layout (bind mounts)
| Host path | Container path | Contents |
|---|---|---|
| `data/instance` | `/app/instance` | SQLite DB (`dashboard.db`), `player_build.json` |
| `data/uploads` | `/app/app/static/uploads` | Media files + `edited_media/` |
| `data/Caddyfile` | `/etc/caddy/Caddyfile` | Reverse-proxy config (**a file, not a directory**) |
| `data/caddy-data` | `/data` | Caddy state (instance UUID, certificates) |
| `data/caddy-config` | `/config` | Caddy autosave |
| `data/caddy-logs` | `/var/log/caddy` | Access logs |
> ⚠️ **`data/Caddyfile` must exist before `docker compose up`.** It is bind-mounted as a *file*;
> if it is missing, Docker creates a **directory** in its place and Caddy fails to start.
> `deploy.sh` seeds it from the version-controlled `Caddyfile.example`. For a manual start:
> ```
> mkdir -p data/instance data/uploads data/caddy-data data/caddy-config data/caddy-logs
> cp Caddyfile.example data/Caddyfile
> docker compose up -d --build
> ```
> ️ The legacy `data/nginx-*` and `data/certbot` folders are **obsolete** — the reverse proxy is
> Caddy. They are no longer created by `deploy.sh`.
### Clean start (wipe all runtime data)
`data/` is **gitignored**, so wiping it is irreversible. To reset to a pristine deployment:
```
docker compose down
docker rmi digiserver-v2-digiserver-app:latest # drop stale image
docker image prune -f && docker builder prune -a -f # reclaim build cache
rm -rf data # WIPES db, uploads, certs
mkdir -p data/instance data/uploads data/caddy-data data/caddy-config data/caddy-logs
cp Caddyfile.example data/Caddyfile
./deploy.sh
```
> ⚠️ Files under `data/caddy-*` are created **root-owned** by the Caddy container, so a plain
> `rm -rf data` may fail with *Permission denied*. Remove them via a helper container:
> ```
> docker run --rm -v "$PWD/data:/data" caddy:2-alpine sh -c 'rm -rf /data/caddy-config /data/caddy-data'
> ```
> Avoid `docker system prune --volumes` — this host also holds volumes for **other** projects.
---
## 5. `deploy.sh` (One-Shot Deployment)
```
1. Validate compose + project; create data/ subdirs; copy nginx configs
2. docker compose up -d + verify containers "Up"
3. Run migration scripts (add_https_config_table, add_player_user_table,
1. Detect compose: `docker compose` (plugin) or `docker-compose` (v1 fallback)
— stored in $COMPOSE and used for every subsequent call
2. Create data/ subdirs (instance, uploads, caddy-data, caddy-config, caddy-logs)
and seed data/Caddyfile from Caddyfile.example
3. $COMPOSE up -d + verify containers "Up"
4. Run migration scripts (add_https_config_table, add_player_user_table,
add_email_to_https_config, migrate_player_user_global,
add_original_filename_to_content)
4. Run /app/https_manager.py enable <hostname> <domain> <email> <ip> <port>
⚠ https_manager.py is NOT in the current repo — this step needs attention
5. Verify DB tables via SQLAlchemy inspector
6. caddy validate + https_manager.py status; print access URLs + default creds
↳ NOTE: the container entrypoint already applies all seven on startup.
This step is idempotent and therefore redundant.
5. /app/https_manager.py enable <hostname> <domain> <email> <ip> <port>
↳ Exit code 2 ("config applied, Caddy not reloaded") is non-fatal.
6. Verify DB tables via SQLAlchemy inspector; caddy validate;
https_manager.py status; print access URLs + default creds
```
### Configuration variables
| Variable | Default | Meaning |
|---|---|---|
| `HOSTNAME` | `digiserver` | Display hostname |
| `HTTPS_MODE` | `internal` | `internal` \| `acme` \| `off` |
| `DOMAIN` | *(empty)* | Required only when `HTTPS_MODE=acme` |
| `IP_ADDRESS` | **auto-detected** | Primary LAN IP (override if needed) |
| `EMAIL` | `admin@example.com` | ACME account email (unused by internal CA) |
| `PORT` | `8443` | Externally published HTTPS port |
> If `IP_ADDRESS` is unset, `deploy.sh` auto-detects it
> (`ip -4 route get 1.1.1.1` → `src` address, falling back to `hostname -I`).
> The old hard-coded defaults (`10.76.152.164`, a `.intra` domain) were wrong for
> most hosts and have been removed.
---
## 6. HTTPS Setup (Caddy)
HTTPS is configured through the **Admin → HTTPS Configuration** page, which:
Three equivalent entry points drive the **same** code path
(`HTTPSConfig` + `CaddyConfigGenerator`) so CLI, env bootstrap and UI cannot diverge:
1. **Env bootstrap (deploy time)** — the container entrypoint runs
`python /app/https_manager.py bootstrap`, which reads `HOSTNAME_INTERNAL` and
`HOST_IP` from the environment and configures Caddy for HTTPS automatically.
2. **CLI**`python /app/https_manager.py enable … | verify | status | disable`
3. **UI***Admin → HTTPS Configuration* (reloads Caddy live; the ongoing source of truth)
### Addressing model — one HTTP endpoint, one HTTPS endpoint
| Port | What it does |
|---|---|
| **80** | Always answers. A catch-all `:80` block serves **any** Host header, plus explicit blocks for the IP and hostname so both work. |
| **443** | HTTPS for the same names, using the internal CA (or ACME for a public domain). |
If HTTPS is disabled or never configured, port 80 simply serves the app — there is
no separate "HTTP mode" to set.
> ⚠️ **`default_sni` is required for IP access.** Browsers send **no SNI** when the
> URL is an IP address (an IP is not a valid SNI hostname). Caddy then identifies the
> connection by the container's own internal IP and aborts the handshake with
> `no certificate available for '<container-ip>'`. To prevent this, the generator emits
> `default_sni <ip>` whenever internal-CA mode is used, so `https://<ip>` works in a
> plain browser. This was found by end-to-end testing — see
> `docs/tools/test_http_https_runtime.sh`.
### Mode selection
| Condition | Result |
|---|---|
| HTTPS off, or no IP/domain | Plain HTTP on port 80 |
| HTTPS on + `ip_address` / `hostname` | `tls internal` per name (no DNS, no ACME) |
| HTTPS on + `domain` set | Let's Encrypt for that name |
### Automatic fallback if HTTPS does not work
After applying a config, `https_manager.py` probes the HTTPS endpoint
(`/api/health`, certificate validation deliberately disabled). If the TLS listener
does not come up, the configuration is **automatically reverted to plain HTTP** so a
failed certificate can never make the site unreachable:
```
enable HTTPS → reload Caddy → probe https://<host>:<port>/api/health
├─ OK → keep HTTPS
└─ FAIL → revert to HTTP-only, log a warning
```
Disable the probe with `HTTPS_VERIFY=false` (or `enable --no-verify`).
Re-check at any time with `python /app/https_manager.py verify`.
### Deploy-time bootstrap via `.env`
Copy `.env.example``.env` and set the host address. `docker-compose.yml`
forwards these to the app container:
| Variable | Effect |
|---|---|
| `HOSTNAME_INTERNAL` | Hostname served (both HTTP and HTTPS) |
| `HOST_IP` | IP served and certified |
| `DOMAIN` | **Leave empty for an intranet name** → internal CA. Set only for Let's Encrypt |
| `SSL_EMAIL` | ACME contact (ignored by internal CA) |
| `HTTP_PORT` / `HTTPS_PORT` | Host ports mapped to Caddy's 80/443 (default `80`/`443`) |
| `HTTPS_HTTP_FALLBACK` | `true` (default) also serves plain HTTP; `false` redirects instead |
| `HTTPS_VERIFY` | `true` (default) probe HTTPS and auto-fall back on failure |
```bash
cp .env.example .env
# set HOSTNAME_INTERNAL and HOST_IP
docker compose up -d --build
```
> **If either `HOSTNAME_INTERNAL` or `HOST_IP` is missing the bootstrap is a no-op** —
> the app starts on plain HTTP and stays reachable. HTTPS can then be enabled from
> *Admin → HTTPS Configuration*, which regenerates the Caddyfile and reloads Caddy
> **without a restart**.
### Who owns the config (env vs admin UI)
The admin UI is the **ongoing source of truth**. The bootstrap runs on every container
start, so it guards against silently overwriting an admin's change by tracking
provenance in `HTTPSConfig.updated_by`:
| Current config | Bootstrap behaviour |
|---|---|
| *(none — first deploy)* | Apply from env ✅ |
| Written by env/CLI (`updated_by='deploy.sh'`) | Apply from env ✅ — so editing `HOST_IP` and redeploying works |
| Written by a user (`updated_by='<username>'`) | **Skip** — the admin's setting is preserved |
So an admin change made in the UI survives restarts even while the env vars remain set.
### Why internal CA (and not Let's Encrypt) for `.intra`
An intranet name such as `digiserver.sibiusb.harting.intra` is **not resolvable from the
public internet**, so Let's Encrypt's HTTP-01/TLS-ALPN challenge cannot succeed. Setting
`DOMAIN=` empty makes Caddy sign the certificate itself with its local CA — no external
dependency at all.
**Trust caveat:** the internal CA is not in any client trust store, so browsers show a
warning and a Kivy player with `verify_ssl: true` will **reject the connection**. Options:
1. **Use HTTP** — port 80 always serves the app, so players need no trust configuration.
2. **Install the root CA** on each device:
```
docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./caddy-root.crt
```
### Ports
| Host → Container | Purpose |
|---|---|
| `80 → 80` | HTTP (always available) |
| `443 → 443` | HTTPS |
| `5000 → 5000` | Direct app access (bypasses Caddy; dev/testing) |
> Ports are configurable via `HTTP_PORT`/`HTTPS_PORT` so the stack also works where
> 80/443 are already taken (e.g. `HTTP_PORT=8080 HTTPS_PORT=8443`).
1. Saves `HTTPSConfig` (hostname, domain, IP, email, port, enabled).
2. `CaddyConfigGenerator.generate_caddyfile(config)` picks a template:
- **HTTP-only** → `:80` reverse proxy
- **Domain** → automatic Let's Encrypt
- **IP** → internal CA self-signed
3. Writes `/etc/caddy/Caddyfile` and reloads Caddy via `POST http://caddy:2019/load`.
The current `data/Caddyfile` (HTTP mode) includes: admin API on `0.0.0.0:2019`, `:80` block → `digiserver-app:5000`, 2 GB body limit, gzip, security headers, access log.
---
@@ -105,17 +297,19 @@ The current `data/Caddyfile` (HTTP mode) includes: admin API on `0.0.0.0:2019`,
Sections checked (pass/fail/warn counters):
- git status
- `.env` / `.env.example`
- Docker + Compose versions + `compose config` syntax
- Docker + Compose versions (plugin **or** v1) + `compose config` syntax
- Dockerfile best practices (HEALTHCHECK, non-root, slim base)
- `requirements.txt` critical packages + versions
- migrations directory
- **SSL cert expiry** (openssl)
- **TLS certificate** — Caddy internal CA expiry (`data/caddy-data/caddy/pki/authorities/local/root.crt`)
- Flask config (`ProductionConfig`, `SESSION_COOKIE_SECURE`)
- nginx.conf checks
- runtime container health
- `data/Caddyfile` checks (reverse_proxy, admin API, TLS mode)
- runtime container health + live HTTP/HTTPS endpoint probes
- security best practices
> ⚠ Note: the script still references `docker-compose` (v1) and `digiserver-nginx` — the current stack uses Compose v2 + Caddy.
> The script now detects `docker compose` (plugin) or `docker-compose` (v1) and warns when
> buildx is too old for compose v1 builds — matching `deploy.sh`, which then falls back to
> `docker build`.
---
+9 -6
View File
@@ -33,21 +33,24 @@ add_original_filename_to_content.py
| Component | Status | Notes |
|---|---|---|
| `app/blueprints/content_old.py` | **Dead code** | Legacy per-player content routes (`/`, `/upload`, `/<id>/edit`, `/bulk/delete`, `/upload-progress`, `/preview`, `/statistics`, `/check-duplicates`, `/<id>/groups`). Not imported by `create_app`. |
| `app/blueprints/content_old.py` | **DELETED** | Legacy per-player content routes. Removed in the sanitization pass together with its templates (`content_list.html`, `edit_content.html`, `upload_content.html`). |
| `app/blueprints/playlist.py` | **Active but legacy** | Per-player playlist routes kept as redirects to the modern content workflow. |
| `Group` model + group routes | **Archived** | `Player` no longer has `group_id`; group routes commented out; `group_player_management.py` and `group_content` association remain for reference. |
| `nginx` stack | **Replaced by Caddy** | `data/nginx.conf`, `data/nginx-custom-domains.conf`, `data/nginx-logs/`, `data/nginx-ssl/` retained. `utils/nginx_config_reader.py` still parses it. |
| `Group` model + group routes | **DELETED** | `models/group.py`, the `group_content` association, `Content.groups` / `Content.group_count`, and the group utility functions were removed. `Player` never had a `group_id` column. |
| `utils/nginx_config_reader.py` | **DELETED** | Legacy nginx parsing — the reverse proxy is Caddy. |
| `nginx` stack | **Replaced by Caddy** | `data/nginx.conf`, `data/nginx-custom-domains.conf`, `data/nginx-logs/`, `data/nginx-ssl/` removed with the Caddy migration. `migrate_network.sh` no longer generates self-signed certs — Caddy issues them. |
| `https_manager.py` | **Missing** | Referenced by `deploy.sh` but not in repo — likely merged into `CaddyConfigGenerator`. |
| `old_code_documentation/` | **Archive** | Full legacy docs, old scripts (`blueprint_groups.py`, `add_muted_column.py`, `fix_player_user_schema.py`, `test_edit_media_*.py`, `check_fix_player.py`, `migrate_add_edit_enabled.py`), deployment guides, HTTPS analysis, player analysis. |
| `QUICK_DEPLOYMENT.md`, `deployment-commands-reference.sh` | **Active reference** | Manual deployment notes. |
| `docs/legacy code/` | **Snapshot** | Full pre-sanitization copy of the codebase. Excluded from the Docker build via `.dockerignore`. |
---
## 3. Recommended Cleanup (optional)
- Remove `content_old.py` and `old_code_documentation/*.py` scripts that are no longer needed (keep the `.md` docs).
- Resolve the missing `https_manager.py` in `deploy.sh` (use `CaddyConfigGenerator` equivalents).
- Update `verify-deployment.sh` to reference Compose v2 and Caddy instead of `docker-compose`/nginx.
- Remove `old_code_documentation/*.py` scripts that are no longer needed (keep the `.md` docs).
- Resolve the missing `https_manager.py` in `deploy.sh` **done**: `https_manager.py` now exists at the repo root.
- Update `verify-deployment.sh` to reference Caddy instead of nginx — **done**.
- Consider removing the legacy `playlist.py` blueprint (see [SANITIZATION-REVIEW.md](SANITIZATION-REVIEW.md) batch B1).
---
+1 -2
View File
@@ -51,7 +51,7 @@ graphify-out/
| Application type | Digital signage content/playlist/player management |
| Graph size | **631 nodes · 1162 edges · 41 communities** |
| Blueprints | 7 active (`main`, `auth`, `admin`, `players`, `content`, `playlist`, `api`) |
| Database tables | 10 (`user`, `player`, `player_edit`, `player_feedback`, `player_user`, `content`, `group`, `playlist`, `server_log`, `https_config`) |
| Database tables | 9 (`user`, `player`, `player_edit`, `player_feedback`, `player_user`, `content`, `playlist`, `server_log`, `https_config`) |
| Reverse proxy | Caddy 2 (automatic HTTPS / Let's Encrypt) |
| Deployment | Docker Compose (app + Caddy) + remote SSH player provisioning |
| Key externals | LibreOffice, Poppler (pdf2image), FFmpeg, sshpass/rsync |
@@ -100,7 +100,6 @@ erDiagram
content ||--o{ player_edit : "cascade"
content ||--o{ player_feedback : ""
playlist ||--o{ content : "playlist_content (M2M)"
content }o--o{ group : "group_content (M2M)"
player_user ||--o{ player_edit : "user_code"
https_config ||--|| https_config : "single row config"
```
+206
View File
@@ -0,0 +1,206 @@
# DigiServer v2 — Code Sanitization Review
**Generated:** 2026-09-10
**Snapshot:** `docs/legacy code/` (1.7 MB, 171 files, 49 Python files) — full restore point.
Analysed **42 Python files / 240 functions / 104 routes / 32 templates** under `app/` and `migrations/`.
> Review each section below and reply with the IDs you want deleted (e.g. `A1, A2, B1`).
> Nothing is deleted until you confirm. Everything is recoverable from `docs/legacy code/`.
---
## ✅ Status — Applied 2026-09-10
**Removed (A1, A2, D1, D2):**
| ID | Removed | Notes |
|---|---|---|
| A1 | `app/blueprints/content_old.py` | + 3 templates orphaned by its removal |
| A2 | `app/utils/nginx_config_reader.py` | |
| D1 | 5 group functions + their `__init__.py` exports | `get_player_status_info` kept (live) |
| D2 | `app/models/group.py`, `Content.groups`, `Content.group_count` | |
**Extra cleanup triggered by A1/D2:**
- Deleted orphaned templates: `upload_content.html` (278), `edit_content.html` (11)
- Removed the dead `groups` key from `/api/system-info` and `group_count` from `/api/content`
- Removed the `'group_id': getattr(player, 'group_id', None)` compat shim from `/api/player-status`
- Updated 8 documentation files
**Also removed (B1, B2) — applied in a second pass:**
| ID | Removed | Notes |
|---|---|---|
| B1 | `app/blueprints/playlist.py` (310 LOC) + its registration in `app.py` | Whole legacy blueprint; its only real route redirected to `content.manage_playlist_content` |
| B2 | 3 routes in `players.py`: `reorder_content`, `reorder_playlist`, `remove_from_playlist` (~103 LOC) | Two queried nonexistent columns (`Content.player_id`, `Content.position`, `Player.playlist_version`) → guaranteed 500s |
**Extra cleanup triggered by B1:**
- Deleted `content_list.html` (202 lines) — its only remaining reference was `url_for('playlist.manage_playlist')`. It was **already orphaned** (no Python file rendered it) after `content_old.py` was deleted, so it has been removed for real this time.
- Deleted `players/player_page.html` (227 lines) — it was **never rendered** by any view (the `players.player_page` route redirects to `manage_player`), so it was dead UI. Corrects the earlier "false positive" note below.
> ⚠️ **Functional note:** `players.regenerate_auth_code` (`POST /players/<id>/regenerate-auth`) is now
> referenced by **no template**`player_page.html` was its only caller. The endpoint still works if
> invoked directly. The equivalent control lives in `manage_player.html` via the quickconnect flow.
> Restore `player_page.html` from `docs/legacy code/` if you want that button back.
**Result (A + B + D combined):**
```
42 → 38 Python modules 9,311 → 8,296 LOC
104 → 82 routes 32 → 28 templates
7 → 6 blueprints dead modules: 2 → 0, orphan templates: 0
```
**Verified:** all files compile; smoke test passes on a fresh DB (every API endpoint + key UI route returns
< 500); `db.metadata` no longer registers `group`/`group_content`; app boots against a migrated copy of the
real `dashboard.db` with all data intact; `app.blueprints` no longer contains `playlist`.
> ⚠️ **Still open:** the real `data/instance/dashboard.db` predates the `original_filename` migration.
> On startup the entrypoint now applies it automatically. To fix locally, run:
> ```
> DATABASE_URL=sqlite:///$PWD/data/instance/dashboard.db ./.venv/bin/python migrations/add_original_filename_to_content.py
> ```
---
## Section A — Dead modules (zero importers)
| ID | Target | LOC | Evidence | Risk |
|---|---|---|---|---|
| **A1** | `app/blueprints/content_old.py` | 500 | `app.py` imports `content.py`; this file's `content_bp` is **never registered**. Superseded "old" content workflow. | **Low** |
| **A2** | `app/utils/nginx_config_reader.py` | 120 | Never imported anywhere. Stack migrated nginx → Caddy, so the reader is obsolete. | **Low** |
```mermaid
graph LR
app_py["app.py<br/>register_blueprints()"] --> content["content.py<br/>content_bp ✅ ACTIVE"]
content_old["content_old.py<br/>content_bp ❌ DEAD"] -.->|never imported| x1[" "]
nginx["nginx_config_reader.py<br/>❌ DEAD"] -.->|never imported| x2[" "]
caddy["caddy_manager.py<br/>✅ ACTIVE"] --> app_py
style content_old fill:#7f1d1d,color:#fff
style nginx fill:#7f1d1d,color:#fff
```
---
## Section B — Legacy duplicate route surface — ✅ **REMOVED**
Two blueprints exposed **parallel implementations of the same operations**. Only the `content.*`
versions were wired to the UI; the legacy ones had no template references.
| ID | Target | LOC | Evidence | Risk |
|---|---|---|---|---|
| **B1** ✅ | `app/blueprints/playlist.py` (whole file + registration) | 310 | Entire file was legacy per-player playlist. Its `manage_playlist` route did nothing but **redirect** to the modern `content.manage_playlist_content`. The other 6 routes had **no template reference**. | **LowMed** |
| **B2** ✅ | 3 routes in `players.py`: `reorder_content`, `reorder_playlist`, `remove_from_playlist` | ~103 | Superseded by `content.*`. Two queried nonexistent columns (`Content.player_id`, `.position`, `Player.playlist_version`) → guaranteed HTTP 500 if called. | **Low** |
**Duplicate operation matrix**
| Operation | Modern (LIVE) | Legacy (DEAD) |
|---|---|---|
| Add content | `content.add_content_to_playlist` | `playlist.add_to_playlist` |
| Remove content | `content.remove_content_from_playlist` | `playlist.remove_from_playlist`, `players.remove_from_playlist` ⚠️broken |
| Reorder | `content.reorder_playlist_content` | `playlist.reorder_playlist`, `players.reorder_content` ⚠️broken, `players.reorder_playlist` ⚠️broken |
| Set duration | `content.update_playlist_content_duration` | `playlist.update_duration` |
| Mute audio | `content.update_playlist_content_muted` | `playlist.update_muted` |
| Toggle edit | `content.update_playlist_content_edit_enabled` | — |
| Clear | — | `playlist.clear_playlist` |
---
## Section C — Broken code: references to columns that do not exist
Confirmed against the live DB schema. These raised `AttributeError`/`OperationalError` at runtime.
**All resolved by deleting A1 + B2.**
| ID | Location | Broken reference | Reachable? |
|---|---|---|---|
| **C1** ✅ | `players.py:768,775` (`remove_from_playlist`) | `player.playlist_version` | Via route only (no UI link) |
| **C2** ✅ | `players.py:~700` (`reorder_playlist`) | `Content.player_id`, `Content.position` | Via route only (no UI link) |
| **C3** | `content_old.py:189-190` | `player.playlist_version` | No (dead module) |
| **C4** | `content_old.py:50,57` | `content.player_id`, `player.group` | No (dead module) |
> ✅ **Resolved by deleting A1 + B2.** If you keep those files, they must be rewritten.
**Not a bug (verified by hand):** `Content._playlist_duration` /
`._playlist_position` / `._playlist_muted` in `api.py` are set **dynamically** by
`Playlist.get_content_ordered()`. These are intentional and work correctly — the
static analyzer flags them because it only sees model class attributes.
---
## Section D — Legacy groups subsystem
Groups are fully deprecated (0 rows, `/api/groups` already commented out), but the code lingers.
| ID | Target | LOC | Evidence | Risk |
|---|---|---|---|---|
| **D1** | 5 group functions in `app/utils/group_player_management.py`: `get_group_statistics`, `assign_player_to_group`, `bulk_assign_players_to_group`, `get_online_players_count`, `get_players_by_status` + their `__init__.py` exports | ~130 | **Zero callers outside the module.** All three group functions reference `player.group_id`, **which does not exist** → broken. | **Low** |
| **D2** | `app/models/group.py` (Group model + `group_content` table) | 71 | Retained only because `Content.groups` FK relationship and `Content.group_count` reference it. Requires touching the Content model. | **Medium** |
> ⚠️ **Keep:** `get_player_status_info()` (top of the same file) is **live** — used at
> `players.py:28` and `players.py:432`. Only the group functions should go.
---
## Section E — Legacy redirect stubs
Thin compatibility shims that only redirect to the modern UI. They're harmless but keep dead
URL surface alive.
| ID | Target | Evidence |
|---|---|---|
| **E1** | `players.player_page` (`/players/<id>`) | Body is a single `redirect(url_for('players.manage_player'))`. Still `url_for`-referenced by 2 templates, so keeping it is fine. |
| **E2** | `playlist.manage_playlist` (`/playlist/<id>`) | Part of B1 — already covered by deleting that file. |
---
## Section F — Orphan templates / assets
| ID | Target | LOC | Evidence |
|---|---|---|---|
| — | (none) | — | After the B1/B2 pass the codebase has **0 orphan templates**. |
---
## Recommended batches — ✅ **ALL APPLIED**
| Batch | Contents | Total removed | Status |
|---|---|---|---|
| **Batch 1 — Safe clean** | **A1, A2** | ~620 LOC | ✅ done |
| **Batch 2 — Legacy playlist** | **B1, B2** | ~413 LOC | ✅ done |
| **Batch 3 — Groups** | **D1** | ~130 LOC | ✅ done |
| **Batch 4 — Group model** | **D2** | ~71 LOC | ✅ done |
**Every batch was followed by:** compile-all + app-factory boot + route smoke test, so hidden
dependencies were caught before moving on.
---
## How I verified this (so you can trust it)
| Check | Method |
|---|---|
| Module reachability | AST import extraction + `register_blueprint` cross-reference |
| Route usage | `url_for('endpoint')` **and** literal path matching against all templates/JS |
| Broken columns | Compared every `var.attr` access against live SQLite `PRAGMA table_info` |
| Dynamic attributes | Manually inspected `get_content_ordered()` to rule out false positives |
| Duplicate bodies | `ast.dump` body hashing across all functions (result: 0 exact duplicates) |
**Reproduce anytime:**
```
./.venv/bin/python docs/tools/sanitize_report.py # dead code + broken refs
./.venv/bin/python docs/tools/sanitize_audit.py # full function inventory
./.venv/bin/python docs/tools/sanitize_templates.py # orphan templates
./.venv/bin/python docs/tools/smoke_test.py # post-change smoke test
```
---
## ⚠️ Rollback / hygiene notes
1. **`docs/legacy code/` is excluded from the Docker image** (via `legacy code/` and
`**/legacy code/` in `.dockerignore`) so it never
ships to production or bloats the build.
2. It is **not** git-ignored, so it will appear in `git status`. Decide:
- commit it as a recovery point, or
- add `legacy code/` to `.gitignore` if you'd rather rely on git history.
3. Deleting files listed here is **not** recoverable from git unless committed first — the
`docs/legacy code/` copy is your safety net.
+22
View File
@@ -0,0 +1,22 @@
# Architectural Compass - /home/scheianu/digiserver-v2 (2026-08-16)
> [!NOTE]
> This is a token-optimized summary. For deep logic, see GRAPH_REPORT.md.
## Core Abstractions (God Nodes)
1. `log_action()` (116 edges)
2. `PlayerEdit` (99 edges)
3. `PlayerUser` (74 edges)
4. `Playlist` (33 edges)
5. `CaddyConfigGenerator` (31 edges)
6. `HTTPSConfig` (30 edges)
7. `Content` (24 edges)
8. `User` (19 edges)
9. `create_app()` (13 edges)
10. `Models package for digiserver-v2.` (13 edges)
## System Layers
- **L0: Global/Entry**:
- **L1: Strategic/Core**:
- **L2: Implementation**:
- **L3: Utility**:
+45
View File
@@ -0,0 +1,45 @@
# System Domains (Communities)
| ID | Domain | Rationale |
|---|---|---|
| 0 | Community 0 | |
| 1 | Community 1 | |
| 2 | Community 2 | |
| 3 | Community 3 | |
| 4 | Community 4 | |
| 5 | Community 5 | |
| 6 | Community 6 | |
| 7 | Community 7 | |
| 8 | Community 8 | |
| 9 | Community 9 | |
| 10 | Community 10 | |
| 11 | Community 11 | |
| 12 | Community 12 | |
| 13 | Community 13 | |
| 14 | Community 14 | |
| 15 | Community 15 | |
| 16 | Community 16 | |
| 17 | Community 17 | |
| 18 | Community 18 | |
| 19 | Community 19 | |
| 20 | Community 20 | |
| 21 | Community 21 | |
| 22 | Community 22 | |
| 23 | Community 23 | |
| 24 | Community 24 | |
| 25 | Community 25 | |
| 26 | Community 26 | |
| 27 | Community 27 | |
| 28 | Community 28 | |
| 29 | Community 29 | |
| 30 | Community 30 | |
| 31 | Community 31 | |
| 32 | Community 32 | |
| 33 | Community 33 | |
| 34 | Community 34 | |
| 35 | Community 35 | |
| 36 | Community 36 | |
| 37 | Community 37 | |
| 38 | Community 38 | |
| 39 | Community 39 | |
| 40 | Community 40 | |
+342
View File
@@ -0,0 +1,342 @@
# Graph Report - /home/scheianu/digiserver-v2 (2026-08-16)
## Corpus Check
- 49 files · ~210,805 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 631 nodes · 1162 edges · 41 communities detected
- Extraction: 56% EXTRACTED · 44% INFERRED · 0% AMBIGUOUS · INFERRED: 512 edges (avg confidence: 0.62)
- Token cost: 0 input · 0 output
## Community Hubs (Navigation)
- [[_COMMUNITY_Community 0|Community 0]]
- [[_COMMUNITY_Community 1|Community 1]]
- [[_COMMUNITY_Community 2|Community 2]]
- [[_COMMUNITY_Community 3|Community 3]]
- [[_COMMUNITY_Community 4|Community 4]]
- [[_COMMUNITY_Community 5|Community 5]]
- [[_COMMUNITY_Community 6|Community 6]]
- [[_COMMUNITY_Community 7|Community 7]]
- [[_COMMUNITY_Community 8|Community 8]]
- [[_COMMUNITY_Community 9|Community 9]]
- [[_COMMUNITY_Community 10|Community 10]]
- [[_COMMUNITY_Community 11|Community 11]]
- [[_COMMUNITY_Community 12|Community 12]]
- [[_COMMUNITY_Community 13|Community 13]]
- [[_COMMUNITY_Community 14|Community 14]]
- [[_COMMUNITY_Community 15|Community 15]]
- [[_COMMUNITY_Community 16|Community 16]]
- [[_COMMUNITY_Community 17|Community 17]]
- [[_COMMUNITY_Community 18|Community 18]]
- [[_COMMUNITY_Community 19|Community 19]]
- [[_COMMUNITY_Community 20|Community 20]]
- [[_COMMUNITY_Community 21|Community 21]]
- [[_COMMUNITY_Community 22|Community 22]]
- [[_COMMUNITY_Community 23|Community 23]]
- [[_COMMUNITY_Community 24|Community 24]]
- [[_COMMUNITY_Community 25|Community 25]]
- [[_COMMUNITY_Community 26|Community 26]]
- [[_COMMUNITY_Community 27|Community 27]]
- [[_COMMUNITY_Community 28|Community 28]]
- [[_COMMUNITY_Community 29|Community 29]]
- [[_COMMUNITY_Community 30|Community 30]]
- [[_COMMUNITY_Community 31|Community 31]]
- [[_COMMUNITY_Community 32|Community 32]]
- [[_COMMUNITY_Community 33|Community 33]]
- [[_COMMUNITY_Community 34|Community 34]]
- [[_COMMUNITY_Community 35|Community 35]]
- [[_COMMUNITY_Community 36|Community 36]]
- [[_COMMUNITY_Community 37|Community 37]]
- [[_COMMUNITY_Community 38|Community 38]]
- [[_COMMUNITY_Community 39|Community 39]]
- [[_COMMUNITY_Community 40|Community 40]]
## God Nodes (most connected - your core abstractions)
1. `log_action()` - 116 edges
2. `PlayerEdit` - 99 edges
3. `PlayerUser` - 74 edges
4. `Playlist` - 33 edges
5. `CaddyConfigGenerator` - 31 edges
6. `HTTPSConfig` - 30 edges
7. `Content` - 24 edges
8. `User` - 19 edges
9. `create_app()` - 13 edges
10. `Models package for digiserver-v2.` - 13 edges
## Surprising Connections (you probably didn't know these)
- `reset_user_password()` --calls--> `log_action()` [INFERRED]
/home/scheianu/digiserver-v2/app/blueprints/admin.py → /home/scheianu/digiserver-v2/app/utils/logger.py
- `upload_header_logo()` --calls--> `log_action()` [INFERRED]
/home/scheianu/digiserver-v2/app/blueprints/admin.py → /home/scheianu/digiserver-v2/app/utils/logger.py
- `delete_editing_user()` --calls--> `log_action()` [INFERRED]
/home/scheianu/digiserver-v2/app/blueprints/admin.py → /home/scheianu/digiserver-v2/app/utils/logger.py
- `delete_playlist()` --calls--> `log_action()` [INFERRED]
/home/scheianu/digiserver-v2/app/blueprints/content.py → /home/scheianu/digiserver-v2/app/utils/logger.py
- `Main playlist management page.` --uses--> `PlayerEdit` [INFERRED]
/home/scheianu/digiserver-v2/app/blueprints/content.py → /home/scheianu/digiserver-v2/app/models/player_edit.py
## Communities
### Community 0 - "Community 0"
Cohesion: 0.03
Nodes (80): change_password(), login(), logout(), Authentication Blueprint - Login, Logout, Register, register(), add_content_to_group(), add_player_to_group(), delete_group() (+72 more)
### Community 1 - "Community 1"
Cohesion: 0.04
Nodes (72): Add player_user table for user code mappings., admin_panel(), admin_required(), build_player(), change_theme(), change_user_role(), clear_logs(), create_user() (+64 more)
### Community 2 - "Community 2"
Cohesion: 0.04
Nodes (61): add_content_to_playlist(), add_weblink(), add_weblink_to_playlist(), assign_player_to_playlist(), bulk_remove_from_playlist(), content_list(), create_fullhd_image(), delete_playlist() (+53 more)
### Community 3 - "Community 3"
Cohesion: 0.06
Nodes (57): api_not_found(), authenticate_player(), deploy_player(), get_cached_playlist(), get_logs(), get_player_playlist(), get_player_status(), get_playlist_by_quickconnect() (+49 more)
### Community 4 - "Community 4"
Cohesion: 0.07
Nodes (42): add_muted_column(), Add muted column to playlist_content association table., configure_login_manager(), create_app(), DigiServer v2 - Application Factory Modern Flask application with blueprint arch, Configure Flask-Login, Register error handlers, Register CLI commands (+34 more)
### Community 5 - "Community 5"
Cohesion: 0.04
Nodes (27): Content, Content model for media files., String representation of Content., Check if content is an image., Check if content is a video., Content model representing media files for display. Attributes:, Check if content is a PDF., Check if content is a web link (URL) rather than an uploaded file. (+19 more)
### Community 6 - "Community 6"
Cohesion: 0.05
Nodes (45): Add https_config table for HTTPS configuration management., Write Caddyfile to disk. Args: caddyfile_content: C, Reload Caddy configuration without restart. Note: Caddy monitor, Generate a complete Caddyfile. Behaviour: - HTTPS disabled / no, Write Caddyfile to disk. The default path is /etc/caddy/Caddyfile — the, Push the current Caddyfile to Caddy via its admin API (/load). Caddy ap, HTTPSConfig, String representation of HTTPSConfig. (+37 more)
### Community 7 - "Community 7"
Cohesion: 0.06
Nodes (26): create_group(), delete_media(), Delete a media file and remove it from all playlists., Group, Group model for organizing players and content., Group model for organizing players with shared content. Attributes:, String representation of Group., Add a player to this group. Args: player: Player in (+18 more)
### Community 8 - "Community 8"
Cohesion: 0.23
Nodes (23): check_database_integrity(), Colors, get_player_auth_code(), get_sample_content(), main(), print_error(), print_info(), print_section() (+15 more)
### Community 9 - "Community 9"
Cohesion: 0.11
Nodes (20): Get upload progress for a specific upload., upload_content(), upload_progress_status(), clear_upload_progress(), delete_file(), get_file_size(), get_upload_progress(), process_pdf_file() (+12 more)
### Community 10 - "Community 10"
Cohesion: 0.12
Nodes (18): background_player_deployment(), Background task execution for long-running operations., Run a function in a background thread, with a Flask app context pushed., Deploy player code to host in background. Args: hostname: SSH h, run_background_task(), deploy_player_to_host(), generate_app_config(), generate_player_config() (+10 more)
### Community 11 - "Community 11"
Cohesion: 0.15
Nodes (18): build_player_action(), Build/refresh the staged player code and/or write its base config., build_player_files(), get_player_server_settings(), get_short_head(), load_build_settings(), make_build_record(), Utilities for building/staging the player files on the server. Admins use the " (+10 more)
### Community 12 - "Community 12"
Cohesion: 0.29
Nodes (7): cleanup_libreoffice_processes(), pptx_to_pdf_libreoffice(), PowerPoint to PDF converter using LibreOffice., Clean up any hanging LibreOffice processes., Convert PPTX to PDF using LibreOffice for highest quality. This functio, Validate if file is a valid PowerPoint file. Args: filepath: Pa, validate_pptx_file()
### Community 13 - "Community 13"
Cohesion: 0.5
Nodes (3): migrate(), Migration: Add edit_on_player_enabled column to playlist_content table., Add edit_on_player_enabled column to playlist_content.
### Community 14 - "Community 14"
Cohesion: 1.0
Nodes (1): Migrate player_user table to remove player_id and make user_code unique globally
### Community 15 - "Community 15"
Cohesion: 1.0
Nodes (1): Add original_filename column to content table. This preserves the pristine uplo
### Community 16 - "Community 16"
Cohesion: 1.0
Nodes (1): Add url column to content table for weblink support.
### Community 17 - "Community 17"
Cohesion: 1.0
Nodes (1): Add deployment tracking columns to player table.
### Community 18 - "Community 18"
Cohesion: 1.0
Nodes (1): Add email field to https_config table.
### Community 19 - "Community 19"
Cohesion: 1.0
Nodes (1): Flask extensions initialization Centralized extension management for the applica
### Community 20 - "Community 20"
Cohesion: 1.0
Nodes (1): Check if feedback indicates an error.
### Community 21 - "Community 21"
Cohesion: 1.0
Nodes (1): Get age of feedback in seconds.
### Community 22 - "Community 22"
Cohesion: 1.0
Nodes (1): Get most recent feedback for a player. Args: player
### Community 23 - "Community 23"
Cohesion: 1.0
Nodes (1): Get the current HTTPS configuration. Returns: HTTPS
### Community 24 - "Community 24"
Cohesion: 1.0
Nodes (1): Create or update HTTPS configuration. Args: https_e
### Community 25 - "Community 25"
Cohesion: 1.0
Nodes (1): Check if user has admin role.
### Community 26 - "Community 26"
Cohesion: 1.0
Nodes (1): Check if player is online (seen in last 5 minutes).
### Community 27 - "Community 27"
Cohesion: 1.0
Nodes (1): Authenticate a player by hostname and password or quickconnect code.
### Community 28 - "Community 28"
Cohesion: 1.0
Nodes (1): Create an info level log entry. Args: message: Log
### Community 29 - "Community 29"
Cohesion: 1.0
Nodes (1): Create a warning level log entry. Args: message: Lo
### Community 30 - "Community 30"
Cohesion: 1.0
Nodes (1): Create an error level log entry. Args: message: Log
### Community 31 - "Community 31"
Cohesion: 1.0
Nodes (1): Get number of content items in this group.
### Community 32 - "Community 32"
Cohesion: 1.0
Nodes (1): Get file size in megabytes.
### Community 33 - "Community 33"
Cohesion: 1.0
Nodes (1): Get number of groups containing this content.
### Community 34 - "Community 34"
Cohesion: 1.0
Nodes (1): Name of the original (unedited) file for display purposes.
### Community 35 - "Community 35"
Cohesion: 1.0
Nodes (1): Path (relative to uploads/) where the original unedited file lives. Whe
### Community 36 - "Community 36"
Cohesion: 1.0
Nodes (1): Path (relative to uploads/) of the current/latest version to display.
### Community 37 - "Community 37"
Cohesion: 1.0
Nodes (1): Whether this content has been edited on a player.
### Community 38 - "Community 38"
Cohesion: 1.0
Nodes (1): Display name of the original (unedited) file.
### Community 39 - "Community 39"
Cohesion: 1.0
Nodes (1): uploads/-relative path of the pristine original file. After a player ed
### Community 40 - "Community 40"
Cohesion: 1.0
Nodes (0):
## Knowledge Gaps
- **178 isolated node(s):** `Migrate player_user table to remove player_id and make user_code unique globally`, `Add original_filename column to content table. This preserves the pristine uplo`, `Add url column to content table for weblink support.`, `Add deployment tracking columns to player table.`, `Add email field to https_config table.` (+173 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **Thin community `Community 14`** (2 nodes): `migrate_player_user_global.py`, `Migrate player_user table to remove player_id and make user_code unique globally`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 15`** (2 nodes): `Add original_filename column to content table. This preserves the pristine uplo`, `add_original_filename_to_content.py`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 16`** (2 nodes): `Add url column to content table for weblink support.`, `add_url_to_content.py`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 17`** (2 nodes): `Add deployment tracking columns to player table.`, `add_deployment_fields_to_player.py`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 18`** (2 nodes): `Add email field to https_config table.`, `add_email_to_https_config.py`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 19`** (2 nodes): `Flask extensions initialization Centralized extension management for the applica`, `extensions.py`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 20`** (1 nodes): `Check if feedback indicates an error.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 21`** (1 nodes): `Get age of feedback in seconds.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 22`** (1 nodes): `Get most recent feedback for a player. Args: player`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 23`** (1 nodes): `Get the current HTTPS configuration. Returns: HTTPS`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 24`** (1 nodes): `Create or update HTTPS configuration. Args: https_e`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 25`** (1 nodes): `Check if user has admin role.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 26`** (1 nodes): `Check if player is online (seen in last 5 minutes).`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 27`** (1 nodes): `Authenticate a player by hostname and password or quickconnect code.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 28`** (1 nodes): `Create an info level log entry. Args: message: Log`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 29`** (1 nodes): `Create a warning level log entry. Args: message: Lo`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 30`** (1 nodes): `Create an error level log entry. Args: message: Log`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 31`** (1 nodes): `Get number of content items in this group.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 32`** (1 nodes): `Get file size in megabytes.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 33`** (1 nodes): `Get number of groups containing this content.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 34`** (1 nodes): `Name of the original (unedited) file for display purposes.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 35`** (1 nodes): `Path (relative to uploads/) where the original unedited file lives. Whe`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 36`** (1 nodes): `Path (relative to uploads/) of the current/latest version to display.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 37`** (1 nodes): `Whether this content has been edited on a player.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 38`** (1 nodes): `Display name of the original (unedited) file.`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 39`** (1 nodes): `uploads/-relative path of the pristine original file. After a player ed`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 40`** (1 nodes): `check_fix_player.py`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_utils_portal_sso_py", "label": "portal_sso.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "portal_sso_init_portal_sso", "label": "init_portal_sso()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L17", "complexity": 4, "loc": 16}, {"id": "portal_sso_get_or_create_user", "label": "_get_or_create_user()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L35", "complexity": 4, "loc": 18}, {"id": "portal_sso_rationale_1", "label": "Portal SSO middleware for DigiServer v2. When the umbrella nginx verifies the p", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L1"}, {"id": "portal_sso_rationale_18", "label": "Register the SSO before_request handler on the given Flask app.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L18"}], "edges": [{"source": "home_scheianu_digiserver_v2_app_utils_portal_sso_py", "target": "secrets", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L12", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_utils_portal_sso_py", "target": "flask", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L13", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_utils_portal_sso_py", "target": "flask_login", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L14", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_utils_portal_sso_py", "target": "portal_sso_init_portal_sso", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L17", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_utils_portal_sso_py", "target": "portal_sso_get_or_create_user", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L35", "weight": 1.0}, {"source": "portal_sso_rationale_1", "target": "home_scheianu_digiserver_v2_app_utils_portal_sso_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L1", "weight": 1.0}, {"source": "portal_sso_rationale_18", "target": "portal_sso_init_portal_sso", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L18", "weight": 1.0}], "raw_calls": [{"caller_nid": "portal_sso_get_or_create_user", "callee": "first", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L40"}, {"caller_nid": "portal_sso_get_or_create_user", "callee": "filter_by", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L40"}, {"caller_nid": "portal_sso_get_or_create_user", "callee": "decode", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L42"}, {"caller_nid": "portal_sso_get_or_create_user", "callee": "generate_password_hash", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L42"}, {"caller_nid": "portal_sso_get_or_create_user", "callee": "token_hex", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L42"}, {"caller_nid": "portal_sso_get_or_create_user", "callee": "User", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L43"}, {"caller_nid": "portal_sso_get_or_create_user", "callee": "add", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L48"}, {"caller_nid": "portal_sso_get_or_create_user", "callee": "commit", "source_file": "/home/scheianu/digiserver-v2/app/utils/portal_sso.py", "source_location": "L49"}]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_migrations_add_https_config_table_py", "label": "add_https_config_table.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/migrations/add_https_config_table.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "add_https_config_table_rationale_1", "label": "Add https_config table for HTTPS configuration management.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/migrations/add_https_config_table.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_migrations_add_https_config_table_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_https_config_table.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_https_config_table_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_https_config_table.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_https_config_table_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_https_config_table.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_https_config_table_py", "target": "app_models_https_config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_https_config_table.py", "source_location": "L7", "weight": 1.0}, {"source": "add_https_config_table_rationale_1", "target": "home_scheianu_digiserver_v2_migrations_add_https_config_table_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_https_config_table.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_blueprints_init_py", "label": "__init__.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/blueprints/__init__.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "init_rationale_1", "label": "Blueprints package initialization", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/blueprints/__init__.py", "source_location": "L1"}], "edges": [{"source": "init_rationale_1", "target": "home_scheianu_digiserver_v2_app_blueprints_init_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/blueprints/__init__.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_old_code_documentation_check_fix_player_py", "label": "check_fix_player.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/check_fix_player.py", "source_location": "L1", "complexity": 1, "loc": 1}], "edges": [{"source": "home_scheianu_digiserver_v2_old_code_documentation_check_fix_player_py", "target": "app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/check_fix_player.py", "source_location": "L4", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_check_fix_player_py", "target": "app_models", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/check_fix_player.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_check_fix_player_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/check_fix_player.py", "source_location": "L6", "weight": 1.0}], "raw_calls": []}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_models_player_edit_py", "label": "player_edit.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "player_edit_playeredit", "label": "PlayerEdit", "file_type": "code", "type": "CLASS", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L8", "complexity": 4, "loc": 53}, {"id": "player_edit_playeredit_repr", "label": ".__repr__()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L42", "complexity": 1, "loc": 3}, {"id": "player_edit_playeredit_to_dict", "label": ".to_dict()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L46", "complexity": 4, "loc": 15}, {"id": "player_edit_rationale_1", "label": "Player edit model for tracking media edited on players.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L1"}, {"id": "player_edit_rationale_9", "label": "Player edit model for tracking media files edited on player devices. At", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L9"}, {"id": "player_edit_rationale_43", "label": "String representation of PlayerEdit.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L43"}, {"id": "player_edit_rationale_47", "label": "Convert to dictionary for API responses.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L47"}], "edges": [{"source": "home_scheianu_digiserver_v2_app_models_player_edit_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_player_edit_py", "target": "typing", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L3", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_player_edit_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_player_edit_py", "target": "player_edit_playeredit", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L8", "weight": 1.0}, {"source": "player_edit_playeredit", "target": "player_edit_playeredit_repr", "relation": "method", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L42", "weight": 1.0}, {"source": "player_edit_playeredit", "target": "player_edit_playeredit_to_dict", "relation": "method", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L46", "weight": 1.0}, {"source": "player_edit_rationale_1", "target": "home_scheianu_digiserver_v2_app_models_player_edit_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L1", "weight": 1.0}, {"source": "player_edit_rationale_9", "target": "player_edit_playeredit", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L9", "weight": 1.0}, {"source": "player_edit_rationale_43", "target": "player_edit_playeredit_repr", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L43", "weight": 1.0}, {"source": "player_edit_rationale_47", "target": "player_edit_playeredit_to_dict", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L47", "weight": 1.0}], "raw_calls": [{"caller_nid": "player_edit_playeredit_to_dict", "callee": "isoformat", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L57"}, {"caller_nid": "player_edit_playeredit_to_dict", "callee": "isoformat", "source_file": "/home/scheianu/digiserver-v2/app/models/player_edit.py", "source_location": "L58"}]}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_migrations_add_deployment_fields_to_player_py", "label": "add_deployment_fields_to_player.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "add_deployment_fields_to_player_rationale_1", "label": "Add deployment tracking columns to player table.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_migrations_add_deployment_fields_to_player_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_deployment_fields_to_player_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_deployment_fields_to_player_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_deployment_fields_to_player_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py", "source_location": "L7", "weight": 1.0}, {"source": "add_deployment_fields_to_player_rationale_1", "target": "home_scheianu_digiserver_v2_migrations_add_deployment_fields_to_player_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_models_init_py", "label": "__init__.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "init_rationale_1", "label": "Models package for digiserver-v2.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_user", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_player", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L3", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_group", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L4", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_playlist", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_content", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_server_log", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L7", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_player_feedback", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L8", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_player_edit", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L9", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_player_user", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L10", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_init_py", "target": "app_models_https_config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L11", "weight": 1.0}, {"source": "init_rationale_1", "target": "home_scheianu_digiserver_v2_app_models_init_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/__init__.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_old_code_documentation_add_muted_column_py", "label": "add_muted_column.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "add_muted_column_add_muted_column", "label": "add_muted_column()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L6", "complexity": 3, "loc": 25}, {"id": "add_muted_column_rationale_7", "label": "Add muted column to playlist_content association table.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L7"}], "edges": [{"source": "home_scheianu_digiserver_v2_old_code_documentation_add_muted_column_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L3", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_add_muted_column_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L4", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_add_muted_column_py", "target": "add_muted_column_add_muted_column", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L6", "weight": 1.0}, {"source": "add_muted_column_rationale_7", "target": "add_muted_column_add_muted_column", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L7", "weight": 1.0}], "raw_calls": [{"caller_nid": "add_muted_column_add_muted_column", "callee": "create_app", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L8"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "app_context", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L10"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "fetchall", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L13"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "execute", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L13"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "text", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L13"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "print", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L17"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "execute", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L21"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "text", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L21"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "commit", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L25"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "print", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L26"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "print", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L27"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "rollback", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L29"}, {"caller_nid": "add_muted_column_add_muted_column", "callee": "print", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/add_muted_column.py", "source_location": "L30"}]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_utils_script_name_fix_py", "label": "script_name_fix.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "script_name_fix_scriptnamefix", "label": "ScriptNameFix", "file_type": "code", "type": "CLASS", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L15", "complexity": 3, "loc": 12}, {"id": "script_name_fix_scriptnamefix_init", "label": ".__init__()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L16", "complexity": 1, "loc": 2}, {"id": "script_name_fix_scriptnamefix_call", "label": ".__call__()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L19", "complexity": 3, "loc": 8}, {"id": "script_name_fix_rationale_1", "label": "ScriptNameFix WSGI middleware. When nginx strips the path prefix before forward", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_app_utils_script_name_fix_py", "target": "script_name_fix_scriptnamefix", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L15", "weight": 1.0}, {"source": "script_name_fix_scriptnamefix", "target": "script_name_fix_scriptnamefix_init", "relation": "method", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L16", "weight": 1.0}, {"source": "script_name_fix_scriptnamefix", "target": "script_name_fix_scriptnamefix_call", "relation": "method", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L19", "weight": 1.0}, {"source": "script_name_fix_rationale_1", "target": "home_scheianu_digiserver_v2_app_utils_script_name_fix_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L1", "weight": 1.0}], "raw_calls": [{"caller_nid": "script_name_fix_scriptnamefix_call", "callee": "rstrip", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L20"}, {"caller_nid": "script_name_fix_scriptnamefix_call", "callee": "get", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L20"}, {"caller_nid": "script_name_fix_scriptnamefix_call", "callee": "get", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L23"}, {"caller_nid": "script_name_fix_scriptnamefix_call", "callee": "startswith", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L24"}, {"caller_nid": "script_name_fix_scriptnamefix_call", "callee": "len", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L25"}, {"caller_nid": "script_name_fix_scriptnamefix_call", "callee": "app", "source_file": "/home/scheianu/digiserver-v2/app/utils/script_name_fix.py", "source_location": "L26"}]}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_old_code_documentation_fix_player_user_schema_py", "label": "fix_player_user_schema.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "fix_player_user_schema_main", "label": "main()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L10", "complexity": 1, "loc": 13}], "edges": [{"source": "home_scheianu_digiserver_v2_old_code_documentation_fix_player_user_schema_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L3", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_fix_player_user_schema_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_fix_player_user_schema_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L7", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_fix_player_user_schema_py", "target": "app_models_player_user", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L8", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_old_code_documentation_fix_player_user_schema_py", "target": "fix_player_user_schema_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L10", "weight": 1.0}], "raw_calls": [{"caller_nid": "fix_player_user_schema_main", "callee": "create_app", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L11"}, {"caller_nid": "fix_player_user_schema_main", "callee": "app_context", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L12"}, {"caller_nid": "fix_player_user_schema_main", "callee": "print", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L14"}, {"caller_nid": "fix_player_user_schema_main", "callee": "execute", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L15"}, {"caller_nid": "fix_player_user_schema_main", "callee": "text", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L15"}, {"caller_nid": "fix_player_user_schema_main", "callee": "commit", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L16"}, {"caller_nid": "fix_player_user_schema_main", "callee": "print", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L19"}, {"caller_nid": "fix_player_user_schema_main", "callee": "create", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L20"}, {"caller_nid": "fix_player_user_schema_main", "callee": "print", "source_file": "/home/scheianu/digiserver-v2/old_code_documentation/fix_player_user_schema.py", "source_location": "L22"}]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_models_player_user_py", "label": "player_user.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "player_user_playeruser", "label": "PlayerUser", "file_type": "code", "type": "CLASS", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L7", "complexity": 3, "loc": 31}, {"id": "player_user_playeruser_repr", "label": ".__repr__()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L25", "complexity": 1, "loc": 3}, {"id": "player_user_playeruser_to_dict", "label": ".to_dict()", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L29", "complexity": 3, "loc": 9}, {"id": "player_user_rationale_1", "label": "Player user model for managing user codes and names.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L1"}, {"id": "player_user_rationale_8", "label": "Player user model for managing user codes and names globally. Attribute", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L8"}, {"id": "player_user_rationale_26", "label": "String representation of PlayerUser.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L26"}, {"id": "player_user_rationale_30", "label": "Convert to dictionary for API responses.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L30"}], "edges": [{"source": "home_scheianu_digiserver_v2_app_models_player_user_py", "target": "datetime", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_player_user_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L4", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_models_player_user_py", "target": "player_user_playeruser", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L7", "weight": 1.0}, {"source": "player_user_playeruser", "target": "player_user_playeruser_repr", "relation": "method", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L25", "weight": 1.0}, {"source": "player_user_playeruser", "target": "player_user_playeruser_to_dict", "relation": "method", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L29", "weight": 1.0}, {"source": "player_user_rationale_1", "target": "home_scheianu_digiserver_v2_app_models_player_user_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L1", "weight": 1.0}, {"source": "player_user_rationale_8", "target": "player_user_playeruser", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L8", "weight": 1.0}, {"source": "player_user_rationale_26", "target": "player_user_playeruser_repr", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L26", "weight": 1.0}, {"source": "player_user_rationale_30", "target": "player_user_playeruser_to_dict", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L30", "weight": 1.0}], "raw_calls": [{"caller_nid": "player_user_playeruser_to_dict", "callee": "isoformat", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L35"}, {"caller_nid": "player_user_playeruser_to_dict", "callee": "isoformat", "source_file": "/home/scheianu/digiserver-v2/app/models/player_user.py", "source_location": "L36"}]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_migrations_migrate_player_user_global_py", "label": "migrate_player_user_global.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "migrate_player_user_global_rationale_1", "label": "Migrate player_user table to remove player_id and make user_code unique globally", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_migrations_migrate_player_user_global_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_migrate_player_user_global_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_migrate_player_user_global_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_migrate_player_user_global_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py", "source_location": "L7", "weight": 1.0}, {"source": "migrate_player_user_global_rationale_1", "target": "home_scheianu_digiserver_v2_migrations_migrate_player_user_global_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_migrations_add_original_filename_to_content_py", "label": "add_original_filename_to_content.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "add_original_filename_to_content_rationale_1", "label": "Add original_filename column to content table. This preserves the pristine uplo", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_migrations_add_original_filename_to_content_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py", "source_location": "L8", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_original_filename_to_content_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py", "source_location": "L11", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_original_filename_to_content_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py", "source_location": "L12", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_original_filename_to_content_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py", "source_location": "L13", "weight": 1.0}, {"source": "add_original_filename_to_content_rationale_1", "target": "home_scheianu_digiserver_v2_migrations_add_original_filename_to_content_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_migrations_add_email_to_https_config_py", "label": "add_email_to_https_config.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "add_email_to_https_config_rationale_1", "label": "Add email field to https_config table.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_migrations_add_email_to_https_config_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_email_to_https_config_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_email_to_https_config_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_email_to_https_config_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py", "source_location": "L7", "weight": 1.0}, {"source": "add_email_to_https_config_rationale_1", "target": "home_scheianu_digiserver_v2_migrations_add_email_to_https_config_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_extensions_py", "label": "extensions.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "extensions_rationale_1", "label": "Flask extensions initialization Centralized extension management for the applica", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_app_extensions_py", "target": "flask_sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_extensions_py", "target": "flask_bcrypt", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_extensions_py", "target": "flask_login", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L7", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_extensions_py", "target": "flask_migrate", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L8", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_extensions_py", "target": "flask_caching", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L9", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_extensions_py", "target": "flask_cors", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L10", "weight": 1.0}, {"source": "extensions_rationale_1", "target": "home_scheianu_digiserver_v2_app_extensions_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/extensions.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_migrations_add_url_to_content_py", "label": "add_url_to_content.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/migrations/add_url_to_content.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "add_url_to_content_rationale_1", "label": "Add url column to content table for weblink support.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/migrations/add_url_to_content.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_migrations_add_url_to_content_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_url_to_content.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_url_to_content_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_url_to_content.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_url_to_content_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_url_to_content.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_url_to_content_py", "target": "sqlalchemy", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_url_to_content.py", "source_location": "L7", "weight": 1.0}, {"source": "add_url_to_content_rationale_1", "target": "home_scheianu_digiserver_v2_migrations_add_url_to_content_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_url_to_content.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_app_utils_init_py", "label": "__init__.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/app/utils/__init__.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "init_rationale_1", "label": "Utils package for digiserver-v2.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/app/utils/__init__.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_app_utils_init_py", "target": "app_utils_logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/__init__.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_utils_init_py", "target": "app_utils_uploads", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/__init__.py", "source_location": "L3", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_utils_init_py", "target": "app_utils_group_player_management", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/__init__.py", "source_location": "L13", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_app_utils_init_py", "target": "app_utils_pptx_converter", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/__init__.py", "source_location": "L21", "weight": 1.0}, {"source": "init_rationale_1", "target": "home_scheianu_digiserver_v2_app_utils_init_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/app/utils/__init__.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "home_scheianu_digiserver_v2_migrations_add_player_user_table_py", "label": "add_player_user_table.py", "file_type": "code", "type": "FUNCTION", "source_file": "/home/scheianu/digiserver-v2/migrations/add_player_user_table.py", "source_location": "L1", "complexity": 1, "loc": 1}, {"id": "add_player_user_table_rationale_1", "label": "Add player_user table for user code mappings.", "file_type": "rationale", "source_file": "/home/scheianu/digiserver-v2/migrations/add_player_user_table.py", "source_location": "L1"}], "edges": [{"source": "home_scheianu_digiserver_v2_migrations_add_player_user_table_py", "target": "sys", "relation": "imports", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_player_user_table.py", "source_location": "L2", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_player_user_table_py", "target": "app_app", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_player_user_table.py", "source_location": "L5", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_player_user_table_py", "target": "app_extensions", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_player_user_table.py", "source_location": "L6", "weight": 1.0}, {"source": "home_scheianu_digiserver_v2_migrations_add_player_user_table_py", "target": "app_models_player_user", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_player_user_table.py", "source_location": "L7", "weight": 1.0}, {"source": "add_player_user_table_rationale_1", "target": "home_scheianu_digiserver_v2_migrations_add_player_user_table_py", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "/home/scheianu/digiserver-v2/migrations/add_player_user_table.py", "source_location": "L1", "weight": 1.0}], "raw_calls": []}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+36
View File
@@ -0,0 +1,36 @@
{
"hotspots": [
{
"label": "receive_edited_media()",
"risk": 0.62,
"type": "FUNCTION"
},
{
"label": "deploy_player_to_host()",
"risk": 0.614,
"type": "FUNCTION"
},
{
"label": "add_player()",
"risk": 0.592,
"type": "FUNCTION"
},
{
"label": "upload_media()",
"risk": 0.537,
"type": "FUNCTION"
},
{
"label": "manage_player()",
"risk": 0.429,
"type": "FUNCTION"
}
],
"blast_radius": {
"log_action()": 116,
"PlayerEdit": 99,
"PlayerUser": 74,
"Playlist": 33,
"CaddyConfigGenerator": 31
}
}
+159
View File
@@ -0,0 +1,159 @@
{
"projectName": "digiserver-v2",
"communityLabels": {
"0": "Community 0",
"1": "Community 1",
"2": "Community 2",
"3": "Community 3",
"4": "Community 4",
"5": "Community 5",
"6": "Community 6",
"7": "Community 7",
"8": "Community 8",
"9": "Community 9",
"10": "Community 10",
"11": "Community 11",
"12": "Community 12",
"13": "Community 13",
"14": "Community 14",
"15": "Community 15",
"16": "Community 16",
"17": "Community 17",
"18": "Community 18",
"19": "Community 19",
"20": "Community 20",
"21": "Community 21",
"22": "Community 22",
"23": "Community 23",
"24": "Community 24",
"25": "Community 25",
"26": "Community 26",
"27": "Community 27",
"28": "Community 28",
"29": "Community 29",
"30": "Community 30",
"31": "Community 31",
"32": "Community 32",
"33": "Community 33",
"34": "Community 34",
"35": "Community 35",
"36": "Community 36",
"37": "Community 37",
"38": "Community 38",
"39": "Community 39",
"40": "Community 40"
},
"communitySummaries": {
"0": "",
"1": "",
"2": "",
"3": "",
"4": "",
"5": "",
"6": "",
"7": "",
"8": "",
"9": "",
"10": "",
"11": "",
"12": "",
"13": "",
"14": "",
"15": "",
"16": "",
"17": "",
"18": "",
"19": "",
"20": "",
"21": "",
"22": "",
"23": "",
"24": "",
"25": "",
"26": "",
"27": "",
"28": "",
"29": "",
"30": "",
"31": "",
"32": "",
"33": "",
"34": "",
"35": "",
"36": "",
"37": "",
"38": "",
"39": "",
"40": ""
},
"communityLinks": {
"1": {
"11": 3,
"0": 21,
"4": 1,
"6": 5,
"10": 1,
"3": 27
},
"11": {
"0": 1,
"1": 2,
"3": 1
},
"0": {
"9": 2,
"4": 1,
"10": 1,
"7": 2
},
"4": {},
"6": {
"7": 1,
"5": 1,
"0": 14,
"11": 1,
"1": 16,
"10": 1,
"3": 16
},
"10": {
"6": 1,
"11": 1
},
"3": {
"0": 14,
"5": 5,
"7": 1,
"1": 25,
"10": 1,
"2": 1
},
"9": {
"0": 5,
"5": 1
},
"5": {
"3": 9,
"4": 1,
"7": 1,
"0": 2,
"1": 1,
"6": 3,
"2": 1
},
"2": {
"7": 2,
"3": 25,
"5": 6,
"0": 25
},
"7": {
"0": 3,
"3": 2,
"8": 1,
"6": 1,
"1": 1
},
"8": {}
}
}
+1
View File
@@ -0,0 +1 @@
[]
@@ -0,0 +1,243 @@
# CaddyConfigGenerator
> God node · 31 connections · [/home/scheianu/digiserver-v2/app/utils/caddy_manager.py](file:///home/scheianu/digiserver-v2/app/utils/caddy_manager.py#L36)
## Call Trace Diagram
```mermaid
sequenceDiagram
participant P0 as CaddyConfigGenerator
participant P1 as HTTPSConfig
participant P2 as Models package for digiserver-v2.
participant P3 as PlayerEdit
participant P4 as PlayerUser
participant P5 as Playlist
participant P6 as Content
participant P7 as User
participant P8 as Player
participant P9 as ServerLog
participant P10 as Group
participant P11 as PlayerFeedback
participant P12 as Players blueprint for player management and display.
participant P13 as Display list of all players.
participant P14 as Add a new player with optional SSH deployment.
participant P15 as Regenerate authentication code for a player.
participant P16 as Redirect to manage player page (combined view).
participant P17 as Manage player - edit credentials, assign playlist, view logs.
participant P18 as Display all edited media files from this player.
participant P19 as Display a tabular report of all edited media from this player.
participant P20 as Display player fullscreen view (no authentication required for players).
participant P21 as Get playlist for a player based on their assigned playlist. Args:
participant P22 as Legacy endpoint - Content reordering now handled in playlist management.
participant P23 as Delete multiple players at once.
participant P24 as Assign multiple players to a playlist.
participant P25 as Return deployment status for all players (used by polling JS).
participant P26 as Reorder items in player's playlist.
participant P27 as Remove content from player's playlist.
participant P28 as Add https_config table for HTTPS configuration management.
participant P29 as Caddy configuration generator and manager.
participant P30 as Generate Caddyfile configuration based on HTTPSConfig.
participant P31 as Generate a complete Caddyfile. Behaviour: - HTTPS disabled / no
participant P32 as Write Caddyfile to disk. The default path is /etc/caddy/Caddyfile — the
participant P33 as Push the current Caddyfile to Caddy via its admin API (/load). Caddy ap
participant P34 as Write Caddyfile to disk. Args: caddyfile_content: C
participant P35 as Reload Caddy configuration without restart. Note: Caddy monitor
participant P36 as Admin blueprint for user management and system settings.
participant P37 as Decorator to require admin role for route access.
participant P38 as Display admin panel with system overview.
participant P39 as Create a new user account.
participant P40 as Change user role between user and admin.
participant P41 as Delete a user account.
participant P42 as Change application theme.
participant P43 as Upload custom logo for application.
participant P44 as Clear all server logs.
participant P45 as Display user management page.
participant P46 as Get system information as JSON.
participant P47 as Display leftover media files not assigned to any playlist.
participant P48 as Delete all leftover images that are not part of any playlist
participant P49 as Delete all leftover videos that are not part of any playlist
participant P50 as Delete a single leftover content file
participant P51 as Show system dependencies status.
participant P52 as Install LibreOffice for PPTX conversion.
participant P53 as Install Emoji Fonts for better UI display.
participant P54 as Logo customization page.
participant P55 as Upload login page logo.
participant P56 as Display and manage users that edit images on players.
participant P57 as Update editing user name.
participant P58 as Display HTTPS configuration management page.
participant P59 as Update HTTPS configuration.
participant P60 as Get current HTTPS configuration status as JSON.
participant P61 as Path to the persisted player-build settings (in the instance folder).
participant P62 as Display the 'Build player files for deployment' admin page.
participant P63 as Build/refresh the staged player code and/or write its base config.
P0->>+ P1: uses
P1-->>- P0: return
P1->>+ P0: uses
P0-->>- P1: return
P1->>+ P2: uses
P2-->>- P1: return
P2->>+ P3: uses
P3-->>- P2: return
P2->>+ P4: uses
P4-->>- P2: return
P2->>+ P5: uses
P5-->>- P2: return
P2->>+ P1: uses
P1-->>- P2: return
P2->>+ P6: uses
P6-->>- P2: return
P2->>+ P7: uses
P7-->>- P2: return
P2->>+ P8: uses
P8-->>- P2: return
P2->>+ P9: uses
P9-->>- P2: return
P2->>+ P10: uses
P10-->>- P2: return
P2->>+ P11: uses
P11-->>- P2: return
P1->>+ P12: uses
P12-->>- P1: return
P12->>+ P3: uses
P3-->>- P12: return
P12->>+ P4: uses
P4-->>- P12: return
P12->>+ P1: uses
P1-->>- P12: return
P1->>+ P13: uses
P13-->>- P1: return
P1->>+ P14: uses
P14-->>- P1: return
P1->>+ P15: uses
P15-->>- P1: return
P1->>+ P16: uses
P16-->>- P1: return
P1->>+ P17: uses
P17-->>- P1: return
P1->>+ P18: uses
P18-->>- P1: return
P1->>+ P19: uses
P19-->>- P1: return
P1->>+ P20: uses
P20-->>- P1: return
P1->>+ P21: uses
P21-->>- P1: return
P1->>+ P22: uses
P22-->>- P1: return
P1->>+ P23: uses
P23-->>- P1: return
P1->>+ P24: uses
P24-->>- P1: return
P1->>+ P25: uses
P25-->>- P1: return
P1->>+ P26: uses
P26-->>- P1: return
P1->>+ P27: uses
P27-->>- P1: return
P1->>+ P28: uses
P28-->>- P1: return
P1->>+ P29: uses
P29-->>- P1: return
P1->>+ P30: uses
P30-->>- P1: return
P1->>+ P31: uses
P31-->>- P1: return
P1->>+ P32: uses
P32-->>- P1: return
P1->>+ P33: uses
P33-->>- P1: return
P1->>+ P34: uses
P34-->>- P1: return
P1->>+ P35: uses
P35-->>- P1: return
P0->>+ P36: uses
P36-->>- P0: return
P0->>+ P37: uses
P37-->>- P0: return
P0->>+ P38: uses
P38-->>- P0: return
P0->>+ P39: uses
P39-->>- P0: return
P0->>+ P40: uses
P40-->>- P0: return
P0->>+ P41: uses
P41-->>- P0: return
P0->>+ P42: uses
P42-->>- P0: return
P0->>+ P43: uses
P43-->>- P0: return
P0->>+ P44: uses
P44-->>- P0: return
P0->>+ P45: uses
P45-->>- P0: return
P0->>+ P46: uses
P46-->>- P0: return
P0->>+ P47: uses
P47-->>- P0: return
P0->>+ P48: uses
P48-->>- P0: return
P0->>+ P49: uses
P49-->>- P0: return
P0->>+ P50: uses
P50-->>- P0: return
P0->>+ P51: uses
P51-->>- P0: return
P0->>+ P52: uses
P52-->>- P0: return
P0->>+ P53: uses
P53-->>- P0: return
P0->>+ P54: uses
P54-->>- P0: return
P0->>+ P55: uses
P55-->>- P0: return
P0->>+ P56: uses
P56-->>- P0: return
P0->>+ P57: uses
P57-->>- P0: return
P0->>+ P58: uses
P58-->>- P0: return
P0->>+ P59: uses
P59-->>- P0: return
P0->>+ P60: uses
P60-->>- P0: return
P0->>+ P61: uses
P61-->>- P0: return
P0->>+ P62: uses
P62-->>- P0: return
P0->>+ P63: uses
P63-->>- P0: return
```
## Connections by Relation
### contains
- [[caddy_manager.py]] `EXTRACTED`
### rationale_for
- [[Generate Caddyfile configuration based on HTTPSConfig.]] `EXTRACTED`
### uses
- [[HTTPSConfig]] `INFERRED`
- [[Admin blueprint for user management and system settings.]] `INFERRED`
- [[Decorator to require admin role for route access.]] `INFERRED`
- [[Display admin panel with system overview.]] `INFERRED`
- [[Create a new user account.]] `INFERRED`
- [[Change user role between user and admin.]] `INFERRED`
- [[Delete a user account.]] `INFERRED`
- [[Change application theme.]] `INFERRED`
- [[Upload custom logo for application.]] `INFERRED`
- [[Clear all server logs.]] `INFERRED`
- [[Display user management page.]] `INFERRED`
- [[Get system information as JSON.]] `INFERRED`
- [[Display leftover media files not assigned to any playlist.]] `INFERRED`
- [[Delete all leftover images that are not part of any playlist]] `INFERRED`
- [[Delete all leftover videos that are not part of any playlist]] `INFERRED`
- [[Delete a single leftover content file]] `INFERRED`
- [[Show system dependencies status.]] `INFERRED`
- [[Install LibreOffice for PPTX conversion.]] `INFERRED`
- [[Install Emoji Fonts for better UI display.]] `INFERRED`
- [[Logo customization page.]] `INFERRED`
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+66
View File
@@ -0,0 +1,66 @@
# Community 0
> 90 nodes · cohesion 0.03
## Key Concepts
- [log_action()](file:///home/scheianu/digiserver-v2/app/utils/logger.py#L9) (116 connections)
- [content_old.py](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py#L1) (13 connections)
- [blueprint_groups.py](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L1) (13 connections)
- [ServerLog](file:///home/scheianu/digiserver-v2/app/models/server_log.py#L8) (12 connections)
- [group_player_management.py](file:///home/scheianu/digiserver-v2/app/utils/group_player_management.py#L1) (8 connections)
- [get_player_status_info()](file:///home/scheianu/digiserver-v2/app/utils/group_player_management.py#L10) (7 connections)
- [logger.py](file:///home/scheianu/digiserver-v2/app/utils/logger.py#L1) (7 connections)
- [auth.py](file:///home/scheianu/digiserver-v2/app/blueprints/auth.py#L1) (5 connections)
- [server_log.py](file:///home/scheianu/digiserver-v2/app/models/server_log.py#L1) (5 connections)
- [group_fullscreen()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L214) (4 connections)
- [group_stats()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L394) (4 connections)
- [groups_list()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L16) (4 connections)
- [manage_group()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L175) (4 connections)
- [get_group_statistics()](file:///home/scheianu/digiserver-v2/app/utils/group_player_management.py#L54) (4 connections)
- [add_content_to_group()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L298) (3 connections)
- [add_player_to_group()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L239) (3 connections)
- [remove_content_from_group()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L335) (3 connections)
- [remove_player_from_group()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L269) (3 connections)
- [reorder_group_content()](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py#L365) (3 connections)
- [bulk_delete_content()](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py#L337) (3 connections)
- [check_duplicates()](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py#L453) (3 connections)
- [content_groups_info()](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py#L478) (3 connections)
- [content_list()](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py#L30) (3 connections)
- [content_statistics()](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py#L419) (3 connections)
- [delete_by_filename()](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py#L289) (3 connections)
- *... and 65 more nodes in this community*
## Class Diagram
```mermaid
classDiagram
class ServerLog {
+server_log.py()
+.__repr__()
}
```
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/blueprints/auth.py](file:///home/scheianu/digiserver-v2/app/blueprints/auth.py)
- [/home/scheianu/digiserver-v2/app/blueprints/content_old.py](file:///home/scheianu/digiserver-v2/app/blueprints/content_old.py)
- [/home/scheianu/digiserver-v2/app/blueprints/main.py](file:///home/scheianu/digiserver-v2/app/blueprints/main.py)
- [/home/scheianu/digiserver-v2/app/models/server_log.py](file:///home/scheianu/digiserver-v2/app/models/server_log.py)
- [/home/scheianu/digiserver-v2/app/utils/group_player_management.py](file:///home/scheianu/digiserver-v2/app/utils/group_player_management.py)
- [/home/scheianu/digiserver-v2/app/utils/logger.py](file:///home/scheianu/digiserver-v2/app/utils/logger.py)
- [/home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py](file:///home/scheianu/digiserver-v2/old_code_documentation/blueprint_groups.py)
## Audit Trail
- EXTRACTED: 180 (52%)
- INFERRED: 165 (48%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+69
View File
@@ -0,0 +1,69 @@
# Community 1
> 80 nodes · cohesion 0.04
## Key Concepts
- [PlayerUser](file:///home/scheianu/digiserver-v2/app/models/player_user.py#L7) (74 connections)
- [CaddyConfigGenerator](file:///home/scheianu/digiserver-v2/app/utils/caddy_manager.py#L36) (31 connections)
- [admin.py](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1) (31 connections)
- [get_config()](file:///home/scheianu/digiserver-v2/app/models/https_config.py#L43) (8 connections)
- [build_player()](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1028) (7 connections)
- [update_https_config()](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L886) (7 connections)
- [https_config_status()](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L995) (5 connections)
- [caddy_manager.py](file:///home/scheianu/digiserver-v2/app/utils/caddy_manager.py#L1) (5 connections)
- [create_user()](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L79) (4 connections)
- [https_config()](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L856) (4 connections)
- [_player_build_meta_path()](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1019) (4 connections)
- [Admin blueprint for user management and system settings.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1) (4 connections)
- [Path to the persisted player-build settings (in the instance folder).](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1020) (4 connections)
- [Display the 'Build player files for deployment' admin page.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1029) (4 connections)
- [Change user role between user and admin.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L126) (4 connections)
- [Delete a user account.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L160) (4 connections)
- [Change application theme.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L188) (4 connections)
- [Decorator to require admin role for route access.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L19) (4 connections)
- [Upload custom logo for application.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L212) (4 connections)
- [Clear all server logs.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L254) (4 connections)
- [Display user management page.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L274) (4 connections)
- [Get system information as JSON.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L323) (4 connections)
- [Display leftover media files not assigned to any playlist.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L355) (4 connections)
- [Display admin panel with system overview.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L36) (4 connections)
- [Delete all leftover images that are not part of any playlist](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L407) (4 connections)
- *... and 55 more nodes in this community*
## Class Diagram
```mermaid
classDiagram
class CaddyConfigGenerator {
+caddy_manager.py()
}
class PlayerUser {
+player_user.py()
+.__repr__()
+.to_dict()
}
```
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/blueprints/admin.py](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py)
- [/home/scheianu/digiserver-v2/app/models/https_config.py](file:///home/scheianu/digiserver-v2/app/models/https_config.py)
- [/home/scheianu/digiserver-v2/app/models/player_edit.py](file:///home/scheianu/digiserver-v2/app/models/player_edit.py)
- [/home/scheianu/digiserver-v2/app/models/player_user.py](file:///home/scheianu/digiserver-v2/app/models/player_user.py)
- [/home/scheianu/digiserver-v2/app/utils/caddy_manager.py](file:///home/scheianu/digiserver-v2/app/utils/caddy_manager.py)
- [/home/scheianu/digiserver-v2/migrations/add_player_user_table.py](file:///home/scheianu/digiserver-v2/migrations/add_player_user_table.py)
## Audit Trail
- EXTRACTED: 156 (41%)
- INFERRED: 229 (59%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+45
View File
@@ -0,0 +1,45 @@
# Community 10
> 20 nodes · cohesion 0.12
## Key Concepts
- [ssh_deploy.py](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L1) (8 connections)
- [deploy_player_to_host()](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L311) (8 connections)
- [background_player_deployment()](file:///home/scheianu/digiserver-v2/app/utils/background_tasks.py#L29) (4 connections)
- [generate_app_config()](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L267) (4 connections)
- [get_local_player_code_status()](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L15) (4 connections)
- [run_background_task()](file:///home/scheianu/digiserver-v2/app/utils/background_tasks.py#L9) (3 connections)
- [background_tasks.py](file:///home/scheianu/digiserver-v2/app/utils/background_tasks.py#L1) (3 connections)
- [parse_server_address()](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L241) (3 connections)
- [test_ssh_connection()](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L85) (3 connections)
- [generate_player_config()](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L149) (2 connections)
- [Background task execution for long-running operations.](file:///home/scheianu/digiserver-v2/app/utils/background_tasks.py#L1) (1 connections)
- [Run a function in a background thread, with a Flask app context pushed.](file:///home/scheianu/digiserver-v2/app/utils/background_tasks.py#L10) (1 connections)
- [Deploy player code to host in background. Args: hostname: SSH h](file:///home/scheianu/digiserver-v2/app/utils/background_tasks.py#L43) (1 connections)
- [SSH deployment utilities for player provisioning.](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L1) (1 connections)
- [Generate player configuration JSON for connecting to DigiServer. Args:](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L156) (1 connections)
- [Check status of pre-staged player code. Args: player_code_dir: Opti](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L16) (1 connections)
- [Derive the values the player needs from a DigiServer URL. The player's conf](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L242) (1 connections)
- [Generate the config/app_config.json the player actually reads. This is what](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L277) (1 connections)
- [Deploy player code to remote host. Args: hostname: Target hostn](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L326) (1 connections)
- [Test SSH connection to a remote host. Args: hostname: Target ho](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py#L86) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/utils/background_tasks.py](file:///home/scheianu/digiserver-v2/app/utils/background_tasks.py)
- [/home/scheianu/digiserver-v2/app/utils/ssh_deploy.py](file:///home/scheianu/digiserver-v2/app/utils/ssh_deploy.py)
## Audit Trail
- EXTRACTED: 45 (87%)
- INFERRED: 7 (13%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+44
View File
@@ -0,0 +1,44 @@
# Community 11
> 19 nodes · cohesion 0.15
## Key Concepts
- [build_player_action()](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1074) (9 connections)
- [player_build.py](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L1) (9 connections)
- [build_player_files()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L49) (5 connections)
- [get_short_head()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L38) (5 connections)
- [Build/refresh the staged player code and/or write its base config.](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py#L1075) (4 connections)
- [get_player_server_settings()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L188) (4 connections)
- [load_build_settings()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L165) (4 connections)
- [write_base_config()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L128) (4 connections)
- [make_build_record()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L208) (3 connections)
- [_run_git()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L28) (3 connections)
- [save_build_settings()](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L176) (3 connections)
- [Utilities for building/staging the player files on the server. Admins use the "](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L1) (1 connections)
- [Write a base ``config/app_config.json`` into the staged player code. ``scre](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L137) (1 connections)
- [Load saved build settings from ``meta_path`` (or None if absent/invalid).](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L166) (1 connections)
- [Persist build settings to ``meta_path``.](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L177) (1 connections)
- [Return the saved server address settings for deployment, if available. Retu](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L189) (1 connections)
- [Assemble the metadata record to persist after a build.](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L210) (1 connections)
- [Return the short git commit of the staged code, or 'unknown'.](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L39) (1 connections)
- [Clone or refresh the player source into ``player_code_dir``. If the directo](file:///home/scheianu/digiserver-v2/app/utils/player_build.py#L50) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/blueprints/admin.py](file:///home/scheianu/digiserver-v2/app/blueprints/admin.py)
- [/home/scheianu/digiserver-v2/app/utils/player_build.py](file:///home/scheianu/digiserver-v2/app/utils/player_build.py)
## Audit Trail
- EXTRACTED: 44 (72%)
- INFERRED: 17 (28%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+32
View File
@@ -0,0 +1,32 @@
# Community 12
> 8 nodes · cohesion 0.29
## Key Concepts
- [pptx_converter.py](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L1) (4 connections)
- [cleanup_libreoffice_processes()](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L11) (3 connections)
- [pptx_to_pdf_libreoffice()](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L20) (3 connections)
- [validate_pptx_file()](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L86) (2 connections)
- [PowerPoint to PDF converter using LibreOffice.](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L1) (1 connections)
- [Clean up any hanging LibreOffice processes.](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L12) (1 connections)
- [Convert PPTX to PDF using LibreOffice for highest quality. This functio](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L21) (1 connections)
- [Validate if file is a valid PowerPoint file. Args: filepath: Pa](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py#L87) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/utils/pptx_converter.py](file:///home/scheianu/digiserver-v2/app/utils/pptx_converter.py)
## Audit Trail
- EXTRACTED: 16 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+28
View File
@@ -0,0 +1,28 @@
# Community 13
> 4 nodes · cohesion 0.50
## Key Concepts
- [migrate_add_edit_enabled.py](file:///home/scheianu/digiserver-v2/old_code_documentation/migrate_add_edit_enabled.py#L1) (2 connections)
- [migrate()](file:///home/scheianu/digiserver-v2/old_code_documentation/migrate_add_edit_enabled.py#L7) (2 connections)
- [Migration: Add edit_on_player_enabled column to playlist_content table.](file:///home/scheianu/digiserver-v2/old_code_documentation/migrate_add_edit_enabled.py#L1) (1 connections)
- [Add edit_on_player_enabled column to playlist_content.](file:///home/scheianu/digiserver-v2/old_code_documentation/migrate_add_edit_enabled.py#L8) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/old_code_documentation/migrate_add_edit_enabled.py](file:///home/scheianu/digiserver-v2/old_code_documentation/migrate_add_edit_enabled.py)
## Audit Trail
- EXTRACTED: 6 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+26
View File
@@ -0,0 +1,26 @@
# Community 14
> 2 nodes · cohesion 1.00
## Key Concepts
- [migrate_player_user_global.py](file:///home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py#L1) (1 connections)
- [Migrate player_user table to remove player_id and make user_code unique globally](file:///home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py#L1) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py](file:///home/scheianu/digiserver-v2/migrations/migrate_player_user_global.py)
## Audit Trail
- EXTRACTED: 2 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+26
View File
@@ -0,0 +1,26 @@
# Community 15
> 2 nodes · cohesion 1.00
## Key Concepts
- [Add original_filename column to content table. This preserves the pristine uplo](file:///home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py#L1) (1 connections)
- [add_original_filename_to_content.py](file:///home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py#L1) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py](file:///home/scheianu/digiserver-v2/migrations/add_original_filename_to_content.py)
## Audit Trail
- EXTRACTED: 2 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+26
View File
@@ -0,0 +1,26 @@
# Community 16
> 2 nodes · cohesion 1.00
## Key Concepts
- [Add url column to content table for weblink support.](file:///home/scheianu/digiserver-v2/migrations/add_url_to_content.py#L1) (1 connections)
- [add_url_to_content.py](file:///home/scheianu/digiserver-v2/migrations/add_url_to_content.py#L1) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/migrations/add_url_to_content.py](file:///home/scheianu/digiserver-v2/migrations/add_url_to_content.py)
## Audit Trail
- EXTRACTED: 2 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+26
View File
@@ -0,0 +1,26 @@
# Community 17
> 2 nodes · cohesion 1.00
## Key Concepts
- [Add deployment tracking columns to player table.](file:///home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py#L1) (1 connections)
- [add_deployment_fields_to_player.py](file:///home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py#L1) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py](file:///home/scheianu/digiserver-v2/migrations/add_deployment_fields_to_player.py)
## Audit Trail
- EXTRACTED: 2 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+26
View File
@@ -0,0 +1,26 @@
# Community 18
> 2 nodes · cohesion 1.00
## Key Concepts
- [Add email field to https_config table.](file:///home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py#L1) (1 connections)
- [add_email_to_https_config.py](file:///home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py#L1) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py](file:///home/scheianu/digiserver-v2/migrations/add_email_to_https_config.py)
## Audit Trail
- EXTRACTED: 2 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+26
View File
@@ -0,0 +1,26 @@
# Community 19
> 2 nodes · cohesion 1.00
## Key Concepts
- [Flask extensions initialization Centralized extension management for the applica](file:///home/scheianu/digiserver-v2/app/extensions.py#L1) (1 connections)
- [extensions.py](file:///home/scheianu/digiserver-v2/app/extensions.py#L1) (1 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/extensions.py](file:///home/scheianu/digiserver-v2/app/extensions.py)
## Audit Trail
- EXTRACTED: 2 (100%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+52
View File
@@ -0,0 +1,52 @@
# Community 2
> 68 nodes · cohesion 0.04
## Key Concepts
- [content.py](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L1) (27 connections)
- [.increment_version()](file:///home/scheianu/digiserver-v2/app/models/playlist.py#L70) (18 connections)
- [upload_media()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L1220) (9 connections)
- [playlist.py](file:///home/scheianu/digiserver-v2/app/blueprints/playlist.py#L1) (8 connections)
- [process_file_in_background()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L798) (7 connections)
- [process_presentation_file()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L977) (7 connections)
- [add_weblink()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L272) (5 connections)
- [add_weblink_to_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L352) (5 connections)
- [process_pdf_file()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L727) (5 connections)
- [process_video_file_extended()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L702) (5 connections)
- [playlist.py](file:///home/scheianu/digiserver-v2/app/models/playlist.py#L1) (5 connections)
- [add_content_to_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L222) (4 connections)
- [bulk_remove_from_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L455) (4 connections)
- [optimize_image_to_fullhd()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L1203) (4 connections)
- [process_image_file()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L676) (4 connections)
- [remove_content_from_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L418) (4 connections)
- [reorder_playlist_content()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L497) (4 connections)
- [resize_image_to_fullhd()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L1145) (4 connections)
- [update_playlist_content_duration()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L620) (4 connections)
- [update_playlist_content_edit_enabled()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L579) (4 connections)
- [update_playlist_content_muted()](file:///home/scheianu/digiserver-v2/app/blueprints/content.py#L538) (4 connections)
- [add_to_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/playlist.py#L33) (4 connections)
- [clear_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/playlist.py#L278) (4 connections)
- [remove_from_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/playlist.py#L88) (4 connections)
- [reorder_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/playlist.py#L143) (4 connections)
- *... and 43 more nodes in this community*
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/blueprints/content.py](file:///home/scheianu/digiserver-v2/app/blueprints/content.py)
- [/home/scheianu/digiserver-v2/app/blueprints/playlist.py](file:///home/scheianu/digiserver-v2/app/blueprints/playlist.py)
- [/home/scheianu/digiserver-v2/app/models/playlist.py](file:///home/scheianu/digiserver-v2/app/models/playlist.py)
## Audit Trail
- EXTRACTED: 154 (64%)
- INFERRED: 86 (36%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 20
> 1 nodes · cohesion 1.00
## Key Concepts
- [Check if feedback indicates an error.](file:///home/scheianu/digiserver-v2/app/models/player_feedback.py#L43) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/player_feedback.py](file:///home/scheianu/digiserver-v2/app/models/player_feedback.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 21
> 1 nodes · cohesion 1.00
## Key Concepts
- [Get age of feedback in seconds.](file:///home/scheianu/digiserver-v2/app/models/player_feedback.py#L48) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/player_feedback.py](file:///home/scheianu/digiserver-v2/app/models/player_feedback.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 22
> 1 nodes · cohesion 1.00
## Key Concepts
- [Get most recent feedback for a player. Args: player](file:///home/scheianu/digiserver-v2/app/models/player_feedback.py#L54) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/player_feedback.py](file:///home/scheianu/digiserver-v2/app/models/player_feedback.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 23
> 1 nodes · cohesion 1.00
## Key Concepts
- [Get the current HTTPS configuration. Returns: HTTPS](file:///home/scheianu/digiserver-v2/app/models/https_config.py#L44) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/https_config.py](file:///home/scheianu/digiserver-v2/app/models/https_config.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 24
> 1 nodes · cohesion 1.00
## Key Concepts
- [Create or update HTTPS configuration. Args: https_e](file:///home/scheianu/digiserver-v2/app/models/https_config.py#L56) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/https_config.py](file:///home/scheianu/digiserver-v2/app/models/https_config.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 25
> 1 nodes · cohesion 1.00
## Key Concepts
- [Check if user has admin role.](file:///home/scheianu/digiserver-v2/app/models/user.py#L38) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/user.py](file:///home/scheianu/digiserver-v2/app/models/user.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 26
> 1 nodes · cohesion 1.00
## Key Concepts
- [Check if player is online (seen in last 5 minutes).](file:///home/scheianu/digiserver-v2/app/models/player.py#L61) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/player.py](file:///home/scheianu/digiserver-v2/app/models/player.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 27
> 1 nodes · cohesion 1.00
## Key Concepts
- [Authenticate a player by hostname and password or quickconnect code.](file:///home/scheianu/digiserver-v2/app/models/player.py#L122) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/player.py](file:///home/scheianu/digiserver-v2/app/models/player.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 28
> 1 nodes · cohesion 1.00
## Key Concepts
- [Create an info level log entry. Args: message: Log](file:///home/scheianu/digiserver-v2/app/models/server_log.py#L31) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/server_log.py](file:///home/scheianu/digiserver-v2/app/models/server_log.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 29
> 1 nodes · cohesion 1.00
## Key Concepts
- [Create a warning level log entry. Args: message: Lo](file:///home/scheianu/digiserver-v2/app/models/server_log.py#L46) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/server_log.py](file:///home/scheianu/digiserver-v2/app/models/server_log.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+71
View File
@@ -0,0 +1,71 @@
# Community 3
> 62 nodes · cohesion 0.06
## Key Concepts
- [PlayerEdit](file:///home/scheianu/digiserver-v2/app/models/player_edit.py#L8) (99 connections)
- [Playlist](file:///home/scheianu/digiserver-v2/app/models/playlist.py#L19) (33 connections)
- [api.py](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L1) (23 connections)
- [receive_edited_media()](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L736) (6 connections)
- [authenticate_player()](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L107) (5 connections)
- [get_cached_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L378) (5 connections)
- [get_playlist_by_quickconnect()](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L207) (5 connections)
- [receive_player_feedback()](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L429) (5 connections)
- [.get_content_ordered()](file:///home/scheianu/digiserver-v2/app/models/playlist.py#L75) (5 connections)
- [deploy_player()](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L980) (4 connections)
- [get_player_playlist()](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L305) (4 connections)
- [API blueprint for REST endpoints and player communication.](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L1) (4 connections)
- [Get server SSL certificate.](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L101) (4 connections)
- [Handle 404 errors in API.](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L1050) (4 connections)
- [Handle 405 errors in API.](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L1056) (4 connections)
- [Handle 500 errors in API.](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L1062) (4 connections)
- [Authenticate a player and return auth code and configuration. Request J](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L108) (4 connections)
- [Verify an auth code and return player information. Request JSON:](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L164) (4 connections)
- [Get playlist using hostname and quickconnect code (Kivy player compatible).](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L208) (4 connections)
- [Rate limiting decorator. Args: max_requests: Maximum number of](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L22) (4 connections)
- [Get playlist for a specific player. Requires player authentication via](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L306) (4 connections)
- [Get current playlist version for a player. Lightweight endpoint for pla](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L350) (4 connections)
- [Get cached playlist for a player based on assigned playlist.](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L379) (4 connections)
- [Receive feedback/status updates from players (Kivy player compatible).](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L430) (4 connections)
- [Get current status of a player (public endpoint for monitoring).](file:///home/scheianu/digiserver-v2/app/blueprints/api.py#L541) (4 connections)
- *... and 37 more nodes in this community*
## Class Diagram
```mermaid
classDiagram
class PlayerEdit {
+player_edit.py()
+.__repr__()
+.to_dict()
}
class Playlist {
+playlist.py()
+.__repr__()
+.increment_version()
+.get_content_ordered()
}
```
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/blueprints/api.py](file:///home/scheianu/digiserver-v2/app/blueprints/api.py)
- [/home/scheianu/digiserver-v2/app/blueprints/content.py](file:///home/scheianu/digiserver-v2/app/blueprints/content.py)
- [/home/scheianu/digiserver-v2/app/models/player.py](file:///home/scheianu/digiserver-v2/app/models/player.py)
- [/home/scheianu/digiserver-v2/app/models/player_edit.py](file:///home/scheianu/digiserver-v2/app/models/player_edit.py)
- [/home/scheianu/digiserver-v2/app/models/playlist.py](file:///home/scheianu/digiserver-v2/app/models/playlist.py)
## Audit Trail
- EXTRACTED: 123 (35%)
- INFERRED: 228 (65%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 30
> 1 nodes · cohesion 1.00
## Key Concepts
- [Create an error level log entry. Args: message: Log](file:///home/scheianu/digiserver-v2/app/models/server_log.py#L61) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/server_log.py](file:///home/scheianu/digiserver-v2/app/models/server_log.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 31
> 1 nodes · cohesion 1.00
## Key Concepts
- [Get number of content items in this group.](file:///home/scheianu/digiserver-v2/app/models/group.py#L46) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/group.py](file:///home/scheianu/digiserver-v2/app/models/group.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 32
> 1 nodes · cohesion 1.00
## Key Concepts
- [Get file size in megabytes.](file:///home/scheianu/digiserver-v2/app/models/content.py#L50) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/content.py](file:///home/scheianu/digiserver-v2/app/models/content.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 33
> 1 nodes · cohesion 1.00
## Key Concepts
- [Get number of groups containing this content.](file:///home/scheianu/digiserver-v2/app/models/content.py#L57) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/content.py](file:///home/scheianu/digiserver-v2/app/models/content.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 34
> 1 nodes · cohesion 1.00
## Key Concepts
- [Name of the original (unedited) file for display purposes.](file:///home/scheianu/digiserver-v2/app/models/content.py#L62) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/content.py](file:///home/scheianu/digiserver-v2/app/models/content.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 35
> 1 nodes · cohesion 1.00
## Key Concepts
- [Path (relative to uploads/) where the original unedited file lives. Whe](file:///home/scheianu/digiserver-v2/app/models/content.py#L67) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/content.py](file:///home/scheianu/digiserver-v2/app/models/content.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*
+25
View File
@@ -0,0 +1,25 @@
# Community 36
> 1 nodes · cohesion 1.00
## Key Concepts
- [Path (relative to uploads/) of the current/latest version to display.](file:///home/scheianu/digiserver-v2/app/models/content.py#L79) (0 connections)
## Relationships
- No strong cross-community connections detected
## Source Files
- [/home/scheianu/digiserver-v2/app/models/content.py](file:///home/scheianu/digiserver-v2/app/models/content.py)
## Audit Trail
- EXTRACTED: 0 (0%)
- INFERRED: 0 (0%)
- AMBIGUOUS: 0 (0%)
---
*Part of the graphify knowledge wiki. See [[index]] to navigate.*

Some files were not shown because too many files have changed in this diff Show More