Главная / Для трекеров / Документация API

ReSeeder API — документация утилиты

Серверная утилита на Python: индексирует .torrent-файлы трекера и отдаёт пользователям готовые раздачи по сигнатурам их медиатеки. Этот документ — единый источник правды по установке, конфигурации и эксплуатации.

⊙ Python 3.10+ ⊙ FastAPI + SQLite ⊙ Linux / Windows ⊙ MIT License

1.Требования

  • Python 3.10+
  • SQLite — встроен в Python, отдельно не нужен
  • Tkinter (опционально, только для локального GUI) — apt install python3-tk
  • Доступ на чтение к папкам с .torrent-файлами трекера

Питон-зависимости из requirements.txt:

bencodepy      # парсинг .torrent
fastapi        # HTTP API
uvicorn        # ASGI-сервер
pydantic       # валидация запросов
watchdog       # inotify/real-time мониторинг папок

2.Установка

# клонировать репозиторий и перейти в папку утилиты
cd reseeder_api

# создать изолированную среду
python3 -m venv .venv
source .venv/bin/activate

# установить зависимости
pip install -r requirements.txt

3.Быстрый старт

# 1. Первичное сканирование папки(ок) с .torrent файлами
python -m reseeder_api --scan /var/trackers/torrents

# 2. Проверить что получилось
python -m reseeder_api --stats

# 3. Запустить API сервер
python -m reseeder_api --serve --host 0.0.0.0 --port 8080

Документация API доступна на http://<host>:8080/docs (Swagger UI).

4.CLI команды

python -m reseeder_api                                # GUI (Tkinter)
python -m reseeder_api --scan PATH [PATH…]            # сканирование путей
python -m reseeder_api --stats                        # статистика БД
python -m reseeder_api --watch                        # фоновый мониторинг
python -m reseeder_api --serve [--host H] [--port P]  # HTTP API сервер
python -m reseeder_api --backup                       # создать бэкап БД сейчас
python -m reseeder_api --backup-list                  # список существующих бэкапов
python -m reseeder_api --restore /path/to/backup.db   # восстановить БД из бэкапа
python -m reseeder_api --db /path/to/custom.db …      # другой путь к БД

--scan и --stats можно комбинировать. --serve блокирующий.

5.База данных

По умолчанию reseeder_api.db (SQLite) создаётся в рабочей директории, откуда запущен процесс. Для production рекомендуется фиксированный путь:

python -m reseeder_api --db /var/lib/reseeder_api/reseeder_api.db --serve

Схема включает 5 таблиц: torrents, torrent_files, scan_paths, match_log, settings. Все создаются автоматически при первом запуске.

WAL-режим включён. БД безопасна для одновременного чтения из API-сервера и записи из watcher/scanner.

Дубликаты

Ограничений по info_hash нет: если один и тот же торрент лежит в нескольких папках — в БД попадут все копии. Матчер в ответе клиенту дедуплицирует по info_hash автоматически.

6.Настройки

Хранятся в таблице settings, редактируются через GUI или SQL. Дефолты создаются при первом запуске.

ПараметрДефолтОписание
min_file_size 104857600 (100 МБ) Передаётся клиенту в handshake. Клиент сам фильтрует свои медиафайлы перед отправкой. Не влияет на индексацию — в БД попадают все файлы любого размера.
max_files_per_request 10000 Максимум файлов в одном запросе от клиента.
max_torrents_per_response 500 Максимум .torrent в одном ответе.
watch_interval_sec 60 Интервал polling-fallback для watcher, если watchdog недоступен.
log_level info debug / info / warn / error.
log_file reseeder_api.log Путь к файлу логов.
db_path reseeder_api.db Путь к SQLite. Переопределяется флагом --db.
hash_duplicates_log 0 Если 1 — при сканировании считается SHA1 каждого .torrent, дубликаты логируются группами. По умолчанию выключено (удлиняет скан на больших коллекциях).
backup_interval_hours 0 Интервал авто-бэкапа БД в часах. 0 = выключено. Бэкап делается онлайн (SQLite Backup API), не блокирует API-сервер и watcher.
backup_dir backups Папка для бэкапов. Относительный путь разрешается относительно каталога БД (db_path). Для production обычно абсолютный: /var/lib/reseeder_api/backups.
backup_keep 7 Сколько последних бэкапов хранить. Старые удаляются автоматически после создания нового.

