Spaces:
Running
Running
File size: 5,252 Bytes
3dc6c49 fb9658c 3dc6c49 fb9658c d973914 fb9658c d973914 fb9658c d973914 fb9658c d973914 fb9658c d973914 3dc6c49 d973914 3dc6c49 d973914 3dc6c49 d973914 3dc6c49 fb9658c 3dc6c49 d973914 3dc6c49 4cc0fc9 3dc6c49 c43ad59 3e27b44 3dc6c49 fb9658c | 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 | #!/usr/bin/env python
import os
import re
import tempfile
from pathlib import Path
import pdfplumber
import docx
import gradio as gr
def clean_text_for_rag(text: str) -> str:
"""Normalise et nettoie le texte pour un usage RAG."""
# Normalisation des caractères typographiques
text = re.sub(
r"[’‘“”«»–—\u00A0\u202F…œŒæÆ©®™§°±×÷]",
lambda m: {
"’": "'", "‘": "'", "“": '"', "”": '"',
"«": '"', "»": '"', "–": "-", "—": "-",
"…": "...", "œ": "oe", "Œ": "OE",
"æ": "ae", "Æ": "AE", "©": "(c)", "®": "(R)",
"™": "TM", "§": "§", "°": "°", "±": "+/-",
"×": "x", "÷": "/"
}.get(m.group(0), m.group(0)),
text,
)
# Conserver uniquement les caractères suivants
text = re.sub(r'[^a-zA-ZÀ-ÿæ-œ0-9\s\.\,\:\;\!\?\-\_\'\"\\\(\)]', '', text)
# Réduire les espaces multiples
return re.sub(r'\s+', ' ', text).strip()
def extract_and_clean_pdf(pdf_path: str) -> str:
"""Ouvre le PDF, récupère le texte et le nettoie."""
print(f"[+] Extraction du PDF : {pdf_path}")
all_pages = []
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
txt = page.extract_text()
if txt:
all_pages.append(txt)
return clean_text_for_rag(" ".join(all_pages))
def extract_and_clean_docx(docx_path: str) -> str:
"""Lit un fichier DOCX et le nettoie."""
print(f"[+] Extraction du DOCX : {docx_path}")
doc = docx.Document(docx_path)
paragraphs = []
for para in doc.paragraphs:
text = para.text.strip()
if text:
paragraphs.append(text)
return clean_text_for_rag(" ".join(paragraphs))
def extract_and_clean_txt(txt_path: str) -> str:
"""Lit un fichier texte (txt, md, …) et le nettoie."""
print(f"[+] Lecture du fichier texte : {txt_path}")
with open(txt_path, "r", encoding="utf-8") as f:
lines = f.readlines()
cleaned = [
clean_text_for_rag(line.strip())
for line in lines
if line.strip()
]
return "\n".join(cleaned)
def process_file(input_file, output_name):
"""
- Detecte le type (PDF ou texte)
- Effectue l'extraction + nettoyage
- Crée un fichier temporaire **avec le nom choisi** (output_name)
- Retourne le chemin du fichier temporaire (Gradio le propose en téléchargement)
"""
if input_file is None:
return None
if hasattr(input_file, "read"):
data = input_file.read()
filename = input_file.name
elif isinstance(input_file, str):
filename = input_file
with open(input_file, "rb") as f:
data = f.read()
else:
filename = input_file[0].name
data = input_file[0].read()
# écrire dans /tmp (important sur HF Spaces)
suffix = os.path.splitext(filename)[1]
tmp_path = os.path.join(tempfile.gettempdir(), "upload" + suffix)
with open(tmp_path, "wb") as f:
f.write(data)
ext = suffix.lower()
if ext == ".pdf":
cleaned_text = extract_and_clean_pdf(tmp_path)
elif ext == ".docx":
cleaned_text = extract_and_clean_docx(tmp_path)
else:
cleaned_text = extract_and_clean_txt(tmp_path)
if not output_name.lower().endswith(".md"):
output_name += ".md"
out_path = os.path.join(tempfile.gettempdir(), output_name)
with open(out_path, "w", encoding="utf-8") as f:
f.write(cleaned_text)
return out_path
with gr.Blocks(title="Nettoyage de texte pour RAG") as demo:
gr.Markdown("# 📄 Nettoyage d'un fichier pour optimisation de vos pipelines RAG")
gr.Markdown(
"Déposez simplement votre fichier : nous nous chargeons d’extraire son contenu textuel, de le nettoyer "
"puis de vous le restituer en format markdown **sous le nom que vous choisissez.**"
)
with gr.Row():
with gr.Column(scale=1):
input_file = gr.File(
label="Déposez votre fichier ici",
file_types=[".pdf", ".txt", ".md", ".docx"],
file_count="single",
)
output_name = gr.Textbox(
value="output.md",
label="Nom du fichier de sortie (en .md)",
placeholder="exemple.md",
interactive=True,
)
submit_btn = gr.Button("Traiter le fichier", variant="primary")
with gr.Column(scale=1):
output_file = gr.File(
label="Fichier nettoyé (.md)",
file_types=["md"],
)
submit_btn.click(
fn=process_file,
inputs=[input_file, output_name],
outputs=output_file,
)
gr.Markdown(
"""
---
**Prétraitements effectués :**
- Suppression des symboles non imprimables et des caractères parasites
- Conservation des lettres (y compris accentuées), chiffres, espaces et ponctuation simple
- Normalisation des espaces pour un texte harmonieux
- Export automatique au format **`.md`**
"""
)
if __name__ == "__main__":
demo.launch() |