API для трекеров

↓ Скачать утилиту

ReSeeder API — серверная утилита на Python, которая индексирует .torrent файлы трекера и отдаёт пользователям готовые раздачи по сигнатурам их медиатеки. Пользователь подключает свои файлы — получает торренты без ручного поиска по сайту.

⊙ Python 3.10+ ⊙ FastAPI + SQLite ⊙ Linux / Windows ⊙ Open Source

Зачем это трекеру

Матч между тем, что у пользователя уже лежит на диске, и тем, что раздаётся на трекере. Никаких файлов на сервер не отправляется — только сигнатуры.

Больше сидов

Пользователи начинают раздавать то, что уже было скачано, но отвязано от трекера. На старые раздачи мгновенно появляются новые сиды.

Приватность

Клиент отправляет только имена, размеры и SHA1 по первым 32 МБ файлов. Сами файлы никогда не покидают компьютер пользователя.

Низкие требования

FastAPI + SQLite в WAL-режиме. Держит сотни тысяч торрентов на любом дешёвом VPS. Авто-бэкап с ротацией включён.

Простая интеграция

Четыре HTTP-эндпоинта, JSON-протокол. Авторизация и rate-limit — на стороне трекера (через reverse-proxy или свой middleware).

Как это работает

Клиент ReSeeder вызывает эндпоинты последовательно. Каждый шаг независим и идемпотентен.

1

POST /match/handshake — рукопожатие

Клиент получает параметры утилиты: минимальный размер файла, лимиты на запрос/ответ. Сразу знает, сколько файлов можно отправить за раз и какие фильтры применить локально.

2

POST /match/phase1 — матч по имени + размеру

Клиент отправляет список файлов с именами и размерами. Сервер возвращает найденные .torrent в base64 с метаданными. Это быстрый путь для файлов с оригинальными именами.

3

POST /match/phase2 — матч только по размеру

Файлы, не найденные в фазе 1 (например, переименованные), отправляются без имени. Совпадения проверяются клиентом по SHA1 кусков — сервер отдаёт все торренты с подходящим размером, клиент сам выбирает нужный.

4

POST /match/report — отчёт (опционально)

Клиент отправляет результат матча — что было успешно подтверждено. Сервер логирует для статистики (ретеншн, популярные раздачи). Не влияет на работу клиента.

API reference

Все запросы — application/json, все ответы — JSON. Авторизация делегируется трекеру.

GET /health Проверка состояния + статистика БД

Response

{
  "status": "ok",
  "stats": {
    "torrents": 182540,
    "files": 1248301,
    "scan_paths": 3
  }
}
POST /match/handshake Параметры утилиты для клиента

Request

{
  "user_id": "12345"
}

Response

{
  "status": "ok",
  "min_file_size": 104857600,
  "max_files_per_request": 10000,
  "max_torrents_per_response": 500
}

user_id — идентификатор пользователя, передаётся трекером. Используется только для логирования (match_log).

POST /match/phase1 Матч по имени + размеру

Request

{
  "user_id": "12345",
  "phase": 1,
  "files": [
    {"name": "movie.mkv", "size": 4294967296},
    {"name": "show.s01e01.mkv", "size": 1073741824}
  ]
}

Response

{
  "status": "ok",
  "matched_torrents": [
    {
      "torrent_id": 42,
      "info_hash": "abc123...",
      "name": "Movie Name",
      "torrent_file": "<base64 .torrent>"
    }
  ],
  "matched_files_count": 1
}
POST /match/phase2 Матч только по размеру

Request

{
  "user_id": "12345",
  "phase": 2,
  "files": [{"size": 4294967296}],
  "exclude_torrent_ids": [42, 55]
}

exclude_torrent_ids — id торрентов, отданных клиенту в фазе 1. Сервер их не повторит.

Response

{
  "status": "ok",
  "matched_torrents": [ ... ],
  "matched_files_count": 3
}
POST /match/report Отчёт клиента о результате

Request

{
  "user_id": "12345",
  "confirmed": [{"info_hash": "abc123...", "pieces_verified": 12}],
  "rejected":  [{"info_hash": "def456..."}]
}

Структура тела произвольная — сервер принимает любой JSON и пишет в лог. Используется для статистики качества матча.

Response

