diff --git a/jd-webgui/app.py b/jd-webgui/app.py index 390826d..4fc2064 100644 --- a/jd-webgui/app.py +++ b/jd-webgui/app.py @@ -321,6 +321,50 @@ def sanitize_name(name: str) -> str: out = "".join("_" if c in bad else c for c in name).strip() return re.sub(r"\s+", " ", out) +def format_proxy_lines(raw: str, scheme: str) -> str: + """ + Takes raw lines (ip:port or scheme://ip:port) and outputs normalized lines: + scheme://ip:port (one per line). Ignores empty lines and comments. + """ + scheme = scheme.strip().lower() + if scheme not in {"socks5", "socks4", "http"}: + raise ValueError("Unsupported proxy scheme") + + out = [] + for line in (raw or "").splitlines(): + s = line.strip() + if not s or s.startswith("#"): + continue + + if "://" in s: + s = s.split("://", 1)[1].strip() + + if ":" not in s: + continue + + host, port = s.rsplit(":", 1) + host = host.strip() + port = port.strip() + + if not host or not port.isdigit(): + continue + + out.append(f"{scheme}://{host}:{port}") + + seen = set() + dedup = [] + for x in out: + if x not in seen: + seen.add(x) + dedup.append(x) + + return "\n".join(dedup) + +def fetch_proxy_list(url: str) -> str: + req = urllib.request.Request(url) + with urllib.request.urlopen(req, timeout=20) as resp: + return resp.read().decode("utf-8", "replace") + def pick_library_target(library_choice: str, filename: str, package_name: str) -> str: if library_choice not in {"movies", "series", "auto"}: library_choice = "auto" @@ -733,6 +777,7 @@ def render_page(error: str = "") -> str:

JD → Jellyfin

+ {render_nav("downloads")} {err_html}
@@ -773,6 +818,62 @@ def render_page(error: str = "") -> str: """ +def render_nav(active: str) -> str: + def link(label: str, href: str, key: str) -> str: + style = "font-weight:700;" if active == key else "" + return f"{label}" + return ( + "
" + + link("Downloads", "/", "downloads") + + link("Proxies", "/proxies", "proxies") + + "
" + ) + +def render_proxies_page(error: str = "", socks5_in: str = "", socks4_in: str = "", http_in: str = "", out_text: str = "") -> str: + err_html = f"

{error}

" if error else "" + return f""" + + + + + JD → Jellyfin (Proxies) + + +

JD → Jellyfin

+ {render_nav("proxies")} + {err_html} + + +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ + +
+ +

JDownloader Import-Liste

+

Format: socks5://IP:PORT, socks4://IP:PORT, http://IP:PORT. Keine Prüfung/Validierung.

+ +
+ +
+ + + + + """ + @app.get("/", response_class=HTMLResponse) def index(): try: @@ -830,3 +931,50 @@ def cancel(jobid: str): job.cancel_requested = True job.message = "Abbruch angefordert…" return RedirectResponse(url="/", status_code=303) + +@app.get("/proxies", response_class=HTMLResponse) +def proxies_get(): + try: + socks5_in = fetch_proxy_list("https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks5.txt") + socks4_in = fetch_proxy_list("https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks4.txt") + http_in = fetch_proxy_list("https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/http.txt") + + 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()]) + return HTMLResponse(render_proxies_page( + socks5_in=socks5_in, + socks4_in=socks4_in, + http_in=http_in, + out_text=combined + )) + except Exception as e: + return HTMLResponse(render_proxies_page(error=str(e)), status_code=502) + +@app.post("/proxies", response_class=HTMLResponse) +def proxies_post( + 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()]) + return HTMLResponse(render_proxies_page( + socks5_in=socks5_in, + socks4_in=socks4_in, + http_in=http_in, + out_text=combined + )) + 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="" + ), status_code=400)