36 lines
1.1 KiB
Python
36 lines
1.1 KiB
Python
"""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())
|