Spaces:
Sleeping
Sleeping
nettoyage des html dans transformation en txt
Browse files
main.py
CHANGED
@@ -687,6 +687,30 @@ async def clean_html_content(html_content: str, image_counter: List[int], images
|
|
687 |
# Return the cleaned HTML as a string
|
688 |
return str(soup)
|
689 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
690 |
|
691 |
def reinsert_images(html_content: str, images_data: Dict[str, Dict[str, str]]) -> str:
|
692 |
"""Function to re-integrate images and their descriptions into the final HTML code."""
|
@@ -803,11 +827,15 @@ async def get_result(job_id: str):
|
|
803 |
|
804 |
|
805 |
def delete_temp_files(file_paths: list):
|
806 |
-
"""
|
807 |
for file_path in file_paths:
|
808 |
-
|
809 |
-
os.
|
810 |
-
|
|
|
|
|
|
|
|
|
811 |
|
812 |
@app.post("/convert_to_txt/")
|
813 |
async def convert_file_to_txt(
|
@@ -815,32 +843,42 @@ async def convert_file_to_txt(
|
|
815 |
background_tasks: BackgroundTasks = BackgroundTasks()
|
816 |
):
|
817 |
try:
|
818 |
-
#
|
819 |
original_filename = file.filename
|
820 |
base_filename, ext = os.path.splitext(original_filename)
|
821 |
ext = ext.lower()
|
822 |
|
823 |
-
#
|
824 |
allowed_extensions = [
|
825 |
'.odt', '.pdf', '.docx', '.html', '.htm', '.md', '.txt', '.rtf', '.epub',
|
826 |
'.tex', '.xml', '.org', '.commonmark', '.cm', '.wiki', '.opml'
|
827 |
]
|
828 |
|
829 |
if ext not in allowed_extensions:
|
830 |
-
raise HTTPException(status_code=400, detail=f"
|
831 |
|
832 |
-
#
|
833 |
with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as input_tmp_file:
|
834 |
input_filename = input_tmp_file.name
|
835 |
with open(input_filename, "wb") as f:
|
836 |
shutil.copyfileobj(file.file, f)
|
837 |
-
logging.debug(f"
|
838 |
-
|
839 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
840 |
unique_id = uuid.uuid4().hex
|
841 |
output_filename = os.path.join(tempfile.gettempdir(), f"{base_filename}_{unique_id}.txt")
|
842 |
|
843 |
-
# PDF
|
844 |
if ext == '.pdf':
|
845 |
text = ""
|
846 |
with fitz.open(input_filename) as doc:
|
@@ -848,27 +886,40 @@ async def convert_file_to_txt(
|
|
848 |
text += page.get_text()
|
849 |
with open(output_filename, "w", encoding="utf-8") as f:
|
850 |
f.write(text)
|
851 |
-
logging.debug(f"PDF
|
852 |
|
853 |
-
#
|
854 |
else:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
855 |
output = pypandoc.convert_file(input_filename, 'plain', outputfile=output_filename)
|
856 |
-
logging.debug(f"Conversion
|
857 |
|
858 |
-
#
|
859 |
if not os.path.exists(output_filename):
|
860 |
-
logging.error(f"
|
861 |
-
raise HTTPException(status_code=500, detail="
|
862 |
|
863 |
-
#
|
864 |
-
|
|
|
|
|
|
|
|
|
865 |
|
866 |
-
#
|
867 |
return FileResponse(output_filename, filename=f"{base_filename}.txt")
|
868 |
|
869 |
except HTTPException as http_exc:
|
870 |
-
logging.error(f"HTTP
|
871 |
return JSONResponse(status_code=http_exc.status_code, content={"message": http_exc.detail})
|
872 |
except Exception as e:
|
873 |
-
logging.error(f"
|
874 |
-
return JSONResponse(status_code=500, content={"message": f"
|
|
|
|
687 |
# Return the cleaned HTML as a string
|
688 |
return str(soup)
|
689 |
|
690 |
+
def clean_html_file(input_filepath: str, cleaned_output_filepath: str) -> bool:
|
691 |
+
"""
|
692 |
+
Nettoie le contenu HTML en utilisant readability-lxml et écrit le contenu nettoyé dans un nouveau fichier.
|
693 |
+
|
694 |
+
Args:
|
695 |
+
input_filepath (str): Chemin vers le fichier HTML original.
|
696 |
+
cleaned_output_filepath (str): Chemin vers le fichier HTML nettoyé.
|
697 |
+
|
698 |
+
Returns:
|
699 |
+
bool: True si le nettoyage a réussi, False sinon.
|
700 |
+
"""
|
701 |
+
try:
|
702 |
+
with open(input_filepath, 'r', encoding='utf-8') as f:
|
703 |
+
html_content = f.read()
|
704 |
+
doc = Document(html_content)
|
705 |
+
cleaned_html = doc.summary() # Extrait le HTML principal
|
706 |
+
with open(cleaned_output_filepath, 'w', encoding='utf-8') as f:
|
707 |
+
f.write(cleaned_html)
|
708 |
+
logging.debug("Contenu HTML nettoyé avec readability-lxml.")
|
709 |
+
return True
|
710 |
+
except Exception as e:
|
711 |
+
logging.error(f"Erreur lors du nettoyage du fichier HTML {input_filepath} : {str(e)}")
|
712 |
+
return False
|
713 |
+
|
714 |
|
715 |
def reinsert_images(html_content: str, images_data: Dict[str, Dict[str, str]]) -> str:
|
716 |
"""Function to re-integrate images and their descriptions into the final HTML code."""
|
|
|
827 |
|
828 |
|
829 |
def delete_temp_files(file_paths: list):
|
830 |
+
"""Fonction pour supprimer les fichiers temporaires après la réponse."""
|
831 |
for file_path in file_paths:
|
832 |
+
try:
|
833 |
+
if os.path.exists(file_path):
|
834 |
+
os.remove(file_path)
|
835 |
+
logging.debug(f"Fichier temporaire supprimé : {file_path}")
|
836 |
+
except Exception as e:
|
837 |
+
logging.error(f"Erreur lors de la suppression du fichier {file_path} : {str(e)}")
|
838 |
+
|
839 |
|
840 |
@app.post("/convert_to_txt/")
|
841 |
async def convert_file_to_txt(
|
|
|
843 |
background_tasks: BackgroundTasks = BackgroundTasks()
|
844 |
):
|
845 |
try:
|
846 |
+
# Nom de fichier original et extension
|
847 |
original_filename = file.filename
|
848 |
base_filename, ext = os.path.splitext(original_filename)
|
849 |
ext = ext.lower()
|
850 |
|
851 |
+
# Extensions autorisées pour la conversion
|
852 |
allowed_extensions = [
|
853 |
'.odt', '.pdf', '.docx', '.html', '.htm', '.md', '.txt', '.rtf', '.epub',
|
854 |
'.tex', '.xml', '.org', '.commonmark', '.cm', '.wiki', '.opml'
|
855 |
]
|
856 |
|
857 |
if ext not in allowed_extensions:
|
858 |
+
raise HTTPException(status_code=400, detail=f"Extension de fichier non supportée : {ext}")
|
859 |
|
860 |
+
# Créer un fichier temporaire d'entrée avec la bonne extension
|
861 |
with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as input_tmp_file:
|
862 |
input_filename = input_tmp_file.name
|
863 |
with open(input_filename, "wb") as f:
|
864 |
shutil.copyfileobj(file.file, f)
|
865 |
+
logging.debug(f"Fichier téléchargé enregistré : {input_filename}")
|
866 |
+
|
867 |
+
# Si le fichier est HTML ou HTM, effectuer le nettoyage
|
868 |
+
if ext in ['.html', '.htm']:
|
869 |
+
cleaned_input_filename = input_filename + '_cleaned.html'
|
870 |
+
nettoyage_reussi = clean_html_file(input_filename, cleaned_input_filename)
|
871 |
+
if not nettoyage_reussi:
|
872 |
+
raise HTTPException(status_code=500, detail="Erreur lors du nettoyage du fichier HTML.")
|
873 |
+
# Utiliser le fichier nettoyé pour la conversion
|
874 |
+
input_filename = cleaned_input_filename
|
875 |
+
logging.debug(f"Fichier HTML nettoyé enregistré : {input_filename}")
|
876 |
+
|
877 |
+
# Définir le nom du fichier de sortie, en conservant le même nom de base mais avec l'extension .txt
|
878 |
unique_id = uuid.uuid4().hex
|
879 |
output_filename = os.path.join(tempfile.gettempdir(), f"{base_filename}_{unique_id}.txt")
|
880 |
|
881 |
+
# Conversion de PDF en texte avec PyMuPDF
|
882 |
if ext == '.pdf':
|
883 |
text = ""
|
884 |
with fitz.open(input_filename) as doc:
|
|
|
886 |
text += page.get_text()
|
887 |
with open(output_filename, "w", encoding="utf-8") as f:
|
888 |
f.write(text)
|
889 |
+
logging.debug(f"Conversion PDF réussie avec PyMuPDF : {output_filename}")
|
890 |
|
891 |
+
# Conversion des autres formats en texte avec Pandoc
|
892 |
else:
|
893 |
+
# Pour Markdown, assurez-vous que le contenu est nettoyé si nécessaire
|
894 |
+
if ext in ['.md', '.markdown']:
|
895 |
+
with open(input_filename, 'r', encoding='utf-8') as f:
|
896 |
+
content = f.read()
|
897 |
+
# Optionnel : appliquer des nettoyages spécifiques au Markdown
|
898 |
+
with open(input_filename, 'w', encoding='utf-8') as f:
|
899 |
+
f.write(content) # Ici, aucun nettoyage spécifique
|
900 |
+
|
901 |
output = pypandoc.convert_file(input_filename, 'plain', outputfile=output_filename)
|
902 |
+
logging.debug(f"Conversion réussie avec Pandoc : {output_filename}")
|
903 |
|
904 |
+
# Vérifier si le fichier .txt existe
|
905 |
if not os.path.exists(output_filename):
|
906 |
+
logging.error(f"Le fichier {output_filename} n'a pas été généré.")
|
907 |
+
raise HTTPException(status_code=500, detail="Erreur lors de la conversion.")
|
908 |
|
909 |
+
# Ajouter les fichiers temporaires à la tâche d'arrière-plan pour suppression après l'envoi de la réponse
|
910 |
+
# Inclure le fichier nettoyé s'il existe
|
911 |
+
temp_files_to_delete = [input_filename, output_filename]
|
912 |
+
if ext in ['.html', '.htm']:
|
913 |
+
temp_files_to_delete.append(cleaned_input_filename)
|
914 |
+
background_tasks.add_task(delete_temp_files, temp_files_to_delete)
|
915 |
|
916 |
+
# Retourner le fichier converti au client, avec le même nom de base et l'extension .txt
|
917 |
return FileResponse(output_filename, filename=f"{base_filename}.txt")
|
918 |
|
919 |
except HTTPException as http_exc:
|
920 |
+
logging.error(f"Erreur HTTP lors de la conversion : {str(http_exc.detail)}")
|
921 |
return JSONResponse(status_code=http_exc.status_code, content={"message": http_exc.detail})
|
922 |
except Exception as e:
|
923 |
+
logging.error(f"Erreur interne lors de la conversion : {str(e)}")
|
924 |
+
return JSONResponse(status_code=500, content={"message": f"Erreur interne : {str(e)}"})
|
925 |
+
|