Изменить значение напрямую через SQL:

sqlite3 reseeder_api.db "UPDATE settings SET value='20000' WHERE key='max_files_per_request'"
API-сервер перечитывает настройки на каждом запросе — перезапуск не нужен.

7.Сканирование и watcher

Первичное сканирование

python -m reseeder_api --scan /path/to/torrents

Рекурсивный обход, парсинг .torrent через bencode, вычисление info_hash, запись в БД. Инкрементально: повторный запуск обработает только новые/изменённые/удалённые файлы (сравнение по mtime).

Watch-режим

python -m reseeder_api --watch

Мониторит папки, отслеживает создание, удаление, переименование, изменение .torrent файлов в реальном времени. На Linux использует inotify через watchdog. Если watchdog не установлен — polling с интервалом watch_interval_sec.

Обработка событий

  • created / modified — перепарс файла и запись в БД (новый или обновление)
  • deleted — удаление записи из БД
  • moved (rename) — удаление по старому пути + добавление по новому

Каждое событие обрабатывается немедленно. При modified сравнивается mtime — если не изменился, парсинг пропускается. Если во время копирования большого файла событие приходит раньше, чем файл дописан — парсер вернёт error, но это безвредно: следующее modified (по завершении записи) корректно добавит торрент.

Пути для сканирования

Добавляются через GUI (вкладка «Сканирование») или напрямую в БД:

sqlite3 reseeder_api.db "INSERT INTO scan_paths(path, enabled) VALUES('/var/trackers/torrents', 1)"

8.HTTP API

Все запросы — application/json, все ответы — JSON. Авторизация и rate-limit делегируются трекеру (через reverse-proxy или middleware).

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"}

Формат ошибок

{"status": "error", "code": "TOO_MANY_FILES",  "message": "Максимум 10000 файлов…"}
{"status": "error", "code": "INVALID_REQUEST", "message": "..."}
{"status": "error", "code": "SERVER_ERROR",    "message": "..."}

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

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

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

/etc/systemd/system/reseeder-watch.service — отдельный сервис для real-time мониторинга:

[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 и авторизацию добавляйте здесь
}

Права на файлы

Юзер reseeder должен иметь read на папки с .torrent файлами трекера и read/write на /var/lib/reseeder_api/.

10.Тюнинг Linux

Лимит inotify watches

При сотнях тысяч .torrent-файлов (и их папок) стандартного лимита может не хватить. Проверить:

cat /proc/sys/fs/inotify/max_user_watches

Увеличить:

echo "fs.inotify.max_user_watches=524288" | sudo tee /etc/sysctl.d/90-reseeder.conf
sudo sysctl -p /etc/sysctl.d/90-reseeder.conf

Если увеличивать нельзя — отключите watch-сервис и используйте периодический --scan по cron:

*/15 * * * * /opt/reseeder_api/.venv/bin/python -m reseeder_api \
    --db /var/lib/reseeder_api/reseeder_api.db --scan /var/trackers/torrents

SQLite ручной дамп

Помимо встроенного авто-бэкапа (см. ниже):

sqlite3 /var/lib/reseeder_api/reseeder_api.db ".backup /backup/reseeder_api.db"

11.GUI (опционально)

На десктопе (Windows / Linux с X11):

python -m reseeder_api

Пять вкладок:

  • Сканирование — управление путями (с отображением количества торрентов в БД на каждый путь), запуск скана, watch toggle, журнал с возможностью копирования
  • Статистика — счётчики БД, распределение piece_length
  • Настройки — все параметры (см. раздел 6). min_file_size задаётся и отображается в МБ. hash_duplicates_log — чекбокс
  • Бэкап — создание/удаление/восстановление бэкапов, статус авто-таймера, список бэкапов с датой и размером
  • Тестирование — ручная отправка JSON-запросов (handshake / phase1 / phase2) напрямую через матчер, без HTTP. Шаблоны по каждому эндпоинту

GUI не нужен для production — все функции доступны через CLI и БД напрямую.

12.Бэкап и восстановление

Утилита умеет делать горячий бэкап БД (через SQLite Online Backup API — безопасен во время активных запросов), хранить историю, автоматически ротировать и восстанавливать.

