2026-05-17 media-pipeline tracker parsers doc: genres fix, pitfalls, status update
This commit is contained in:
@@ -0,0 +1,98 @@
|
|||||||
|
---
|
||||||
|
title: Media Pipeline — Multi-Tracker Support
|
||||||
|
created: '2026-05-17'
|
||||||
|
updated: '2026-05-17'
|
||||||
|
status: active
|
||||||
|
tags:
|
||||||
|
- media-pipeline
|
||||||
|
- rutracker
|
||||||
|
- rutor
|
||||||
|
- nnm-club
|
||||||
|
---
|
||||||
|
# Media Pipeline — Multi-Tracker Support
|
||||||
|
|
||||||
|
## Текущее состояние
|
||||||
|
|
||||||
|
✅ Реализовано и задеплоено на Kraken:
|
||||||
|
|
||||||
|
- `TrackerPageParserRegistry` — dispatch по `url.host`, парсеры: Rutracker, Rutor, NNMClub, PirateBay, Nyaa
|
||||||
|
- `RutrackerPageParser` — CP1251 decode через `/usr/bin/iconv`, SwiftSoup парсинг
|
||||||
|
- Жанры извлекаются из `[...]` в заголовке топика, страны фильтруются
|
||||||
|
- KP/IMDb ID extraction работает
|
||||||
|
- `TorrentSourceStrategy` использует registry вместо прямого вызова `RutrackerAPI`
|
||||||
|
- Fallback NFO при unresolved + `torrentPageMetadata.hasRichData`
|
||||||
|
|
||||||
|
## Архитектура
|
||||||
|
|
||||||
|
### TrackerPageParser protocol
|
||||||
|
|
||||||
|
```swift
|
||||||
|
public protocol TrackerPageParser: Sendable {
|
||||||
|
var supportedHosts: [String] { get }
|
||||||
|
func parse(data: Data, url: URL) throws -> TorrentPageMetadata
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### TrackerPageParserRegistry
|
||||||
|
|
||||||
|
```swift
|
||||||
|
public struct TrackerPageParserRegistry: Sendable {
|
||||||
|
public static let defaults: [TrackerPageParser] = [
|
||||||
|
RutrackerPageParser(),
|
||||||
|
RutorPageParser(),
|
||||||
|
NNMClubPageParser(),
|
||||||
|
PirateBayPageParser(),
|
||||||
|
NyaaPageParser(),
|
||||||
|
]
|
||||||
|
public func parser(for url: URL) -> TrackerPageParser?
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Парсеры по трекерам
|
||||||
|
|
||||||
|
### RutrackerPageParser ✅
|
||||||
|
- Encoding: Windows-1251 (через `/usr/bin/iconv` temp files — swift-corelibs-foundation не поддерживает CP1251 на Linux)
|
||||||
|
- Title selector: `#topic-title`, `h1.maintitle`, `a.topictitle`
|
||||||
|
- **Genres: из заголовка топика `[YEAR, жанр1, жанр2, ..., TECH-TAG]`** — не из поста
|
||||||
|
- Страны фильтруются через `countryNames: Set<String>` (30+ стран RU+EN)
|
||||||
|
- Poster: первый img в `div.post_body` не из rutracker UI
|
||||||
|
- IDs: `imdb.com/title/tt\d+`, `kinopoisk.ru/film/\d+`
|
||||||
|
|
||||||
|
### RutorPageParser ✅ (структура реализована)
|
||||||
|
- Encoding: UTF-8
|
||||||
|
- Title: `h1.topic-header` / `div#topic-title`
|
||||||
|
- Genres: паттерн `Жанр:` в тексте
|
||||||
|
|
||||||
|
### NNMClubPageParser ✅ (структура реализована)
|
||||||
|
- Encoding: Windows-1251 (тот же iconv путь)
|
||||||
|
- Title: `h1.maintitle` / `a.maintitle`
|
||||||
|
|
||||||
|
### PirateBayPageParser ✅ (структура реализована)
|
||||||
|
- Encoding: UTF-8
|
||||||
|
- Title: `<h1 id="title">`
|
||||||
|
- Нет IMDb/KP ссылок обычно → только title/year из названия торрента
|
||||||
|
|
||||||
|
### NyaaPageParser ✅ (структура реализована)
|
||||||
|
- Encoding: UTF-8
|
||||||
|
- Аниме: title из `h3.panel-title`, AniDB ID если есть
|
||||||
|
|
||||||
|
## Ключевые питфоллы
|
||||||
|
|
||||||
|
- `extractGenres` должен парсить из **заголовка топика** (`#topic-title`), а не из тела поста — Rutracker кодирует жанры в `[YEAR, жанр, ...]` в title
|
||||||
|
- CP1251 decode: использовать `/usr/bin/iconv` через temp files — единственный способ на Linux
|
||||||
|
- Кеш хранит сырые байты (binary) — `grep` по кешу не работает для CP1251 файлов
|
||||||
|
- `TrackerParsers.swift` — боевой файл (используется в продакшне); `RutrackerAPI.swift` — legacy, параллельно существует
|
||||||
|
|
||||||
|
## Файлы
|
||||||
|
|
||||||
|
- `Sources/MediaSources/APIs/TrackerParsers.swift` — все парсеры + registry (боевой)
|
||||||
|
- `Sources/MediaSources/APIs/RutrackerAPI.swift` — legacy парсер (используется в части flow)
|
||||||
|
- `Sources/MediaSources/Providers/TorrentSourceStrategy.swift` — dispatch через registry
|
||||||
|
- `Sources/MediaDomain/Facts/TorrentPageMetadataFact.swift` — модель: title, year, genres, posterURL, description, externalLinks
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- [ ] Шаг B — новые типы медиа: игры, музыка, книги (следующий)
|
||||||
|
- [ ] Реальные HTML fixture тесты для каждого трекера (rutor, nnm-club)
|
||||||
|
- [ ] Верификация RutorPageParser/NNMClubPageParser на живых торрентах
|
||||||
|
- [ ] `MediaKind` detection по категории торрента (напр. "Игры PC" → `.game`)
|
||||||
Reference in New Issue
Block a user