{"status": "ok"}
POST Errors Формат ошибок для фаз 1/2
{"status": "error", "code": "TOO_MANY_FILES",  "message": "Максимум 10000 файлов"}
{"status": "error", "code": "INVALID_REQUEST", "message": "..."}
{"status": "error", "code": "SERVER_ERROR",    "message": "Внутренняя ошибка утилиты"}

HTTP-статус — 400 для ошибок валидации/бизнес-логики, 500 для необработанных исключений.

Установка и запуск

Минимум пять команд. Для production — systemd-unit в следующем разделе.

Быстрый старт

cd reseeder_api
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# первичное сканирование папки с .torrent
python -m reseeder_api --scan /var/trackers/torrents

# статистика
python -m reseeder_api --stats

# запуск API
python -m reseeder_api --serve --host 0.0.0.0 --port 8080

Swagger UI доступен на http://<host>:8080/docs. База создаётся автоматически при первом запуске (по умолчанию reseeder_api.db в рабочей директории, переопределяется флагом --db).

Развёртывание на Linux

Рекомендованная схема: два systemd-сервиса — API и watcher. Nginx как reverse-proxy для HTTPS и rate-limit на стороне трекера.

systemd: API-сервер

/etc/systemd/system/reseeder-api.service

[Unit]
Description=ReSeeder API — tracker matching utility
After=network.target

[Service]
Type=simple
User=reseeder
Group=reseeder
WorkingDirectory=/opt/reseeder_api
ExecStart=/opt/reseeder_api/.venv/bin/python -m reseeder_api \
    --db /var/lib/reseeder_api/reseeder_api.db \
    --serve --host 127.0.0.1 --port 8080
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

systemd: watcher

Отдельный сервис для real-time мониторинга папок с .torrent. Использует inotify через watchdog.

[Unit]
Description=ReSeeder API — torrent folder watcher
After=network.target

[Service]
Type=simple
User=reseeder
Group=reseeder
WorkingDirectory=/opt/reseeder_api
ExecStart=/opt/reseeder_api/.venv/bin/python -m reseeder_api \
    --db /var/lib/reseeder_api/reseeder_api.db --watch
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Активация

sudo useradd -r -s /bin/false reseeder
sudo mkdir -p /var/lib/reseeder_api
sudo chown reseeder:reseeder /var/lib/reseeder_api
sudo systemctl daemon-reload
sudo systemctl enable --now reseeder-api reseeder-watch

Reverse proxy (nginx)

location /reseeder_api/ {
    proxy_pass http://127.0.0.1:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    # rate-limit и авторизацию добавляйте здесь
}

На больших коллекциях (сотни тысяч .torrent) увеличьте лимит inotify: fs.inotify.max_user_watches=524288 в /etc/sysctl.d/.

Настройки утилиты

Хранятся в таблице settings. Редактируются через GUI или напрямую SQL. Перечитываются на каждом запросе — рестарт не нужен.

min_file_size

Минимальный размер файла для матча (байты). Передаётся клиенту в handshake — он фильтрует свои медиафайлы локально. Не влияет на индексацию. Дефолт: 100 МБ.

max_files_per_request

Сколько файлов клиент может отправить за один запрос. Дефолт: 10000.

max_torrents_per_response

Сколько торрентов возвращается за один ответ. Дефолт: 500.

backup_interval_hours

Интервал авто-бэкапа БД (онлайн, через SQLite Backup API). 0 = выключено. Рекомендация production: 6.

backup_dir / backup_keep

Папка для бэкапов и количество хранимых файлов. Относительный путь резолвится от каталога БД — работает одинаково на Linux и Windows.

hash_duplicates_log

Если 1 — при сканировании считается SHA1 каждого .torrent, дубликаты группируются в лог. Удлиняет скан на больших коллекциях.

Скачать утилиту

Архив содержит все исходники Python-утилиты, README и requirements.txt. MIT-лицензия, используйте и модифицируйте свободно.

reseeder_api · версия 1.0

FastAPI + SQLite, CLI и опциональный Tkinter GUI (5 вкладок: сканирование, статистика, настройки, бэкап, тестирование API). Архив весит ~35 КБ, после pip install ≈ 50 МБ с зависимостями.

Вопросы по интеграции

Нужна помощь с развёртыванием на вашем трекере или хотите попасть в дефолтный список поддерживаемых — напишите.

Готов помочь с интеграцией, написать middleware под авторизацию вашего трекера или добавить поддержку нестандартных схем .torrent-хранилища.