feat(ingest+поиск): приём ZIP через интерфейс, регистронезависимый поиск, чистка очереди
- Загрузка архива (§4.1): POST /ingest распаковывает ZIP, дораспознаёт и догружает прайсы в базу (append). Виджет в админке. Кэш эмбеддингов справочника (dict_emb.npy) — догрузка считает только новый файл, эмбеддинги best-effort с откатом на fuzzy при сбое Gemini. - Поиск по name_norm (lowercase): «УЗИ» и «узи» дают одинаковый результат — SQLite LIKE не сворачивает регистр для кириллицы. - Фильтр названий: код-мнемоники («МОЗО.15») больше не попадают в очередь. - /stats считается из базы — цифры на дашборде обновляются после загрузки. - Деплой через Dockerfile (зависимости в образе, код монтируется томом). - ruff: ядро и весь репозиторий проходят проверку. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
многолистовых книг и многотабличных PDF. Сырой текст нужен для аудита и для
|
||||
детектора битого текстового слоя.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
@@ -29,14 +30,19 @@ def partner_from_name(name: str) -> str:
|
||||
|
||||
def detect_format(path: str) -> str:
|
||||
ext = Path(path).suffix.lower()
|
||||
return {".xlsx": "xlsx", ".xls": "xls", ".docx": "docx", ".pdf": "pdf"}.get(ext, ext.lstrip("."))
|
||||
return {".xlsx": "xlsx", ".xls": "xls", ".docx": "docx", ".pdf": "pdf"}.get(
|
||||
ext, ext.lstrip(".")
|
||||
)
|
||||
|
||||
|
||||
def docx_grids(path: str) -> tuple[list[Grid], str]:
|
||||
import docx
|
||||
|
||||
document = docx.Document(path)
|
||||
grids = [[[clean(cell.text) for cell in row.cells] for row in table.rows] for table in document.tables]
|
||||
grids = [
|
||||
[[clean(cell.text) for cell in row.cells] for row in table.rows]
|
||||
for table in document.tables
|
||||
]
|
||||
text = "\n".join(p.text for p in document.paragraphs)
|
||||
return grids, text
|
||||
|
||||
|
||||
Reference in New Issue
Block a user