# ani-cli web Local web UI for a system-wide `ani-cli` install. Current version: `0.47.0` ## What it does - Search anime in `sub` or `dub`, with poster-style results shown below the selection panel and the first English alternate title when available - Queue downloads with folder, quality, media type, season, and episode controls - Optionally retry failed `ani-cli` downloads with `anipy-cli` - Track shows in a watchlist with `Watching`, `Planned`, `Finished`, and `Dropped` categories - Expose a small JSON summary endpoint for Homepage dashboard widgets - Refresh watchlist episode counts manually or on a schedule - Auto-download missing episodes for `Watching` entries after later refreshes, with a per-show `Source name` override for `ani-cli` search - Move fully completed libraries into Jellyfin TV or movie folders with a tracked background handoff job - Send optional Discord webhook notifications ## Pages - `/`: Search and queue downloads, with poster-card search results below the selection box and alternate English titles under the main name when available - `/queue`: Monitor jobs, inspect logs, retry failed jobs, remove finished jobs - `/watchlist`: Track shows, refresh them, download all available episodes, and manage auto-download settings such as `Source name`, library `Name`, season, and episode offset - `/config`: Save defaults, toggle `anipy-cli` fallback retries, schedule refreshes, configure Jellyfin and Discord, monitor Jellyfin handoff progress, and view runtime info and the changelog ## Quick start Requirements: - `ani-cli` installed and available in `PATH` - Optional: `anipy-cli` installed and available in `PATH` if you want automatic fallback retries - Common runtime tools used by `ani-cli`, especially `curl`, `ffmpeg`, `fzf`, `grep`, `openssl`, `sed`, `aria2c`, and `yt-dlp` Run locally: ```sh ./ani-cli-web ``` Open: ```text http://127.0.0.1:8421/ ``` Useful flags and env: - `./ani-cli-web --debug` - `ANI_CLI_WEB_HOST=0.0.0.0` - `ANI_CLI_WEB_PORT=8421` - `ANI_CLI_BIN=/path/to/ani-cli` - `ANIPY_CLI_BIN=/path/to/anipy-cli` ## Docker Build: ```sh docker build -t ani-cli-web . ``` Run: ```sh docker run --rm \ -p 8421:8421 \ -e USER_UID="$(id -u)" \ -e USER_GID="$(id -g)" \ -v "$(pwd)/downloads:/downloads" \ -v "$(pwd)/.ani-cli-web:/app/.ani-cli-web" \ ani-cli-web ``` Compose: ```sh USER_UID="$(id -u)" USER_GID="$(id -g)" docker compose up --build -d ``` Docker notes: - The container serves on `0.0.0.0:8421` - Downloads are written under `/downloads` - App state is stored under `/app/.ani-cli-web` - `USER_UID` and `USER_GID` help keep mounted files owned by your host user - `UPDATE_ON_START=true` runs `ani-cli --update` before startup ## Key behavior ### Watchlist - Adding a show tracks it without downloading immediately - Later manual refreshes or scheduled refreshes can queue missing episodes - `Download all` queues every currently available episode for the chosen mode - Successful downloads sync back into the watchlist - TV entries move to `Finished` when the selected downloaded mode reaches the expected episode count - Movie entries can be treated as complete after download and routed to movie storage ### Auto-download - Runs only for entries in `Watching` - Uses the per-show language, quality, `Source name` search override, season, library name, and optional episode offset settings - Can queue backlog episodes that were already available before the show was first tracked ### Download fallback - Optional and configured from `/config` - When enabled, a failed `ani-cli` queue job retries once with `anipy-cli` - `anipy-cli` should be installed separately on the host or inside your container if you want the retry path to be available ### Jellyfin handoff - Optional and configured from `/config` - TV libraries move only after the show is finished and download-complete - Movie libraries move after download completion - Manual `Run now` scans the watchlist in a background job and shows live progress for processed entries, moved files, and the current destination path - Recent Jellyfin handoff jobs survive page reloads and show their latest status after app restarts ## Homepage widget API For Homepage's Custom API widget, use: ```text http://127.0.0.1:8421/api/watchlist/homepage ``` Example response: ```json { "watchlist": 12, "planned": 4, "finished": 31, "dropped": 2, "total": 49 } ``` This endpoint is intentionally small so Homepage can map the returned values directly into its widget fields. ## Runtime info The Config page runtime panel shows: - `ani-cli-web` version loaded from `VERSION` - Installed `ani-cli` version - Installed `anipy-cli` version and dependency status - A `Changelog` button that opens a scrollable viewer backed by `CHANGELOG.md` ## Remote access By default the app only serves loopback clients. To allow LAN or remote access: ```sh ANI_CLI_WEB_ALLOW_REMOTE=1 ANI_CLI_WEB_AUTH_USERNAME=admin ANI_CLI_WEB_AUTH_PASSWORD=choose-a-long-random-password ``` Optional remote path restriction: ```sh ANI_CLI_WEB_REMOTE_PATH_ROOTS=/downloads:/srv/jellyfin-tv:/srv/jellyfin-movies ``` ## State and storage Project state is stored in: ```text ani-cli-web/.ani-cli-web/ ``` Main contents: - `config.json` - `remote-sessions.json` - `state.sqlite3` - `thumbnails/` Downloaded files are organized like this: ```text ANI_CLI_DOWNLOAD_DIR/tv/Show Name/Season 01/Show Name - S01E01.mp4 ANI_CLI_DOWNLOAD_DIR/movie/Movie Name/Movie Name.mp4 ``` ## Configuration Most users only need these environment variables: - `ANI_CLI_BIN` - `ANIPY_CLI_BIN` - `ANI_CLI_WEB_HOST` - `ANI_CLI_WEB_PORT` - `ANI_CLI_WEB_ALLOW_REMOTE` - `ANI_CLI_WEB_AUTH_USERNAME` - `ANI_CLI_WEB_AUTH_PASSWORD` - `ANI_CLI_WEB_REMOTE_PATH_ROOTS` - `ANI_CLI_WEB_DEBUG` - `ANI_CLI_WEB_STATE_ROOT` Container-specific variables: - `UPDATE_ON_START` - `USER_UID` - `USER_GID` Everything else can usually be configured from `/config`. ## Testing Run the regression suite with: ```sh python3 -m unittest test_app.py ```