No description
  • Python 61.8%
  • JavaScript 28.9%
  • CSS 7.9%
  • Dockerfile 0.6%
  • HTML 0.5%
  • Other 0.3%
Find a file
2026-06-16 20:19:33 +02:00
backend/xtream_dl_app retry all implementetd 2026-06-15 07:48:58 +02:00
frontend queue count 2026-06-16 20:19:33 +02:00
tests retry all implementetd 2026-06-15 07:48:58 +02:00
.dockerignore first app commit 2026-06-09 21:37:26 +02:00
.gitignore first app commit 2026-06-09 21:37:26 +02:00
docker-compose.yml first app commit 2026-06-09 21:37:26 +02:00
Dockerfile first app commit 2026-06-09 21:37:26 +02:00
README.md retry all implementetd 2026-06-15 07:48:58 +02:00
requirements.txt first app commit 2026-06-09 21:37:26 +02:00
run.ps1 first app commit 2026-06-09 21:37:26 +02:00

xtream-dl

LAN-ready Xtream download web app with a FastAPI backend, a static web client, and a sequential Curl-based download queue.

Features

  • Setup/config page for one Xtream connection
  • App password for LAN access
  • Movies and series grouped by category
  • Tile view with poster, metadata, and description when provided by the Xtream provider
  • Download movies, full series, full seasons, or individual episodes
  • Queue with exactly one active download at a time
  • Optional global download speed limit in KB/s
  • Per-job and global queue controls: pause, resume, stop, and clear queue
  • Persistent metadata cache for movie/series categories and lists
  • Automatic cache refresh every 6 hours plus manual refresh in the UI
  • Curl transport with fixed User-Agent okhttp/4.9.3
  • Resume via .part files and skip already existing target files
  • Masked logging without plaintext credentials

Start With Docker

The intended deployment is a single Docker container. The container includes Python, FastAPI, the web client, and the required system curl.

docker compose up -d --build

Open the app in your browser:

http://localhost:8081

On first launch, configure the following in the web UI:

  • App password for LAN access
  • Xtream base URL
  • Username
  • Password
  • Download directory
  • Optional download speed limit in KB/s (0 means unlimited)

When running in Docker, set the download directory in the app config to:

/downloads

Data is persisted on the host through volumes:

./data      -> /data       Config, password hash, queue state, metadata cache
./Downloads -> /downloads  Downloaded movies and series

Show container logs:

docker compose logs -f

The app also writes rotating log files to ./data. server.log and server.err.log each rotate at 50 MB and keep one backup file. This limits each log stream to about 100 MB maximum.

Stop the container:

docker compose down

Rebuild after code changes

docker compose up -d --build

Local Development Start

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
.\run.ps1

Open the app in your browser:

http://localhost:8081

For LAN access, the app listens on 0.0.0.0:8081. You may need to allow the port in Windows Firewall.

Data

By default, the app writes state and queue data to:

./data/state.json

This file also contains the metadata cache and the last refresh status. The cache includes:

  • Movie categories
  • Series categories
  • All movie list entries
  • All series list entries

Individual movie/series detail data is still loaded live when the detail view is opened. The cache refreshes automatically every 6 hours. A manual refresh can be started from the movie/series view.

The download directory is set in the app config. Without changes, the local default is:

./Downloads

Inside the Docker container, the default is set through the environment to /downloads.

Queue Behavior

The queue downloads only one item at a time. A paused active download terminates the current Curl process in a controlled way and keeps the .part file. When resumed, the same job is placed back into the queue and Curl continues via resume. Stop marks jobs as cancelled. Clear queue removes all non-running entries from the list. The queue view includes a separate button to remove only completed and skipped jobs.

The optional download speed limit is global and applies to newly started Curl downloads. Set it to 0 to download without a limit.

If Curl exits with code 18 because the provider closed the transfer early, the job is automatically retried after a 60 second cooldown. Retries use the existing .part file and Curl resume. The automatic retry limit is 10 attempts; after that, the job is marked as failed. Suspiciously tiny provider Content-Length values are ignored for progress display.

Tests

$env:PYTHONPATH = "$PWD\backend"
python -m unittest discover -s tests

Notes

All Xtream API calls and media downloads run server-side through the system curl. The User-Agent is intentionally fixed to okhttp/4.9.3 because some panels block Python HTTP clients.