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
+69 -47
View File
@@ -1072,11 +1072,14 @@ def build_player():
@login_required
@admin_required
def build_player_action():
"""Build/refresh the staged player code and/or write its base config."""
from app.utils.player_build import (
build_player_files, write_base_config, get_short_head,
save_build_settings, make_build_record,
)
"""Start building/refreshing the staged player code.
The build runs in a background thread because a full clone of the player
repository takes far longer than gunicorn's worker timeout; running it
in-request would get the worker killed mid-clone and leave a broken
checkout. The page then polls ``admin.build_player_status`` for progress.
"""
from app.utils.player_build import start_background_build, is_build_running
player_code_dir = current_app.config['PLAYER_CODE_DIR']
action = request.form.get('action', 'build_and_config')
@@ -1090,16 +1093,14 @@ def build_player_action():
orientation = request.form.get('orientation', 'Landscape').strip() or 'Landscape'
max_resolution = request.form.get('max_resolution', '1920x1080').strip() or '1920x1080'
# Validation
# Validation (unchanged — fail fast before starting any work)
errors = []
if action in ('build_files', 'build_and_config') and not repo_url:
errors.append('Repository URL is required to build player files.')
if action in ('save_config', 'build_and_config') and not server_ip:
errors.append('Server IP / domain is required for the player configuration.')
try:
port_num = int(port)
if port_num < 1 or port_num > 65535:
errors.append('Port must be between 1 and 65535.')
int(port)
except ValueError:
errors.append('Port must be a valid number.')
@@ -1108,51 +1109,72 @@ def build_player_action():
flash(err, 'warning')
return redirect(url_for('admin.build_player'))
messages = []
success = True
version = None
# Step 1: build/refresh files from the repository.
if action in ('build_files', 'build_and_config'):
result = build_player_files(player_code_dir, repo_url, branch)
version = result.get('version')
messages.append(result['message'])
if not result['success']:
success = False
log_action('error', f'Player build failed by {current_user.username}: {result["message"]}')
# Step 2: write the base config (only if the previous step didn't fail).
if success and action in ('save_config', 'build_and_config'):
# 'save_config' only writes the config file — it touches no network and is
# fast, so it stays synchronous.
if action == 'save_config':
from app.utils.player_build import (
write_base_config, get_short_head, save_build_settings, make_build_record,
)
cfg_result = write_base_config(
player_code_dir=player_code_dir,
server_ip=server_ip,
port=port,
use_https=use_https,
verify_ssl=verify_ssl,
orientation=orientation,
server_ip=server_ip, port=port, use_https=use_https,
verify_ssl=verify_ssl, orientation=orientation,
max_resolution=max_resolution,
)
messages.append(cfg_result['message'])
if not cfg_result['success']:
success = False
# Persist settings so deployment uses the same server address.
if version is None:
version = get_short_head(player_code_dir)
save_build_settings(
_player_build_meta_path(),
make_build_record(
repo_url=repo_url, branch=branch, server_ip=server_ip, port=port,
use_https=use_https, verify_ssl=verify_ssl, orientation=orientation,
max_resolution=max_resolution, version=version, built_by=current_user.username,
),
save_build_settings(
_player_build_meta_path(),
make_build_record(
repo_url=repo_url, branch=branch, server_ip=server_ip, port=port,
use_https=use_https, verify_ssl=verify_ssl, orientation=orientation,
max_resolution=max_resolution, version=version,
built_by=current_user.username,
),
)
if cfg_result['success']:
log_action('info', f'Player config saved by {current_user.username}')
flash(f"{cfg_result['message']}", 'success')
else:
log_action('error', f'Player config write failed: {cfg_result["message"]}')
flash(f"⚠️ {cfg_result['message']}", 'danger')
return redirect(url_for('admin.build_player'))
# build_files / build_and_config → background thread.
if is_build_running():
flash('⚠️ A build is already running — wait for it to finish.', 'warning')
return redirect(url_for('admin.build_player'))
config_payload = None
if action == 'build_and_config':
config_payload = {
'server_ip': server_ip, 'port': port, 'use_https': use_https,
'verify_ssl': verify_ssl, 'orientation': orientation,
'max_resolution': max_resolution,
}
started = start_background_build(
player_code_dir=player_code_dir,
repo_url=repo_url,
branch=branch,
config_payload=config_payload,
meta_path=_player_build_meta_path(),
built_by=current_user.username,
)
summary = ' '.join(messages) if messages else 'No action performed.'
if success:
log_action('info', f'Player files built by {current_user.username} (version {version})')
flash(f'{summary}', 'success')
if not started:
flash('⚠️ A build is already running — wait for it to finish.', 'warning')
else:
flash(f'⚠️ {summary}', 'danger')
log_action('info', f'Player build started by {current_user.username} '
f'({branch} @ {repo_url})')
flash('⏳ Build started — this page will update automatically.', 'info')
return redirect(url_for('admin.build_player'))
@admin_bp.route('/build-player/status', methods=['GET'])
@login_required
@admin_required
def build_player_status():
"""JSON progress for the running/last player build (polled by the page)."""
from app.utils.player_build import get_build_state
return jsonify(get_build_state())