Минимальный плагин: пункты в меню долгого нажатия на торренте, чтобы перекинуть раздачу в Transmission вместо просмотра онлайн. Никаких настроек и RPC.
Плюс плагин Top — три пункта меню вместо «странной ленты» (см. ниже).
| Плагин | URL для Настройки → Расширения → «+» |
|---|---|
| transmission-send | https://0x3654.github.io/transmission-send/transmission-send.js |
| top | https://0x3654.github.io/transmission-send/top.js |
На каждом устройстве отдельно (PWA на iPhone — отдельно от вкладки Safari).
Четыре пункта в главном меню:
o=6, rutor в этом режиме не участвует). Раздачи, не сматчившиеся с TMDB
(софт, игры, сборники), не показываются.activity (category_full + discover/…) и сохраняет последний
фильтр. Кнопка открывает список: последний применённый + именованные пресеты
(сохранить/удалить там же).torrents_sort + per-карточный torrents_filter_data) как именованный пресет;
применение на открытом списке перерисовывает его, вне списка — становится
глобальным дефолтом.Фильтры «Топа» и «Топа трекеров» вызываются кнопкой вправо на экране — листом с вложенным выбором, как штатный фильтр торрентов (сортировка, качество, озвучки, тумблеры, «Показать»); значения те же, что в Настройки → Топ.
Настройки плагина: Настройки → Топ:
| Параметр | Что делает |
|---|---|
| Адрес сервера топа | URL tracker-top (рабочий — https://micro-tracker.koi-uaru.ts.net) |
| «Топ» вместо главной | при запуске открывается последний вариант «Топа» вместо ленты |
| Мин. качество (трекеры) | Любое / 720p+ / 1080p+ / 2160p+ |
| Скрывать CAM/TS | камрипы и «звук с TS» вычищаются ДО дедупа: фильм только с такими раздачами исчезает целиком, с нормальной — остаётся с ней (по умолчанию вкл) |
| Только дубляж (трекеры) | в топе только фильмы, у которых есть раздача с дубляжом |
Матчинг: запрос search/multi по оригинальному (или русскому) названию,
жёсткий фильтр по году ±1 для фильмов (для сезонных раздач допуск больше),
порог похожести названия; дубликаты раздач схлопываются по TMDB id (остаётся
самая сидируемая).
Go, один статический бинарник (образ scratch, ~11 МБ). Источники:
tracker.php?o=10, топ по сидам; видео-поддерево категорий
парсится со страницы (не хардкод), cp1251browse/0/{cat}/0/0/2/ (сортировка по раздающим);
видео-категории: 1/5 фильмы, 4/16 сериалы, 7 мультипликация, 10 аниме, 12 докиФилософия: отдаём фильмы для поиска, а не ленту раздач — дубликаты раздач одного фильма схлопываются в одну позицию (сиды суммируются, представителем становится лучшая раздача по качеству/размеру). Качество и озвучку пользователь выбирает позже в парсере Lampa на странице фильма; серверные фильтры оставлены как параметры API на всякий случай.
GET /top?src=both|nnm|rut&cat=video|all&pages=1..3&minq=720|1080|2160&audio=all|dub|no_ts
GET /healthz
Кэш в памяти (TTL, 600 с), CORS *. Зеркала — env NNM_BASE / RUTOR_BASE.
Локально: cd tracker-top && go run . (тесты: go test ./... — парсеры
прогоняются на живых снимках страниц из tests/).
Образ собирает CI: ghcr.io/0x3654/tracker-top (multi-stage: deps → test →
build → scratch; тесты валит сборку при сломанном парсере; non-root, healthcheck).
Рабочий инстанс: micro, /git/docker/tracker-top/compose.yaml
(network_mode: host + лейблы tsdproxy tsdproxy.name=micro-tracker +
watchtower) → https://micro-tracker.koi-uaru.ts.net. Нюанс tsdproxy: он
дайлит порты на интерфейсах хоста — контейнер должен быть либо host-сети
(как transmission), либо публиковать порт; общей docker-сети недостаточно.
Сервер переносим: micro, VPN-сервер — в плагине меняется только адрес. В Lampa (https) адрес нужен https — проще всего через tsdproxy (tailnet-домен с сертом).
Клон lostfilmfeed для NNM-Club, модель один в один: главная публична, отдельных логинов нет — passkey трекера и есть личность (как TrackerId у lostfilm). Ввёл свой passkey → открылась твоя страница с подписками и историями.
Passkey — постоянный ключ NNM-Club из трекер-URL любого своего торрента
(bt02.nnm-club.cc:2710/<passkey>/announce), никогда не истекает. Статистика:
ленты отдают магниты с персональным announce юзера — клиент аннонсит его
ключом, раздачи зачисляются ему. Гостю виден только магнит главной раздачи
темы (у постов-эпизодов магнитов нет, download.php по passkey — 404,
логин по паролю — капча), поэтому единица подписки на раздачу = текущая
главная раздача: батч обновился (новый hash) → новый item, клиент скачает
обновление.
Четыре ленты на профиль (время — TZ_OFFSET, по умолчанию +4):
| Лента | URL | Что внутри |
|---|---|---|
| Авто | /rss/<pk> |
подписки с тумблером «авто» — слежение за изменением конкретных раздач |
| Общая | /rss/<pk>/all |
все подписки (разделы = вариант поиска: смотреть без автоскачивания) |
| Топ 7 дней | /rss/<pk>/top/7 |
популярное по сидам за окно |
| Топ 14 дней | /rss/<pk>/top/14 |
то же, окно шире |
rss.php?f=&t=1 — новые раздачи) или раздача
(rss.php?topic= — изменение главной раздачи); вставка любой ссылки —
ссылку на пост сервис сам конвертирует в тему и тянет название+постерPUT /api/forums/data (без внешней БД); «сессия» — кука
с самим passkey на годenv: NNM_BASE, PORT (8356), DATA_DIR (/data), TTL (600),
TZ_OFFSET (4)
GET / публичная главная + «Моя подписка» POST /api/open открыть свою страницу по passkey (кука) GET /api/forums, PUT /api/forums разделы топ-лент (галки) GET /rss/{passkey}[/all|/top/{7|14}] GET /healthz
Тесты: в контейнере — docker run --rm -v "$PWD":/src -w /src -v nnm-gomod:/go/pkg/mod
golang:1.27-alpine go test ./... (парсеры на живых снимках из tests/).
Образ: ghcr.io/0x3654/nnm-rss (CI, deps → test → build → scratch, non-root,
healthcheck). Инстанс: micro, /git/docker/nnm-rss/compose.yaml (host-сеть +
tsdproxy micro-nnm). Ленту transmission-rss на том же хосте берёт с
http://127.0.0.1:8356/rss/<passkey>.
В порядке появления (наши — после встроенных пунктов Lampa):
| Пункт | Когда показывается | Что делает |
|---|---|---|
| Скопировать магнет | есть магнет | магнет в буфер обмена |
| Открыть магнет (всегда последним) | есть магнет | window.location = magnet: → системный обработчик схемы |
«Скачать .torrent» убран: у раздач почти никогда нет прямой http-ссылки, пункт был вечно пустой.
Сценарии:
magnet:
(например, Transmission Remote GUI) → добавление на сервер. Запасной путь:
«Скопировать магнет» → вставить в TRG.Системного UI для схем нет; переключается записью в LaunchServices
(TRG здесь для примера, bundle id com.transgui):
defaults write com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers \
-array-add '<dict><key>LSHandlerURLScheme</key><string>magnet</string>\
<key>LSHandlerRoleAll</key><string>com.transgui</string></dict>'
killall lsd
Проверить: open 'magnet:?xt=urn:btih:0000000000000000000000000000000000000000'.
Bundle id любого приложения: osascript -e 'id of app "Имя"'.
Тесты — в контейнерах (хост не пачкаем):
docker run --rm -v "$PWD":/src -w /src node:24-alpine node smoke-top.js — top-плагинdocker run --rm -v "$PWD":/src -w /src node:24-alpine node smoke-test.js — transmission-senddocker run --rm -v "$PWD"/tracker-top:/src -w /src golang:1.27-alpine go test ./... — парсеры/фильтры/дедупLampa.Listener('torrent'/'torrent_file', onlong) — официальная точка
расширения (пуш пунктов в e.menu с собственным onSelect), проверено по
исходникам Lampa 3.3.3 (github.com/yumata/lampa-source)Lampa.InteractionCategory (нативные карточки/пагинация,
приём официального плагина collections) + Lampa.Api.sources.tmdb.get;
меню: Lampa.Menu.addButton; настройки: Lampa.SettingsApi