Files
catalog_doc/README.md
Andrey Kruchinkin 49f91247c7 Каталогизатор документов: разбор папки, тезисы, поиск, GUI
Программа принимает папку с документами, извлекает из них текст и
метаданные и строит каталог: краткое описание, тезисы и ключевые слова
для каждого файла плюс поиск по всему собранному.

Ядро:
- extract: PDF, DJVU, DOC(X), RTF, ODT, CHM, EPUB, FB2, PPT(X), XLS(X), TXT;
  PDF передаётся MuPDF потоком в память (работают длинные пути) и ограничен
  по времени — повреждённый файл иначе чинится минутами;
- summarize: экстрактивное реферирование по TF-IDF, посчитанному на самой
  библиотеке, с лёгким стеммером для русского и английского;
- db: SQLite с полнотекстовым индексом FTS5, морфологический поиск с BM25;
- scanner: инкрементальный многопоточный обход, счётчик попыток защищает
  от файла, обрывающего разбор;
- report: автономный HTML с поиском, Markdown, JSON, CSV.

Интерфейс:
- окно PySide6 в тёмной теме: вкладки разбора и поиска, фоновый поток,
  карточка документа, правка своих ключевых слов;
- командная строка: build, scan, analyze, report, search, show, tag, stats;
- у каждой папки свой каталог, последняя обработанная запоминается.

Сборка: scripts/build_exe.py даёт Catalogizer.exe в Windows и
Catalogizer.app в macOS, иконки .ico и .icns рисуются кодом.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 19:20:29 +03:00

16 KiB
Raw Blame History

Каталогизатор документов

Программа принимает папку с документами, разбирает её и строит каталог: для каждого файла — краткое описание, тезисы и ключевые слова, плюс поиск по каталогу — в окне программы, в командной строке и в автономной HTML-странице.

Всё работает локально: файлы только читаются, никаких обращений в сеть.

Программа работает в Windows, macOS и Linux — исходники одни и те же.

Запуск

Windows — двойной щелчок по CATALOG.bat или dist\Catalogizer.exe. macOS — двойной щелчок по CATALOG.command или dist/Catalogizer.app. Ни Python, ни библиотек при этом не требуется.

Из исходников (любая система):

pip install -r requirements.txt
python catalog_gui.py

Окно программы

Две вкладки:

  • Разбор папки — поле пути и «Обзор…», параметры (потоков чтения, страниц на документ, «перечитать всё заново»), кнопки «Построить каталог» и «Остановить», индикатор хода работы и журнал. Разбор идёт в фоновом потоке, окно не подвисает; остановка безопасна — разобранное уже в базе, следующий запуск продолжит с того же места.
  • Каталог и поиск — строка поиска, фильтры по формату, языку и разделу, таблица найденного и карточка документа с описанием, тезисами, ключевыми словами и фрагментом текста с подсветкой. Двойной щелчок открывает документ, «Показать в папке» — проводник на нём.

Кнопки «Пересобрать отчёты» и «Открыть HTML-каталог» — на вкладке разбора.

Командная строка

Папка — обычный аргумент:

python catalog.py build "E:\Yandex.Disk\литература"
Команда Что делает
gui [ПАПКА] графическое окно (то же, что запуск без аргументов)
scan ПАПКА обход папки, извлечение текста и метаданных в базу
analyze ключевые слова, тезисы и описания по всей библиотеке
report выгрузка catalog.html, catalog.md, catalog.json, catalog.csv
build ПАПКА полный цикл: scan + analyze + report
search ЗАПРОС поиск по каталогу
show ID|ИМЯ карточка одного документа
tag ДОКУМЕНТ СЛОВА свои ключевые слова документа
stats сводка: форматы, разделы, частые темы

Последняя обработанная папка запоминается, поэтому дальше путь можно не повторять: python catalog.py search "инвертор". Обратиться к другому каталогу — ключ -c: python catalog.py -c "D:\books" stats.

У каждой папки своя база (catalogs/<имя>-<хеш>.db) и своя папка отчётов (out/<имя>-<хеш>/), каталоги разных папок не смешиваются.

Полезные ключи scan/build:

