Files
janssen/claude-memory/project_mailstore.md
2026-06-13 21:45:28 +02:00

11 KiB
Raw Permalink Blame History

name, description, metadata
name description metadata
project-mailstore MailStore Server na 192.168.1.53 — archiv emailů, Management API, IMAP přístup, Claws Mail klient
node_type type originSessionId
memory project 49cbd8a2-c71e-49be-8c52-59dfa5ac7680

MailStore Server v26.2.1.24065 na 192.168.1.53 (hostname MAILSTORE, Win). Archiv ~2,3 mil emailů, data na Z:\MailArchive. Největší schránka vladimir.buzalka@buzalka.cz: 1 077 799 zpráv / 273 GB.

Přístupy:

  • Windows admin (WinRM): administrator / Vlado7309208104++. WinRM remoting funguje z U:/janssen PC (TrustedHosts nastaveno).
  • MailStore admin: admin / *$N(B)vMUym!%

Management API (HTTPS, port 8463): zapnuté v configu MailStoreServer.json (API via HTTPS Configuration.Enabled=true). Volá se POST https://192.168.1.53:8463/api/invoke/<Funkce>, Basic Auth, parametry jako form body (application/x-www-form-urlencoded), ne JSON. Self-signed cert → -SkipCertificateCheck. Async operace vrátí token+statusCode=running, výsledek se poluje přes POST /api/get-status (params token, lastKnownStatusVersion, millisecondsTimeout); result je v poslední odpovědi po succeeded. ~90 funkcí (GetUsers, GetStores, GetMessages, GetChildFolders, GetFolderStatistics, RunProfile, CreateBackup…). Dokumentace: help.mailstore.com/en/server/Administration_API_-_Function_Reference. GetMessages chce přesnou cestu složky (např. vladimir.buzalka@buzalka.cz/Exchange vladimir.buzalka/Sent Items).

IMAP (port 143, STARTTLS): zapnuté v configu (IMAP Server Configuration.Enabled=true). Po STARTTLS server nabízí jen AUTH=PLAIN, ale prostý IMAP LOGIN command funguje (Python imaplib.login OK, curl --ssl-reqd OK). Jako admin vidět všechny archivy. Lze stáhnout raw EML konkrétní zprávy.

Claves Mail (Windows) klient: Metoda autentizace MUSÍ být "Prostý text" (= prostý LOGIN command). "PLAIN"/"LOGIN"/"Automaticky" selhávají — Claws/libetpan na Windows je bez SASL pluginů ("PLAIN" → "Bad arguments", "LOGIN" → chybějící SASL plugin). Nastavení: server 192.168.1.53:143, STARTTLS, auth "Prostý text", admin / heslo. Na první zobrazení složek nutno "Obnovit strom složek" → Ano.

Bezpečnost: port 8463 ani 143 NEjsou forwardované na MikroTiku (192.168.1.2), přístup jen z LAN. MikroTik API na 8728 (admin/Vlado9674+).

Nástroje v U:/janssen/mailstore/ (ruční prohlížeč archivu, schránka→složka→zpráva, spouštět .venv\Scripts\python.exe):

  • mailstore_map_v1.0.py <schránka> — strom složek z API GetChildFolders (+--no-stats, --list). Arg = top-level složka (např. vladimir.buzalka@buzalka.cz).
  • mailstore_folder_v1.0.py "<plná cesta složky>" — seznam zpráv (datum|od|předmět) přes dávkový IMAP FETCH hlaviček (+--limit N, --all, --oldest).
  • mailstore_read_v1.0.py "<složka>" <číslo> — plný obsah jedné zprávy (hlavičky, tělo, přílohy) přes IMAP FETCH RFC822 (+--uid, --save DIR, --raw).

Ingest do Mongo — mailstore_ingest_v1.0.py <schránka> --since ROK [--dry-run] [--folder X] [--limit N]: backfill staré historie z MailStore do Mongo kolekce emaily. Dedup podle internet Message-ID (= _id v Mongu, shoduje se 1:1 s IMAP hlavičkou). Filtr data client-side z DATE headeru (NE IMAP SEARCH). Schéma dokumentu = jako Graph import. --dry-run spočítá kolik chybí bez zápisu. PILOT OVĚŘEN end-to-end 2026-06-11: MailStore IMAP → ingest → Mongo → enrich_fulltext → PG → MCP emaily search našel zprávu z 2020. Header scan ~490 zpráv/s (1M ≈ 30 min). vladimir.buzalka@buzalka.cz: Sent Items má 20k zpráv 2020+ k dobrání (i odeslané chybí z Graphu!). Plán: roztáhnout celou schránku, pak --since hlouběji do minulosti.

