Перейти к содержанию

Workflow процесса сканирования и записи на диск

Основной процесс сканирования

1. Запуск сканирования
2. Инициализация (TMDBClient, MediaDatabase, MediaScanner)
3. Базовое сканирование (сканируются папки "фильмы" и "сериалы")
4. Классификация медиа через TMDB + Gemini (PersistentGenreClassifier)
5. Поиск дубликатов между дисками (db.update_duplicates)
6. Назначение порядковых номеров (db.assign_numbers)
7. Глубокое сканирование сериалов (эпизоды)
8. Поиск торрентов и исправление путей
9. Генерация отчётов (JSON и Markdown)
10. Аудит (сверка с физическим наличием)
11. Назначение категорий и меток торрентам
12. Отчет о дубликатах
13. Открытие отчёта в браузере

Модули

Модуль Назначение
media_scanner.py Классы TMDBClient и MediaScanner для сканирования файловой структуры и получения данных из TMDB API
media_auditor.py Класс MediaAuditor для сверки данных БД с физическим наличием файлов на диске и состоянием торрентов
genre_classifier.py Классы GenreClassifier и PersistentGenreClassifier для классификации медиа по жанрам через TMDB и Gemini
report_generator.py Функции export_disk_json, export_disk_md для экспорта данных из БД в JSON и Markdown
media_rebuild.py Функция rebuild_db для консолидации дублирующихся записей в БД
media_tracker.py Утилиты для фильтрации путей, поиска торрентов, назначения категорий

Структура базы данных

Правило: Структура записи определяется полем media_type[movie, serial, season, episode]

Логическая иерархия: episode → season → serial (эпизод принадлежит сезону, сезон принадлежит сериалу)

Связи: - Для season: parent_id указывает на id сериала - Для episode: parent_id указывает на id сезона

Структура таблицы media:

Поле Тип Описание
disk_name TEXT Имя диска
path TEXT Полный путь к файлу/папке
number INTEGER Порядковый номер
title TEXT Название медиа
title_orig TEXT Оригинальное название
title_ru TEXT Русское название
type TEXT Тип: movie, series, season, episode
year INTEGER Год
main_category TEXT Основная категория
country TEXT Страна
genres TEXT JSON-массив жанров
directors TEXT JSON-массив режиссёров
cast TEXT JSON-массив актёров
num_of_seasons INTEGER Количество сезонов (для сериалов)
num_episodes_per_season TEXT JSON-массив количества серий по сезонам
status TEXT Статус (для сериалов)
rating TEXT JSON-объект с оценками (IMDb, TMDB)
awards TEXT JSON-массив наград
plot TEXT Сюжет
atmosphere TEXT Атмосфера
why_watch TEXT Почему стоит смотреть
mood TEXT Настроение
final_verdict TEXT Финальный вердикт
can_stop_at TEXT Можно остановиться после (сезон/серия)
quote TEXT Цитата
facts TEXT JSON-массив интересных фактов
similar TEXT JSON-массив похожих медиа
parent_id INTEGER ID родительского элемента (для season/episode)
episode_scan_skipped INTEGER 1 если сканирование эпизодов пропущено для длинного сериала, 0 — если выполнено

Правила заполнения полей по типам:

Тип num_of_seasons num_episodes_per_season parent_id
movie игнорируется игнорируется 0 или NULL
series количество сезонов сериала JSON-массив количества серий по сезонам 0 или NULL
season игнорируется JSON-массив количества серий сезона (обычно [n]) ID сериала
episode игнорируется игнорируется ID сезона

Примечания: - Для movie и series поле parent_id равно 0 или NULL - Все JSON-поля хранятся как TEXT в SQLite и автоматически десериализуются при чтении

Взаимодействие с моделью Gemini

Логика запросов:

1. Для фильма (movie)

Запрос: "Напиши подробную карточку фильма [название]" Ожидаемый формат: JSON как в примере фильма в instruction.md

2. Для сериала (series)

Запрос: "Напиши подробную карточку сериала [название] (все сезоны)" Ожидаемый формат: JSON как в примере сериала в instruction.md, с массивом seasons

Умное сканирование эпизодов: - Система проверяет количество сезонов и общее количество эпизодов через TMDB API - Если сезонов > 15 ИЛИ общее количество эпизодов > 100, или сериал является длинным ежедневным шоу: - Запрос детальных эпизодов к Gemini пропускается (или переключается на overview) - В БД сохраняется episode_scan_skipped = true - Аудит пропускает проверку количества эпизодов

3. Для сезона (season)

Запрос: "Напиши подробную карточку [номер] сезона сериала [название]" Ожидаемый формат: JSON с полями: - Все поля как для фильма (title, plot, atmosphere, rating, facts, similar, review и т.д.) - season_number — номер сезона - episodes — массив эпизодов с episode_number, begins, ends, final_verdict - final_verdict — вердикт по сезону - parent_id указывает на ID сериала

4. Для эпизода (episode)

Запрос: "Напиши подробное описание [номер] эпизода [номер] сезона сериала [название]" Ожидаемый формат: JSON с полями: - Все поля как для фильма (title, plot, atmosphere, rating, facts, similar, review и т.д.) - episode_number — номер эпизода - season_number — номер сезона - parent_id указывает на ID сезона

Примечание: Запросы для эпизодов и сезонов выполняются только если сериал прошёл проверку на длину (сезонов ≤ 15 и эпизодов ≤ 100). Для длинных сериалов генерация детальной разбивки пропускается.

Общие правила: - Для всех типов заполняются одинаковые поля (как для фильма) - Разница только в иерархии связи через parent_id - num_of_seasons, num_episodes_per_season, status — только для сериала - Размер plot: 100-150 слов - Размер liked, disliked: 10-20 слов каждый - Размер atmosphere: ~15 слов