python catalog.py scan --ext pdf djvu     # только выбранные форматы
python catalog.py scan --max-pages 40     # читать больше страниц из каждого файла
python catalog.py scan --jobs 8           # потоков чтения: HDD 2-4, SSD 8-16
python catalog.py scan --limit 50         # пробный прогон на 50 файлах
python catalog.py scan --force            # перечитать всё заново
python catalog.py scan --retry-broken     # снова попробовать «битые» файлы

Поиск

python catalog.py search "инвертор"
python catalog.py search "цифровая обработка сигналов" -n 30
python catalog.py search stm32 dma --ext pdf
python catalog.py search "операционный усилитель" --lang ru --year-from 2010
python catalog.py search "\"частотное преобразование\""   # точная фраза
python catalog.py search fpga -verilog                    # минус — исключить слово
python catalog.py search can --section datasheet          # только в разделе

Поиск морфологический: слова приводятся к основе, поэтому «инвертор» находит «инверторы» и «инвертора». Ранжирование — BM25 с повышенным весом названия и ключевых слов; в выдаче показывается фрагмент текста с подсветкой.

Свои ключевые слова

Кроме слов, вычисленных из текста, к любому документу можно добавить свои — рубрику, проект, пометку «нужное». Они полноправно участвуют в поиске и даже весят в нём больше вычисленных.

В окне: выбрать документ, вписать слова через запятую в строку «Свои ключевые слова» под карточкой и нажать «Сохранить» (или Enter, или Ctrl+S). При вводе подсказываются слова, уже заведённые в этом каталоге.

В командной строке:

python catalog.py tag opamp "силовая электроника, к проекту А"   # добавить
python catalog.py tag 137 --remove "к проекту А"                 # убрать
python catalog.py tag 137 --set "только это"                     # заменить список
python catalog.py tag 137 --set                                  # очистить
python catalog.py tag 137                                        # показать
python catalog.py tag --all                                      # все слова каталога
python catalog.py search "к проекту А"                           # найти помеченные

Документ указывается номером id или частью имени, пути либо названия.

Слова хранятся отдельно от результатов разбора и привязаны к пути файла, поэтому переживают повторный разбор папки и перестроение каталога. В отчёты они попадают отдельной строкой («Свои ключевые слова»), в HTML-каталоге выделены цветом, в CSV — отдельной колонкой.

Отчёты

После report в папке out/:

  • catalog.html — автономная страница: поиск по мере ввода, фильтры, тезисы и ключевые слова у каждого документа, ссылки на файлы. Открывается двойным щелчком, без сервера;
  • catalog.md — каталог по разделам для чтения и печати;
  • catalog.json, catalog.csv — выгрузка для других программ (CSV с BOM, открывается в Excel).

Как строятся описания и тезисы

Реферирование экстрактивное — фразы берутся из самого документа, ничего не досочиняется:

  1. из файла читаются первые --max-pages страниц, оглавление и метаданные;
  2. слова приводятся к основе (лёгкий стеммер для русского и английского), считаются частоты; слова из названия и оглавления получают больший вес;
  3. по всей библиотеке считается IDF — так отсеиваются слова, общие для всей техлитературы, и остаются характерные именно для этого документа;
  4. ключевые слова — верхние основы по TF-IDF, показанные самой короткой частой словоформой;
  5. тезисы — предложения с наибольшей плотностью ключевых слов, с бонусом началу документа (аннотация, введение) и оборотам вида «рассматривается», «предназначено», this book describes; близкие по составу фразы отбрасываются;
  6. описание — тип издания, язык, объём, темы и первый тезис.

Для сканов без текстового слоя тезисы берутся из оглавления PDF, а если его нет — документ попадает в каталог с пометкой «скан» и описанием по имени файла. Найти такие файлы: python catalog.py stats.

Форматы и внешние утилиты

Разбираются PDF, DJVU, DOC, DOCX, RTF, ODT, CHM, EPUB, FB2, PPT, PPTX, XLS, XLSX, TXT, MD. Обязательна только pymupdf (PDF); дополнительно, если есть в PATH:

  • antiword — качественный разбор старых .doc (иначе грубая выборка строк);
  • djvutxt из DjVuLibre — текстовый слой .djvu (иначе для DJVU остаются только название, число страниц и раздел).

Сборка исполняемого файла

