Docfile commited on
Commit
5d73b6a
·
verified ·
1 Parent(s): 811b997

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -399
app.py DELETED
@@ -1,399 +0,0 @@
1
- from flask import Flask, render_template, request, send_file
2
- import os
3
- import convertapi
4
- from docx import Document
5
- from docx.shared import Pt, Cm, RGBColor
6
- from docx.enum.text import WD_ALIGN_PARAGRAPH
7
- from docx.enum.table import WD_TABLE_ALIGNMENT
8
- from docx.oxml.ns import nsdecls
9
- from docx.oxml import parse_xml
10
-
11
- # Configuration des identifiants ConvertAPI
12
- convertapi.api_credentials = 'secret_8wCI6pgOP9AxLVJG'
13
-
14
- # --- Classe de génération de document ---
15
- class EvaluationGymnique:
16
- def __init__(self):
17
- self.document = Document()
18
- self.document.sections[0].page_height = Cm(29.7)
19
- self.document.sections[0].page_width = Cm(21)
20
- self.document.sections[0].left_margin = Cm(1.5)
21
- self.document.sections[0].right_margin = Cm(1.5)
22
- self.document.sections[0].top_margin = Cm(1)
23
- self.document.sections[0].bottom_margin = Cm(1)
24
-
25
- # Informations d'en-tête par défaut
26
- self.centre_examen = "Centre d'examen"
27
- self.type_examen = "Bac Général"
28
- self.serie = "Série"
29
- self.etablissement = "Établissement"
30
- self.session = "2025"
31
- self.nom_candidat = "Candidat"
32
-
33
- # Liste vide pour les éléments techniques
34
- self.elements_techniques = []
35
- self.appreciations = ["M", "PM", "NM", "NR"]
36
-
37
- def ajouter_entete_colore(self):
38
- header_paragraph = self.document.add_paragraph()
39
- header_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
40
- header_paragraph.space_after = Pt(6)
41
- header_run = header_paragraph.add_run("ÉVALUATION GYMNASTIQUE")
42
- header_run.bold = True
43
- header_run.font.size = Pt(14)
44
- header_run.font.color.rgb = RGBColor(0, 32, 96)
45
-
46
- header_table = self.document.add_table(rows=3, cols=2)
47
- header_table.style = 'Table Grid'
48
- header_table.autofit = False
49
-
50
- for row in header_table.rows:
51
- row.height = Cm(0.8)
52
- for row in header_table.rows:
53
- for cell in row.cells:
54
- shading_elm = parse_xml(f'<w:shd {nsdecls("w")} w:fill="D9E2F3"/>')
55
- cell._tc.get_or_add_tcPr().append(shading_elm)
56
-
57
- # Première ligne
58
- cell = header_table.cell(0, 0)
59
- paragraph = cell.paragraphs[0]
60
- run = paragraph.add_run("Centre d'examen: ")
61
- run.bold = True
62
- run.font.size = Pt(10)
63
- run.font.color.rgb = RGBColor(0, 32, 96)
64
- paragraph.add_run(self.centre_examen).font.size = Pt(10)
65
-
66
- cell = header_table.cell(0, 1)
67
- paragraph = cell.paragraphs[0]
68
- run = paragraph.add_run("Examen: ")
69
- run.bold = True
70
- run.font.size = Pt(10)
71
- run.font.color.rgb = RGBColor(0, 32, 96)
72
- paragraph.add_run(self.type_examen).font.size = Pt(10)
73
-
74
- # Deuxième ligne
75
- cell = header_table.cell(1, 0)
76
- paragraph = cell.paragraphs[0]
77
- run = paragraph.add_run("Série: ")
78
- run.bold = True
79
- run.font.size = Pt(10)
80
- run.font.color.rgb = RGBColor(0, 32, 96)
81
- paragraph.add_run(self.serie).font.size = Pt(10)
82
-
83
- cell = header_table.cell(1, 1)
84
- paragraph = cell.paragraphs[0]
85
- run = paragraph.add_run("Établissement: ")
86
- run.bold = True
87
- run.font.size = Pt(10)
88
- run.font.color.rgb = RGBColor(0, 32, 96)
89
- paragraph.add_run(self.etablissement).font.size = Pt(10)
90
-
91
- # Troisième ligne
92
- cell = header_table.cell(2, 0)
93
- paragraph = cell.paragraphs[0]
94
- run = paragraph.add_run("Session: ")
95
- run.bold = True
96
- run.font.size = Pt(10)
97
- run.font.color.rgb = RGBColor(0, 32, 96)
98
- paragraph.add_run(self.session).font.size = Pt(10)
99
-
100
- cell = header_table.cell(2, 1)
101
- paragraph = cell.paragraphs[0]
102
- run = paragraph.add_run("Candidat: ")
103
- run.bold = True
104
- run.font.size = Pt(10)
105
- run.font.color.rgb = RGBColor(0, 32, 96)
106
- paragraph.add_run(self.nom_candidat).font.size = Pt(10)
107
-
108
- self.document.add_paragraph().space_after = Pt(4)
109
-
110
- def creer_tableau_elements(self):
111
- table = self.document.add_table(rows=len(self.elements_techniques) + 1, cols=5)
112
- table.style = 'Table Grid'
113
- table.alignment = WD_TABLE_ALIGNMENT.CENTER
114
-
115
- # Configuration des largeurs de colonnes
116
- for cell in table.columns[0].cells:
117
- cell.width = Cm(8)
118
- for cell in table.columns[1].cells:
119
- cell.width = Cm(3)
120
- for cell in table.columns[2].cells:
121
- cell.width = Cm(2)
122
- for cell in table.columns[3].cells:
123
- cell.width = Cm(2.5)
124
- for cell in table.columns[4].cells:
125
- cell.width = Cm(2.5)
126
-
127
- # Réduire la hauteur des lignes
128
- for row in table.rows:
129
- row.height = Cm(0.8) # Réduit de 1cm à 0.8cm
130
-
131
- # En-tête du tableau
132
- header_row = table.rows[0]
133
- for cell in header_row.cells:
134
- shading_elm = parse_xml(f'<w:shd {nsdecls("w")} w:fill="BDD7EE"/>')
135
- cell._tc.get_or_add_tcPr().append(shading_elm)
136
-
137
- headers = ["ELEMENTS TECHNIQUES", "CATEGORIES D'ELEMENTS TECHNIQUES ET PONDERATION", "", "APPRECIATIONS", "POINTS Accordés"]
138
- for i, header in enumerate(headers):
139
- cell = table.cell(0, i)
140
- cell.text = header
141
- cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
142
- run = cell.paragraphs[0].runs[0]
143
- run.bold = True
144
- run.font.size = Pt(9)
145
- run.font.color.rgb = RGBColor(0, 32, 96)
146
- table.cell(0, 1).merge(table.cell(0, 2))
147
-
148
- # Ajout des éléments techniques
149
- for i, element in enumerate(self.elements_techniques, 1):
150
- element_cell = table.cell(i, 0)
151
- element_cell.text = element["nom"]
152
- element_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.LEFT
153
- run = element_cell.paragraphs[0].runs[0]
154
- run.bold = True
155
- run.font.size = Pt(9)
156
-
157
- categorie_cell = table.cell(i, 1)
158
- categorie_cell.text = element["categorie"]
159
- categorie_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
160
- run = categorie_cell.paragraphs[0].runs[0]
161
- run.bold = True
162
- run.font.size = Pt(9)
163
- run.italic = True
164
-
165
- points_cell = table.cell(i, 2)
166
- points_cell.text = str(element["points"])
167
- points_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
168
- run = points_cell.paragraphs[0].runs[0]
169
- run.bold = True
170
- run.font.size = Pt(9)
171
- run.italic = True
172
-
173
- def ajouter_note_jury(self):
174
- para = self.document.add_paragraph()
175
- para.space_before = Pt(4)
176
- para.space_after = Pt(4)
177
- run = para.add_run("NB1 : Zone réservée aux membres du jury ! Le jury cochera le point correspondant au niveau de réalisation de l'élément gymnique par le candidat.")
178
- run.bold = True
179
- run.font.color.rgb = RGBColor(255, 0, 0)
180
- run.font.size = Pt(9)
181
-
182
- def creer_tableau_recapitulatif(self):
183
- note_table = self.document.add_table(rows=3, cols=13)
184
- note_table.style = 'Table Grid'
185
- note_table.alignment = WD_TABLE_ALIGNMENT.CENTER
186
-
187
- for row in note_table.rows:
188
- row.height = Cm(0.6)
189
- for cell in note_table.rows[0].cells:
190
- shading_elm = parse_xml(f'<w:shd {nsdecls("w")} w:fill="BDD7EE"/>')
191
- cell._tc.get_or_add_tcPr().append(shading_elm)
192
-
193
- for col, (type_lettre, points) in enumerate([("A", "1pt"), ("B", "1,5pt"), ("C", "2pts"), ("D", "2,5pts"), ("E", "3pts")]):
194
- idx = col * 2
195
- if idx + 1 < len(note_table.columns):
196
- cell = note_table.cell(0, idx)
197
- cell.merge(note_table.cell(0, idx + 1))
198
- cell.text = f"Type {type_lettre}\n{points}"
199
- cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
200
- for run in cell.paragraphs[0].runs:
201
- run.bold = True
202
- run.font.size = Pt(9)
203
- run.font.color.rgb = RGBColor(0, 32, 96)
204
-
205
- for col, (titre, points) in enumerate([("ROV", "2pts"), ("Projet", "2pts"), ("Réalisation", "16pts")], 10):
206
- if col < len(note_table.columns):
207
- cell = note_table.cell(0, col)
208
- cell.text = f"{titre}\n{points}"
209
- cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
210
- for run in cell.paragraphs[0].runs:
211
- run.bold = True
212
- run.font.size = Pt(9)
213
- run.font.color.rgb = RGBColor(0, 32, 96)
214
-
215
- for col in range(5):
216
- idx = col * 2
217
- if idx + 1 < len(note_table.columns):
218
- neg_cell = note_table.cell(1, idx)
219
- neg_cell.text = "NEG"
220
- neg_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
221
- for run in neg_cell.paragraphs[0].runs:
222
- run.italic = True
223
- run.font.size = Pt(9)
224
-
225
- note_cell = note_table.cell(1, idx + 1)
226
- note_cell.text = "Note"
227
- note_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
228
- for run in note_cell.paragraphs[0].runs:
229
- run.italic = True
230
- run.font.size = Pt(9)
231
-
232
- for col in range(10, 13):
233
- if col < len(note_table.columns):
234
- cell = note_table.cell(1, col)
235
- cell.text = "Note"
236
- cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
237
- for run in cell.paragraphs[0].runs:
238
- run.italic = True
239
- run.font.size = Pt(9)
240
-
241
- for col, type_lettre in enumerate(["A", "B", "C", "D", "E"]):
242
- idx = col * 2
243
- if idx < len(note_table.columns):
244
- neg_cell = note_table.cell(2, idx)
245
- neg_cell.text = ""
246
- neg_cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
247
-
248
- def ajouter_zone_note(self):
249
- zone_note = self.document.add_table(rows=1, cols=2)
250
- zone_note.style = 'Table Grid'
251
- zone_note.alignment = WD_TABLE_ALIGNMENT.RIGHT
252
-
253
- # Réduire la largeur des cellules
254
- cell_width = Cm(1.8) # Réduit de 2cm à 1.8cm
255
-
256
- cell_libelle = zone_note.cell(0, 0)
257
- cell_libelle.width = cell_width
258
- cell_libelle.text = "Note finale"
259
- cell_libelle.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.RIGHT
260
- run = cell_libelle.paragraphs[0].runs[0]
261
- run.bold = True
262
- run.font.size = Pt(10) # Légèrement réduit de 11pt à 10pt
263
- run.font.color.rgb = RGBColor(0, 32, 96)
264
-
265
- cell_saisie = zone_note.cell(0, 1)
266
- cell_saisie.width = cell_width
267
- # Réduire la hauteur de la ligne également
268
- zone_note.rows[0].height = Cm(1.2) # Réduit de 2cm à 1.2cm
269
- shading_elm = parse_xml(f'<w:shd {nsdecls("w")} w:fill="F2F2F2"/>')
270
- cell_saisie._tc.get_or_add_tcPr().append(shading_elm)
271
- cell_saisie.text = "/20"
272
- cell_saisie.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
273
- run = cell_saisie.paragraphs[0].runs[0]
274
- run.bold = True
275
- run.font.size = Pt(10) # Légèrement réduit de 11pt à 10pt
276
-
277
- def ajouter_note_candidat_avec_cadre(self):
278
- # Pas d'espace supplémentaire avant
279
- note_table = self.document.add_table(rows=1, cols=1)
280
- note_table.style = 'Table Grid'
281
- note_table.alignment = WD_TABLE_ALIGNMENT.CENTER
282
-
283
- cell = note_table.cell(0, 0)
284
- shading_elm = parse_xml(f'<w:shd {nsdecls("w")} w:fill="E2EFDA"/>')
285
- cell._tc.get_or_add_tcPr().append(shading_elm)
286
-
287
- p = cell.paragraphs[0]
288
- run = p.add_run("NB2: Après le choix des catégories d'éléments gymniques par le candidat, ce dernier remplira la colonne de pointage selon l'orientation suivante: A (0.25; 0.5; 0.75; 1) B (0.25; 0.5; 0.75; 1; 1.25; 1.5) C (0.5; 0.75; 1; 1.25; 1.5; 2) D (0.75; 1; 1.25; 1.5; 2; 2.5) et E (0.75; 1; 1.5; 2; 2.5; 3) également, le candidat devra fournir 2 copies de son projet sur une page! (appréciations: NR, NM, PM, M).")
289
- run.italic = True
290
- run.font.size = Pt(7) # Légèrement réduit de 8pt à 7pt
291
-
292
- # Ajouter un petit espace après
293
- self.document.add_paragraph().space_after = Pt(3)
294
-
295
- def ajouter_lignes_correcteurs(self):
296
- # Réduire l'espace avant
297
- para_intro = self.document.add_paragraph()
298
- para_intro.space_before = Pt(3) # Réduit de 6pt à 3pt
299
-
300
- for role in ["Projet", "principal", "ROV"]:
301
- para = self.document.add_paragraph()
302
- para.space_before = Pt(1) # Réduit de 2pt à 1pt
303
- para.space_after = Pt(1) # Réduit de 2pt à 1pt
304
- run = para.add_run(f"Correcteur {role} : ")
305
- run.bold = True
306
- para.add_run(".................................................................")
307
-
308
- # Méthodes de modification des données
309
- def modifier_centre_examen(self, nom):
310
- self.centre_examen = nom
311
-
312
- def modifier_type_examen(self, type_examen):
313
- self.type_examen = type_examen
314
-
315
- def modifier_serie(self, serie):
316
- self.serie = serie
317
-
318
- def modifier_etablissement(self, nom):
319
- self.etablissement = nom
320
-
321
- def modifier_session(self, annee):
322
- self.session = annee
323
-
324
- def modifier_candidat(self, nom):
325
- self.nom_candidat = nom
326
-
327
- def ajouter_element(self, nom, categorie, points):
328
- self.elements_techniques.append({
329
- "nom": nom,
330
- "categorie": categorie,
331
- "points": float(points)
332
- })
333
-
334
- def generer_document(self, nom_fichier="evaluation_gymnastique.docx"):
335
- self.ajouter_entete_colore()
336
- self.creer_tableau_elements()
337
- self.ajouter_note_jury()
338
- self.creer_tableau_recapitulatif()
339
- self.ajouter_zone_note() # Zone de note finale
340
- self.ajouter_note_candidat_avec_cadre() # NB2 juste après la note finale
341
- self.ajouter_lignes_correcteurs() # Déplacé après le NB2
342
- self.document.save(nom_fichier)
343
- return nom_fichier
344
-
345
- # --- Application Flask ---
346
- app = Flask(__name__)
347
-
348
- @app.route("/", methods=["GET", "POST"])
349
- def index():
350
- if request.method == "POST":
351
- # Récupération des informations depuis le formulaire
352
- centre_examen = request.form.get("centre_examen", "Centre d'examen")
353
- type_examen = request.form.get("type_examen", "Bac Général")
354
- serie = request.form.get("serie", "Série")
355
- etablissement = request.form.get("etablissement", "Établissement")
356
- session_value = request.form.get("session", "2025")
357
- nom_candidat = request.form.get("nom_candidat", "Candidat")
358
-
359
- # Création et configuration du document
360
- evaluation = EvaluationGymnique()
361
- evaluation.modifier_centre_examen(centre_examen)
362
- evaluation.modifier_type_examen(type_examen)
363
- evaluation.modifier_serie(serie)
364
- evaluation.modifier_etablissement(etablissement)
365
- evaluation.modifier_session(session_value)
366
- evaluation.modifier_candidat(nom_candidat)
367
-
368
- # Récupération des éléments techniques ajoutés dynamiquement
369
- element_names = request.form.getlist("new_element_name")
370
- element_categories = request.form.getlist("new_element_categorie")
371
- element_points = request.form.getlist("new_element_points")
372
- for name, cat, pts in zip(element_names, element_categories, element_points):
373
- if name and cat and pts:
374
- evaluation.ajouter_element(name, cat, pts)
375
-
376
- # Génération du document DOCX
377
- filename = "evaluation_gymnastique.docx"
378
- evaluation.generer_document(filename)
379
-
380
- # Vérification du format de sortie demandé
381
- output_format = request.form.get("format", "docx")
382
- if output_format == "pdf":
383
- # Conversion en PDF via ConvertAPI
384
- result = convertapi.convert('pdf', {
385
- 'File': filename,
386
- 'FileName': 'evaluation_gymnastique',
387
- 'ConvertMetadata': 'false',
388
- 'ConvertHeadings': 'false'
389
- }, from_format='doc')
390
- pdf_filename = "evaluation_gymnastique.pdf"
391
- result.save_files(pdf_filename)
392
- return send_file(pdf_filename, as_attachment=True)
393
- else:
394
- return send_file(filename, as_attachment=True)
395
-
396
- return render_template("index.html")
397
-
398
- if __name__ == "__main__":
399
- app.run(debug=True)