gmao/app_new/messagerie/routes.py

246 lines
10 KiB
Python
Raw Normal View History

2026-08-14 18:02:25 +02:00
"""
Messagerie unifiee - GMAO College
Page unique regroupant:
- Interpretations a traiter (Outlook + ENT)
- 10 derniers messages Outlook
- 10 derniers messages ENT
- Boutons d'import/sync
"""
from flask import Blueprint, render_template, jsonify
from flask_login import login_required, current_user
from app_new.extensions import db
messagerie_bp = Blueprint('messagerie', __name__, template_folder='templates')
@messagerie_bp.route('/messagerie')
@login_required
def index():
"""Page de messagerie unifiee."""
from datetime import datetime
# 1. Interpretations Outlook en attente
outlook_interps = []
try:
from app_new.outlook.models import OutlookMailInterpretation, OutlookMail
pending = OutlookMailInterpretation.query.filter_by(
status='pending', user_id=current_user.id
).order_by(OutlookMailInterpretation.created_at.desc()).limit(15).all()
for p in pending:
outlook_interps.append({
'id': p.id,
'source': 'outlook',
'date': p.created_at,
'subject': p.mail.subject if p.mail else 'N/A',
'from': p.mail.from_name if p.mail else 'N/A',
'description': p.suggested_description or '',
'equipment': p.suggested_equipment or '',
'action': p.analysis_action or '',
'confidence': getattr(p, 'analysis_confidence', 0.5),
'detail_url': f'/outlook/{p.mail.account_id}/mail/{p.mail_id}' if p.mail else '#',
'create_url': f'/interventions/new?from_interpretation={p.id}&source=outlook',
})
except Exception as e:
outlook_interps = []
# 2. Interpretations ENT en attente
ent_interps = []
try:
from app_new.ent.interpretation_models import EntMessageInterpretation
pending_ent = EntMessageInterpretation.query.filter_by(status='pending')\
.order_by(EntMessageInterpretation.created_at.desc()).limit(15).all()
for p in pending_ent:
ent_interps.append({
'id': p.id,
'source': 'ent',
'date': p.created_at,
'subject': p.message.subject if p.message else 'N/A',
'from': p.message.author if p.message else 'N/A',
'description': p.suggested_description or '',
'equipment': p.suggested_equipment or '',
'action': p.analysis_action or '',
'confidence': getattr(p, 'analysis_confidence', 0.5),
'detail_url': f'/ent/message/{p.message_id}' if p.message else '/ent/interpretations',
'create_url': f'/interventions/new?from_interpretation={p.id}&source=ent',
})
except Exception:
ent_interps = []
# Combiner et trier par date
all_interps = outlook_interps + ent_interps
all_interps.sort(key=lambda x: x['date'] if x['date'] else datetime.min, reverse=True)
# 3. 10 derniers messages Outlook
outlook_mails = []
try:
from app_new.outlook.models import OutlookMail
mails = OutlookMail.query.order_by(OutlookMail.received_at.desc()).limit(10).all()
for m in mails:
outlook_mails.append({
'id': m.id,
'subject': m.subject or '(sans objet)',
'from_name': m.from_name or '',
'from_email': m.from_email or '',
'received_at': m.received_at,
'is_read': m.is_read,
'has_interpretation': m.interpretations.count() > 0 if hasattr(m, 'interpretations') else False,
})
except Exception:
outlook_mails = []
# 4. 10 derniers messages ENT
ent_messages = []
try:
from app_new.ent.models import EntMessage
msgs = EntMessage.query.order_by(EntMessage.received_at.desc()).limit(10).all()
for m in msgs:
ent_messages.append({
'id': m.id,
'subject': m.subject or '(sans objet)',
'author': m.author or '',
'received_at': m.received_at,
'has_interpretation': hasattr(m, 'interpretations') and m.interpretations.count() > 0,
})
except Exception:
ent_messages = []
return render_template('messagerie/index.html',
all_interpretations=all_interps,
outlook_mails=outlook_mails,
ent_messages=ent_messages,
outlook_count=len(outlook_interps),
ent_count=len(ent_interps),
last_outlook_mail=outlook_mails[0] if outlook_mails else None,
last_ent_message=ent_messages[0] if ent_messages else None,
last_interpretation=all_interps[0] if all_interps else None)
@messagerie_bp.route('/messagerie/api/interpret-now', methods=['POST'])
@login_required
def interpret_now():
"""Lance l'interpretation manuelle des emails Outlook + messages ENT."""
results = {}
# Interpretation Outlook
try:
from app_new.outlook.auto_interpret import run_auto_interpret
result = run_auto_interpret()
results['outlook'] = {
'success': result.get('success', False),
'processed': result.get('processed', 0),
'created': result.get('created', 0),
'errors': result.get('errors', [])
}
except Exception as e:
results['outlook'] = {'success': False, 'error': str(e)[:200]}
# Interpretation ENT
try:
from app_new.lib_ext.ent_service import _process_credential
from app_new.ent.models import EntCredential, EntConfig
from flask import current_app
creds = EntCredential.query.filter_by(is_active=True).all()
config = EntConfig.query.first()
app = current_app._get_current_object()
ent_created = 0
for cred in creds:
try:
r = _process_credential(cred, config, app)
if isinstance(r, int):
ent_created += r
except Exception:
pass
results['ent'] = {'success': True, 'created': ent_created}
except Exception as e:
results['ent'] = {'success': False, 'error': str(e)[:200]}
return jsonify({
'success': True,
'results': results,
'message': f"Outlook: {results.get('outlook', {}).get('created', 0)} interpretations, ENT: {results.get('ent', {}).get('created', 0)} interpretations"
})
@messagerie_bp.route('/messagerie/api/import-outlook', methods=['POST'])
@login_required
def import_outlook():
"""Importe les 10 derniers emails Outlook (sync manuelle)."""
try:
from app_new.outlook.models import OutlookAccount
from app_new.outlook.sync import api_sync_mails
accounts = OutlookAccount.query.all()
if not accounts:
return jsonify({'success': False, 'error': 'Aucun compte Outlook configure'}), 400
total_saved = 0
total_updated = 0
errors = []
for account in accounts:
try:
# Chercher le dossier inbox pour ce compte
from app_new.outlook.models import OutlookFolder
inbox = OutlookFolder.query.filter_by(account_id=account.id, folder_type='inbox').first()
if not inbox:
inbox = OutlookFolder.query.filter(
OutlookFolder.account_id == account.id,
OutlookFolder.name.like('%ception%')
).first()
folder_id = inbox.id if inbox else 'inbox'
result = api_sync_mails(account.id, folder_id=folder_id)
total_saved += result.get('saved', 0) if isinstance(result, dict) else 0
total_updated += result.get('updated', 0) if isinstance(result, dict) else 0
except Exception as e:
errors.append(f'Compte {account.id}: {str(e)[:100]}')
return jsonify({
'success': True,
'saved': total_saved,
'updated': total_updated,
'message': f"{total_saved} nouveaux, {total_updated} mis a jour" + (f" ({len(errors)} erreurs)" if errors else "")
})
except Exception as e:
return jsonify({'success': False, 'error': str(e)[:200]}), 500
@messagerie_bp.route('/messagerie/api/import-ent', methods=['POST'])
@login_required
def import_ent():
"""Importe les 10 derniers messages ENT (sync manuelle)."""
try:
from app_new.lib_ext.ent_service import _process_credential, fetch_new_messages, login_ent
from app_new.lib_ext.ent_crypto import decrypt_value
from app_new.ent.models import EntCredential, EntMessage, EntConfig
from app_new.extensions import db
from flask import current_app
creds = EntCredential.query.filter_by(is_active=True).all()
if not creds:
return jsonify({'success': False, 'error': 'Aucun credential ENT configure'}), 400
config = EntConfig.query.first()
app = current_app._get_current_object()
total_new = 0
total_interventions = 0
errors = []
for cred in creds:
try:
result = _process_credential(cred, config, app)
if isinstance(result, int):
total_interventions += result
elif isinstance(result, dict):
total_interventions += result.get('new_messages', 0)
except Exception as e:
errors.append(str(e)[:100])
# Compter les messages recents en DB
recent_count = EntMessage.query.count()
return jsonify({
'success': True,
'saved': recent_count,
'message': f"{recent_count} messages en base, {total_interventions} intervention(s) creee(s)" + (f" ({len(errors)} erreurs)" if errors else "")
})
except Exception as e:
return jsonify({'success': False, 'error': str(e)[:200]}), 500