Приём: добавление загрузки по .torrent-файлу
Принимаем .torrent как загруженные байты — через файл-пикер в веб-форме и Telegram-документ, наряду с magnet. Файл несёт полные метаданные: работает там, где magnet не резолвится (закрытые трекеры, без DHT), и даёт максимум контекста для распознавания без сети. - internal/torrent: парсер поверх anacrolix/torrent/metainfo — инфохэш(и) (v1 SHA1 исходных байтов info; v2 BEP52 при наличии) + Context() из имени, дерева файлов, размера, трекеров. Извлечение файлов панико-безопасно (недоверенный вход). - Персистентность байтов: таблица-спутник download_torrent (миграция 0009); пишется в транзакции создания загрузки, только на ветке создания (не при дедупе). Байты живут весь срок строки — нужны для повторного добавления при retry. - ingest: Request.TorrentData/TorrentName, диспетч парсера; source_ref — человекочитаемый референс (имя раздачи/файла), не адрес добавления. - worker: общий sourceAddParts ветвит по source_type в ОБОИХ add-путях — processCatched и Retry (torrent добавляется файлом, не magnet-хешем). - Транспорты: multipart-форма с файл-пикером (деградация без JS) и приём Telegram-документа (скачивание с редактированием токена из ошибок — секрет не в логи; обработка до ветки pending/текста). Разработка по OpenSpec (SDD): change torrent-file-ingest, два чекпоинта ревью (дизайн до кода, код до архива) сабагентами; дельты влиты в спеки, change архивирован. Ручная проверка на живом qBittorrent (7.3) — за деплоем. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Загрузка .torrent-файла на форме добавления
|
||||
|
||||
Форма добавления загрузки веб-UI SHALL позволять выбрать локальный
|
||||
`.torrent`-файл рядом со строкой ввода источника (кнопка/поле выбора файла).
|
||||
При отправке формы с выбранным файлом система SHALL принять его байты
|
||||
(`multipart/form-data`) и провести приём по `.torrent` (см. `ingest` «Приём
|
||||
источника из .torrent-файла»); при пустом файловом поле — приём по тексту
|
||||
источника, как прежде.
|
||||
|
||||
Файловый ввод SHALL деградировать без JavaScript: обычная отправка
|
||||
`multipart`-формы SHALL приводить к приёму файла и тем же результатом, что и
|
||||
htmx-путь (список обновляется/происходит редирект — как у существующего
|
||||
добавления). Размер принимаемого файла UI/обработчик SHALL ограничивать (см.
|
||||
ограничение размера в `ingest`); превышение SHALL давать понятную ошибку без
|
||||
создания загрузки.
|
||||
|
||||
#### Scenario: Добавление выбором .torrent-файла
|
||||
|
||||
- **GIVEN** пользователь открыл форму добавления и выбрал `.torrent`-файл
|
||||
- **WHEN** форма отправлена
|
||||
- **THEN** файл принимается байтами и заводится загрузка (`source_type =
|
||||
torrent`)
|
||||
- **AND** список загрузок отражает новую задачу (как при добавлении по magnet)
|
||||
|
||||
#### Scenario: Файл не выбран — приём по тексту
|
||||
|
||||
- **GIVEN** пользователь оставил файловое поле пустым и ввёл magnet/текст
|
||||
- **WHEN** форма отправлена
|
||||
- **THEN** выполняется приём по тексту источника, как прежде
|
||||
Reference in New Issue
Block a user