Автоматический бэкап

Настраивается тремя параметрами (раздел 6):

  • backup_interval_hours — интервал в часах (0 = выключено)
  • backup_dir — папка для бэкапов
  • backup_keep — сколько последних файлов хранить

Таймер запускается автоматически вместе с --serve, --watch и GUI. Каждые 60 секунд проверяет настройки и при наступлении времени делает бэкап, затем удаляет старые файлы сверх лимита.

Имя файла бэкапа: reseeder_api_YYYYMMDD_HHMMSS.db — таймштамп легко сортируется.

Рекомендации:
  • Production: backup_interval_hours=6, backup_keep=14 — каждые 6 часов, две недели истории.
  • Небольшой трекер: backup_interval_hours=24, backup_keep=7.
  • Если на сервере есть внешний бэкап (restic/borg/rsnapshot) — можно держать backup_keep=1 и отдавать ротацию внешней системе.

Ручной бэкап

CLI:

python -m reseeder_api --backup
python -m reseeder_api --backup-list

GUI: вкладка Бэкап → «Создать бэкап сейчас». Там же список всех существующих бэкапов с датой и размером.

Восстановление

CLI (рекомендуется для production):

# Остановите сервис перед восстановлением
sudo systemctl stop reseeder-api reseeder-watch

python -m reseeder_api --db /var/lib/reseeder_api/reseeder_api.db \
    --restore /var/lib/reseeder_api/backups/reseeder_api_20260405_153000.db

sudo systemctl start reseeder-api reseeder-watch

Спросит подтверждение [y/N]. После y заменит текущую БД файлом бэкапа (copy2 — работает одинаково на Linux и Windows).

GUI: вкладка Бэкап → выбрать строку → «Восстановить выбранный». GUI остановит watcher/backup-timer, перезапишет БД и закроет окно — запустите утилиту заново.

Где физически лежат бэкапы

  • backup_dir абсолютный путь (/var/lib/reseeder_api/backups) — используется как есть.
  • backup_dir относительный (дефолт backups) — разрешается от каталога, где лежит файл БД:
    • Linux: /var/lib/reseeder_api/reseeder_api.db/var/lib/reseeder_api/backups/
    • Windows: D:\reseeder_api\reseeder_api.dbD:\reseeder_api\backups\

Такое поведение делает путь одинаковым на обеих ОС — не нужно переопределять настройки при переносе.

WAL-файлы и безопасность восстановления. При восстановлении утилита автоматически удаляет побочные файлы -wal, -shm, -journal рядом с БД перед копированием — иначе SQLite может смешать старые незафиксированные транзакции с восстановленными данными. Учтено в --restore и кнопке восстановления в GUI.

13.Troubleshooting

Scan complete: +0 new, ~0 updated, -0 removed, err=N

err — количество .torrent-файлов, которые не удалось распарсить. Причины:

  • Битый bencode / обрезанный файл
  • Нет info словаря
  • Ошибка чтения с диска (права, битый inode)

Включите log_level=debug и пересканируйте — в логе будут конкретные пути.

Watcher не видит изменения

  1. Проверьте что watchdog установлен: pip list | grep watchdog
  2. Проверьте лимит inotify (раздел 10)
  3. В логе будет Watcher started (polling) если watchdog упал — разберитесь почему

База заблокирована (database is locked)

WAL-режим должен это предотвращать. Если всё равно возникает — проверьте, что нет второго процесса, пишущего в ту же БД с отключённым WAL.

14.Структура проекта

reseeder_api/
├── __init__.py
├── __main__.py
├── reseeder_tool.py    # CLI + GUI entry point
├── config.py           # настройки, дефолты
├── logger.py           # логирование
├── database.py         # SQLite: схема, CRUD, матч-запросы, backup_to
├── scanner.py          # парсер .torrent, синхронизация БД
├── matcher.py          # фаза 1/2, handshake, payload validation
├── watcher.py          # inotify/polling мониторинг, мгновенная обработка
├── backup.py           # авто-бэкап, ротация, восстановление (cross-platform)
├── api.py              # FastAPI сервер
├── gui.py              # Tkinter GUI (5 вкладок)
├── requirements.txt
└── README.md

15.Скачать

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

↓ reseeder_api.zip

Вопросы по интеграции — на странице для трекеров.