Claude Codes login på værten holder 28 dage, og et langtidstoken kan ikke bruges til Remote Control, så der skal logges ind igen hver 4. uge. Hidtil krævede det en terminal for at kopiere en adresse ud og en kode ind igen. /admin/claude-login viser hvornår login udløber og har en "Start login"-knap. Værten (claude-login-agent, som spørger portalen, ikke omvendt) starter `claude auth login`, og siden viser login-adressen; koden fra Claudes side indsættes på samme side og hentes af værten et par sekunder senere. Portalen gemmer kun den korte kode, indtil den er hentet; den virker kun sammen med login-processen på værten (PKCE). Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
114 lines
6.3 KiB
Python
114 lines
6.3 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
|
|
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"
|
|
MCP_REGISTRY = DATA / "mcp_registry.json"
|
|
MCP_SELF_URL = os.environ.get("MCP_SELF_URL", "https://weircon.dk/mcp")
|
|
|
|
# ---- 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: medieserverens Pascal-GPU 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": "invitations", "title": "Invitationer", "icon": "✉️",
|
|
"desc": "Lav et invitationslink med gruppe og udløbstid. Modtageren opretter selv sit login."},
|
|
{"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."},
|
|
{"key": "secrets", "title": "Hemmeligheder til Claude", "icon": "🔏",
|
|
"desc": "Giv et token eller kodeord til serveren krypteret, uden at skrive det i chatten."},
|
|
{"key": "claude-login", "title": "Claude-login", "icon": "🤖",
|
|
"desc": "Log Claude på serveren ind igen fra telefonen, uden terminal."},
|
|
{"key": "mcp-keys", "title": "MCP-nøgler", "icon": "🔑",
|
|
"desc": "Opret og se API-nøgler til alle MCP-servere (crawlkit, Gitea, HA, Paperless, portal)."},
|
|
]
|