443 lines
8.4 KiB
Markdown
443 lines
8.4 KiB
Markdown
# PROJECT_STATE.md
|
||
|
||
# Anime Automation Project
|
||
|
||
Версия документа: 0.1
|
||
|
||
Последнее обновление: 2026-06-27
|
||
|
||
---
|
||
|
||
# 1. Цель проекта
|
||
|
||
Разработать полностью автоматизированный pipeline обработки новых аниме-релизов после завершения скачивания через qBittorrent.
|
||
|
||
Автоматизация должна работать в локальном экземпляре n8n и выполнять все операции без участия пользователя.
|
||
|
||
---
|
||
|
||
# 2. Окружение
|
||
|
||
## n8n
|
||
|
||
* Version: 2.26.8
|
||
* Deployment: Docker
|
||
* Доступ осуществляется по HTTPS через доменное имя.
|
||
|
||
## Torrent Client
|
||
|
||
* qBittorrent
|
||
* Загрузка через RSS
|
||
* После окончания скачивания вызывается Bash Script.
|
||
* Bash Script отправляет HTTP POST в Webhook n8n.
|
||
|
||
## NAS
|
||
|
||
* Synology DSM
|
||
* Доступ только по SSH
|
||
* Python3 установлен
|
||
* 7z установлен
|
||
* crc32 отсутствует
|
||
* rhash отсутствует
|
||
* 7zz отсутствует
|
||
|
||
---
|
||
|
||
# 3. Архитектурные решения
|
||
|
||
## Решение №1
|
||
|
||
Вся бизнес-логика находится в n8n.
|
||
|
||
На NAS не создаются дополнительные Python-скрипты.
|
||
|
||
Причина:
|
||
|
||
* переносимость
|
||
* отсутствие зависимости от конкретного NAS
|
||
* простота резервного копирования
|
||
* вся автоматизация хранится в одном месте
|
||
|
||
Статус:
|
||
|
||
ПРИНЯТО
|
||
|
||
---
|
||
|
||
## Решение №2
|
||
|
||
NAS используется исключительно как:
|
||
|
||
* файловое хранилище
|
||
* SSH endpoint
|
||
|
||
Статус:
|
||
|
||
ПРИНЯТО
|
||
|
||
---
|
||
|
||
## Решение №3
|
||
|
||
Все вычисления выполняются средствами:
|
||
|
||
* SSH Node
|
||
* Code Node
|
||
* HTTP Request
|
||
* IF
|
||
* Merge
|
||
* Set
|
||
|
||
Статус:
|
||
|
||
ПРИНЯТО
|
||
|
||
---
|
||
|
||
## Решение №4
|
||
|
||
Разработка ведется небольшими шагами.
|
||
|
||
Каждый следующий шаг начинается только после проверки предыдущего.
|
||
|
||
Статус:
|
||
|
||
ПРИНЯТО
|
||
|
||
---
|
||
|
||
## Решение №5
|
||
|
||
Если возникает необходимость изменить ранее предложенное решение, обязательно фиксируются:
|
||
|
||
* что изменилось;
|
||
* почему изменилось;
|
||
* нужно ли переделывать предыдущие шаги.
|
||
|
||
Статус:
|
||
|
||
ПРИНЯТО
|
||
|
||
---
|
||
|
||
# 4. Правила разработки
|
||
|
||
Работа ведется исключительно для n8n 2.26.8.
|
||
|
||
Не использовать рекомендации для других версий.
|
||
|
||
Перед созданием новой Node необходимо:
|
||
|
||
1. Указать тип Node.
|
||
2. Указать название Node.
|
||
3. Полностью привести настройки.
|
||
4. Полностью привести код.
|
||
5. Объяснить механизм работы.
|
||
6. Описать ожидаемый результат.
|
||
7. Описать способ проверки.
|
||
|
||
Если синтаксис конкретной Node вызывает сомнение, сначала создается минимальный тест (MRT), затем используется проверенный шаблон.
|
||
|
||
Никогда не выдавать предположения за проверенные решения.
|
||
|
||
Каждое утверждение должно иметь один из статусов:
|
||
|
||
* ФАКТ
|
||
* ГИПОТЕЗА
|
||
* РЕКОМЕНДАЦИЯ
|
||
|
||
---
|
||
|
||
# 5. Особенности SSH Node
|
||
|
||
Подтверждено экспериментально.
|
||
|
||
Command в режиме Expression должен использовать синтаксис:
|
||
|
||
{{'команда'}}
|
||
|
||
Например:
|
||
|
||
{{'echo test'}}
|
||
|
||
Preview:
|
||
|
||
echo test
|
||
|
||
Рабочий пример:
|
||
|
||
{{'python3 -c 'print("OK")''}}
|
||
|
||
Preview:
|
||
|
||
python3 -c 'print("OK")'
|
||
|
||
Данный шаблон использовать для всех последующих SSH-команд.
|
||
|
||
---
|
||
|
||
# 6. Реализованные этапы
|
||
|
||
## ✔ Webhook
|
||
|
||
Получает:
|
||
|
||
name
|
||
|
||
savepath
|
||
|
||
hash
|
||
|
||
Проверено.
|
||
|
||
---
|
||
|
||
## ✔ Normalize
|
||
|
||
Формирует единый формат данных.
|
||
|
||
Результат:
|
||
|
||
received_at
|
||
|
||
torrent_name
|
||
|
||
save_path
|
||
|
||
torrent_hash
|
||
|
||
Проверено.
|
||
|
||
---
|
||
|
||
## ✔ Parse Release
|
||
|
||
Поддерживается формат релизов SubsPlease.
|
||
|
||
Получаются поля:
|
||
|
||
group
|
||
|
||
title
|
||
|
||
episode
|
||
|
||
resolution
|
||
|
||
crc
|
||
|
||
extension
|
||
|
||
Проверено.
|
||
|
||
---
|
||
|
||
## ✔ Check File Exists
|
||
|
||
Через SSH проверяется наличие скачанного файла.
|
||
|
||
Проверено.
|
||
|
||
---
|
||
|
||
## ✔ Calculate CRC
|
||
|
||
Через SSH и Python3 вычисляется CRC32 скачанного файла.
|
||
|
||
Проверено.
|
||
|
||
Пример результата:
|
||
|
||
8D8395C0
|
||
|
||
---
|
||
|
||
## ✔ Compare CRC
|
||
|
||
Code Node сравнивает:
|
||
|
||
CRC из имени релиза
|
||
|
||
с
|
||
|
||
CRC вычисленным по содержимому файла.
|
||
|
||
Результат:
|
||
|
||
crc_match = true
|
||
|
||
Проверено.
|
||
|
||
---
|
||
|
||
# 7. Текущее состояние Workflow
|
||
|
||
Webhook
|
||
|
||
↓
|
||
|
||
Normalize
|
||
|
||
↓
|
||
|
||
Parse Release
|
||
|
||
↓
|
||
|
||
Check File Exists
|
||
|
||
↓
|
||
|
||
Calculate CRC
|
||
|
||
↓
|
||
|
||
Compare CRC
|
||
|
||
Все перечисленные узлы полностью реализованы и протестированы.
|
||
|
||
---
|
||
|
||
# 8. Текущая точка остановки
|
||
|
||
Последняя успешно протестированная Node:
|
||
|
||
Compare CRC
|
||
|
||
Последний подтвержденный результат:
|
||
|
||
crc_match = true
|
||
|
||
Ошибок нет.
|
||
|
||
На этом работа предыдущего чата завершена.
|
||
|
||
---
|
||
|
||
# 9. Следующий шаг
|
||
|
||
Создать IF Node.
|
||
|
||
Название:
|
||
|
||
Check CRC
|
||
|
||
Условие:
|
||
|
||
crc_match == true
|
||
|
||
Ветка TRUE:
|
||
|
||
Продолжить обработку.
|
||
|
||
Ветка FALSE:
|
||
|
||
Завершить Workflow.
|
||
|
||
(Уведомление об ошибке будет реализовано позднее.)
|
||
|
||
До создания IF Node не переходить к интеграции с AniList.
|
||
|
||
---
|
||
|
||
# 10. Backlog
|
||
|
||
После успешного создания IF Node реализовать:
|
||
|
||
1.
|
||
|
||
Интеграцию с AniList.
|
||
|
||
Получить:
|
||
|
||
* ID
|
||
* название
|
||
* описание
|
||
* жанры
|
||
* постер
|
||
* баннер
|
||
|
||
2.
|
||
|
||
Спроектировать структуру медиатеки.
|
||
|
||
Максимальная совместимость с Kodi.
|
||
|
||
3.
|
||
|
||
Создать каталоги.
|
||
|
||
4.
|
||
|
||
Создать hardlink.
|
||
|
||
5.
|
||
|
||
Создать metadata.
|
||
|
||
На первом этапе допускается хранение в виде отдельных файлов.
|
||
|
||
Позже перейти к полноценным NFO.
|
||
|
||
6.
|
||
|
||
Настроить SMTP.
|
||
|
||
7.
|
||
|
||
Отправлять итоговое уведомление.
|
||
|
||
---
|
||
|
||
# 11. Журнал архитектурных решений
|
||
|
||
2026-06-27
|
||
|
||
Отказались от варианта размещения Python-скриптов на NAS.
|
||
|
||
Причина:
|
||
|
||
Вся логика должна находиться в n8n.
|
||
|
||
NAS не должен содержать бизнес-логику.
|
||
|
||
Статус:
|
||
|
||
ПРИНЯТО.
|
||
|
||
---
|
||
|
||
2026-06-27
|
||
|
||
Для проверки целостности релизов SubsPlease принято использовать CRC, содержащийся в имени файла.
|
||
|
||
Сравнение производится с CRC, вычисленным по содержимому файла.
|
||
|
||
Получение CRC с сайта релизной группы признано избыточным.
|
||
|
||
Статус:
|
||
|
||
ПРИНЯТО.
|
||
|
||
---
|
||
|
||
# 12. Правило продолжения проекта
|
||
|
||
Каждый новый чат начинается с чтения данного документа.
|
||
|
||
После этого определяется:
|
||
|
||
1.
|
||
|
||
Какой этап завершен.
|
||
|
||
2.
|
||
|
||
Какой этап является следующим.
|
||
|
||
Только после этого предлагаются новые Node.
|
||
|
||
После завершения каждого этапа данный документ обновляется.
|
||
|
||
Этот документ является единственным источником актуального состояния проекта.
|