gmao/app_new/outlook/pages.py

156 lines
6 KiB
Python
Raw Normal View History

2026-08-14 18:02:25 +02:00
"""Outlook Pages Routes - GMAO Collège"""
from flask import Blueprint, render_template, redirect, url_for, request, flash, jsonify, send_file
from flask_login import login_required, current_user
from app_new.extensions import db
from ..outlook.models import OutlookAccount, OutlookMail, OutlookFolder, OutlookAttachment, OutlookMailInterpretation, GmaoContext
import os
import subprocess
import json
import tempfile
pages_bp = Blueprint('outlook_pages', __name__, template_folder='templates')
"""
Outlook Routes - GMAO Collège
Intégration Outlook/Microsoft
"""
from flask import Blueprint, render_template, redirect, url_for, request, flash, jsonify, send_file
from flask_login import login_required, current_user
from app_new.extensions import db
from ..outlook.models import OutlookAccount, OutlookMail, OutlookFolder, OutlookAttachment, OutlookMailInterpretation, GmaoContext
import os
import subprocess
import json
import tempfile
outlook_bp = Blueprint('outlook', __name__, template_folder='templates')
# ─── Pages principales ─────────────────────────────────────────────────────
@pages_bp.route('/')
@login_required
def index():
"""Page principale: Liste des comptes Outlook."""
accounts = OutlookAccount.query.filter_by(user_id=current_user.id).all()
return render_template('outlook/add.html', accounts=accounts)
@pages_bp.route('/add')
@login_required
def add_account():
"""Page d'ajout de compte Outlook."""
accounts = OutlookAccount.query.filter_by(user_id=current_user.id).all()
return render_template('outlook/add.html', accounts=accounts)
@pages_bp.route('/<int:account_id>/reactivate', methods=['POST'])
@login_required
def reactivate_account(account_id):
"""Réauthentifier un compte Outlook (supprime l'ancien token et redirige vers l'ajout)."""
account = OutlookAccount.query.get_or_404(account_id)
if account.user_id != current_user.id:
flash('Compte non autorisé.', 'error')
return redirect(url_for('outlook_pages.index'))
# Supprimer le compte existant pour relancer le flux OAuth2
email = account.email
OutlookMail.query.filter_by(account_id=account_id).delete()
OutlookFolder.query.filter_by(account_id=account_id).delete()
db.session.delete(account)
db.session.commit()
flash(f'Compte {email} supprimé. Veuillez le recréer.', 'success')
return redirect(url_for('outlook_pages.add_account'))
@pages_bp.route('/<int:account_id>')
@login_required
def account_detail(account_id):
"""Détails d'un compte avec ses dossiers."""
account = OutlookAccount.query.get_or_404(account_id)
# Récupérer tous les dossiers
all_folders = OutlookFolder.query.filter_by(account_id=account_id).all()
# Construire un index par ID
folder_by_id = {f.id: f for f in all_folders}
# Identifier les dossiers racines (parent_id non existant dans la base)
root_folders = []
for folder in all_folders:
if not folder.parent_id or folder.parent_id not in folder_by_id:
root_folders.append(folder)
# Fonction récursive pour construire l'arbre
def build_folder_tree(folders):
result = []
for folder in folders:
# Trouver les enfants
children = [f for f in all_folders if f.parent_id == folder.id]
folder_dict = {
'id': folder.id,
'name': folder.display_name or folder.name,
'total_items': folder.total_items,
'unread_items': folder.unread_items,
'folder_type': folder.folder_type,
'children': build_folder_tree(children) if children else []
}
result.append(folder_dict)
return result
folders_tree = build_folder_tree(root_folders)
return render_template('outlook/account.html', account=account, folders_tree=folders_tree)
@pages_bp.route('/<int:account_id>/folder/<folder_id>')
@login_required
def folder_view(account_id, folder_id):
"""Affiche les emails d'un dossier."""
account = OutlookAccount.query.get_or_404(account_id)
folder = OutlookFolder.query.get_or_404(folder_id)
mails = OutlookMail.query.filter_by(folder_id=folder_id).order_by(OutlookMail.received_at.desc()).limit(50).all()
# Compter les non lus
unread_count = sum(1 for m in mails if not m.is_read)
return render_template('outlook/folder.html', account=account, folder=folder, mails=mails, unread_count=unread_count)
@pages_bp.route('/<int:account_id>/mail/<mail_id>')
@login_required
def mail_view(account_id, mail_id):
"""Affiche un email en détail avec interprétation Hermes."""
account = OutlookAccount.query.get_or_404(account_id)
mail = OutlookMail.query.get_or_404(mail_id)
# Marquer comme lu
if not mail.is_read:
mail.is_read = True
db.session.commit()
# Récupérer les pièces jointes
attachments = OutlookAttachment.query.filter_by(mail_id=mail_id).all()
# Récupérer les interprétations
interpretations = OutlookMailInterpretation.query.filter_by(mail_id=mail_id).order_by(OutlookMailInterpretation.created_at.desc()).all()
return render_template('outlook/mail.html', account=account, mail=mail, attachments=attachments, interpretations=interpretations)
@pages_bp.route('/<int:account_id>/delete', methods=['POST'])
@login_required
def delete_account(account_id):
"""Supprime un compte Outlook."""
account = OutlookAccount.query.get_or_404(account_id)
if account.user_id != current_user.id:
flash('Non autorisé.', 'danger')
return redirect(url_for('outlook_pages.index'))
# Supprimer les mails et dossiers associés
OutlookMail.query.filter_by(account_id=account_id).delete()
OutlookFolder.query.filter_by(account_id=account_id).delete()
db.session.delete(account)
db.session.commit()
flash('Compte Outlook supprimé.', 'success')
return redirect(url_for('outlook_pages.index'))