STAV 2026-06-13: backfill 2019+2020+ KOMPLETNÍ. Mongo kolekce vladimir.buzalka@buzalka.cz: 332 204 zpráv (z toho 256 808 z mailstore), PG fulltext 100 % (pg_indexed=mongo_total). 2019 dobrán samostatným během --since 2019 --until 2019 s vlastním checkpointem ingest_done_2019.txt (stávající checkpoint 2020+ by 2019 minul — přeskočí složky před scanem!). Pozn.: mailstore_uid v dokumentech je ve skutečnosti sekvenční číslo (ne IMAP UID), fetch přes M.fetch(seq,'(RFC822)') + kontrola Message-ID.

Přílohy → SeaweedFS (PoC, project-seaweedfs): mailstore_attachments_poc.py — re-fetch EML přes IMAP, přílohy do Fileru 192.168.1.50:8888 (PUT raw), dedup SHA-256, write-back pole seaweed_attachments[] (filename, sha256, seaweed_url) + marker seaweed_synced_at. Dávkový samostránkující režim (NE jeden dlouhý kurzor — CursorNotFound po hodině!). 88 930 mailů s přílohami 100 % hotovo, 0 failed; SeaweedFS 72k objektů / 27 GB. Drift sekvencí u živých složek (Sent Items, Odeslaná pošta — dostávaly poštu během ingestu) → --remap-failed režim: naskenuje mapu Message-ID→aktuální seq a dofetchne správně. Běží z toweru přes _run_poc.py (_run_ingest_2019.py pro 2019 ingest).

Běh na serveru (python-runner kontejner na Unraidu .76): skript v /mnt/user/Scripts/MailStore/ (deploy přes paramiko SFTP _deploy.py, SSH root@192.168.1.76 heslo 7309208104). Kontejner má pymongo, dosáhne na MailStore .53 i Mongo .76. DŮLEŽITÉ: Unraid agresivně zabíjí odpojené procesydocker exec -d, nohup &, setsid (host i kontejner) VŠECHNY selžou (i prostý sleep 60 zmizí; SSH session cleanup zabije celý user slice; screen/tmux/at nejsou). Jediné co funguje: blokující docker exec držený aktivním spojením (paramiko z PC v background tasku, _run_ingest.py). Ingest je idempotentní (dedup Message-ID + $setOnInsert) → přerušení (notebook usne) nevadí, příští běh dobere zbytek.

