Nyt admin-modul /admin/yt: indsæt en YouTube-URL, og videoen hentes med yt-dlp til Emby-biblioteket "YouTube" (/media/yt-offline) — klar til offline-brug. Oprydningen er bevidst modsat mediaclean.py: dér tæller selv delvis afspilning som "set" for at frede alt der er rørt, her slettes kun videoer der er eksplicit markeret som set (Emby UserData.Played). Halvt sete videoer bliver liggende. Favoritter slettes aldrig, og en favoritering i karensperioden freder igen. Sikkerhedsnet: oprydningen rører kun filer portalen selv har hentet (registreret med fuld sti i yt_state.json). Det eksisterende YT-bibliotek er urørligt, og download-træet er lagt uden for det, så Emby ikke indekserer dobbelt. Standardvalg: - H.264/AAC foretrækkes frem for AV1. Pascal-GPU'en i CT100 kan ikke afkode AV1, og mange afspillere kan det slet ikke offline. Koster ~1,8x diskplads. - SponsorBlock klipper sponsorater ud og beholder resten som kapitler. - Undertekster hentes hvis de findes, men er aldrig et krav: YouTube rate-limiter undertekst-endpointet uafhængigt af videoen, så en 429 dér ville ellers vælte hele hentningen. Fald-tilbage henter videoen uden undertekster. - Metadata, miniature og kapitler indlejres, så Emby har noget at vise. Alt kan redigeres i UI'et. Natlig timer (yt-offline.timer) tømmer køen og rydder op. Claude-Session: https://claude.ai/code/session_011WxG8pbLj61jYU1MMaD7VC
105 lines
5.5 KiB
Python
105 lines
5.5 KiB
Python
"""Konfiguration (env) + konstanter for portalen."""
|
|
import os
|
|
from pathlib import Path
|
|
|
|
BASE = Path(__file__).resolve().parent
|
|
DATA = Path(os.environ.get("PORTAL_DATA", "/opt/portal/data"))
|
|
DATA.mkdir(parents=True, exist_ok=True)
|
|
|
|
AUTHENTIK = os.environ["AUTHENTIK_BASE"].rstrip("/")
|
|
CLIENT_ID = os.environ["OIDC_CLIENT_ID"]
|
|
CLIENT_SECRET = os.environ["OIDC_CLIENT_SECRET"]
|
|
API_TOKEN = os.environ["AUTHENTIK_API_TOKEN"]
|
|
SECRET_KEY = os.environ["SESSION_SECRET"]
|
|
REDIRECT_URI = os.environ.get("OIDC_REDIRECT_URI", "https://weircon.dk/auth/callback")
|
|
ADMIN_GROUP = os.environ.get("ADMIN_GROUP", "authentik Admins")
|
|
|
|
MATOMO_BASE = os.environ.get("MATOMO_BASE", "https://matomo.weircon.dk").rstrip("/")
|
|
MATOMO_TOKEN = os.environ.get("MATOMO_TOKEN", "")
|
|
MATOMO_SITE = os.environ.get("MATOMO_SITE", "2")
|
|
RP_BASE_URL = os.environ.get("RP_BASE_URL", "https://rp.weircon.dk").rstrip("/")
|
|
RP_API_KEY = os.environ.get("RP_API_KEY", "")
|
|
ASSETS_VERSION_URL = os.environ.get("ASSETS_VERSION_URL", "https://assets.weircon.dk/VERSION")
|
|
GEOIP_DB = os.environ.get("GEOIP_DB", str(DATA / "dbip-country.mmdb"))
|
|
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", "") # valgfri: hæver GitHub-rate-limit 60→5000/t
|
|
NTFY_URL = os.environ.get("NTFY_URL", "") # fx https://ntfy.weircon.dk
|
|
NTFY_TOPIC = os.environ.get("NTFY_TOPIC", "ops")
|
|
NTFY_TOKEN = os.environ.get("NTFY_TOKEN", "") # tk_… publish-token
|
|
DISCO_BASE_URL = os.environ.get("DISCO_BASE_URL", "") # DiscoPanel Connect-RPC (CT137)
|
|
DISCO_API_TOKEN = os.environ.get("DISCO_API_TOKEN", "")
|
|
DISCO_PANEL_URL = os.environ.get("DISCO_PANEL_URL", "") # bruger-vendt panel-URL til forsiden
|
|
|
|
USERPREFS = DATA / "userprefs.json"
|
|
IP_LABELS_LOCAL = DATA / "ip_labels.json"
|
|
IP_LABELS_REMOTE = os.environ.get("IP_LABELS_REMOTE", "")
|
|
SETTINGS_PATH = DATA / "settings.json"
|
|
|
|
# ---- Medie-oprydning (Emby + Sonarr/Radarr) ----
|
|
EMBY_URL = os.environ.get("EMBY_URL", "").rstrip("/")
|
|
EMBY_API_KEY = os.environ.get("EMBY_API_KEY", "")
|
|
RADARR_URL = os.environ.get("RADARR_URL", "").rstrip("/")
|
|
RADARR_API_KEY = os.environ.get("RADARR_API_KEY", "")
|
|
SONARR_URL = os.environ.get("SONARR_URL", "").rstrip("/")
|
|
SONARR_API_KEY = os.environ.get("SONARR_API_KEY", "")
|
|
NTFY_MEDIA_TOPIC = os.environ.get("NTFY_MEDIA_TOPIC", "media")
|
|
MEDIA_STATE_PATH = DATA / "media_state.json"
|
|
MEDIA_SETTINGS_PATH = DATA / "media_settings.json"
|
|
# Standardindstillinger — kan redigeres i /admin/media:
|
|
MEDIA_DEFAULTS = {
|
|
"enabled": False, # dry-run indtil du selv slår sletning til
|
|
"age_days": 90, # tilføjet for mindst så længe siden
|
|
"grace_days": 14, # "på vej ud"-vindue før sletning
|
|
"disk_throttle": True, # slet kun når lageret er over disk_high %
|
|
"disk_high": 85, # start sletning over denne fyldningsgrad
|
|
"disk_low": 80, # stop igen når under denne
|
|
"do_movies": True,
|
|
"do_series": True,
|
|
}
|
|
|
|
|
|
# ---- YouTube offline (yt-dlp + Emby) ----
|
|
YT_DOWNLOAD_DIR = os.environ.get("YT_DOWNLOAD_DIR", "/media/yt-offline")
|
|
YT_DLP_BIN = os.environ.get("YT_DLP_BIN", "/usr/local/bin/yt-dlp")
|
|
YT_STATE_PATH = DATA / "yt_state.json"
|
|
YT_SETTINGS_PATH = DATA / "yt_settings.json"
|
|
# Standardindstillinger - kan redigeres i /admin/yt:
|
|
YT_DEFAULTS = {
|
|
"enabled": True, # slet sete videoer automatisk
|
|
"grace_days": 7, # dage fra markeret-som-set til sletning
|
|
# H.264 foretrukket: Pascal-GPU'en i CT100 kan ikke afkode AV1, og AV1 kan
|
|
# mange afspillere slet ikke offline. Falder tilbage til alt-andet hvis
|
|
# YouTube ikke har H.264 i den oenskede oploesning.
|
|
"quality": "bestvideo[vcodec^=avc1][height<=1080]+bestaudio[acodec^=mp4a]/bestvideo[vcodec^=avc1][height<=1080]+bestaudio/best[vcodec^=avc1][height<=1080]/bestvideo[height<=1080]+bestaudio/best",
|
|
"sponsorblock": True, # klip sponsorater ud, behold resten som kapitler
|
|
"subtitles": True, # rigtige undertekster, ellers YouTubes automatiske
|
|
"sub_langs": "da,en,-live_chat",
|
|
"metadata": True, # titel/kanal/dato + miniature + kapitler i filen
|
|
"library_name": "YouTube",
|
|
}
|
|
|
|
GROUP_ORDER = {n: i for i, n in enumerate(
|
|
["Home", "Familie", "Medie", "Social", "AI", "Office", "Finans", "dev", "game", "Admin"])}
|
|
|
|
ADMIN_MODULES = [
|
|
{"key": "ip-labels", "title": "IP → label & land", "icon": "🌍",
|
|
"desc": "Mærk kendte IP-adresser (netværk/land) i statistikken."},
|
|
{"key": "cookies", "title": "Cookie-tekster", "icon": "🍪",
|
|
"desc": "Teksten på cookie-banneret og /cookies-siden."},
|
|
{"key": "stats", "title": "Statistik", "icon": "📊",
|
|
"desc": "Hurtigt overblik fra Matomo."},
|
|
{"key": "apps", "title": "App-beskrivelser & grupper", "icon": "🧩",
|
|
"desc": "Rediger beskrivelse og gruppe på dine Authentik-apps."},
|
|
{"key": "ops", "title": "Drift / egress", "icon": "🛰️",
|
|
"desc": "Static-assets-version + random-proxy egress, rollover & inflight."},
|
|
{"key": "users", "title": "Brugere", "icon": "👤",
|
|
"desc": "Opret og administrér brugere + adgang (via grupper)."},
|
|
{"key": "groups", "title": "Grupper", "icon": "👥",
|
|
"desc": "Grupper og medlemmer — styrer hvilke services brugere har adgang til."},
|
|
{"key": "access", "title": "Adgang til services", "icon": "🔐",
|
|
"desc": "Hvilke brugere og grupper kan tilgå hver enkelt service."},
|
|
{"key": "media", "title": "Medie-oprydning", "icon": "🎬",
|
|
"desc": "Slet aldrig-set film & serier automatisk — med karens, behold-liste og ntfy."},
|
|
{"key": "yt", "title": "YouTube offline", "icon": "📺",
|
|
"desc": "Hent YouTube-videoer til Emby - og slet dem igen naar de er set."},
|
|
]
|