Spaces:
Sleeping
Sleeping
revert etat fonctionnel
Browse files
main.py
CHANGED
@@ -13,11 +13,6 @@ import shutil
|
|
13 |
import json
|
14 |
import asyncio
|
15 |
import hashlib
|
16 |
-
import camelot
|
17 |
-
from pptx import Presentation
|
18 |
-
from pptx.enum.shapes import MSO_SHAPE_TYPE
|
19 |
-
from docx import Document as DocxDocument
|
20 |
-
|
21 |
|
22 |
from openai import AsyncOpenAI
|
23 |
from readability import Document
|
@@ -726,40 +721,6 @@ def delete_temp_files(file_paths: list):
|
|
726 |
# MODIFICATIONS START
|
727 |
import hashlib
|
728 |
|
729 |
-
def extract_tables_from_docx(input_filename: str) -> List[str]:
|
730 |
-
doc = DocxDocument(input_filename)
|
731 |
-
table_texts = []
|
732 |
-
for table in doc.tables:
|
733 |
-
for row in table.rows:
|
734 |
-
row_text = "\t".join(cell.text.strip() for cell in row.cells)
|
735 |
-
table_texts.append(row_text)
|
736 |
-
table_texts.append("") # Ajoute une ligne vide entre les tables
|
737 |
-
return table_texts
|
738 |
-
|
739 |
-
def extract_tables_from_pptx(input_filename: str) -> List[str]:
|
740 |
-
prs = Presentation(input_filename)
|
741 |
-
table_texts = []
|
742 |
-
for slide in prs.slides:
|
743 |
-
for shape in slide.shapes:
|
744 |
-
if shape.shape_type == MSO_SHAPE_TYPE.TABLE:
|
745 |
-
table = shape.table
|
746 |
-
for row in table.rows:
|
747 |
-
row_text = "\t".join(cell.text.strip() for cell in row.cells)
|
748 |
-
table_texts.append(row_text)
|
749 |
-
table_texts.append("") # Ligne vide entre les tables
|
750 |
-
return table_texts
|
751 |
-
|
752 |
-
def extract_tables_from_pdf(input_filename: str) -> List[str]:
|
753 |
-
tables = camelot.read_pdf(input_filename, pages='all', flavor='stream')
|
754 |
-
table_texts = []
|
755 |
-
for table in tables:
|
756 |
-
df = table.df
|
757 |
-
for _, row in df.iterrows():
|
758 |
-
row_text = "\t".join(cell.strip() for cell in row)
|
759 |
-
table_texts.append(row_text)
|
760 |
-
table_texts.append("") # Ligne vide entre les tables
|
761 |
-
return table_texts
|
762 |
-
|
763 |
def extract_images_from_pdf(input_filename: str) -> List[bytes]:
|
764 |
images = []
|
765 |
hashes = set() # Pour stocker les hashes des images uniques
|
@@ -866,17 +827,16 @@ async def convert_file_to_txt(
|
|
866 |
|
867 |
text = ""
|
868 |
images = []
|
869 |
-
|
870 |
-
|
871 |
-
seen_hashes = set()
|
872 |
|
873 |
-
# Extraction du texte
|
874 |
if ext == '.pdf':
|
875 |
with fitz.open(input_filename) as doc:
|
876 |
for page in doc:
|
877 |
text += page.get_text()
|
|
|
878 |
images = extract_images_from_pdf(input_filename)
|
879 |
-
tables = extract_tables_from_pdf(input_filename)
|
880 |
elif ext == '.pptx':
|
881 |
if 'Presentation' not in globals():
|
882 |
raise HTTPException(status_code=500, detail="La librairie python-pptx n'est pas installée.")
|
@@ -887,45 +847,34 @@ async def convert_file_to_txt(
|
|
887 |
if hasattr(shape, "text"):
|
888 |
text_content.append(shape.text)
|
889 |
text = "\n".join(text_content)
|
890 |
-
images =
|
891 |
-
|
892 |
-
elif ext == '.docx':
|
893 |
-
if 'DocxDocument' not in globals():
|
894 |
-
raise HTTPException(status_code=500, detail="La librairie python-docx n'est pas installée.")
|
895 |
-
tables = extract_tables_from_docx(input_filename)
|
896 |
-
doc = DocxDocument(input_filename)
|
897 |
-
text_content = []
|
898 |
-
for para in doc.paragraphs:
|
899 |
-
text_content.append(para.text)
|
900 |
-
text = "\n".join(text_content)
|
901 |
-
# Extraction des images si nécessaire
|
902 |
-
elif ext == '.doc':
|
903 |
if 'textract' not in globals():
|
904 |
raise HTTPException(status_code=500, detail="La librairie textract n'est pas installée.")
|
905 |
text = textract.process(input_filename).decode('utf-8', errors='replace')
|
906 |
images = extract_images_from_ppt(input_filename)
|
907 |
-
|
|
|
|
|
|
|
|
|
|
|
908 |
else:
|
909 |
-
# Autres formats pris en charge par pandoc
|
910 |
pypandoc.convert_file(input_filename, 'plain', outputfile=output_filename)
|
911 |
with open(output_filename, "r", encoding="utf-8") as f:
|
912 |
text = f.read()
|
913 |
-
|
914 |
-
|
915 |
-
# Ajout des tables au texte
|
916 |
-
if tables:
|
917 |
-
text += "\n\n--- Tables extraites ---\n"
|
918 |
-
for table_text in tables:
|
919 |
-
text += table_text + "\n"
|
920 |
|
921 |
# Analyse des images avec déduplication basée sur le hash
|
922 |
if images:
|
923 |
image_descriptions = []
|
924 |
for i, img_bytes in enumerate(images, start=1):
|
|
|
925 |
img_hash = hashlib.sha256(img_bytes).hexdigest()
|
926 |
if img_hash in seen_hashes:
|
927 |
logging.debug(f"Image {i} est un doublon (hash: {img_hash}).")
|
928 |
-
description = image_hash_map[img_hash]
|
929 |
else:
|
930 |
seen_hashes.add(img_hash)
|
931 |
base64_image = base64.b64encode(img_bytes).decode('utf-8')
|
@@ -933,14 +882,15 @@ async def convert_file_to_txt(
|
|
933 |
base64_image,
|
934 |
prompt="Cette image est incluse dans un cours. Je voudrais que tu me donnes les informations pertinentes qu'elle contient. Ne commente pas les figures, les couleurs ni les formes.\n- Si l'image ne contient que des textes, il faut simplement les retranscrire.\n- Si l'image contient des schémas, il faut exposer ce qu'ils signifient, et les reformuler avec des phrases complètes, claires et compréhensibles, comme si tu le commentais pendant un cours.\nSi l'image ne contient aucune information textuelle ou schématique, renvoie simplement \"no-text\"."
|
935 |
)
|
936 |
-
image_hash_map[img_hash] = description
|
937 |
image_descriptions.append((i, description))
|
938 |
|
939 |
-
#
|
940 |
text += "\n\n--- Voici l'ensemble des images utilisées dans ce document ---\n"
|
941 |
for num, desc in image_descriptions:
|
942 |
if desc != "no-text":
|
943 |
text += f"\nImage {num} : {desc}\n"
|
|
|
944 |
|
945 |
with open(output_filename, "w", encoding="utf-8") as f:
|
946 |
f.write(text)
|
@@ -961,5 +911,4 @@ async def convert_file_to_txt(
|
|
961 |
return JSONResponse(status_code=http_exc.status_code, content={"message": http_exc.detail})
|
962 |
except Exception as e:
|
963 |
logging.error(f"Erreur interne lors de la conversion : {str(e)}")
|
964 |
-
return JSONResponse(status_code=500, content={"message": f"Erreur interne : {str(e)}"})
|
965 |
-
|
|
|
13 |
import json
|
14 |
import asyncio
|
15 |
import hashlib
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
from openai import AsyncOpenAI
|
18 |
from readability import Document
|
|
|
721 |
# MODIFICATIONS START
|
722 |
import hashlib
|
723 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
724 |
def extract_images_from_pdf(input_filename: str) -> List[bytes]:
|
725 |
images = []
|
726 |
hashes = set() # Pour stocker les hashes des images uniques
|
|
|
827 |
|
828 |
text = ""
|
829 |
images = []
|
830 |
+
image_hash_map = {} # Dictionnaire pour mapper les hashes aux descriptions
|
831 |
+
seen_hashes = set() # Ensemble pour suivre les hashes déjà traités
|
|
|
832 |
|
833 |
+
# MODIFICATIONS START: Extraction du texte et des images
|
834 |
if ext == '.pdf':
|
835 |
with fitz.open(input_filename) as doc:
|
836 |
for page in doc:
|
837 |
text += page.get_text()
|
838 |
+
# Extraire les images du PDF
|
839 |
images = extract_images_from_pdf(input_filename)
|
|
|
840 |
elif ext == '.pptx':
|
841 |
if 'Presentation' not in globals():
|
842 |
raise HTTPException(status_code=500, detail="La librairie python-pptx n'est pas installée.")
|
|
|
847 |
if hasattr(shape, "text"):
|
848 |
text_content.append(shape.text)
|
849 |
text = "\n".join(text_content)
|
850 |
+
images = extract_images_from_ppt(input_filename)
|
851 |
+
elif ext == '.ppt':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
852 |
if 'textract' not in globals():
|
853 |
raise HTTPException(status_code=500, detail="La librairie textract n'est pas installée.")
|
854 |
text = textract.process(input_filename).decode('utf-8', errors='replace')
|
855 |
images = extract_images_from_ppt(input_filename)
|
856 |
+
elif ext == '.doc':
|
857 |
+
if 'textract' not in globals():
|
858 |
+
raise HTTPException(status_code=500, detail="La librairie textract n'est pas installée.")
|
859 |
+
text = textract.process(input_filename).decode('utf-8', errors='replace')
|
860 |
+
# Pas d'extraction d'images simple pour .doc ici
|
861 |
+
images = []
|
862 |
else:
|
863 |
+
# Autres formats pris en charge par pandoc (sans extraction d'image)
|
864 |
pypandoc.convert_file(input_filename, 'plain', outputfile=output_filename)
|
865 |
with open(output_filename, "r", encoding="utf-8") as f:
|
866 |
text = f.read()
|
867 |
+
images = []
|
|
|
|
|
|
|
|
|
|
|
|
|
868 |
|
869 |
# Analyse des images avec déduplication basée sur le hash
|
870 |
if images:
|
871 |
image_descriptions = []
|
872 |
for i, img_bytes in enumerate(images, start=1):
|
873 |
+
# Calculer le hash de l'image
|
874 |
img_hash = hashlib.sha256(img_bytes).hexdigest()
|
875 |
if img_hash in seen_hashes:
|
876 |
logging.debug(f"Image {i} est un doublon (hash: {img_hash}).")
|
877 |
+
description = image_hash_map[img_hash] # Réutiliser la description existante
|
878 |
else:
|
879 |
seen_hashes.add(img_hash)
|
880 |
base64_image = base64.b64encode(img_bytes).decode('utf-8')
|
|
|
882 |
base64_image,
|
883 |
prompt="Cette image est incluse dans un cours. Je voudrais que tu me donnes les informations pertinentes qu'elle contient. Ne commente pas les figures, les couleurs ni les formes.\n- Si l'image ne contient que des textes, il faut simplement les retranscrire.\n- Si l'image contient des schémas, il faut exposer ce qu'ils signifient, et les reformuler avec des phrases complètes, claires et compréhensibles, comme si tu le commentais pendant un cours.\nSi l'image ne contient aucune information textuelle ou schématique, renvoie simplement \"no-text\"."
|
884 |
)
|
885 |
+
image_hash_map[img_hash] = description # Stocker la description pour les doublons
|
886 |
image_descriptions.append((i, description))
|
887 |
|
888 |
+
# On ajoute les descriptions à la fin du texte
|
889 |
text += "\n\n--- Voici l'ensemble des images utilisées dans ce document ---\n"
|
890 |
for num, desc in image_descriptions:
|
891 |
if desc != "no-text":
|
892 |
text += f"\nImage {num} : {desc}\n"
|
893 |
+
# MODIFICATIONS END
|
894 |
|
895 |
with open(output_filename, "w", encoding="utf-8") as f:
|
896 |
f.write(text)
|
|
|
911 |
return JSONResponse(status_code=http_exc.status_code, content={"message": http_exc.detail})
|
912 |
except Exception as e:
|
913 |
logging.error(f"Erreur interne lors de la conversion : {str(e)}")
|
914 |
+
return JSONResponse(status_code=500, content={"message": f"Erreur interne : {str(e)}"})
|
|