Velký backfill 2026-06-12 (vladimir.buzalka@buzalka.cz --since 2020) — DOKONČEN: 168 364 zpráv z mailstore v Mongo (kolekce celkem 243 607). Cestou vyřešeno + zpevněno ve skriptu (v aktuální verzi ~20kB):

  • ROOT CAUSE celého dne (zjištěno až nakonec): plný disk C:. MailStore měl v configu "IMAP Server Connection Debug Log Enabled": true → náš těžký IMAP provoz (FETCH celých těl) vygeneroval za den 65 GB Connection debug logů do C:\ProgramData\MailStore\Debug Log\Connection\ (jednotlivé soubory 10-35 GB!). C: (jen 99 GB) se zaplnil na 0 → Firebird story na Z: házely Unable to open the archive store ... Code 335544373 SetFilePointer failed, IMAP wedgoval pod zátěží (nešlo psát temp/zámky), a po restartu story nešly mountnout (API GetChildFolders=0 pro VŠECHNY schránky, GetStores ukázal chyby). Fix: vypnout Connection debug log (config MailStoreServer.json v C:\Program Files (x86)\MailStore\MailStore Server\, hodnotu na false, stop/edit/start; záloha .bak_20260613) + smazat logy (C:\ProgramData\MailStore\Debug Log\Connection\* — pozor: harness blokuje Remove-Item na ProgramData, použij Get-ChildItem | %{$_.Delete()}). Po smazání 65 GP uvolněno, restart → story OK, 1795 složek, archiv online. Diagnostika: _store_status.py (GetStores přes API, POST i bez params = data=b"", dekóduj utf-8-sig kvůli BOM).
  • MailStore IMAP se pod zátěží ZASEKNE NATVRDO (abort: command: FETCH/CAPABILITY/EXAMINE => socket error: EOF) — primárně to byl důsledek plného C: výše. Port 143 přijme TCP, ale server spojení hned utne — i z PC. Probudí ho JEN restart služby MailStoreServer (retry nepomůže). Restart přes WinRM: Restart-Service -Name MailStoreServer -Force (admin administrator/Vlado7309208104++, TrustedHosts OK). Po wedgi 0 established spojení, služba "Running" — zaseklé je IMAP vlákno gateway. Při dalším velkém ingestu HLÍDAT volné místo na C:! (s vypnutým debug logem by problém neměl nastat).
  • Po wedgi login projde, ale FETCH hned EOFne → skript dělal kaskádu falešných přeskoků a vracel falešné rc=0. Fix: čítač consec_aborts, po 4 abortech v řadě return 2 → orchestrátor pozná wedge.
  • coll.distinct("_id") překročí 16MB cap u velké kolekce → nahrazeno kurzorem find({},{_id:1}).batch_size(5000).
  • imap_connect() má retry (6×5s) na abort/error/OSError.
  • --checkpoint FILE (hotové složky, jedna cesta/řádek) → po wedgi další běh přeskočí hotové BEZ FETCH (rychlé navázání). Složka se zapíše až po úplném dokončení; abort během fetche ji NEoznačí.
  • Orchestrátor _orchestrate.ps1: smyčka run ingest → rc≠0 → Restart-Service MailStore přes WinRM → čekej až IMAP odpoví (_imap_test.py) → zkus znovu. Konec na rc=0. Konverguje díky checkpointu.
  • HEADER_BATCH snížen 2000→500 (šetrnější).
  • Dvě obří složky (Odstraněná 170k, Doručená 47k) jdou re-scanovat jen na čerstvém MailStore — jinak deterministicky wedgnou na 1. FETCH. Přijaty jako hotové ~99 % (Odstraněná 14 637/14 728, Doručená 2 666/2 719; data zapsaly dřívější běhy) a ručně seednuty do checkpointu (_seed_checkpoint.py). Zbývá ~150 stragglerů + 2 maličké složky (_OPTUM_PATROc, 27646 — v Mongu 0) na pozdější šetrný doběh.
  • PO forced restartu Management API (8463) chvíli vrací 0 složek (GetChildFolders/collect_folders = 0) — MailStore mountuje index obří schránky (273 GB) minuty. Opakované forced restarty počet složek degradovaly 1795→1507→0. Nehammrovat restarty; nechat MailStore dosednout. collect_folders=0 → běh nemá co dělat → falešné rc=0 (pozor v orchestraci).

Pro denní udržování plánováno: Unraid User Scripts plugin nebo python-runner cron (nezávislé na SSH) + sync_state (UID watermark). Pomocné skripty v mailstore/: _run_ingest.py, _orchestrate.ps1, _status_check.py, _mongo_count.py, _tail_log.py, _checkpoint_diff.py, _imap_test.py, _seed_checkpoint.py, _deploy.py, _folder_coverage.py.

vladimir.buzalka@buzalka.cz1795 složek (hluboká struktura #Innopharma/!Zpracovat/@Zpracovat po studiích). Velké: Odstraněná pošta 170k, Sent Items 63k, Doručená pošta 47k. Header scan ~490 zpráv/s (velká složka ~2-4 min).

Tři gotchas (vyřešené): 0. IMAP názvy složek s diakritikou (Doručená pošta) musí být v modified UTF-7 (RFC 3501) — MailStore neumí UTF8=ACCEPT. encode_mutf7() ve všech 3 IMAP skriptech. A nestandardní charsety hlaviček/těl (unknown-8bit) shazují bytes.decode_safe_decode() s fallbackem utf-8/latin-1.

  1. Kolekce emaily má unique+sparse index na graph_id. MailStore dokument musí pole graph_id ÚPLNĚ VYNECHAT (ne None) — explicitní null koliduje (sparse ignoruje jen chybějící pole). Jinak E11000 duplicate key.
  2. Mongo {'graph_id': None} matchuje i dokumenty BEZ pole — delete_many tím smete i validní dokumenty. Pozor při úklidu.
  3. enrich_fulltext spouštět přes U:/janssen/.venv/Scripts/python.exe (system Python C:\Python312 nemá psycopg).

IMAP SEARCH je slepá ulička (78s, vrací jen ~10 výsledků). API GetMessages dává jen metadata (id, date, uid1=Message-ID, outgoing), ne obsah — obsah jen přes IMAP. API id (1:947923) ≠ IMAP UID, most je Message-ID (=uid1).

Pracovní adresář: U:/janssen/mailstore/. Pozn.: feedback-admin-powershell — admin příkazy (winget) rovnou psát uživateli.