From 899b2980484ff2718a58ad5fccd4107b4d113d35 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 16 Aug 2026 13:14:18 +0000 Subject: [PATCH] Corriger les watchdogs ENT et Outlook --- app_new/outlook/models.py | 8 ++-- ent_watchdog.py | 8 ++-- gmao_watchdog.py | 7 ++- ...f1a2b3c4d5e6_expand_outlook_attachments.py | 43 +++++++++++++++++++ 4 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 migrations/versions/f1a2b3c4d5e6_expand_outlook_attachments.py diff --git a/app_new/outlook/models.py b/app_new/outlook/models.py index 65132b7..2ca32a0 100644 --- a/app_new/outlook/models.py +++ b/app_new/outlook/models.py @@ -4,7 +4,7 @@ Intégration avec Outlook/Microsoft """ from datetime import datetime, timezone from app_new.extensions import db -from sqlalchemy.dialects.mysql import LONGTEXT +from sqlalchemy.dialects.mysql import LONGTEXT, LONGBLOB class OutlookAccount(db.Model): @@ -96,14 +96,16 @@ class OutlookAttachment(db.Model): """Pièce jointe d'un email Outlook.""" __tablename__ = "outlook_attachments" - id = db.Column(db.String(100), primary_key=True) # Attachment ID from Microsoft + # Les identifiants Microsoft Graph peuvent dépasser 100 caractères. + id = db.Column(db.String(500), primary_key=True) # Attachment ID from Microsoft mail_id = db.Column(db.String(500), db.ForeignKey("outlook_mails.id"), nullable=False) name = db.Column(db.String(500), nullable=False) content_type = db.Column(db.String(100), nullable=True) size = db.Column(db.Integer, default=0) is_inline = db.Column(db.Boolean, default=False) content_id = db.Column(db.String(200), nullable=True) # Pour les images inline - content = db.Column(db.LargeBinary, nullable=True) # Contenu binaire de la pièce jointe + # Les PDF et documents doivent pouvoir dépasser 64 Kio (BLOB). + content = db.Column(LONGBLOB, nullable=True) # Contenu binaire de la pièce jointe def __repr__(self): return f"" diff --git a/ent_watchdog.py b/ent_watchdog.py index fb5aaa1..bf29009 100644 --- a/ent_watchdog.py +++ b/ent_watchdog.py @@ -179,8 +179,10 @@ def analyze_ent_message_with_hermes(msg, gmao_context): from app_new.core.models.settings import AppSettings import requests - api_key_setting = AppSettings.query.filter_by(key='openrouter_api_key').first() - api_key = api_key_setting.value if api_key_setting else None + # AppSettings.get déchiffre les valeurs sensibles stockées sous la forme + # ``enc:...``. Lire directement ``.value`` envoyait la valeur chiffrée à + # OpenRouter et provoquait une réponse 401. + api_key = AppSettings.get('openrouter_api_key') if not api_key: return {'error': 'Clé API OpenRouter non configurée'} @@ -395,7 +397,7 @@ def run_watchdog(): db.session.add(interpretation) created_count += 1 elif result and result.get('error'): - log(f"Erreur analyse message {msg.id}: {result.get('error')}") + log(f"Erreur analyse message {msg.id}: {result.get('error')}", level='error') processed_count += 1 diff --git a/gmao_watchdog.py b/gmao_watchdog.py index 2480195..0a7a47d 100644 --- a/gmao_watchdog.py +++ b/gmao_watchdog.py @@ -208,7 +208,10 @@ def sync_inbox(): pdf_count += 1 log(f" PDF téléchargé: {att_name}") except Exception as e: - log(f" Erreur téléchargement pièce jointe: {str(e)[:50]}") + # Une pièce jointe défectueuse ne doit pas empoisonner la + # transaction et faire échouer toute la synchronisation. + db.session.rollback() + log(f" Erreur téléchargement pièce jointe {att_name}: {str(e)[:200]}", level='error') if pdf_count > 0: db.session.commit() @@ -268,7 +271,7 @@ def run_watchdog(): if result.get('errors'): for err in result.get('errors', []): - log(f" ⚠ Erreur email: {err[:100]}") + log(f" Erreur email: {err[:300]}", level='error') save_last_run() log("save_last_run done") diff --git a/migrations/versions/f1a2b3c4d5e6_expand_outlook_attachments.py b/migrations/versions/f1a2b3c4d5e6_expand_outlook_attachments.py new file mode 100644 index 0000000..37c411f --- /dev/null +++ b/migrations/versions/f1a2b3c4d5e6_expand_outlook_attachments.py @@ -0,0 +1,43 @@ +"""Étend le stockage des pièces jointes Outlook. + +Revision ID: f1a2b3c4d5e6 +Revises: e2f6a7b8c9d0 +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +revision = 'f1a2b3c4d5e6' +down_revision = 'e2f6a7b8c9d0' +branch_labels = None +depends_on = None + + +def upgrade(): + op.alter_column( + 'outlook_attachments', 'id', + existing_type=sa.String(length=100), + type_=sa.String(length=500), + existing_nullable=False, + ) + op.alter_column( + 'outlook_attachments', 'content', + existing_type=sa.LargeBinary(), + type_=mysql.LONGBLOB(), + existing_nullable=True, + ) + + +def downgrade(): + op.alter_column( + 'outlook_attachments', 'content', + existing_type=mysql.LONGBLOB(), + type_=sa.LargeBinary(), + existing_nullable=True, + ) + op.alter_column( + 'outlook_attachments', 'id', + existing_type=sa.String(length=500), + type_=sa.String(length=100), + existing_nullable=False, + )