File size: 10,294 Bytes
b1fdf62
 
7755c1f
 
7f4ad42
7755c1f
 
7f4ad42
7755c1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7f4ad42
7755c1f
b1fdf62
7755c1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b1fdf62
 
7755c1f
 
 
 
b1fdf62
 
7755c1f
 
b1fdf62
7755c1f
 
 
 
 
 
 
 
 
 
 
 
 
b1fdf62
7755c1f
 
 
 
 
 
 
 
 
 
 
b1fdf62
 
1e9998c
7755c1f
1e9998c
7755c1f
b1fdf62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7755c1f
 
 
 
b1fdf62
 
7755c1f
 
b1fdf62
7755c1f
 
 
 
 
 
 
 
 
 
b1fdf62
 
ba1ef6a
7755c1f
 
 
 
 
 
 
b1fdf62
 
 
 
 
7755c1f
 
 
0b9d6a6
 
7755c1f
 
0b9d6a6
b1fdf62
 
 
 
0b9d6a6
7f4ad42
 
b1fdf62
 
0b9d6a6
b1fdf62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7755c1f
 
b1fdf62
7f4ad42
0b9d6a6
b1fdf62
 
 
7755c1f
b1fdf62
 
 
 
 
7755c1f
0b9d6a6
b1fdf62
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#-- START OF FILE app - 2025-04-08T095242.046.py ---

from flask import Flask, render_template, request, jsonify
import google.generativeai as genai
from google.generativeai import types
import os
from PIL import Image
import io

app = Flask(__name__)

# Configuration de l'API Gemini
token = os.environ.get("TOKEN")
genai.configure(api_key=token)

generation_config = {
    "temperature": 1,
    "max_output_tokens": 8192,
}