Сборщик один — scripts/build_exe.py; что получится, зависит от системы, на которой идёт сборка: PyInstaller не умеет собирать под чужую платформу. Программу для macOS собирают на Mac, для Windows — на Windows.

Windowsdist\Catalogizer.exe:

BUILD_EXE.bat --setup      # один раз: .venv с PySide6, pymupdf, PyInstaller
BUILD_EXE.bat              # сборка

macOSdist/Catalogizer.app:

chmod +x BUILD_APP.command CATALOG.command   # один раз, после переноса файлов
./BUILD_APP.command --setup                  # один раз: .venv и зависимости
./BUILD_APP.command                          # сборка

Оба сценария можно просто запустить двойным щелчком. Ключи передаются в scripts/build_exe.py: --onedir (папка вместо одного файла, запускается быстрее; в macOS так всегда — .app и есть папка), --console (оставить консоль для traceback), --cli (собрать ещё и консольную программу catalog). После сборки автоматически выполняется самопроверка --check: окно строится целиком и программа выходит.

Иконки генерируются кодом — python scripts/make_icon.py создаёт ico/catalog.ico для Windows и ico/catalog.icns для macOS.

Куда программа кладёт базы и отчёты: в Windows и Linux — рядом с исполняемым файлом, в macOS — в ~/Library/Application Support/Catalogizer, потому что содержимое .app считается неизменяемым.

Что учтено для macOS

  • пути и \?\-префикс применяются только в Windows;
  • «Показать в папке» открывает Finder на файле (open -R), «Открыть документ» — open;
  • ссылки на файлы в HTML-каталоге строятся из абсолютного пути и работают и с /Users/..., и с E:\...;
  • в теме заданы системные шрифты (SF Pro Text, SF Mono) как замена windows-овским;
  • папка по умолчанию — ~/Documents, если жёстко прописанной библиотеки нет;
  • .command-файлы сохранены с переводами строк LF, иначе bash их не примет.

Первый запуск неподписанного .app macOS блокирует: правой кнопкой по Catalogizer.app → «Открыть» → «Открыть» в диалоге. Либо снять карантин: xattr -dr com.apple.quarantine dist/Catalogizer.app.

Устройство

CATALOG.bat             запуск окна в Windows
CATALOG.command         запуск окна в macOS
BUILD_EXE.bat           сборка exe в Windows
BUILD_APP.command       сборка .app в macOS
catalog_gui.py          точка входа окна (её упаковывает PyInstaller)
catalog.py              точка входа командной строки
catalogizer/
    app.py              сборка QApplication, ключ --check
    config.py           папка по умолчанию, форматы, ограничения разбора
    extract.py          чтение PDF, DJVU, DOC(X), RTF, CHM, EPUB, FB2, XLS(X), TXT
    textutil.py         язык, токенизация, стемминг, разбиение на предложения
    summarize.py        TF-IDF, ключевые слова, тезисы, описание
    scanner.py          обход папки, многопоточное извлечение
    analyze.py          проход анализа по всей базе
    search.py           запросы к полнотекстовому индексу
    report.py           HTML, Markdown, JSON, CSV
    db.py               SQLite + FTS5
    ui/                 тёмная тема, главное окно, вкладки, фоновый поток
scripts/build_exe.py    сборка exe/.app — под ту систему, где запущен
scripts/make_icon.py    генерация иконок .ico и .icns

Замечания по работе

  • Файлы длиннее 260 символов пути читаются через префикс \\?\; PDF передаются MuPDF потоком в память, поэтому нестандартные пути не мешают.
  • Кодировка русских .txt определяется перебором (utf-8, cp1251, koi8-r, cp866).
  • Разбор одного PDF ограничен по времени (PDF_TIME_BUDGET, 25 с): повреждённый файл MuPDF чинит страницу за страницей и может занять минуты.
  • Сбой на файле не останавливает обход: причина сохраняется в поле error и видна в stats. Файл, трижды оборвавший разбор, дальше пропускается — вернуть его в очередь можно ключом --retry-broken.
  • Если папка лежит под управлением клиента синхронизации (Яндекс.Диск, OneDrive), его драйвер может надолго придерживать открытые файлы. На время первого разбора синхронизацию лучше приостановить.