flask webui

This commit is contained in:
absalom 2025-10-15 06:19:08 +00:00
parent 6095717dd3
commit 1ecb31ae12
2 changed files with 70 additions and 14 deletions

View file

@ -1,5 +1,6 @@
FROM python:3.11-slim FROM python:3.11-slim
WORKDIR /app WORKDIR /app
COPY ta_symlink.py . COPY ta_symlink.py .
RUN pip install --no-cache-dir requests RUN pip install --no-cache-dir requests flask
EXPOSE 5000
CMD ["python", "ta_symlink.py"] CMD ["python", "ta_symlink.py"]

View file

@ -1,8 +1,10 @@
from pathlib import Path from pathlib import Path
import os import os
import requests import requests
import re import re
import sys import sys
from flask import Flask, jsonify, render_template_string, request
# Load config from environment variables # Load config from environment variables
API_URL = os.getenv("API_URL", "http://localhost:8457/api") API_URL = os.getenv("API_URL", "http://localhost:8457/api")
@ -12,6 +14,10 @@ SOURCE_DIR = Path("/app/source")
TARGET_DIR = Path("/app/target") TARGET_DIR = Path("/app/target")
HEADERS = {"Authorization": f"Token {API_TOKEN}"} HEADERS = {"Authorization": f"Token {API_TOKEN}"}
app = Flask(__name__)
processed_videos = []
# Utility functions # Utility functions
def sanitize(text): def sanitize(text):
text = text.encode("ascii", "ignore").decode() text = text.encode("ascii", "ignore").decode()
@ -42,38 +48,31 @@ def fetch_video_metadata(video_id):
return None return None
# Main logic # Main logic
def process_videos():
print("📁 Starting video processing...", flush=True)
def process_videos():
global processed_videos
processed_videos = []
try: try:
for channel_path in SOURCE_DIR.iterdir(): for channel_path in SOURCE_DIR.iterdir():
if not channel_path.is_dir(): if not channel_path.is_dir():
continue continue
for video_file in channel_path.glob("*.*"): for video_file in channel_path.glob("*.*"):
video_id = video_file.stem video_id = video_file.stem
meta = fetch_video_metadata(video_id) meta = fetch_video_metadata(video_id)
if not meta: if not meta:
print(f"⚠️ Skipped {video_id}: could not fetch metadata", flush=True)
continue continue
sanitized_channel_name = sanitize(meta["channel_name"]) sanitized_channel_name = sanitize(meta["channel_name"])
channel_dir = TARGET_DIR / sanitized_channel_name channel_dir = TARGET_DIR / sanitized_channel_name
channel_dir.mkdir(parents=True, exist_ok=True) channel_dir.mkdir(parents=True, exist_ok=True)
sanitized_title = sanitize(meta["title"]) sanitized_title = sanitize(meta["title"])
folder_name = f"{meta['published']} - {sanitized_title}" folder_name = f"{meta['published']} - {sanitized_title}"
video_dir = channel_dir / folder_name video_dir = channel_dir / folder_name
video_dir.mkdir(parents=True, exist_ok=True) video_dir.mkdir(parents=True, exist_ok=True)
actual_file = next(channel_path.glob(f"{video_id}.*"), None) actual_file = next(channel_path.glob(f"{video_id}.*"), None)
if not actual_file: if not actual_file:
print(f"⚠️ Video file not found for {video_id} in {channel_path}", flush=True)
continue continue
host_path_root = Path("/mnt/user/tubearchives/bp") host_path_root = Path("/mnt/user/tubearchives/bp")
host_source_path = host_path_root / actual_file.relative_to(SOURCE_DIR) host_source_path = host_path_root / actual_file.relative_to(SOURCE_DIR)
dest_file = video_dir / f"video{actual_file.suffix}" dest_file = video_dir / f"video{actual_file.suffix}"
try: try:
if dest_file.exists(): if dest_file.exists():
@ -84,11 +83,67 @@ def process_videos():
os.symlink(host_source_path, dest_file) os.symlink(host_source_path, dest_file)
else: else:
os.symlink(host_source_path, dest_file) os.symlink(host_source_path, dest_file)
print(f"✅ Linked: {dest_file}", flush=True)
except Exception: except Exception:
pass pass
processed_videos.append({
"video_id": video_id,
"title": meta["title"],
"channel": meta["channel_name"],
"published": meta["published"],
"symlink": str(dest_file)
})
except Exception as e: except Exception as e:
print(f"💥 Unhandled error: {e}", file=sys.stderr, flush=True) return str(e)
return None
# Flask routes
@app.route("/")
def index():
return render_template_string('''
<html>
<head><title>TA Organizerr</title></head>
<body>
<h1>TA Organizerr</h1>
<form method="post" action="/process">
<button type="submit">Process Videos</button>
</form>
<h2>Processed Videos</h2>
<ul>
{% for v in videos %}
<li>{{v.published}} - {{v.title}} ({{v.channel}}) <br>Symlink: {{v.symlink}}</li>
{% endfor %}
</ul>
</body>
</html>
''', videos=processed_videos)
@app.route("/process", methods=["POST"])
def process():
error = process_videos()
if error:
return f"Error: {error}", 500
return render_template_string('''
<html>
<head><title>TA Organizerr</title></head>
<body>
<h1>TA Organizerr</h1>
<form method="post" action="/process">
<button type="submit">Process Videos</button>
</form>
<h2>Processed Videos</h2>
<ul>
{% for v in videos %}
<li>{{v.published}} - {{v.title}} ({{v.channel}}) <br>Symlink: {{v.symlink}}</li>
{% endfor %}
</ul>
</body>
</html>
''', videos=processed_videos)
@app.route("/api/videos")
def api_videos():
return jsonify(processed_videos)
if __name__ == "__main__": if __name__ == "__main__":
process_videos() app.run(host="0.0.0.0", port=5000)