From 141dcd9c700b8731f279afdcdcdd788817691036 Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 1 Aug 2026 17:21:16 +0200 Subject: [PATCH] Add curl-impersonate for ani-cli v5 --- CHANGELOG.md | 6 ++++++ Dockerfile | 9 +++++++++ README.md | 6 ++++-- VERSION | 2 +- http_handler.py | 6 ++++++ test_app.py | 7 +++++++ 6 files changed, 33 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e79715f..c0cc5d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.50.0 - 2026-08-01 + +- Added `curl-impersonate` to Docker images using the maintained `lexiforest/curl-impersonate` image so `ani-cli` v5 can use browser-like curl wrappers before falling back to plain `curl`. +- Exposed `curl-impersonate` availability in the Config page dependency status. +- Updated Docker/runtime documentation for the new `ani-cli` v5 Cloudflare workaround. + ## 0.49.9 - 2026-07-26 - Changed the Config page `ani-cli` version probe to run with `ANI_CLI_PLAYER=download`, avoiding false missing-player failures on headless installs without `mpv` or `vlc`. diff --git a/Dockerfile b/Dockerfile index a5fb137..f4a8f6f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,5 @@ +FROM lexiforest/curl-impersonate:latest AS curl-impersonate + FROM python:3.12-slim-bookworm ARG ANI_CLI=https://github.com/pystardust/ani-cli.git @@ -22,6 +24,7 @@ ENV DEBIAN_FRONTEND=noninteractive \ RUN apt-get update \ && apt-get install -y --no-install-recommends \ aria2 \ + bash \ botan \ ca-certificates \ curl \ @@ -32,6 +35,7 @@ RUN apt-get update \ grep \ libxml2-dev \ libxslt1-dev \ + libstdc++6 \ openssl \ patch \ python3.11 \ @@ -41,6 +45,11 @@ RUN apt-get update \ util-linux \ && rm -rf /var/lib/apt/lists/* +COPY --from=curl-impersonate /usr/local /usr/local + +RUN curl_firefox135 --version \ + && curl_chrome136 --version + RUN git clone --depth 1 --branch "${ANI_CLI_BRANCH}" "${ANI_CLI}" /tmp/ani-cli-src \ && install -m 0755 /tmp/ani-cli-src/ani-cli /usr/local/bin/ani-cli \ && ani_cli_raw_repo="$(printf '%s' "${ANI_CLI}" | sed -E 's#^https://github.com/##; s#\\.git$##')" \ diff --git a/README.md b/README.md index cd34936..77c04ed 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Local web UI for a system-wide `ani-cli` install. -Current version: `0.49.9` +Current version: `0.50.0` ## What it does @@ -30,7 +30,7 @@ Requirements: - `ani-cli` installed and available in `PATH` - Optional: `anipy-cli` and/or `animdl` installed and available in `PATH` if you want automatic fallback retries outside Docker -- Common runtime tools used by `ani-cli`, especially `curl`, `ffmpeg`, `fzf`, `grep`, `openssl`, `sed`, `aria2c`, `botan`, and `yt-dlp` +- Common runtime tools used by `ani-cli`, especially `curl` or `curl-impersonate`, `ffmpeg`, `fzf`, `grep`, `openssl`, `sed`, `aria2c`, `botan`, and `yt-dlp` Run locally: @@ -90,6 +90,7 @@ Docker notes: - `USER_UID` and `USER_GID` help keep mounted files owned by your host user - `UPDATE_ON_START=true` runs `ani-cli --update` before startup - `ANI_CLI_WEB_JOB_STDOUT=true` mirrors download job output to container stdout for log collectors; set it to `false` to keep job output only in the Queue page +- `curl-impersonate` is installed inside the container and exposes the browser wrapper commands used by `ani-cli` v5, such as `curl_firefox135` and `curl_chrome136`, so provider requests can avoid Cloudflare blocks that affect plain `curl` - `botan` is installed inside the container for providers or scripts that need Botan cryptography tooling - `anipy-cli` and `animdl` are installed systemwide inside the container at `/usr/local/bin`, linked from `/usr/bin`, and included in the runtime `PATH`; `animdl` is isolated in a Python 3.11 virtualenv so its pinned dependencies stay executable @@ -118,6 +119,7 @@ Docker notes: - Checked methods are tried in this order: `ani-cli`, `anipy-cli`, then `animdl` - Selecting one method disables fallback retry; selecting multiple methods makes later methods automatic fallbacks - Queue `ani-cli` downloads explicitly run with `ANI_CLI_PLAYER=download` so headless Docker installs do not need `mpv` or `vlc` just to save files +- Docker images include `curl-impersonate` wrappers before plain `curl` on `PATH`, matching the preference order used by `ani-cli` v5 - Fallback retries keep the queued episode numbers when fallback downloader filenames are renumbered from `1` - Docker images install `anipy-cli` and `animdl` automatically; non-Docker installs should provide the selected tools in `PATH` themselves diff --git a/VERSION b/VERSION index f9ebf27..564edf8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.49.9 +0.50.0 diff --git a/http_handler.py b/http_handler.py index 0214a66..7c52bf1 100644 --- a/http_handler.py +++ b/http_handler.py @@ -97,6 +97,12 @@ def build_handler_class(context): def dependency_status(): checks = ["curl", "sed", "grep", "openssl", "fzf", "aria2c", "ffmpeg", "yt-dlp"] result = {name: bool(shutil.which(name)) for name in checks} + result["curl-impersonate"] = cli_executable_exists_any( + "curl_firefox135", + "curl_chrome136", + "curl_chrome116", + "curl_ff117", + ) result["ani-cli"] = cli_executable_exists(ANI_CLI) result["anipy-cli"] = cli_executable_exists_any( ANIPY_CLI, diff --git a/test_app.py b/test_app.py index 87b6d91..bf5e22d 100644 --- a/test_app.py +++ b/test_app.py @@ -3340,6 +3340,7 @@ class HandlerRouteTests(unittest.TestCase): handler = DummyHandler("/api/dependencies") APP.Handler.do_GET(handler) self.assertEqual(handler.json_status, HTTPStatus.OK) + self.assertIn("curl-impersonate", handler.json_payload) self.assertIn("anipy-cli", handler.json_payload) self.assertIn("animdl", handler.json_payload) @@ -3350,6 +3351,12 @@ class HandlerRouteTests(unittest.TestCase): status = http_handler.dependency_status() self.assertTrue(status["animdl"]) + exists_any.assert_any_call( + "curl_firefox135", + "curl_chrome136", + "curl_chrome116", + "curl_ff117", + ) exists_any.assert_any_call( http_handler.ANIMDL, "animdl",