mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-10-11 22:36:35 +08:00
# Requirements Updated - fastapi==0.116.0 - retrying==1.4.0 - uvicorn==0.35.0 # New Features - **Web UI**: Introduced a new Web UI for configuring and managing qBit Manage. - Visual Configuration Editor for YAML files. - Command Execution directly from the UI. - Undo/Redo History for changes. - Theme Support (light/dark mode). - Responsive Design for desktop and mobile. - Real-time YAML Preview. - Pass skip qbitorrent check as optional parameter to the API (Adds #860)\ **Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.4.0...v4.5.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: ineednewpajamas <73252768+ineednewpajamas@users.noreply.github.com>
259 lines
7.2 KiB
Markdown
259 lines
7.2 KiB
Markdown
# Web API Documentation
|
|
|
|
## Overview
|
|
|
|
qBit Manage provides a REST API that allows you to trigger commands via HTTP requests. The API server runs on port 8080 by default and can be configured using the `--port` option or `QBT_PORT` environment variable.
|
|
|
|
## Running the Web Server
|
|
|
|
### Command Line
|
|
|
|
```bash
|
|
python qbit_manage.py --web-server --port 8080
|
|
```
|
|
|
|
### Docker
|
|
|
|
```yaml
|
|
version: "3"
|
|
services:
|
|
qbit_manage:
|
|
image: bobokun/qbit_manage:latest
|
|
container_name: qbit_manage
|
|
environment:
|
|
- QBT_WEB_SERVER=true # Enable web server
|
|
- QBT_PORT=8080 # Set web server port
|
|
ports:
|
|
- "8080:8080" # Map container port to host
|
|
volumes:
|
|
- /path/to/config:/config
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### POST /api/run-command
|
|
|
|
Execute qBit Manage commands via the API.
|
|
|
|
#### Request Body
|
|
|
|
```json
|
|
{
|
|
"config_file": "config.yml", // Optional, defaults to "config.yml"
|
|
"commands": ["cat_update", "tag_update"], // Required, list of commands to run
|
|
"hashes": ["<hash1>", "<hash2>"], // Optional, list of torrent hashes to filter by
|
|
"dry_run": false, // Optional, defaults to false
|
|
"skip_cleanup": false, // Optional, defaults to false
|
|
"skip_qb_version_check": false, // Optional, defaults to false
|
|
"log_level": null // Optional, defaults to null (e.g., "info", "debug", "error")
|
|
}
|
|
```
|
|
|
|
#### Response
|
|
|
|
Success:
|
|
|
|
```json
|
|
{
|
|
"status": "success",
|
|
"message": "Commands executed successfully for all configs",
|
|
"results": [
|
|
{
|
|
"config_file": "config.yml",
|
|
"stats": {
|
|
"executed_commands": ["cat_update", "tag_update"],
|
|
"categorized": 5,
|
|
"tagged": 10
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Queued (when scheduled run is in progress):
|
|
|
|
```json
|
|
{
|
|
"status": "queued",
|
|
"message": "Scheduled run in progress. Request queued.",
|
|
"config_file": "config.yml",
|
|
"commands": ["cat_update", "tag_update"]
|
|
}
|
|
```
|
|
|
|
Error:
|
|
|
|
```json
|
|
{
|
|
"detail": "Error message"
|
|
}
|
|
```
|
|
|
|
## Available Commands
|
|
|
|
The following commands can be included in the `commands` array of the API request:
|
|
|
|
| Command | Description | Supports Hashes |
|
|
| ------------------- | ---------------------------------------------------------------- | --------------- |
|
|
| `cat_update` | Update categories based on save paths | Yes |
|
|
| `tag_update` | Add tags based on tracker URLs | Yes |
|
|
| `recheck` | Recheck paused torrents sorted by size and resume completed ones | Yes |
|
|
| `rem_unregistered` | Remove unregistered torrents | Yes |
|
|
| `tag_tracker_error` | Tag torrents with tracker errors | Yes |
|
|
| `rem_orphaned` | Remove orphaned files from root directory | No |
|
|
| `tag_nohardlinks` | Tag torrents with no hard links | Yes |
|
|
| `share_limits` | Apply share limits based on tags/categories | Yes |
|
|
|
|
Example using multiple commands:
|
|
|
|
```json
|
|
{
|
|
"config_file": "config.yml",
|
|
"commands": ["cat_update", "tag_update", "share_limits"],
|
|
"dry_run": true
|
|
}
|
|
```
|
|
|
|
## qBittorrent Integration
|
|
|
|
qBittorrent can call a program after a torrent is added or finished. You can configure this in `Settings > Downloads > Run external program`.
|
|
|
|
Example command to run after torrent added/finished:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
# run_qbit_manage_commands.sh
|
|
#
|
|
# Sends a POST request to qBit Manage with a given torrent hash to trigger
|
|
# actions like "tag_update" and "share_limits".
|
|
#
|
|
# USAGE:
|
|
# ./run_qbit_manage_commands.sh <torrent_hash>
|
|
#
|
|
# EXAMPLE:
|
|
# ./run_qbit_manage_commands.sh 123ABC456DEF789XYZ
|
|
#
|
|
# NOTES:
|
|
# - Make sure this script is executable: chmod +x run_qbit_manage_commands.sh
|
|
# - The torrent hash is typically passed in automatically by qBittorrent via the "%I" variable.
|
|
# - All output is logged to run_qbit_manage_commands.log in the same directory as the script,
|
|
# and also printed to stdout.
|
|
|
|
set -euo pipefail
|
|
|
|
API_URL="http://qbit_manage:8080/api/run-command"
|
|
COMMANDS='["tag_update", "share_limits"]'
|
|
|
|
if [[ $# -lt 1 || -z "$1" ]]; then
|
|
echo "Usage: $0 <torrent_hash>" >&2
|
|
exit 1
|
|
fi
|
|
|
|
TORRENT_HASH="$1"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
LOG_FILE="${SCRIPT_DIR}/run_qbit_manage_commands.log"
|
|
|
|
JSON="{\"commands\":${COMMANDS},\"hashes\":[\"${TORRENT_HASH}\"]}"
|
|
|
|
{
|
|
echo "Sending API call for hash: ${TORRENT_HASH}"
|
|
echo "Payload: ${JSON}"
|
|
} | tee -a "${LOG_FILE}"
|
|
|
|
if curl -fsSL -X POST \
|
|
-H "Content-Type: application/json" \
|
|
-d "${JSON}" \
|
|
"${API_URL}" | tee -a "${LOG_FILE}"; then
|
|
echo "Success" | tee -a "${LOG_FILE}"
|
|
else
|
|
echo "Error: qBit Manage API call failed for hash ${TORRENT_HASH}" | tee -a "${LOG_FILE}"
|
|
fi
|
|
```
|
|
|
|
To use this script:
|
|
|
|
1. Save it as a file (e.g., `run_qbit_manage_commands.sh`).
|
|
2. Make the script executable:
|
|
```bash
|
|
chmod +X /path/to/run_qbit_manage_commands.sh
|
|
```
|
|
3. In qBittorrent, configure `Settings > Downloads > Run external program` to execute this script, passing `%I` as an argument:
|
|
```
|
|
/path/to/run_qbit_manage_commands.sh "%I"
|
|
```
|
|
The script will create a log file named `run_qbit_manage_commands.log` in the same directory where the script is located.
|
|
|
|
## Behavior
|
|
|
|
1. Concurrent Execution:
|
|
|
|
- API requests during scheduled runs are automatically queued
|
|
- Queued requests are processed after the scheduled run completes
|
|
- Double-check mechanism prevents race conditions
|
|
|
|
2. Command Execution:
|
|
|
|
- Commands sent to the API are mandatory and the commands defined in ENV variables and in the config file are not used when using the API.
|
|
- All regular command validations apply
|
|
- Dry run mode available for testing
|
|
|
|
3. Error Handling:
|
|
- Failed requests return appropriate error messages
|
|
- Queue state is preserved even during errors
|
|
- Proper cleanup ensures system stability
|
|
|
|
## Example Usage
|
|
|
|
Using curl:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8080/api/run-command \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"config_file": "config.yml",
|
|
"commands": ["cat_update", "tag_update"],
|
|
"hashes": ["a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"],
|
|
"dry_run": false,
|
|
"skip_cleanup": false,
|
|
"skip_qb_version_check": false,
|
|
"log_level": "info"
|
|
}'
|
|
```
|
|
|
|
Using Python requests:
|
|
|
|
```python
|
|
import requests
|
|
|
|
response = requests.post(
|
|
"http://localhost:8080/api/run-command",
|
|
json={
|
|
"config_file": "config.yml",
|
|
"commands": ["cat_update", "tag_update"],
|
|
"hashes": ["a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"],
|
|
"dry_run": False,
|
|
"skip_cleanup": False,
|
|
"skip_qb_version_check": False,
|
|
"log_level": "info"
|
|
}
|
|
)
|
|
print(response.json())
|
|
```
|
|
|
|
## Command Validation
|
|
|
|
- All commands must be valid command names from the list above
|
|
- Commands are case-sensitive
|
|
- Invalid commands will return a 400 error with detail about the invalid command
|
|
- Empty command list will return a 400 error
|
|
- Commands defined in ENV variables or config files are ignored when using the API
|
|
- The API validates commands before execution and during runtime
|
|
|
|
Example error response for invalid command:
|
|
|
|
```json
|
|
{
|
|
"detail": "Invalid command: invalid_command"
|
|
}
|
|
```
|