153 lines
6.6 KiB
Python
153 lines
6.6 KiB
Python
|
|
"""
|
||
|
|
Configuration du contexte GMAO - GMAO Collège
|
||
|
|
Utilise le modèle GmaoContext existant dans outlook/models.py
|
||
|
|
"""
|
||
|
|
from flask import Blueprint, render_template, request, redirect, url_for, flash
|
||
|
|
from flask_login import login_required, current_user
|
||
|
|
from app_new.extensions import db
|
||
|
|
from app_new.outlook.models import GmaoContext
|
||
|
|
|
||
|
|
gmao_config_bp = Blueprint('gmao_config', __name__, template_folder='templates')
|
||
|
|
|
||
|
|
|
||
|
|
@gmao_config_bp.route('/')
|
||
|
|
@login_required
|
||
|
|
def index():
|
||
|
|
"""Page de configuration du contexte GMAO."""
|
||
|
|
# Récupérer ou créer le contexte pour l'utilisateur actuel
|
||
|
|
context = GmaoContext.get_for_user(current_user.id)
|
||
|
|
|
||
|
|
# Récupérer les comptes Outlook de l'utilisateur (ou tous si admin)
|
||
|
|
from app_new.outlook.models import OutlookAccount
|
||
|
|
from app_new.core.models.settings import AppSettings
|
||
|
|
if current_user.username == 'admin':
|
||
|
|
outlook_accounts = OutlookAccount.query.all()
|
||
|
|
else:
|
||
|
|
outlook_accounts = OutlookAccount.query.filter_by(user_id=current_user.id).all()
|
||
|
|
|
||
|
|
# Recuperer la cle API et le modele OpenRouter
|
||
|
|
openrouter_key = AppSettings.get('openrouter_api_key') or ''
|
||
|
|
openrouter_model = AppSettings.get('openrouter_model', 'poolside/laguna-s-2.1:free')
|
||
|
|
ollama_model = AppSettings.get('ollama_model', 'gemma3:4b-it')
|
||
|
|
|
||
|
|
return render_template('gmao_config/index.html', context=context, outlook_accounts=outlook_accounts,
|
||
|
|
openrouter_key=openrouter_key, openrouter_model=openrouter_model,
|
||
|
|
ollama_model=ollama_model)
|
||
|
|
|
||
|
|
|
||
|
|
@gmao_config_bp.route('/save', methods=['POST'])
|
||
|
|
@login_required
|
||
|
|
def save():
|
||
|
|
"""Sauvegarde le contexte GMAO."""
|
||
|
|
context = GmaoContext.get_for_user(current_user.id)
|
||
|
|
|
||
|
|
# Informations sur l'établissement
|
||
|
|
context.establishment_name = request.form.get('establishment_name', '')
|
||
|
|
context.establishment_type = request.form.get('establishment_type', '')
|
||
|
|
context.address = request.form.get('address', '')
|
||
|
|
|
||
|
|
# Contexte technique
|
||
|
|
context.technical_context = request.form.get('technical_context', '')
|
||
|
|
context.equipment_context = request.form.get('equipment_context', '')
|
||
|
|
context.procedure_context = request.form.get('procedure_context', '')
|
||
|
|
|
||
|
|
# Contexte organisationnel
|
||
|
|
context.staff_info = request.form.get('staff_info', '')
|
||
|
|
context.contact_info = request.form.get('contact_info', '')
|
||
|
|
|
||
|
|
# Instructions pour Hermes
|
||
|
|
context.hermes_instructions = request.form.get('hermes_instructions', '')
|
||
|
|
|
||
|
|
# Expéditeurs exclus
|
||
|
|
context.excluded_senders = request.form.get('excluded_senders', '')
|
||
|
|
|
||
|
|
# Activation du watchdog (interpretation auto Outlook + ENT)
|
||
|
|
context.auto_interpret_enabled = request.form.get('auto_interpret_enabled') == 'on'
|
||
|
|
context.auto_interpret_interval = max(1, int(request.form.get('auto_interpret_interval', 10)))
|
||
|
|
context.auto_interpret_max_emails = max(1, int(request.form.get('auto_interpret_max_emails', 5)))
|
||
|
|
context.auto_interpret_lookback_hours = max(1, int(request.form.get('auto_interpret_lookback_hours', 24)))
|
||
|
|
|
||
|
|
# Activation de la synchronisation PRONOTE
|
||
|
|
context.pronote_sync_enabled = request.form.get('pronote_sync_enabled') == 'on'
|
||
|
|
context.pronote_sync_interval = max(60, int(request.form.get('pronote_sync_interval', 360)))
|
||
|
|
context.pronote_sync_weeks = max(1, int(request.form.get('pronote_sync_weeks', 4)))
|
||
|
|
|
||
|
|
# Activation de la synchronisation Outlook
|
||
|
|
context.outlook_sync_enabled = request.form.get('outlook_sync_enabled') == 'on'
|
||
|
|
context.outlook_sync_interval = max(1, int(request.form.get('outlook_sync_interval', 10)))
|
||
|
|
context.outlook_sync_lookback_hours = max(1, int(request.form.get('outlook_sync_lookback_hours', 24)))
|
||
|
|
|
||
|
|
# Configuration IA
|
||
|
|
from app_new.core.models.settings import AppSettings
|
||
|
|
api_key = request.form.get('openrouter_api_key', '').strip()
|
||
|
|
if api_key:
|
||
|
|
AppSettings.set('openrouter_api_key', api_key)
|
||
|
|
model = request.form.get('openrouter_model', '').strip()
|
||
|
|
if model:
|
||
|
|
AppSettings.set('openrouter_model', model)
|
||
|
|
|
||
|
|
# Provider IA : openrouter (cloud) ou ollama (local auto-identification)
|
||
|
|
context.ai_provider = request.form.get('ai_provider', 'openrouter')
|
||
|
|
ollama_model = request.form.get('ollama_model', '').strip()
|
||
|
|
if ollama_model:
|
||
|
|
context.ollama_model = ollama_model
|
||
|
|
|
||
|
|
# Watchdog interne (cron local)
|
||
|
|
context.watchdog_enabled = request.form.get('watchdog_enabled') == 'on'
|
||
|
|
context.watchdog_interval = max(1, int(request.form.get('watchdog_interval', 10)))
|
||
|
|
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
flash('Contexte GMAO mis à jour avec succès.', 'success')
|
||
|
|
return redirect(url_for('gmao_config.index'))
|
||
|
|
|
||
|
|
|
||
|
|
@gmao_config_bp.route('/test', methods=['POST'])
|
||
|
|
@login_required
|
||
|
|
def test():
|
||
|
|
"""Test l'interpretation avec un email d'exemple."""
|
||
|
|
from app_new.core.models.settings import AppSettings
|
||
|
|
from app_new.outlook.auto_interpret import analyze_email_with_hermes
|
||
|
|
from flask import jsonify
|
||
|
|
|
||
|
|
context = GmaoContext.get_for_user(current_user.id)
|
||
|
|
|
||
|
|
# Verifier la cle API / connexion Ollama selon le provider
|
||
|
|
provider = context.ai_provider or 'openrouter'
|
||
|
|
if provider == 'openrouter':
|
||
|
|
api_key = AppSettings.get('openrouter_api_key')
|
||
|
|
if not api_key:
|
||
|
|
return jsonify({'error': 'Clé API OpenRouter non configurée. Configurez-la dans /gmao-config/.'}), 400
|
||
|
|
elif provider == 'ollama':
|
||
|
|
# Vérifier que le service Ollama est accessible
|
||
|
|
try:
|
||
|
|
ollama_host = AppSettings.get('ollama_host', 'http://ollama:11434')
|
||
|
|
requests.get(f'{ollama_host}/api/tags', timeout=5)
|
||
|
|
except:
|
||
|
|
return jsonify({'error': 'Service Ollama inaccessible.'}), 400
|
||
|
|
|
||
|
|
# Email d'exemple
|
||
|
|
class FakeMail:
|
||
|
|
subject = "Fuite d'eau dans la salle B07 - Intervention urgente"
|
||
|
|
from_name = "M. Dupont"
|
||
|
|
from_email = "dupont@college.fr"
|
||
|
|
to_recipients = ""
|
||
|
|
received_at = None
|
||
|
|
body_content = "Bonjour,\n\nIl y a une fuite d'eau dans la salle B07, pres de la chaufferie. Cela devrait etre regle en urgence s'il vous plait.\n\nMerci,\nM. Dupont"
|
||
|
|
body_preview = body_content
|
||
|
|
attachments = []
|
||
|
|
|
||
|
|
fake_mail = FakeMail()
|
||
|
|
fake_mail.body_preview = fake_mail.body_content
|
||
|
|
|
||
|
|
# Lancer l'interpretation
|
||
|
|
result = analyze_email_with_hermes(fake_mail, context)
|
||
|
|
|
||
|
|
if 'error' in result:
|
||
|
|
return jsonify({'error': result['error']}), 400
|
||
|
|
|
||
|
|
return jsonify({
|
||
|
|
'success': True,
|
||
|
|
'analysis': result,
|
||
|
|
'context_summary': context.get_full_context()[:200] + '...' if context.get_full_context() else 'Vide'
|
||
|
|
})
|