Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
@@ -548,7 +548,7 @@ def reinsert_images(html_content: str, images_data: Dict[str, Dict[str, str]]) -
|
|
548 |
if image_key in images_data:
|
549 |
img_tag = soup.new_tag('img')
|
550 |
img_tag['src'] = f"data:image/jpeg;base64,{images_data[image_key]['base64_image']}"
|
551 |
-
img_tag['alt'] = images_data[image_key]
|
552 |
|
553 |
new_content = soup.new_tag('div')
|
554 |
new_content.append(img_tag)
|
@@ -559,19 +559,20 @@ def reinsert_images(html_content: str, images_data: Dict[str, Dict[str, str]]) -
|
|
559 |
p_tag.append(strong_tag)
|
560 |
p_tag.append(" : ")
|
561 |
|
562 |
-
y_markdown = images_data[image_key]
|
563 |
y_html = markdown_to_html(y_markdown)
|
564 |
y_soup = BeautifulSoup(y_html, 'html.parser')
|
565 |
p_tag.append(y_soup)
|
566 |
|
567 |
new_content.append(p_tag)
|
568 |
comment.replace_with(new_content)
|
|
|
569 |
else:
|
570 |
logging.error(f"Données pour {image_key} non trouvées.")
|
571 |
-
|
572 |
return str(soup)
|
573 |
|
574 |
|
|
|
575 |
def pdf_to_html(input_filename: str) -> str:
|
576 |
soup = BeautifulSoup("<html><head></head><body></body></html>", 'html.parser')
|
577 |
body = soup.body
|
@@ -770,6 +771,7 @@ def extract_text_with_image_markers(input_filename: str) -> Tuple[str, List[Tupl
|
|
770 |
try:
|
771 |
page_data = json.loads(page_json) # Parse le JSON en dict
|
772 |
blocks = page_data["blocks"]
|
|
|
773 |
except json.JSONDecodeError as e:
|
774 |
logging.error(f"Erreur de décodage JSON sur la page {page_num}: {str(e)}")
|
775 |
continue # Passe à la page suivante en cas d'erreur
|
@@ -778,12 +780,13 @@ def extract_text_with_image_markers(input_filename: str) -> Tuple[str, List[Tupl
|
|
778 |
if block['type'] == 0: # Texte
|
779 |
for line in block.get('lines', []):
|
780 |
for span in line.get('spans', []):
|
781 |
-
text += span.get('text', '')
|
|
|
782 |
elif block['type'] == 1: # Image
|
783 |
# Insérer un marqueur unique pour l'image
|
784 |
img_num = len(images) + 1
|
785 |
marker = f"[IMG_{img_num}]"
|
786 |
-
text += marker
|
787 |
# Extraire l'image
|
788 |
xref = block.get('xref')
|
789 |
if xref is not None:
|
@@ -791,11 +794,15 @@ def extract_text_with_image_markers(input_filename: str) -> Tuple[str, List[Tupl
|
|
791 |
base_image = doc.extract_image(xref)
|
792 |
image_bytes = base_image["image"]
|
793 |
images.append((img_num, image_bytes))
|
|
|
794 |
except Exception as e:
|
795 |
logging.error(f"Erreur lors de l'extraction de l'image xref={xref} sur la page {page_num} : {str(e)}")
|
|
|
|
|
796 |
return text, images
|
797 |
|
798 |
|
|
|
799 |
def extract_images_from_ppt(input_filename: str) -> List[Tuple[int, bytes]]:
|
800 |
images = []
|
801 |
if 'Presentation' not in globals():
|
@@ -857,6 +864,7 @@ async def convert_file_to_txt(
|
|
857 |
# Extraction du texte et des images
|
858 |
if ext == '.pdf':
|
859 |
text, images = extract_text_with_image_markers(input_filename)
|
|
|
860 |
elif ext == '.pptx':
|
861 |
if 'Presentation' not in globals():
|
862 |
raise HTTPException(status_code=500, detail="La librairie python-pptx n'est pas installée.")
|
@@ -868,23 +876,27 @@ async def convert_file_to_txt(
|
|
868 |
text_content.append(shape.text)
|
869 |
text = "\n".join(text_content)
|
870 |
images = extract_images_from_ppt(input_filename)
|
|
|
871 |
elif ext == '.ppt':
|
872 |
if 'textract' not in globals():
|
873 |
raise HTTPException(status_code=500, detail="La librairie textract n'est pas installée.")
|
874 |
text = textract.process(input_filename).decode('utf-8', errors='replace')
|
875 |
images = extract_images_from_ppt(input_filename)
|
|
|
876 |
elif ext == '.doc':
|
877 |
if 'textract' not in globals():
|
878 |
raise HTTPException(status_code=500, detail="La librairie textract n'est pas installée.")
|
879 |
text = textract.process(input_filename).decode('utf-8', errors='replace')
|
880 |
# Pas d'extraction d'images simple pour .doc ici
|
881 |
images = []
|
|
|
882 |
else:
|
883 |
# Autres formats pris en charge par pandoc (sans extraction d'image)
|
884 |
pypandoc.convert_file(input_filename, 'plain', outputfile=output_filename)
|
885 |
with open(output_filename, "r", encoding="utf-8") as f:
|
886 |
text = f.read()
|
887 |
images = []
|
|
|
888 |
|
889 |
# Analyse des images et récupération des descriptions
|
890 |
if images:
|
@@ -897,6 +909,7 @@ async def convert_file_to_txt(
|
|
897 |
prompt="Cette image est incluse dans un cours. Je voudrais que tu me donnes toutes les informations pertinentes, pour qu'on puisse comprendre ce qu'elle contient sans la voir. Ne commente pas les couleurs, les formes et la disposition. Ne commente pas le fait que tu décris l'image : fais en sorte que l'image puisse être naturellement remplacée par ta description. Si l'image ne contient aucune information, ne renvoie rien du tout."
|
898 |
)
|
899 |
))
|
|
|
900 |
|
901 |
descriptions = await asyncio.gather(*tasks, return_exceptions=True)
|
902 |
|
@@ -908,16 +921,22 @@ async def convert_file_to_txt(
|
|
908 |
image_descriptions[img_num] = desc
|
909 |
else:
|
910 |
image_descriptions[img_num] = "Description indisponible."
|
|
|
911 |
|
912 |
# Remplacer les marqueurs par les descriptions
|
913 |
for img_num, desc in image_descriptions.items():
|
914 |
marker = f"[IMG_{img_num}]"
|
915 |
description_text = f"Image {img_num}: {desc}"
|
916 |
text = text.replace(marker, description_text)
|
|
|
|
|
|
|
|
|
917 |
|
918 |
# Écriture du texte dans le fichier de sortie
|
919 |
with open(output_filename, "w", encoding="utf-8") as f:
|
920 |
f.write(text)
|
|
|
921 |
|
922 |
if not os.path.exists(output_filename):
|
923 |
logging.error(f"Le fichier {output_filename} n'a pas été généré.")
|
@@ -936,3 +955,4 @@ async def convert_file_to_txt(
|
|
936 |
except Exception as e:
|
937 |
logging.error(f"Erreur interne lors de la conversion : {str(e)}")
|
938 |
return JSONResponse(status_code=500, content={"message": f"Erreur interne : {str(e)}"})
|
|
|
|
548 |
if image_key in images_data:
|
549 |
img_tag = soup.new_tag('img')
|
550 |
img_tag['src'] = f"data:image/jpeg;base64,{images_data[image_key]['base64_image']}"
|
551 |
+
img_tag['alt'] = images_data[image_key].get('description', 'Description indisponible.')
|
552 |
|
553 |
new_content = soup.new_tag('div')
|
554 |
new_content.append(img_tag)
|
|
|
559 |
p_tag.append(strong_tag)
|
560 |
p_tag.append(" : ")
|
561 |
|
562 |
+
y_markdown = images_data[image_key].get('description', '')
|
563 |
y_html = markdown_to_html(y_markdown)
|
564 |
y_soup = BeautifulSoup(y_html, 'html.parser')
|
565 |
p_tag.append(y_soup)
|
566 |
|
567 |
new_content.append(p_tag)
|
568 |
comment.replace_with(new_content)
|
569 |
+
logging.debug(f"Image {image_number} réinsérée avec description.")
|
570 |
else:
|
571 |
logging.error(f"Données pour {image_key} non trouvées.")
|
|
|
572 |
return str(soup)
|
573 |
|
574 |
|
575 |
+
|
576 |
def pdf_to_html(input_filename: str) -> str:
|
577 |
soup = BeautifulSoup("<html><head></head><body></body></html>", 'html.parser')
|
578 |
body = soup.body
|
|
|
771 |
try:
|
772 |
page_data = json.loads(page_json) # Parse le JSON en dict
|
773 |
blocks = page_data["blocks"]
|
774 |
+
logging.debug(f"Page {page_num} blocs: {len(blocks)}")
|
775 |
except json.JSONDecodeError as e:
|
776 |
logging.error(f"Erreur de décodage JSON sur la page {page_num}: {str(e)}")
|
777 |
continue # Passe à la page suivante en cas d'erreur
|
|
|
780 |
if block['type'] == 0: # Texte
|
781 |
for line in block.get('lines', []):
|
782 |
for span in line.get('spans', []):
|
783 |
+
text += span.get('text', '') + ' '
|
784 |
+
text += '\n' # Saut de ligne après chaque ligne de texte
|
785 |
elif block['type'] == 1: # Image
|
786 |
# Insérer un marqueur unique pour l'image
|
787 |
img_num = len(images) + 1
|
788 |
marker = f"[IMG_{img_num}]"
|
789 |
+
text += marker + '\n' # Saut de ligne après le marqueur d'image
|
790 |
# Extraire l'image
|
791 |
xref = block.get('xref')
|
792 |
if xref is not None:
|
|
|
794 |
base_image = doc.extract_image(xref)
|
795 |
image_bytes = base_image["image"]
|
796 |
images.append((img_num, image_bytes))
|
797 |
+
logging.debug(f"Image {img_num} extraite de la page {page_num}.")
|
798 |
except Exception as e:
|
799 |
logging.error(f"Erreur lors de l'extraction de l'image xref={xref} sur la page {page_num} : {str(e)}")
|
800 |
+
logging.debug(f"Total text length: {len(text)} characters.")
|
801 |
+
logging.debug(f"Total images extracted: {len(images)}.")
|
802 |
return text, images
|
803 |
|
804 |
|
805 |
+
|
806 |
def extract_images_from_ppt(input_filename: str) -> List[Tuple[int, bytes]]:
|
807 |
images = []
|
808 |
if 'Presentation' not in globals():
|
|
|
864 |
# Extraction du texte et des images
|
865 |
if ext == '.pdf':
|
866 |
text, images = extract_text_with_image_markers(input_filename)
|
867 |
+
logging.debug(f"Extraction PDF terminée. Texte extrait de {len(text)} caractères. {len(images)} images trouvées.")
|
868 |
elif ext == '.pptx':
|
869 |
if 'Presentation' not in globals():
|
870 |
raise HTTPException(status_code=500, detail="La librairie python-pptx n'est pas installée.")
|
|
|
876 |
text_content.append(shape.text)
|
877 |
text = "\n".join(text_content)
|
878 |
images = extract_images_from_ppt(input_filename)
|
879 |
+
logging.debug(f"Extraction PPTX terminée. Texte extrait de {len(text)} caractères. {len(images)} images trouvées.")
|
880 |
elif ext == '.ppt':
|
881 |
if 'textract' not in globals():
|
882 |
raise HTTPException(status_code=500, detail="La librairie textract n'est pas installée.")
|
883 |
text = textract.process(input_filename).decode('utf-8', errors='replace')
|
884 |
images = extract_images_from_ppt(input_filename)
|
885 |
+
logging.debug(f"Extraction PPT terminée. Texte extrait de {len(text)} caractères. {len(images)} images trouvées.")
|
886 |
elif ext == '.doc':
|
887 |
if 'textract' not in globals():
|
888 |
raise HTTPException(status_code=500, detail="La librairie textract n'est pas installée.")
|
889 |
text = textract.process(input_filename).decode('utf-8', errors='replace')
|
890 |
# Pas d'extraction d'images simple pour .doc ici
|
891 |
images = []
|
892 |
+
logging.debug(f"Extraction DOC terminée. Texte extrait de {len(text)} caractères. Aucune image trouvée.")
|
893 |
else:
|
894 |
# Autres formats pris en charge par pandoc (sans extraction d'image)
|
895 |
pypandoc.convert_file(input_filename, 'plain', outputfile=output_filename)
|
896 |
with open(output_filename, "r", encoding="utf-8") as f:
|
897 |
text = f.read()
|
898 |
images = []
|
899 |
+
logging.debug(f"Conversion avec Pandoc terminée. Texte extrait de {len(text)} caractères. Aucune image trouvée.")
|
900 |
|
901 |
# Analyse des images et récupération des descriptions
|
902 |
if images:
|
|
|
909 |
prompt="Cette image est incluse dans un cours. Je voudrais que tu me donnes toutes les informations pertinentes, pour qu'on puisse comprendre ce qu'elle contient sans la voir. Ne commente pas les couleurs, les formes et la disposition. Ne commente pas le fait que tu décris l'image : fais en sorte que l'image puisse être naturellement remplacée par ta description. Si l'image ne contient aucune information, ne renvoie rien du tout."
|
910 |
)
|
911 |
))
|
912 |
+
logging.debug(f"Lancement de {len(tasks)} tâches pour la description des images.")
|
913 |
|
914 |
descriptions = await asyncio.gather(*tasks, return_exceptions=True)
|
915 |
|
|
|
921 |
image_descriptions[img_num] = desc
|
922 |
else:
|
923 |
image_descriptions[img_num] = "Description indisponible."
|
924 |
+
logging.debug(f"Descriptions des images terminées. {len(image_descriptions)} descriptions générées.")
|
925 |
|
926 |
# Remplacer les marqueurs par les descriptions
|
927 |
for img_num, desc in image_descriptions.items():
|
928 |
marker = f"[IMG_{img_num}]"
|
929 |
description_text = f"Image {img_num}: {desc}"
|
930 |
text = text.replace(marker, description_text)
|
931 |
+
logging.debug("Remplacement des marqueurs d'images par les descriptions terminé.")
|
932 |
+
|
933 |
+
else:
|
934 |
+
logging.debug("Aucune image trouvée. Aucun remplacement de marqueur effectué.")
|
935 |
|
936 |
# Écriture du texte dans le fichier de sortie
|
937 |
with open(output_filename, "w", encoding="utf-8") as f:
|
938 |
f.write(text)
|
939 |
+
logging.debug(f"Écriture du fichier texte terminée : {output_filename}")
|
940 |
|
941 |
if not os.path.exists(output_filename):
|
942 |
logging.error(f"Le fichier {output_filename} n'a pas été généré.")
|
|
|
955 |
except Exception as e:
|
956 |
logging.error(f"Erreur interne lors de la conversion : {str(e)}")
|
957 |
return JSONResponse(status_code=500, content={"message": f"Erreur interne : {str(e)}"})
|
958 |
+
|