Программа принимает папку с документами, извлекает из них текст и метаданные и строит каталог: краткое описание, тезисы и ключевые слова для каждого файла плюс поиск по всему собранному. Ядро: - 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>
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""@file app.py
|
||
@brief Точка входа графического приложения каталогизатора.
|
||
|
||
Собирает QApplication и главное окно. С ключом ``--check`` окно строится,
|
||
но не показывается: так проверяется собранный exe, где traceback показать
|
||
некому.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
from PySide6.QtCore import Qt
|
||
from PySide6.QtWidgets import QApplication
|
||
|
||
from .ui.main_window import MainWindow
|
||
|
||
|
||
def _set_windows_app_id() -> None:
|
||
"""@brief Закрепляет собственную группу приложения на панели задач Windows."""
|
||
if sys.platform != "win32":
|
||
return
|
||
try:
|
||
import ctypes
|
||
|
||
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
|
||
"SET.Catalogizer")
|
||
except (AttributeError, OSError):
|
||
pass
|
||
|
||
|
||
def main(argv: list[str] | None = None) -> int:
|
||
"""@brief Запускает окно каталогизатора.
|
||
|
||
@param argv Аргументы без имени программы: путь к папке и/или ``--check``.
|
||
@return Код выхода приложения.
|
||
"""
|
||
argv = list(sys.argv[1:] if argv is None else argv)
|
||
check = "--check" in argv
|
||
folders = [a for a in argv if not a.startswith("-")]
|
||
|
||
_set_windows_app_id()
|
||
QApplication.setHighDpiScaleFactorRoundingPolicy(
|
||
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
|
||
application = QApplication(sys.argv[:1])
|
||
application.setApplicationName("Каталогизатор")
|
||
application.setOrganizationName("SET")
|
||
|
||
window = MainWindow(Path(folders[0]) if folders else None)
|
||
if check:
|
||
# Самопроверка сборки: окно строится целиком и приложение выходит.
|
||
application.processEvents()
|
||
titles = [window.tabs.tabText(i) for i in range(window.tabs.count())]
|
||
print("Каталогизатор: вкладок", len(titles), "-", ", ".join(titles))
|
||
return 0
|
||
window.show()
|
||
return application.exec()
|