collapse cross-account dupes, Lato UI font, mail-list selection & density tuning
Backend: - Collapse identical cross-account deliveries in a thread: new messages.delivery_id (migration 0011) preserves the real Message-ID even when message_id_hdr is synthesized (§7.1); get_thread groups by it and reports also_in_account_ids; the list count counts distinct deliveries. Backfill script for existing rows. Frontend: - Bundle Lato (SIL OFL) as the UI font; unread mail-list rows use Black weight. - Mail-list selection: hover-avatar checkbox, tri-state "select all", bulk Archive/Pin/Delete (Restore/Delete in Archive/Trash/Spam) with a count in the reading pane; unread blue dot; "also delivered to" note in the thread. - Spacing/size tuning: sender-column width, icon gaps, avatar size, bar heights, and a round of -1px font sizes across the sidebar, mail list, and reading pane. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U72FZiF1W1pb8XxyWBTREA
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
"""One-off: recover delivery_id for messages whose stored Message-ID was
|
||||
synthesized (§7.1 cross-account duplicate). The real Message-ID is still in the
|
||||
raw blob, so re-parse it. Non-synthetic rows were already backfilled by migration
|
||||
0011; here we only touch rows left with delivery_id IS NULL that have a real
|
||||
Message-ID in their raw bytes."""
|
||||
|
||||
import asyncio
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.db import session_scope
|
||||
from app.indexer import blobstore
|
||||
from app.indexer.mime import parse_message
|
||||
from app.models import Message
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
async with session_scope() as session:
|
||||
rows = list(
|
||||
await session.scalars(select(Message).where(Message.delivery_id.is_(None)))
|
||||
)
|
||||
fixed = 0
|
||||
for m in rows:
|
||||
try:
|
||||
raw = blobstore.load(m.user_id, m.blob_sha256)
|
||||
except FileNotFoundError:
|
||||
continue
|
||||
parsed = parse_message(raw)
|
||||
if parsed.message_id:
|
||||
m.delivery_id = parsed.message_id
|
||||
fixed += 1
|
||||
print(f"scanned {len(rows)} null rows, set delivery_id on {fixed}")
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user