67 lines
2.0 KiB
Python
67 lines
2.0 KiB
Python
"""Meilisearch wrapper — index mail bodies and run search queries.
|
|
|
|
Phase 6 scaffolding: connect, ensure index, simple add/search.
|
|
Indexing is triggered from IMAP IDLE pushes (manager) and a nightly reconcile.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Any, Iterable
|
|
|
|
from flask import current_app
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
INDEX_NAME = "messages"
|
|
|
|
|
|
def _client():
|
|
from meilisearch import Client
|
|
url = current_app.config.get("MEILI_URL", "http://localhost:7700")
|
|
key = current_app.config.get("MEILI_KEY", "")
|
|
return Client(url, key) if key else Client(url)
|
|
|
|
|
|
def ensure_index():
|
|
try:
|
|
c = _client()
|
|
try:
|
|
c.get_index(INDEX_NAME)
|
|
except Exception:
|
|
c.create_index(INDEX_NAME, {"primaryKey": "id"})
|
|
idx = c.index(INDEX_NAME)
|
|
idx.update_searchable_attributes(["subject", "from_email", "from_name", "to", "preview", "body"])
|
|
idx.update_filterable_attributes(["owner_email", "folder_key", "uid"])
|
|
return True
|
|
except Exception:
|
|
log.warning("Meili ensure_index failed", exc_info=True)
|
|
return False
|
|
|
|
|
|
def add_documents(docs: Iterable[dict[str, Any]]):
|
|
try:
|
|
c = _client()
|
|
c.index(INDEX_NAME).add_documents(list(docs))
|
|
return True
|
|
except Exception:
|
|
log.warning("Meili add_documents failed", exc_info=True)
|
|
return False
|
|
|
|
|
|
def search(owner_email: str, query: str, limit: int = 30) -> list[dict]:
|
|
try:
|
|
c = _client()
|
|
res = c.index(INDEX_NAME).search(
|
|
query, {"filter": f"owner_email = '{owner_email}'", "limit": limit},
|
|
)
|
|
return list(res.get("hits", []))
|
|
except Exception:
|
|
log.warning("Meili search failed", exc_info=True)
|
|
return []
|
|
|
|
|
|
def doc_id(owner_email: str, folder_key: str, uid: int) -> str:
|
|
# Meili allows only [a-zA-Z0-9_-] in primary keys
|
|
safe_owner = owner_email.replace("@", "_at_").replace(".", "_")
|
|
return f"{safe_owner}__{folder_key}__{uid}"
|