|
|
from flask import Flask, render_template, request, jsonify, send_file, session |
|
|
from google import genai |
|
|
from google.genai import types |
|
|
import os |
|
|
from datetime import datetime |
|
|
import uuid |
|
|
from reportlab.lib.pagesizes import letter |
|
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer |
|
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle |
|
|
from reportlab.lib.enums import TA_JUSTIFY |
|
|
import io |
|
|
|
|
|
app = Flask(__name__) |
|
|
app.secret_key = 'votre_cle_secrete_ici' |
|
|
|
|
|
|
|
|
GEMINI_API_KEY = os.environ.get('GEMINI_API_KEY') |
|
|
client = genai.Client(api_key=GEMINI_API_KEY) |
|
|
|
|
|
|
|
|
def init_session(): |
|
|
if 'discussions' not in session: |
|
|
session['discussions'] = [] |
|
|
session.modified = True |
|
|
|
|
|
@app.route('/') |
|
|
def index(): |
|
|
init_session() |
|
|
return render_template('index.html') |
|
|
|
|
|
@app.route('/api/resume', methods=['POST']) |
|
|
def resume_content(): |
|
|
init_session() |
|
|
|
|
|
try: |
|
|
content = request.form.get('content') |
|
|
resume_type = request.form.get('type', 'court') |
|
|
|
|
|
if not content: |
|
|
return jsonify({'error': 'Aucun contenu fourni'}), 400 |
|
|
|
|
|
|
|
|
prompts = { |
|
|
'court': "Fais un résumé court et concis (3-5 phrases) du texte suivant :\n\n", |
|
|
'detaille': "Fais un résumé détaillé et structuré du texte suivant, en gardant les points importants :\n\n", |
|
|
'points_cles': "Extrais les points clés du texte suivant sous forme de liste à puces :\n\n" |
|
|
} |
|
|
|
|
|
prompt = prompts.get(resume_type, prompts['court']) + content |
|
|
|
|
|
|
|
|
response = client.models.generate_content( |
|
|
model='gemini-2.5-flash', |
|
|
contents=[prompt] |
|
|
) |
|
|
|
|
|
resume = response.text |
|
|
|
|
|
|
|
|
discussion = { |
|
|
'id': str(uuid.uuid4()), |
|
|
'timestamp': datetime.now().isoformat(), |
|
|
'content': content[:200] + '...' if len(content) > 200 else content, |
|
|
'type': resume_type, |
|
|
'resume': resume |
|
|
} |
|
|
|
|
|
discussions = session.get('discussions', []) |
|
|
discussions.insert(0, discussion) |
|
|
session['discussions'] = discussions[-50:] |
|
|
session.modified = True |
|
|
|
|
|
return jsonify({ |
|
|
'success': True, |
|
|
'resume': resume, |
|
|
'id': discussion['id'] |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
return jsonify({'error': str(e)}), 500 |
|
|
|
|
|
@app.route('/api/discussions', methods=['GET']) |
|
|
def get_discussions(): |
|
|
init_session() |
|
|
return jsonify({'discussions': session.get('discussions', [])}) |
|
|
|
|
|
@app.route('/api/discussion/<discussion_id>', methods=['DELETE']) |
|
|
def delete_discussion(discussion_id): |
|
|
init_session() |
|
|
discussions = session.get('discussions', []) |
|
|
discussions = [d for d in discussions if d['id'] != discussion_id] |
|
|
session['discussions'] = discussions |
|
|
session.modified = True |
|
|
return jsonify({'success': True}) |
|
|
|
|
|
@app.route('/api/download/<discussion_id>', methods=['GET']) |
|
|
def download_pdf(discussion_id): |
|
|
init_session() |
|
|
discussions = session.get('discussions', []) |
|
|
discussion = next((d for d in discussions if d['id'] == discussion_id), None) |
|
|
|
|
|
if not discussion: |
|
|
return jsonify({'error': 'Discussion non trouvée'}), 404 |
|
|
|
|
|
|
|
|
buffer = io.BytesIO() |
|
|
doc = SimpleDocTemplate(buffer, pagesize=letter) |
|
|
styles = getSampleStyleSheet() |
|
|
story = [] |
|
|
|
|
|
|
|
|
title_style = ParagraphStyle( |
|
|
'CustomTitle', |
|
|
parent=styles['Heading1'], |
|
|
fontSize=18, |
|
|
textColor='#2c3e50' |
|
|
) |
|
|
story.append(Paragraph(f"Résumé - {discussion['type'].upper()}", title_style)) |
|
|
story.append(Spacer(1, 12)) |
|
|
|
|
|
|
|
|
date_text = f"Généré le : {datetime.fromisoformat(discussion['timestamp']).strftime('%d/%m/%Y %H:%M')}" |
|
|
story.append(Paragraph(date_text, styles['Normal'])) |
|
|
story.append(Spacer(1, 20)) |
|
|
|
|
|
|
|
|
story.append(Paragraph("Contenu original :", styles['Heading2'])) |
|
|
story.append(Spacer(1, 6)) |
|
|
content_style = ParagraphStyle( |
|
|
'ContentStyle', |
|
|
parent=styles['Normal'], |
|
|
alignment=TA_JUSTIFY |
|
|
) |
|
|
story.append(Paragraph(discussion['content'].replace('\n', '<br/>'), content_style)) |
|
|
story.append(Spacer(1, 20)) |
|
|
|
|
|
|
|
|
story.append(Paragraph("Résumé :", styles['Heading2'])) |
|
|
story.append(Spacer(1, 6)) |
|
|
story.append(Paragraph(discussion['resume'].replace('\n', '<br/>'), content_style)) |
|
|
|
|
|
doc.build(story) |
|
|
buffer.seek(0) |
|
|
|
|
|
return send_file( |
|
|
buffer, |
|
|
as_attachment=True, |
|
|
download_name=f"resume_{discussion_id[:8]}.pdf", |
|
|
mimetype='application/pdf' |
|
|
) |
|
|
|
|
|
if __name__ == '__main__': |
|
|
app.run(debug=True) |