4 Commits

Author SHA1 Message Date
Andrey Epifancev
83e55af941 Срез 0 [7.2, fix T2.1 T2.2 T2.4]: горячие папки — повторный листинг после чтения, ENOTDIR в SMB
- T2.1: после чтения набора каталог ответа листается заново (Local и SMB); если снимок (имена и
  размеры) отличается от настоявшегося — None, набор настаивается заново.
- T2.2: SmbHotFolder — ENOTDIR из листинга Output/<job_id> (на месте каталога файл) — None,
  как у LocalHotFolder.
- T2.4: тест SMB — ENOENT / SHARING_VIOLATION / ENOTDIR во время настаивания сбрасывают
  накопленное состояние settle (pending_jobs() == 0).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:18:29 +04:00
Andrey Epifancev
e8453159e8 Срез 0 [7.1]: горячие папки — набор *.json ответа, готовность по settle, служебный каталог Tmp
- HotFolder.poll(job_id) -> list[AnswerFile] | None: все *.json каталога <output>/<job_id>/ по возрастанию
  имени, когда набор не пуст и имена/размеры не менялись SCAN_SETTLE_SECONDS (SettleTracker: состояние по
  job_id, внедряемые часы, сброс при выдаче/опустении, предел 1024 задания, потокобезопасно);
- put: временный .<name>.part в <корень>/<SCAN_TMP_DIR>/ (создаётся), rename в Input (Local и SMB);
- настройки SCAN_TMP_DIR (Tmp) и SCAN_SETTLE_SECONDS (2, >= 0); в .env.test settle = 0 (R-23);
- воркер: переходная прослойка — берётся первый файл набора (склейка всех — Task 3, R-22).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:01:39 +04:00
Andrey Epifancev
5fb046fced Срез 0 [4.2] T8.1-T8.3: inbox_name заменяет символы Windows/SMB, poll ждёт занятый файл, put терпит отказ mkdir при существующем Input
T8.1: inbox_name заменяет `: < > " | ? *` и управляющие символы на `_`, убирает завершающие точки/пробелы;
ValueError только если имени не осталось. validate_name/put остаются строгими.
T8.2: SmbHotFolder.poll возвращает None на STATUS_SHARING_VIOLATION/STATUS_DELETE_PENDING (ИС ещё пишет ответ),
монопольное открытие сохранено.
T8.3: при ошибке mkdir, кроме EEXIST/ENOENT, put продолжает, если smbclient.path.isdir(Input); иначе исходная ошибка.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 03:05:02 +04:00
Andrey Epifancev
1695573b35 Срез 0 [4.2]: SmbHotFolder поверх smbclient (src/gateway/smb.py), фабрика create_hotfolder, unit-тесты, отметка задачи
SmbHotFolder: UNC-корень \\host\SMB_PATH (или полный UNC в SMB_PATH), put — `.<name>.part` + smbclient.replace,
poll — open_file(rb), ENOENT (в т.ч. нет каталога) -> None, healthy — listdir корня без исключений.
create_hotfolder(settings): local -> LocalHotFolder, smb -> SmbHotFolder с ленивым импортом модуля (R-6);
отсутствие импорта src.gateway.smb в режиме local проверяется в отдельном интерпретаторе.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 02:57:31 +04:00