visualisation des corrections et api flask pour modifier le livre
This commit is contained in:
parent
0680c7594e
commit
7095f9633b
14 changed files with 1593 additions and 276 deletions
242
api_corrections.py
Normal file
242
api_corrections.py
Normal file
|
@ -0,0 +1,242 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
API pour traiter les requêtes de correction depuis la page web.
|
||||
Ce script:
|
||||
1. Fournit des endpoints pour appliquer des corrections au fichier livre.org
|
||||
2. Permet d'ajouter des mots au dictionnaire personnalisé
|
||||
3. Permet de marquer des erreurs comme "à ne pas traiter" dans le CSV
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import csv
|
||||
from flask import Flask, request, jsonify, Blueprint
|
||||
|
||||
# Créer un Blueprint pour l'API
|
||||
corrections_api = Blueprint('corrections_api', __name__)
|
||||
|
||||
# Chemin vers les fichiers
|
||||
LIVRE_PATH = 'livre.org'
|
||||
DICT_PATH = 'dictionnaire_personnalise.txt'
|
||||
CSV_PATH = 'resume_erreurs.csv'
|
||||
|
||||
@corrections_api.route('/api/corrections', methods=['POST'])
|
||||
def handle_corrections():
|
||||
"""Endpoint pour traiter les requêtes de correction."""
|
||||
data = request.json
|
||||
|
||||
if not data or 'action' not in data:
|
||||
return jsonify({'success': False, 'message': 'Action non spécifiée'}), 400
|
||||
|
||||
action = data['action']
|
||||
|
||||
if action == 'apply_correction':
|
||||
return apply_correction(data)
|
||||
elif action == 'ignore_error':
|
||||
return ignore_error(data)
|
||||
elif action == 'add_to_dictionary':
|
||||
return add_to_dictionary(data)
|
||||
else:
|
||||
return jsonify({'success': False, 'message': 'Action non reconnue'}), 400
|
||||
|
||||
def apply_correction(data):
|
||||
"""Applique une correction au fichier livre.org."""
|
||||
# Vérifier les paramètres requis
|
||||
required_params = ['error_type', 'chapter', 'error_index', 'correction']
|
||||
if not all(param in data for param in required_params):
|
||||
return jsonify({'success': False, 'message': 'Paramètres manquants'}), 400
|
||||
|
||||
error_type = data['error_type']
|
||||
chapter = data['chapter']
|
||||
error_index = data['error_index']
|
||||
correction = data['correction']
|
||||
|
||||
try:
|
||||
# Lire le contenu du fichier
|
||||
with open(LIVRE_PATH, 'r', encoding='utf-8') as file:
|
||||
content = file.read()
|
||||
|
||||
# Trouver la section du chapitre
|
||||
chapter_pattern = r'^\*\* ' + re.escape(chapter) + r'$(.*?)(?=^\*\* |\Z)'
|
||||
chapter_match = re.search(chapter_pattern, content, re.MULTILINE | re.DOTALL)
|
||||
|
||||
if not chapter_match:
|
||||
return jsonify({'success': False, 'message': f'Chapitre "{chapter}" non trouvé'}), 404
|
||||
|
||||
chapter_content = chapter_match.group(1)
|
||||
chapter_start = chapter_match.start()
|
||||
chapter_end = chapter_match.end()
|
||||
|
||||
# Appliquer la correction en fonction du type d'erreur
|
||||
if error_type == 'spelling':
|
||||
# Charger les erreurs d'orthographe pour ce chapitre
|
||||
errors = load_spelling_errors(chapter)
|
||||
if error_index >= len(errors):
|
||||
return jsonify({'success': False, 'message': 'Index d\'erreur invalide'}), 400
|
||||
|
||||
error = errors[error_index]
|
||||
word = error['word']
|
||||
|
||||
# Remplacer le mot dans le contenu du chapitre
|
||||
modified_chapter = re.sub(r'\b' + re.escape(word) + r'\b', correction, chapter_content)
|
||||
|
||||
# Mettre à jour le contenu complet
|
||||
new_content = content[:chapter_start] + '** ' + chapter + modified_chapter + content[chapter_end:]
|
||||
|
||||
elif error_type == 'grammar':
|
||||
# Charger les erreurs grammaticales pour ce chapitre
|
||||
errors = load_grammar_errors(chapter)
|
||||
if error_index >= len(errors):
|
||||
return jsonify({'success': False, 'message': 'Index d\'erreur invalide'}), 400
|
||||
|
||||
error = errors[error_index]
|
||||
error_text = error['error_text']
|
||||
context = error['context']
|
||||
|
||||
# Trouver le contexte dans le chapitre
|
||||
context_pattern = re.escape(context.replace(error_text, error_text))
|
||||
context_match = re.search(context_pattern, chapter_content)
|
||||
|
||||
if not context_match:
|
||||
return jsonify({'success': False, 'message': 'Contexte non trouvé dans le chapitre'}), 404
|
||||
|
||||
# Remplacer l'erreur dans le contexte
|
||||
corrected_context = context.replace(error_text, correction)
|
||||
|
||||
# Remplacer le contexte dans le chapitre
|
||||
modified_chapter = chapter_content.replace(context, corrected_context)
|
||||
|
||||
# Mettre à jour le contenu complet
|
||||
new_content = content[:chapter_start] + '** ' + chapter + modified_chapter + content[chapter_end:]
|
||||
|
||||
else:
|
||||
return jsonify({'success': False, 'message': 'Type d\'erreur non reconnu'}), 400
|
||||
|
||||
# Écrire le contenu modifié dans le fichier
|
||||
with open(LIVRE_PATH, 'w', encoding='utf-8') as file:
|
||||
file.write(new_content)
|
||||
|
||||
return jsonify({'success': True, 'message': 'Correction appliquée avec succès'})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': f'Erreur lors de l\'application de la correction: {str(e)}'}), 500
|
||||
|
||||
def ignore_error(data):
|
||||
"""Marque une erreur comme 'à ne pas traiter' dans le CSV."""
|
||||
# Vérifier les paramètres requis
|
||||
required_params = ['error_type', 'chapter', 'error_index']
|
||||
if not all(param in data for param in required_params):
|
||||
return jsonify({'success': False, 'message': 'Paramètres manquants'}), 400
|
||||
|
||||
error_type = data['error_type']
|
||||
chapter = data['chapter']
|
||||
error_index = data['error_index']
|
||||
|
||||
try:
|
||||
# Lire le CSV des erreurs
|
||||
rows = []
|
||||
with open(CSV_PATH, 'r', newline='', encoding='utf-8') as csvfile:
|
||||
reader = csv.reader(csvfile)
|
||||
headers = next(reader) # Lire les en-têtes
|
||||
|
||||
# Ajouter les en-têtes à la liste des lignes
|
||||
rows.append(headers)
|
||||
|
||||
# Parcourir les lignes et mettre à jour celle du chapitre concerné
|
||||
for row in reader:
|
||||
if len(row) > 0 and row[0] == chapter:
|
||||
# Mettre à jour la ligne en fonction du type d'erreur
|
||||
if error_type == 'spelling' and len(row) > 1:
|
||||
# Décrémenter le nombre d'erreurs d'orthographe
|
||||
spelling_errors = int(row[1]) - 1
|
||||
row[1] = str(max(0, spelling_errors))
|
||||
# Mettre à jour le total
|
||||
if len(row) > 3:
|
||||
row[3] = str(int(row[3]) - 1)
|
||||
elif error_type == 'grammar' and len(row) > 2:
|
||||
# Décrémenter le nombre d'erreurs grammaticales
|
||||
grammar_errors = int(row[2]) - 1
|
||||
row[2] = str(max(0, grammar_errors))
|
||||
# Mettre à jour le total
|
||||
if len(row) > 3:
|
||||
row[3] = str(int(row[3]) - 1)
|
||||
|
||||
rows.append(row)
|
||||
|
||||
# Écrire les modifications dans le CSV
|
||||
with open(CSV_PATH, 'w', newline='', encoding='utf-8') as csvfile:
|
||||
writer = csv.writer(csvfile)
|
||||
writer.writerows(rows)
|
||||
|
||||
return jsonify({'success': True, 'message': 'Erreur ignorée avec succès'})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': f'Erreur lors de l\'ignorance de l\'erreur: {str(e)}'}), 500
|
||||
|
||||
def add_to_dictionary(data):
|
||||
"""Ajoute un mot au dictionnaire personnalisé."""
|
||||
# Vérifier les paramètres requis
|
||||
if 'word' not in data:
|
||||
return jsonify({'success': False, 'message': 'Mot non spécifié'}), 400
|
||||
|
||||
word = data['word']
|
||||
|
||||
try:
|
||||
# Vérifier si le mot est déjà dans le dictionnaire
|
||||
existing_words = set()
|
||||
if os.path.exists(DICT_PATH):
|
||||
with open(DICT_PATH, 'r', encoding='utf-8') as file:
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#'):
|
||||
existing_words.add(line.lower())
|
||||
|
||||
# Si le mot n'est pas déjà dans le dictionnaire, l'ajouter
|
||||
if word.lower() not in existing_words:
|
||||
with open(DICT_PATH, 'a', encoding='utf-8') as file:
|
||||
file.write(f"\n{word}")
|
||||
|
||||
return jsonify({'success': True, 'message': 'Mot ajouté au dictionnaire avec succès'})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'message': f'Erreur lors de l\'ajout du mot au dictionnaire: {str(e)}'}), 500
|
||||
|
||||
def load_spelling_errors(chapter):
|
||||
"""Charge les erreurs d'orthographe pour un chapitre donné depuis le rapport."""
|
||||
# Cette fonction devrait charger les erreurs d'orthographe depuis le rapport
|
||||
# Pour simplifier, nous utilisons une implémentation fictive
|
||||
# Dans une implémentation réelle, il faudrait parser le rapport d'erreurs
|
||||
|
||||
# Exemple d'implémentation fictive
|
||||
from generate_corrections_page import parse_error_report
|
||||
|
||||
errors_by_chapter = parse_error_report('rapport_orthographe_grammaire.md')
|
||||
|
||||
if chapter in errors_by_chapter:
|
||||
return errors_by_chapter[chapter]['spelling']
|
||||
|
||||
return []
|
||||
|
||||
def load_grammar_errors(chapter):
|
||||
"""Charge les erreurs grammaticales pour un chapitre donné depuis le rapport."""
|
||||
# Cette fonction devrait charger les erreurs grammaticales depuis le rapport
|
||||
# Pour simplifier, nous utilisons une implémentation fictive
|
||||
# Dans une implémentation réelle, il faudrait parser le rapport d'erreurs
|
||||
|
||||
# Exemple d'implémentation fictive
|
||||
from generate_corrections_page import parse_error_report
|
||||
|
||||
errors_by_chapter = parse_error_report('rapport_orthographe_grammaire.md')
|
||||
|
||||
if chapter in errors_by_chapter:
|
||||
return errors_by_chapter[chapter]['grammar']
|
||||
|
||||
return []
|
||||
|
||||
# Pour tester l'API indépendamment
|
||||
if __name__ == '__main__':
|
||||
app = Flask(__name__)
|
||||
app.register_blueprint(corrections_api)
|
||||
app.run(debug=True, port=5001)
|
Loading…
Add table
Add a link
Reference in a new issue