mirror of
https://gitverse.ru/kpa39l/email-local-archive.git
synced 2026-09-29 09:15:11 +00:00
171 lines
7.6 KiB
Markdown
171 lines
7.6 KiB
Markdown
# Dynamic Folder Discovery — решение для хардкода INBOX_SUBFOLDERS
|
||
|
||
## Контекст
|
||
|
||
`mail_archive.py` содержит захардкоженный `INBOX_SUBFOLDERS` (18 папок).
|
||
На IMAP-сервере реально 137 подпапок INBOX, включая многоуровневые.
|
||
|
||
## Текущее состояние
|
||
|
||
### State-файлы (следы прошлых запусков)
|
||
|
||
```
|
||
/opt/hermes/email/state/
|
||
├── mail-archive-last-Archive.json
|
||
├── mail-archive-last-INBOX.json
|
||
├── mail-archive-last-INBOX_!Scan.json
|
||
├── mail-archive-last-Sent.json
|
||
├── mail-archive-last-folder_41a7755da018.json # хэш от не-ASCII имени
|
||
├── mail-archive-last-folder_5dd417336b45.json
|
||
├── mail-archive-last-folder_6dfd3661f092.json
|
||
├── mail-archive-last-folder_a2d2b831a004.json
|
||
├── mail-archive-last-folder_a59f0da18423.json
|
||
├── mail-archive-last-folder_b002f4b75367.json
|
||
├── mail-archive-last-folder_b8338b886347.json
|
||
├── mail-archive-last-folder_ba130b3adfda.json
|
||
├── mail-archive-last-folder_e5dd3de630eb.json
|
||
```
|
||
|
||
State-файлы уже поддерживают произвольные имена папок (через `get_state_file()` —
|
||
MD5-хэш для не-ASCII). Инфраструктура готова.
|
||
|
||
### Хардкод в mail_archive.py (строки 54-73)
|
||
|
||
```python
|
||
INBOX_SUBFOLDERS = [
|
||
"INBOX/!Scan",
|
||
"INBOX/!Битрикс",
|
||
"INBOX/!ВГ Чек листы",
|
||
"INBOX/!Документооборот",
|
||
"INBOX/!Завки",
|
||
"INBOX/!Материалы",
|
||
"INBOX/!Отчеты",
|
||
"INBOX/!Персонал",
|
||
"INBOX/!Протоколы",
|
||
"INBOX/!Реестр оплаты",
|
||
"INBOX/!Торик",
|
||
"INBOX/Бюджет",
|
||
"INBOX/Контрагенты",
|
||
"INBOX/ЛНД",
|
||
"INBOX/Организация работы",
|
||
"INBOX/Приемка и стройка",
|
||
"INBOX/Системы",
|
||
"INBOX/Эксплуатация",
|
||
]
|
||
```
|
||
|
||
### Реальные папки на сервере (137 шт.)
|
||
|
||
Полный список получен через `himalaya folder list`:
|
||
|
||
```
|
||
INBOX/!Scan
|
||
INBOX/!Битрикс
|
||
INBOX/!ВГ Чек листы
|
||
INBOX/!Документооборот
|
||
INBOX/!Завки
|
||
INBOX/!Материалы
|
||
INBOX/!Отчеты
|
||
INBOX/!Персонал
|
||
INBOX/!Персонал/ОТ и ТБ
|
||
INBOX/!Протоколы
|
||
INBOX/!Реестр оплаты
|
||
INBOX/!Реестр оплаты/Акты
|
||
INBOX/!Реестр оплаты/Закупки
|
||
INBOX/!Реестр оплаты/Закупки/10 рабочих мест
|
||
INBOX/!Реестр оплаты/Закупки/NanoCad
|
||
INBOX/!Реестр оплаты/Закупки/Горизонт Ноутбуки
|
||
INBOX/!Реестр оплаты/Закупки/Дооснащение ТГ
|
||
INBOX/!Реестр оплаты/Закупки/Касперский для ВГ
|
||
INBOX/!Реестр оплаты/Закупки/Модернизация Wi-Fi
|
||
INBOX/!Реестр оплаты/Закупки/Оборудование горизонт
|
||
INBOX/!Реестр оплаты/Закупки/Сервер
|
||
INBOX/!Реестр оплаты/Закупки/Цветной МФУ ТГ
|
||
INBOX/!Торик
|
||
INBOX/Бюджет
|
||
INBOX/Бюджет/Винный город
|
||
INBOX/Бюджет/Винный город/CAPEX 2025
|
||
INBOX/Бюджет/Винный город/Capex 2026
|
||
INBOX/Бюджет/Винный город/OPEX 2025
|
||
INBOX/Бюджет/Винный город/OPEX 2026
|
||
INBOX/Бюджет/Винный город/OPEX 2027
|
||
INBOX/Бюджет/Горизонт
|
||
INBOX/Бюджет/Горизонт/CAPEX 2025
|
||
INBOX/Бюджет/Горизонт/CAPEX 2026
|
||
INBOX/Бюджет/Горизонт/OPEX 2026
|
||
INBOX/Бюджет/Тихая гавань
|
||
INBOX/Бюджет/Тихая гавань/CAPEX 2025
|
||
INBOX/Бюджет/Тихая гавань/CAPEX 2026
|
||
INBOX/Бюджет/Тихая гавань/OPEX 2025
|
||
INBOX/Бюджет/Тихая гавань/OPEX 2026
|
||
INBOX/Контрагенты
|
||
INBOX/Контрагенты/iiko
|
||
INBOX/Контрагенты/iiko/Тихая гавань
|
||
INBOX/Контрагенты/АБ-Транзит
|
||
INBOX/Контрагенты/Аврора
|
||
INBOX/Контрагенты/Ассистент
|
||
INBOX/Контрагенты/Билайн
|
||
INBOX/Контрагенты/Интеллект - ilocks - замки
|
||
INBOX/Контрагенты/Интертех Лицензии Huawei
|
||
INBOX/Контрагенты/Квадротек
|
||
INBOX/Контрагенты/Кит
|
||
INBOX/Контрагенты/Компания АйТи
|
||
INBOX/Контрагенты/Кристалл
|
||
INBOX/Контрагенты/Крым-Строй-Сервис
|
||
INBOX/Контрагенты/Лимон
|
||
INBOX/Контрагенты/Медиа-Сервис
|
||
INBOX/Контрагенты/МеталлПрофиль
|
||
INBOX/Контрагенты/Ново-групп
|
||
INBOX/Контрагенты/Орт-Сервис
|
||
INBOX/Контрагенты/Партнер
|
||
INBOX/Контрагенты/Партнеры
|
||
INBOX/Контрагенты/Пиксель
|
||
INBOX/Контрагенты/Поставщики
|
||
INBOX/Контрагенты/Рубикон-С
|
||
INBOX/Контрагенты/СБСС
|
||
INBOX/Контрагенты/Самоваръ
|
||
INBOX/Контрагенты/Сервисный центр
|
||
INBOX/Контрагенты/Смарт
|
||
INBOX/Контрагенты/СпецТехМонтаж
|
||
INBOX/Контрагенты/Стрим
|
||
INBOX/Контрагенты/СтройПартнер
|
||
INBOX/Контрагенты/ТД ТрансМет
|
||
INBOX/Контрагенты/ТД Лайт
|
||
INBOX/Контрагенты/Технологии Доверия
|
||
INBOX/Контрагенты/Технополис
|
||
INBOX/Контрагенты/Типография
|
||
INBOX/Контрагенты/УралТрансПром
|
||
INBOX/Контрагенты/Физ лица
|
||
INBOX/Контрагенты/Цифровые решения
|
||
INBOX/Контрагенты/ЭнергоСпецКомплект
|
||
INBOX/Контрагенты/Энергия
|
||
INBOX/Контрагенты/Югспецодежда
|
||
INBOX/ЛНД
|
||
INBOX/Организация работы
|
||
INBOX/Приемка и стройка
|
||
INBOX/Системы
|
||
INBOX/Эксплуатация
|
||
```
|
||
|
||
## План исправления
|
||
|
||
1. В `mail_archive.py` заменить `INBOX_SUBFOLDERS` на функцию `get_all_folders()`:
|
||
- `himalaya folder list --output json`
|
||
- Фильтр: папки, начинающиеся с `INBOX/` (исключить Trash, Drafts, RSS, Archives)
|
||
- Исключить `INBOX` (корневую — она уже в `FOLDERS`)
|
||
|
||
2. `--all` должен использовать `FOLDERS + get_all_inbox_subfolders()` вместо `FOLDERS + INBOX_SUBFOLDERS`
|
||
|
||
3. `mail-archive-every-5min` cron автоматически получит новые папки без изменения конфигурации
|
||
|
||
4. State-файлы уже готовы — `get_state_file()` работает с любыми именами папок
|
||
|
||
## Edge cases
|
||
|
||
- Папки могут исчезнуть между запусками — `archive_folder()` уже обрабатывает
|
||
`No such folder` через `get_envelopes()` (возвращает `[]`)
|
||
- Новая папка без писем — `get_envelopes()` вернёт пустой список, state не создаётся
|
||
- Папки с `\HasNoChildren` и `\HasChildren` — `himalaya folder list` показывает все
|
||
(независимо от флагов), так что фильтр по `\HasNoChildren` не нужен
|
||
- Очень глубокие папки (3-4 уровня) — `get_state_file()` через MD5-хэш поддерживает
|
||
любую длину имени |