242 lines
No EOL
9.8 KiB
Python
242 lines
No EOL
9.8 KiB
Python
#!/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) |