safety_settings = [
    {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_NONE"},
    {"category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_NONE"},
    {"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"},
    {"category": "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "BLOCK_NONE"},
]

# Choose the Gemini model
model = genai.GenerativeModel(
    model_name="gemini-2.0-flash", # Modèle mis à jour vers 1.5-flash pour potentiellement de meilleures performances
    generation_config=generation_config,
    safety_settings=safety_settings
)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/api/francais', methods=['POST'])
def gpt_francais():
    """Handles French questions."""
    french_prompt = request.form.get('sujet', '').strip()
    choix = request.form.get('choix', '').strip()
    style = request.form.get('style', '').strip()

    if not french_prompt:
        return jsonify({"output": "Veuillez saisir un thème."}), 400

    if choix == "discuter":
        prompt = f""" Je veux faire mon travail de français de niveau lycée sous la forme d'un travail argumentatif.
        La question du travail est la suivante : "{french_prompt}". Tu devras discuter ce thème.
        tu utiliseras la méthodologie suivante :

        # INTRODUCTION:
            - Approche par constat
            - Problématique
            - Annonce du plan

            # DÉVELOPPEMENT:
            ## Partie 1 : Thèse
            - Introduction partielle (énonce la thèse)
            - Argument 1:
                * Explications
                * Illustration (exemple + explication)
            - Argument 2:
                * Explications
                * Illustration (exemple + explication)
           - Argument 3:
                * Explications
                * Illustration (exemple + explication)

            # phrase de Transiton vers la deuxieme partie :

            ## Partie 2 : Antithèse
            - Introduction partielle (énonce l'antithèse)
            - Argument 1:
                * Explications
                * Illustration (exemple + explication)
            - Argument 2:
                * Explications
                * Illustration (exemple + explication)
           - Argument 3:
                * Explications
                * Illustration (exemple + explication)

            #Conclusion
                * Bilan (Synthèse des arguments pour et contre)
                * Ouverture du sujet (sous forme de phrase interrogative )

        Je veux que tu utilises un style d'écriture {style}."""

    elif choix == "dissertation": # NOUVEAU BLOC POUR LA DISSERTATION
        prompt = f""" Je veux faire mon travail de français de niveau lycée sous la forme d'une dissertation.
        La question du travail est la suivante : "{french_prompt}". Tu devras traiter ce sujet de manière approfondie.
        tu utiliseras la méthodologie suivante :

        # INTRODUCTION:
            - Accroche (ou amorce) pertinente
            - Présentation du sujet et reformulation de la question
            - Problématique claire
            - Annonce du plan (généralement en deux ou trois parties)

        # DÉVELOPPEMENT:
        ## Partie 1: Thèse (ou première grande idée)
            - Introduction partielle (énonce l'idée directrice de la partie)
            - Argument 1:
                * Explications
                * Illustration (exemple + explication détaillée)
            - Argument 2:
                * Explications
                * Illustration (exemple + explication détaillée)
            - (Optionnel: Argument 3)
            - Transition vers la partie suivante

        ## Partie 2: Antithèse (ou deuxième grande idée / nuance / contrepoint)
            - Introduction partielle (énonce l'idée directrice de la partie)
            - Argument 1:
                * Explications
                * Illustration (exemple + explication détaillée)
            - Argument 2:
                * Explications
                * Illustration (exemple + explication détaillée)
            - (Optionnel: Argument 3)
            - Transition vers la partie suivante (si applicable) ou la conclusion

        ## (Optionnel: Partie 3: Synthèse / Dépassement)
            - Introduction partielle
            - Arguments développés (synthèse ou dépassement des points précédents)

        # CONCLUSION
            * Bilan synthétique des idées principales du développement (réponse claire à la problématique)
            * Ouverture du sujet (perspective plus large, nouvelle question, lien avec l'actualité ou une autre œuvre...)

        Je veux que tu utilises un style d'écriture {style}."""

    else: # Cas pour "Etaye" et "refute"
        prompt = f"""Je veux faire mon travail de français de niveau lycée sous la forme d'un travail argumentatif.
        La question du travail est la suivante : "{french_prompt}". Tu devras {choix} ce thème.
        tu utiliseras la méthodologie suivante :

        # INTRODUCTION:
            - Approche par constat
            - Problématique
            - Annonce du plan

            # DÉVELOPPEMENT:
            - Phrase chapeau (énonce la thèse principale : pour étayer ou contre pour réfuter)
            - Argument 1:
                * Explications
                * Illustration (exemple + explication)
            - Argument 2:
                * Explications
                * Illustration (exemple + explication)
           - Argument 3:
                * Explications
                * Illustration (exemple + explication)

            #Conclusion
                * Bilan (rappel de la thèse + arguments principaux)
                * Ouverture du sujet ( sous forme de phrase interrogative )

        Je veux que tu utilises un style d'écriture {style}."""

    try:
        response = model.generate_content(prompt)
        return jsonify({"output": response.text}), 200
    except Exception as e:
        # Log l'erreur pour le débogage côté serveur
        print(f"Error generating content: {e}")
        # Retourne un message d'erreur générique à l'utilisateur
        return jsonify({"output": f"Une erreur interne est survenue lors de la génération du contenu. Veuillez réessayer."}), 500


@app.route('/api/etude-texte', methods=['POST'])
def gpt_francais_cc():
    """Handles text analysis for French with multiple images."""
    if 'images' not in request.files:
        return jsonify({"output": "Aucune image n'a été téléchargée."}), 400

    images = request.files.getlist('images')
    if not images or all(not image.filename for image in images): # Vérifie si la liste est vide ou ne contient que des objets vides
        return jsonify({"output": "Aucune image sélectionnée ou les fichiers sont vides."}), 400

    pre_prompt = "Analyse de manière exhaustive et structurée le contenu du devoir présenté dans les images suivantes. Identifie les questions, extrais le texte si présent, et réponds aux questions de manière détaillée en te basant uniquement sur les informations fournies dans les images."

    # Préparer les images pour l'API Gemini
    contents = [pre_prompt]

    valid_images_found = False
    for image in images:
        if image and image.filename: # S'assure que l'objet fichier n'est pas vide et a un nom
            try:
                # Lire l'image avec PIL
                img_bytes = image.read()
                # Vérifier si les bytes lus ne sont pas vides
                if not img_bytes:
                    print(f"Skipping empty file: {image.filename}")
                    continue # Ignore les fichiers vides

                img = Image.open(io.BytesIO(img_bytes))
                img.verify() # Vérifie si l'image est valide/non corrompue
                # Re-ouvrir après verify()
                img = Image.open(io.BytesIO(img_bytes))

                # Convertir en format compatible avec Gemini
                contents.append(img)
                valid_images_found = True

            except (IOError, SyntaxError) as e:
                # Log l'erreur spécifique
                print(f"Error processing image {image.filename}: {e}. It might be corrupted or not a valid image format.")
                # Optionnel: informer l'utilisateur qu'une image spécifique a échoué
                # return jsonify({"output": f"Erreur lors du traitement de l'image {image.filename}: Format invalide ou fichier corrompu."}), 400
            except Exception as e:
                print(f"Unexpected error processing image {image.filename}: {e}")
                # Optionnel: retourner une erreur générique
                # return jsonify({"output": f"Erreur inattendue lors du traitement de l'image {image.filename}."}), 500

    if not valid_images_found:
         return jsonify({"output": "Aucune image valide n'a été trouvée parmi les fichiers téléchargés."}), 400


    try:
        # Générer le contenu avec toutes les images valides
        response = model.generate_content(contents)
        return jsonify({"output": response.text}), 200
    except types.generation_types.BlockedPromptException as e:
         print(f"Content generation blocked: {e}")
         return jsonify({"output": "La génération de contenu a été bloquée car la requête ou les images contenaient potentiellement du contenu non autorisé."}), 400
    except Exception as e:
        # Log l'erreur pour le débogage côté serveur
        print(f"Error during Gemini generation: {e}")
        # Retourne un message d'erreur générique
        return jsonify({"output": f"Une erreur interne est survenue lors de l'analyse des images. Veuillez réessayer."}), 500


if __name__ == '__main__':
    app.run(debug=True)
#--- END OF FILE app - 2025-04-08T095242.046.py ---