03-oct: superguardado automático
This commit is contained in:
73
scripts/monitor_estado/fuentes/correo.py
Normal file
73
scripts/monitor_estado/fuentes/correo.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""correo.py — Fuente de correo de empresa del monitor (RF-2, RF-6, RF-25).
|
||||
|
||||
Recoge los correos de las ultimas 24 h (o los de hoy) de `jminguez@prolongo.es`
|
||||
usando la API de Gmail con el OAuth ya existente (repositorio de negocio).
|
||||
|
||||
SOLO LECTURA: usa `messages().list()` y `messages().get()`; nunca marca correos
|
||||
como leidos ni modifica nada (RF-25).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
from .. import config # noqa: F401 (asegura sys.path con scripts/)
|
||||
|
||||
import infra_paths # ya disponible en sys.path (lo anade config.py)
|
||||
|
||||
|
||||
def _bootstrap_google() -> None:
|
||||
"""Deja importable el paquete `common` del repo de negocio (google/)."""
|
||||
repo = infra_paths.bootstrap_biblioteca_paths()
|
||||
google_dir = repo / "google"
|
||||
if google_dir.exists() and str(google_dir) not in sys.path:
|
||||
sys.path.insert(0, str(google_dir))
|
||||
|
||||
|
||||
def construir_servicio():
|
||||
"""Devuelve el servicio de Gmail autenticado (OAuth existente)."""
|
||||
_bootstrap_google()
|
||||
import common # google/common.py
|
||||
|
||||
return common.gmail_service()
|
||||
|
||||
|
||||
def _consulta(horas: int) -> str:
|
||||
"""Consulta Gmail para la ventana pedida (granularidad en dias)."""
|
||||
dias = max(1, int(horas) // 24)
|
||||
return f"in:inbox newer_than:{dias}d"
|
||||
|
||||
|
||||
def recoger_recientes(gmail=None, horas: int = 24, limite: int = 50) -> list[dict]:
|
||||
"""Devuelve los correos de la ventana, con {id, fecha, de, asunto, snippet}.
|
||||
|
||||
No modifica el estado de los correos (no marca leido).
|
||||
"""
|
||||
gmail = gmail or construir_servicio()
|
||||
res = gmail.users().messages().list(userId="me", q=_consulta(horas), maxResults=limite).execute()
|
||||
salida: list[dict] = []
|
||||
for m in res.get("messages", []):
|
||||
full = gmail.users().messages().get(
|
||||
userId="me", id=m["id"], format="metadata",
|
||||
metadataHeaders=["Subject", "From", "Date"],
|
||||
).execute()
|
||||
headers = {h["name"].lower(): h["value"] for h in full.get("payload", {}).get("headers", [])}
|
||||
salida.append({
|
||||
"id": m["id"],
|
||||
"fecha": headers.get("date", ""),
|
||||
"de": headers.get("from", "?"),
|
||||
"asunto": headers.get("subject", "(sin asunto)"),
|
||||
"snippet": full.get("snippet", ""),
|
||||
})
|
||||
return salida
|
||||
|
||||
|
||||
def render_correo(m: dict) -> str:
|
||||
"""Render Markdown de un correo para el fichero del dia."""
|
||||
asunto = m.get("asunto", "(sin asunto)")
|
||||
de = m.get("de", "?")
|
||||
fecha = m.get("fecha", "")
|
||||
snippet = (m.get("snippet") or "").strip()
|
||||
linea = f"- **{fecha}** — **{de}:** {asunto}"
|
||||
return f"{linea}\n {snippet}" if snippet else linea
|
||||
Reference in New Issue
Block a user