readme
This commit is contained in:
@@ -1,124 +1,325 @@
|
||||
# pyTorrent
|
||||
|
||||
Single-page web UI for rTorrent inspired by the ruTorrent workflow.
|
||||
Modern single-page web UI for managing rTorrent through SCGI/XML-RPC. pyTorrent focuses on fast live updates, multi-profile support, automation, diagnostics and a clean browser-based workflow inspired by ruTorrent.
|
||||
|
||||
## Features
|
||||
> pyTorrent is a controller for your own rTorrent instance. It does not include a BitTorrent engine and does not bypass tracker, copyright or network rules.
|
||||
|
||||
- Flask + Flask-SocketIO.
|
||||
- SQLite storage for preferences, SCGI profiles, Bootstrap theme and UI font.
|
||||
- Multiple rTorrent profiles per user.
|
||||
- Profiles can be added and edited from the UI; the remote profile flag hides local CPU/RAM usage to avoid confusing it with remote rTorrent host resources.
|
||||
- Active rTorrent profile switching from the UI.
|
||||
- Live torrent list over WebSocket.
|
||||
- Application-side cache with patch updates instead of full table reloads.
|
||||
- User operations executed through ThreadPoolExecutor.
|
||||
- `move` and `remove` actions are executed per profile in request order, so later deletes wait for earlier moves.
|
||||
- Job log shows a short date/time in the table and the full timestamp in the tooltip.
|
||||
- Bulk start, pause, stop, resume, recheck, remove and move.
|
||||
- Move supports `move_data=true`; data is physically moved on the rTorrent side in the background and status is polled from a marker file, so long `mv` operations do not hit the SCGI timeout.
|
||||
- Multi-magnet add modal.
|
||||
- Bottom status bar with CPU, RAM, rTorrent version, speeds, limits, total DL/UP and port-check status when enabled.
|
||||
- Torrent context menu.
|
||||
- Keyboard shortcuts.
|
||||
- Details tabs: General, Files, Peers, Trackers and Log.
|
||||
- Smart Queue shows the last 10 operations by default and can expand history to 100 rows.
|
||||
- Peer GeoIP with MaxMind GeoLite2-City.mmdb and IP cache.
|
||||
- Static cache busting with MD5 and cache headers.
|
||||
- Appearance preferences: default Bootstrap or Bootswatch themes Flatly, Litera, Lumen, Minty, Sketchy, Solar, Spacelab, United and Zephyr.
|
||||
- Font preferences: default theme font, Adwaita Mono and additional matching fonts.
|
||||
## Highlights
|
||||
|
||||
## Complete Debian / Ubuntu install
|
||||
- Live torrent table with WebSocket updates and patch-based refreshes.
|
||||
- Multiple rTorrent profiles, including local and remote hosts.
|
||||
- Profile-level permissions, user management and API tokens.
|
||||
- Bulk torrent actions: start, pause, stop, resume, recheck, remove and move.
|
||||
- Background move/remove jobs with operation history.
|
||||
- Smart Queue with recent job status and expandable history.
|
||||
- Download Planner with quiet hours, speed limits, CPU/disk protection and dry-run mode.
|
||||
- Adaptive Poller with configurable intervals and diagnostics.
|
||||
- RSS tools, automation rules and cleanup helpers.
|
||||
- Torrent details: general data, files, peers, trackers and logs.
|
||||
- Peer GeoIP lookup with MaxMind GeoLite2 database support.
|
||||
- Dashboard, smart views, global search and notification center.
|
||||
- OpenAPI docs available from the app.
|
||||
- Offline frontend assets support for self-hosted deployments.
|
||||
|
||||
The repository includes a full installer for Debian and Ubuntu:
|
||||
## Screenshots
|
||||
|
||||
```bash
|
||||
wget -qO /tmp/install_debian_ubuntu.sh "https://git.linuxiarz.pl/gru/pyTorrent/raw/branch/master/scripts/install_debian_ubuntu.sh" && sudo bash /tmp/install_debian_ubuntu.sh
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
The installer installs system packages, creates the dedicated `pytorrent` system user, copies the app to `/opt/pytorrent`, creates a virtual environment, installs Python dependencies, downloads offline frontend libraries and GeoIP data when helper scripts are available, then creates and starts the `pytorrent` systemd service.
|
||||
## Requirements
|
||||
|
||||
Optional environment variables:
|
||||
|
||||
```bash
|
||||
PYTORRENT_USER=pytorrent \
|
||||
PYTORRENT_APP_DIR=/opt/pytorrent \
|
||||
PYTORRENT_SERVICE_NAME=pytorrent \
|
||||
sudo -E bash scripts/install_debian_ubuntu.sh
|
||||
```
|
||||
|
||||
Check the service with:
|
||||
|
||||
```bash
|
||||
sudo systemctl status pytorrent
|
||||
sudo journalctl -u pytorrent -f
|
||||
```
|
||||
|
||||
## Run locally
|
||||
### Application
|
||||
|
||||
- Python 3.10+
|
||||
- rTorrent with SCGI/XML-RPC enabled
|
||||
- Linux server recommended for production
|
||||
|
||||
### Python packages
|
||||
|
||||
The project uses Flask, Flask-SocketIO, python-dotenv, psutil, geoip2, gunicorn and related runtime dependencies listed in `requirements.txt`.
|
||||
|
||||
## Quick start
|
||||
|
||||
Clone the repository and run the local installer:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zdzichu6969/pyTorrent.git
|
||||
cd pyTorrent
|
||||
./install.sh
|
||||
. venv/bin/activate
|
||||
python app.py
|
||||
```
|
||||
|
||||
Default URL: `http://127.0.0.1:8090`.
|
||||
Default URL:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:8090
|
||||
```
|
||||
|
||||
Copy the example environment file before customizing the app:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
## rTorrent SCGI profile
|
||||
|
||||
Example pyTorrent profile URL:
|
||||
|
||||
```text
|
||||
scgi://127.0.0.1:5000/RPC2
|
||||
```
|
||||
|
||||
Example rTorrent configuration:
|
||||
|
||||
```text
|
||||
network.scgi.open_port = 127.0.0.1:5000
|
||||
```
|
||||
|
||||
For production, keep SCGI bound to localhost or a private trusted network only.
|
||||
|
||||
## Stack installer
|
||||
|
||||
The repository includes a stack installer for a clean server. It can install and configure rTorrent + pyTorrent together.
|
||||
|
||||
Supported systems:
|
||||
|
||||
- Debian / Ubuntu
|
||||
- RHEL-compatible distributions: RHEL, Rocky Linux, AlmaLinux, CentOS Stream, Fedora-like systems with `dnf` or `yum`
|
||||
- Arch Linux
|
||||
|
||||
After cloning the repository:
|
||||
|
||||
```bash
|
||||
sudo bash scripts/install_stack.sh
|
||||
```
|
||||
|
||||
The default stack install creates:
|
||||
|
||||
| Component | Default |
|
||||
| --- | --- |
|
||||
| rTorrent user | `rtorrent` |
|
||||
| rTorrent SCGI | `scgi://127.0.0.1:5000` |
|
||||
| BitTorrent port | `51300` |
|
||||
| pyTorrent app dir | `/opt/pytorrent` |
|
||||
| pyTorrent HTTP port | `8090` |
|
||||
| pyTorrent service | `pytorrent` |
|
||||
|
||||
### One-line install with rtorrent
|
||||
|
||||
After publishing the repository, replace `zdzichu6969` and branch name if needed:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/zdzichu6969/pyTorrent/main/scripts/install_stack.sh \
|
||||
| sudo PYTORRENT_REPO_URL=https://github.com/zdzichu6969/pyTorrent \
|
||||
PYTORRENT_REPO_BRANCH=main \
|
||||
PYTORRENT_ARCHIVE_URL=https://github.com/zdzichu6969/pyTorrent/archive/refs/heads/main.tar.gz \
|
||||
bash
|
||||
```
|
||||
|
||||
Common overrides:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/zdzichu6969/pyTorrent/main/scripts/install_stack.sh \
|
||||
| sudo PYTORRENT_REPO_URL=https://github.com/zdzichu6969/pyTorrent \
|
||||
PYTORRENT_REPO_BRANCH=main \
|
||||
PYTORRENT_ARCHIVE_URL=https://github.com/zdzichu6969/pyTorrent/archive/refs/heads/main.tar.gz \
|
||||
PYTORRENT_PORT=8091 \
|
||||
RTORRENT_SCGI_PORT=5001 \
|
||||
PYTORRENT_PROFILE_NAME="Local rTorrent" \
|
||||
bash
|
||||
```
|
||||
|
||||
## Installer variables
|
||||
|
||||
### Bootstrap
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `PYTORRENT_REPO_URL` | repository URL | Repository base URL. |
|
||||
| `PYTORRENT_REPO_BRANCH` | `master` | Branch used by the bootstrap installer. |
|
||||
| `PYTORRENT_ARCHIVE_URL` | derived | Custom repository archive URL. Required for GitHub one-line install unless the script default is updated. |
|
||||
| `PYTORRENT_BOOTSTRAP_DIR` | `/tmp/pytorrent-stack-installer` | Temporary bootstrap directory. |
|
||||
| `PYTORRENT_KEEP_BOOTSTRAP_DIR` | `0` | Set to `1` to keep bootstrap files after install. |
|
||||
|
||||
### rTorrent
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `RTORRENT_USER` | `rtorrent` | System user used to run rTorrent. |
|
||||
| `RTORRENT_HOME` | `/home/${RTORRENT_USER}` | Home directory for the rTorrent user. |
|
||||
| `RTORRENT_BASE_DIR` | `/opt/rtorrent_build` | Build/install directory for source installs. |
|
||||
| `RTORRENT_SCGI_PORT` | `5000` | Local SCGI port. |
|
||||
| `RTORRENT_TORRENT_PORT` | `51300` | Incoming BitTorrent port. |
|
||||
| `RTORRENT_REF` | `v0.16.11` | rTorrent Git tag, branch or commit for source builds. |
|
||||
| `LIBTORRENT_REF` | `v0.16.11` | libtorrent Git tag, branch or commit for source builds. |
|
||||
| `RTORRENT_WITH_XMLRPC_C` | `0` | Set to `1` to build with classic xmlrpc-c. |
|
||||
| `RTORRENT_BUILD_FROM_SOURCE` | distro-specific | On Arch, set to `1` to compile instead of using `pacman`. |
|
||||
| `RTORRENT_FORCE_CONFIG` | `1` | Overwrite generated `.rtorrent.rc` when supported. |
|
||||
|
||||
### pyTorrent
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --- | --- | --- |
|
||||
| `PYTORRENT_APP_DIR` | `/opt/pytorrent` | Installation directory. |
|
||||
| `PYTORRENT_PORT` | `8090` | HTTP port. |
|
||||
| `PYTORRENT_BASE_URL` | `http://127.0.0.1:${PYTORRENT_PORT}` | Base URL used by the API configurator. |
|
||||
| `PYTORRENT_PROFILE_NAME` | `Local rTorrent` | rTorrent profile created in pyTorrent. |
|
||||
| `PYTORRENT_API_TOKEN` | empty | Bearer token for authenticated API calls during setup. |
|
||||
| `PYTORRENT_SERVICE_NAME` | `pytorrent` | systemd service name. |
|
||||
| `PYTORRENT_RTORRENT_SCGI_URL` | `scgi://127.0.0.1:${RTORRENT_SCGI_PORT}` | SCGI URL saved in the generated profile. |
|
||||
|
||||
## Production run
|
||||
|
||||
Preferred mode without development Werkzeug:
|
||||
Recommended production command:
|
||||
|
||||
```bash
|
||||
. venv/bin/activate
|
||||
gunicorn --worker-class gthread --workers 1 --threads 32 --bind 0.0.0.0:8090 --access-logfile - --error-logfile - wsgi:app
|
||||
gunicorn --worker-class gthread \
|
||||
--workers 1 \
|
||||
--threads 32 \
|
||||
--bind 0.0.0.0:8090 \
|
||||
--access-logfile - \
|
||||
--error-logfile - \
|
||||
wsgi:app
|
||||
```
|
||||
|
||||
Note: the app keeps `async_mode="threading"`, so WebSocket, `start_background_task`, operation queues and the poller run in the same model as before.
|
||||
pyTorrent uses Flask-SocketIO with threading mode. Multiple Gunicorn workers are not a drop-in replacement unless a Socket.IO message queue such as Redis, RabbitMQ or Kafka is configured.
|
||||
|
||||
Alternatives reviewed but not enabled by default:
|
||||
## systemd
|
||||
|
||||
- Gunicorn with `eventlet`: works with Flask-SocketIO, but requires green threads and monkey patching, which increases regression risk for file and SCGI operations.
|
||||
- Gunicorn with `gevent`: a valid production option, but it needs extra dependencies and compatibility testing.
|
||||
- Multiple Gunicorn workers: requires Redis, RabbitMQ or Kafka as the Socket.IO message queue, so it is not a drop-in replacement.
|
||||
Useful service commands after stack installation:
|
||||
|
||||
```bash
|
||||
sudo systemctl status pytorrent
|
||||
sudo systemctl status rtorrent@rtorrent.service
|
||||
sudo journalctl -u pytorrent -f
|
||||
sudo journalctl -u rtorrent@rtorrent.service -f
|
||||
```
|
||||
|
||||
Application logs may also be available in:
|
||||
|
||||
```text
|
||||
data/logs/
|
||||
```
|
||||
|
||||
## Reverse proxy
|
||||
|
||||
When pyTorrent is served behind a reverse proxy, enable proxy header handling only when the proxy is trusted:
|
||||
Enable proxy header handling only when pyTorrent is behind a trusted proxy:
|
||||
|
||||
```env
|
||||
PYTORRENT_PROXY_FIX_ENABLE=true
|
||||
PYTORRENT_SESSION_COOKIE_SECURE=true
|
||||
```
|
||||
|
||||
The proxy should forward at least:
|
||||
Forward these headers from the proxy:
|
||||
|
||||
```txt
|
||||
```text
|
||||
X-Forwarded-For
|
||||
X-Forwarded-Proto
|
||||
X-Forwarded-Host
|
||||
X-Forwarded-Port
|
||||
```
|
||||
|
||||
This keeps login redirects, session cookies and same-origin API checks correct when HTTPS is terminated by the proxy. If pyTorrent is mounted under a sub-path, also forward `X-Forwarded-Prefix`.
|
||||
If pyTorrent is mounted under a sub-path, also forward:
|
||||
|
||||
## SCGI profile
|
||||
|
||||
Example:
|
||||
|
||||
```txt
|
||||
scgi://127.0.0.1:5000/RPC2
|
||||
```text
|
||||
X-Forwarded-Prefix
|
||||
```
|
||||
|
||||
On the rTorrent side:
|
||||
For HTTPS deployments, set allowed origins explicitly:
|
||||
|
||||
```txt
|
||||
network.scgi.open_port = 127.0.0.1:5000
|
||||
```env
|
||||
PYTORRENT_SOCKETIO_CORS_ALLOWED_ORIGINS=https://pytorrent.example.com
|
||||
PYTORRENT_API_ALLOWED_ORIGINS=https://pytorrent.example.com
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
pyTorrent supports three authentication providers:
|
||||
|
||||
| Provider | Description |
|
||||
| --- | --- |
|
||||
| `local` | Built-in pyTorrent login screen with username and password. |
|
||||
| `tinyauth` | External authentication through Tinyauth and a trusted reverse proxy header. |
|
||||
| `proxy` | Generic external authentication through a trusted reverse proxy header. |
|
||||
|
||||
Enable authentication:
|
||||
|
||||
```env
|
||||
PYTORRENT_AUTH_ENABLE=true
|
||||
PYTORRENT_AUTH_PROVIDER=local
|
||||
```
|
||||
|
||||
Reset a local user's password:
|
||||
|
||||
```bash
|
||||
. venv/bin/activate
|
||||
python -m pytorrent.cli reset-password admin new_password
|
||||
```
|
||||
|
||||
Without the password argument, the command asks interactively:
|
||||
|
||||
```bash
|
||||
python -m pytorrent.cli reset-password admin
|
||||
```
|
||||
|
||||
### API tokens
|
||||
|
||||
When authentication is enabled, API requests can use a browser session cookie or a per-user API token. Admin users can generate tokens in:
|
||||
|
||||
```text
|
||||
Tools -> Users -> Generate token
|
||||
```
|
||||
|
||||
Use the token as a bearer token or API key:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer pt_xxx" http://127.0.0.1:8090/api/system/status
|
||||
curl -H "X-API-Key: pt_xxx" http://127.0.0.1:8090/api/system/status
|
||||
```
|
||||
|
||||
Token permissions follow the owning user's role and profile permissions. Revoked tokens stop working immediately.
|
||||
|
||||
### External auth through Tinyauth or proxy
|
||||
|
||||
Example Tinyauth configuration:
|
||||
|
||||
```env
|
||||
PYTORRENT_AUTH_ENABLE=true
|
||||
PYTORRENT_AUTH_PROVIDER=tinyauth
|
||||
PYTORRENT_AUTH_PROXY_USER_HEADER=Remote-User
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE=true
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=admin
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE_PERMISSION=rw
|
||||
```
|
||||
|
||||
Example generic proxy configuration:
|
||||
|
||||
```env
|
||||
PYTORRENT_AUTH_ENABLE=true
|
||||
PYTORRENT_AUTH_PROVIDER=proxy
|
||||
PYTORRENT_AUTH_PROXY_USER_HEADER=X-Forwarded-User
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE=true
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=user
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE_PERMISSION=rw
|
||||
```
|
||||
|
||||
`rw` is accepted as an alias for `full`. Admin users can access all profiles.
|
||||
|
||||
Do not use auth bypass on public hostnames. Limit bypass hosts to trusted private addresses only:
|
||||
|
||||
```env
|
||||
PYTORRENT_AUTH_BYPASS_HOSTS=10.11.1.11:8090,10.11.1.11
|
||||
PYTORRENT_AUTH_BYPASS_USER=admin
|
||||
```
|
||||
|
||||
## GeoIP
|
||||
|
||||
The installer downloads GeoLite2-City once to:
|
||||
The installer can download the GeoLite2 City database to:
|
||||
|
||||
```txt
|
||||
```text
|
||||
data/GeoLite2-City.mmdb
|
||||
```
|
||||
|
||||
@@ -128,42 +329,155 @@ Manual download:
|
||||
./scripts/download_geoip.sh
|
||||
```
|
||||
|
||||
The script uses `https://git.io/GeoLite2-City.mmdb` as the primary source and `https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdb` as fallback. The `data` directory is set to `755`, and the database file is set to `644`.
|
||||
Configure the database path:
|
||||
|
||||
## API docs
|
||||
```env
|
||||
PYTORRENT_GEOIP_DB=data/GeoLite2-City.mmdb
|
||||
```
|
||||
|
||||
OpenAPI documentation is available at `/docs`. `/api/profiles` supports `max_parallel_jobs` with default value `5` and `is_remote`; `PUT /api/profiles/{profile_id}` edits an existing profile. `/api/preferences` supports fields including `theme`, `bootstrap_theme`, `font_family`, `table_columns_json`, `peers_refresh_seconds` and `port_check_enabled`. `/api/port-check` returns port status with `checked_at`; for remote profiles the public IP is read through rTorrent with fallbacks when supported. `/api/system/status` returns `usage_available=false` for remote profiles and does not read local CPU/RAM.
|
||||
## OpenAPI
|
||||
|
||||
`/api/openapi.json` includes reusable schemas for main API responses, including `TorrentListResponse`, `TorrentSummary`, `TorrentFilterSummary`, `CleanupSummary` and `AppStatus`. `GET /api/torrents` documents the `summary` field used by sidebar filters.
|
||||
OpenAPI documentation is available at:
|
||||
|
||||
## Admin CLI
|
||||
```text
|
||||
/docs
|
||||
/api/openapi.json
|
||||
```
|
||||
|
||||
Reset an existing user's password:
|
||||
The API includes profile management, torrent actions, preferences, port checks, system status, planner, poller, RSS, backups and diagnostics endpoints.
|
||||
|
||||
## Configuration reference
|
||||
|
||||
Common environment variables:
|
||||
|
||||
```env
|
||||
PYTORRENT_SECRET_KEY=change-me
|
||||
PYTORRENT_DB_PATH=data/pytorrent.sqlite3
|
||||
PYTORRENT_HOST=0.0.0.0
|
||||
PYTORRENT_PORT=8090
|
||||
PYTORRENT_DEBUG=0
|
||||
PYTORRENT_POLL_INTERVAL=1
|
||||
PYTORRENT_WORKERS=16
|
||||
PYTORRENT_USE_OFFLINE_LIBS=true
|
||||
PYTORRENT_LOG_ENABLE=false
|
||||
PYTORRENT_LOG_DIR=data/logs
|
||||
```
|
||||
|
||||
Retention settings:
|
||||
|
||||
```env
|
||||
PYTORRENT_TRAFFIC_HISTORY_RETENTION_DAYS=90
|
||||
PYTORRENT_JOBS_RETENTION_DAYS=30
|
||||
PYTORRENT_SMART_QUEUE_HISTORY_RETENTION_DAYS=30
|
||||
PYTORRENT_LOG_RETENTION_DAYS=30
|
||||
```
|
||||
|
||||
Database maintenance:
|
||||
|
||||
```env
|
||||
PYTORRENT_DB_VACUUM_ENABLE=true
|
||||
PYTORRENT_DB_VACUUM_EVERY_SECONDS=86400
|
||||
PYTORRENT_DB_VACUUM_MIN_FREE_MB=512
|
||||
PYTORRENT_DB_VACUUM_MIN_FREE_RATIO=0.25
|
||||
```
|
||||
|
||||
See `.env.example` for the full list.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Service does not start
|
||||
|
||||
```bash
|
||||
sudo journalctl -u pytorrent -n 100 --no-pager
|
||||
sudo systemctl status pytorrent
|
||||
```
|
||||
|
||||
### rTorrent connection fails
|
||||
|
||||
Check that rTorrent exposes SCGI locally and that the pyTorrent profile uses the same port:
|
||||
|
||||
```text
|
||||
scgi://127.0.0.1:5000/RPC2
|
||||
```
|
||||
|
||||
### External auth creates users without profiles
|
||||
|
||||
Use admin auto-create mode:
|
||||
|
||||
```env
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=admin
|
||||
```
|
||||
|
||||
Or grant read-write profile permissions to non-admin users:
|
||||
|
||||
```env
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=user
|
||||
PYTORRENT_AUTH_PROXY_AUTO_CREATE_PERMISSION=rw
|
||||
```
|
||||
|
||||
### Socket.IO badge stays offline behind reverse proxy
|
||||
|
||||
Forward the same authenticated user header to all pyTorrent paths, including `/socket.io/`:
|
||||
|
||||
```nginx
|
||||
auth_request_set $auth_user $upstream_http_remote_user;
|
||||
proxy_set_header Remote-User $auth_user;
|
||||
```
|
||||
|
||||
### Build logs
|
||||
|
||||
Source-build installers write logs to:
|
||||
|
||||
```text
|
||||
/var/log/pytorrent-installer
|
||||
```
|
||||
|
||||
Enable verbose installer output:
|
||||
|
||||
```bash
|
||||
PYTORRENT_DEBUG_INSTALL=1 sudo bash scripts/install_stack.sh
|
||||
```
|
||||
|
||||
## Security notes
|
||||
|
||||
- Do not expose rTorrent SCGI directly to the public internet.
|
||||
- Use HTTPS and authentication for remote access.
|
||||
- Set a strong `PYTORRENT_SECRET_KEY` before production use.
|
||||
- Review auth bypass settings before publishing or deploying.
|
||||
- Keep `.env` out of Git. Use `.env.example` for public defaults.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
. venv/bin/activate
|
||||
python -m pytorrent.cli reset-password admin new_password
|
||||
python app.py
|
||||
```
|
||||
|
||||
Without the password argument, the CLI asks for it interactively:
|
||||
Run a quick Python compile check:
|
||||
|
||||
```bash
|
||||
python -m pytorrent.cli reset-password admin
|
||||
python -m compileall pytorrent app.py wsgi.py
|
||||
```
|
||||
|
||||
The command uses the same database as the app and respects `PYTORRENT_DB_PATH` from `.env`. The reset changes only the password hash and leaves role and permissions unchanged.
|
||||
|
||||
## API authentication tokens
|
||||
|
||||
When `PYTORRENT_AUTH_ENABLE=0`, API endpoints work without authentication.
|
||||
|
||||
When `PYTORRENT_AUTH_ENABLE=1`, API access can use either the browser session cookie or a per-user API token. Admin users can generate a token in **Tools -> Users** with **Generate token**. Copy the token immediately; only its prefix and metadata are stored afterwards.
|
||||
|
||||
Use a token in one of these forms:
|
||||
Download offline frontend assets when needed:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer pt_xxx" http://127.0.0.1:8080/api/system/status
|
||||
curl -H "X-API-Key: pt_xxx" http://127.0.0.1:8080/api/system/status
|
||||
python scripts/download_frontend_libs.py
|
||||
```
|
||||
|
||||
Token permissions follow the owning user's role and rTorrent profile permissions. Revoked tokens stop working immediately.
|
||||
## Project structure
|
||||
|
||||
```text
|
||||
pytorrent/ Application package
|
||||
pytorrent/routes/ Flask routes and API modules
|
||||
pytorrent/services/ rTorrent, planner, queue and helper services
|
||||
pytorrent/static/ Frontend JavaScript and CSS
|
||||
pytorrent/templates/ HTML templates
|
||||
scripts/ Installers and maintenance tools
|
||||
systemd/ systemd service files
|
||||
data/ Runtime data directory
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
AGPL-3
|
||||
Reference in New Issue
Block a user