Каталогизатор документов: разбор папки, тезисы, поиск, 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>
This commit is contained in:
58
catalogizer/app.py
Normal file
58
catalogizer/app.py
Normal file
@@ -0,0 +1,58 @@
|
||||
"""@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()
|
||||
Reference in New Issue
Block a user