From 00c72a78d2abcf0efe4edcc23ea48e24f4ba7a10 Mon Sep 17 00:00:00 2001 From: DasPoschi Date: Thu, 1 Jan 2026 21:04:41 +0100 Subject: [PATCH] Export proxies as jdproxies file --- jd-webgui/app.py | 75 ++++++++++++++++++++++++++++++++++++-- jd-webgui/static/style.css | 1 + 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/jd-webgui/app.py b/jd-webgui/app.py index 4fc2064..fdf587c 100644 --- a/jd-webgui/app.py +++ b/jd-webgui/app.py @@ -56,6 +56,7 @@ POLL_SECONDS = float(os.environ.get("POLL_SECONDS", "5")) # JDownloader writes here inside container JD_OUTPUT_PATH = "/output" +PROXY_EXPORT_PATH = os.environ.get("PROXY_EXPORT_PATH", "/output/jd-proxies.jdproxies") URL_RE = re.compile(r"^https?://", re.I) @@ -365,6 +366,17 @@ def fetch_proxy_list(url: str) -> str: with urllib.request.urlopen(req, timeout=20) as resp: return resp.read().decode("utf-8", "replace") +def save_proxy_export(text: str) -> str: + if not text.strip(): + raise ValueError("Keine Proxy-Einträge zum Speichern.") + export_path = PROXY_EXPORT_PATH + export_dir = os.path.dirname(export_path) + if export_dir: + os.makedirs(export_dir, exist_ok=True) + with open(export_path, "w", encoding="utf-8") as handle: + handle.write(text.strip() + "\n") + return export_path + def pick_library_target(library_choice: str, filename: str, package_name: str) -> str: if library_choice not in {"movies", "series", "auto"}: library_choice = "auto" @@ -829,8 +841,17 @@ def render_nav(active: str) -> str: + "" ) -def render_proxies_page(error: str = "", socks5_in: str = "", socks4_in: str = "", http_in: str = "", out_text: str = "") -> str: +def render_proxies_page( + error: str = "", + message: str = "", + socks5_in: str = "", + socks4_in: str = "", + http_in: str = "", + out_text: str = "", + export_path: str = "", +) -> str: err_html = f"

{error}

" if error else "" + msg_html = f"

{message}

" if message else "" return f""" @@ -842,6 +863,7 @@ def render_proxies_page(error: str = "", socks5_in: str = "", socks4_in: str = "

JD → Jellyfin

{render_nav("proxies")} {err_html} + {msg_html}
@@ -870,6 +892,18 @@ def render_proxies_page(error: str = "", socks5_in: str = "", socks4_in: str = "
+ +

Datei für Connection Manager

+

Speichert die Liste als .jdproxies im Container, z. B. zum Import in JDownloader → Verbindungsmanager → Importieren.

+ + + + + + +
+ +

Aktueller Pfad: {export_path or PROXY_EXPORT_PATH}

""" @@ -947,7 +981,8 @@ def proxies_get(): socks5_in=socks5_in, socks4_in=socks4_in, http_in=http_in, - out_text=combined + out_text=combined, + export_path=PROXY_EXPORT_PATH, )) except Exception as e: return HTMLResponse(render_proxies_page(error=str(e)), status_code=502) @@ -968,7 +1003,8 @@ def proxies_post( socks5_in=socks5_in, socks4_in=socks4_in, http_in=http_in, - out_text=combined + out_text=combined, + export_path=PROXY_EXPORT_PATH, )) except Exception as e: return HTMLResponse(render_proxies_page( @@ -976,5 +1012,36 @@ def proxies_post( socks5_in=socks5_in, socks4_in=socks4_in, http_in=http_in, - out_text="" + out_text="", + export_path=PROXY_EXPORT_PATH, + ), status_code=400) + +@app.post("/proxies/save", response_class=HTMLResponse) +def proxies_save( + socks5_in: str = Form(""), + socks4_in: str = Form(""), + http_in: str = Form(""), +): + try: + s5 = format_proxy_lines(socks5_in, "socks5") + s4 = format_proxy_lines(socks4_in, "socks4") + hp = format_proxy_lines(http_in, "http") + combined = "\n".join([x for x in [s5, s4, hp] if x.strip()]) + export_path = save_proxy_export(combined) + return HTMLResponse(render_proxies_page( + message=f"Proxy-Liste gespeichert: {export_path}", + socks5_in=socks5_in, + socks4_in=socks4_in, + http_in=http_in, + out_text=combined, + export_path=export_path, + )) + except Exception as e: + return HTMLResponse(render_proxies_page( + error=str(e), + socks5_in=socks5_in, + socks4_in=socks4_in, + http_in=http_in, + out_text="", + export_path=PROXY_EXPORT_PATH, ), status_code=400) diff --git a/jd-webgui/static/style.css b/jd-webgui/static/style.css index 6232238..ab042f6 100644 --- a/jd-webgui/static/style.css +++ b/jd-webgui/static/style.css @@ -15,6 +15,7 @@ th { background:#fbfbfb; text-align:left; } code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; background:#f2f2f2; padding:2px 4px; border-radius:4px; } .hint { color:#555; font-size: 12px; margin-top: 10px; } .error { color:#b00020; font-weight: 700; } +.success { color:#1b7f3a; font-weight: 700; } .progress-row { display:flex; align-items:center; gap:8px; margin-top:6px; } .progress-text { font-size:12px; color:#333; min-width:48px; } .inline-form { margin-top:6px; }