Script python permettant de traduire un long texte
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

main.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import PyPDF2
  2. import requests
  3. import json
  4. from reportlab.lib.pagesizes import letter
  5. from reportlab.lib.units import inch
  6. from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
  7. from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
  8. from reportlab.lib.enums import TA_JUSTIFY
  9. from reportlab.pdfbase import pdfmetrics
  10. from reportlab.pdfbase.ttfonts import TTFont
  11. import os
  12. # Configuration
  13. PDF_PATH = "TaniaBorecMemoir(Ukr).pdf" # Fichier original
  14. OLLAMA_MODEL = "traductionUkrainienVersFrancais:latest"
  15. OLLAMA_URL = "http://localhost:11434/api/generate" # URL par défaut d'Ollama
  16. OUTPUT_PDF_PATH = PDF_PATH.replace(".pdf", " (FR).pdf") # Chemin du PDF de sortie
  17. def extract_text_from_pdf(pdf_path):
  18. """Extrait le texte page par page d'un PDF sans les numéros de pages."""
  19. import re
  20. text_by_page = []
  21. with open(pdf_path, "rb") as file:
  22. reader = PyPDF2.PdfReader(file)
  23. for page in reader.pages:
  24. text = page.extract_text()
  25. # Supprime les numéros de pages (nombres seuls en début/fin de ligne)
  26. text = re.sub(r'^\d+\s*\n', '', text, flags=re.MULTILINE)
  27. text = re.sub(r'\n\s*\d+\s*$', '', text, flags=re.MULTILINE)
  28. text_by_page.append(text)
  29. return text_by_page
  30. def send_to_ollama(prompt, model=OLLAMA_MODEL, context_size=128000):
  31. """Envoie une requête à Ollama et retourne la réponse."""
  32. payload = {
  33. "model": model,
  34. "prompt": prompt,
  35. "stream": False,
  36. "options": {"num_ctx": context_size}
  37. }
  38. response = requests.post(OLLAMA_URL, data=json.dumps(payload))
  39. if response.status_code == 200:
  40. return response.json()["response"]
  41. else:
  42. raise Exception(f"Erreur Ollama: {response.text}")
  43. def register_unicode_font():
  44. """Enregistre une police TrueType qui supporte le cyrilique."""
  45. # Recherche une police système qui supporte le cyrilique
  46. font_paths = [
  47. r"C:\Windows\Fonts\DejaVuSans.ttf",
  48. r"C:\Windows\Fonts\Calibri.ttf",
  49. r"C:\Windows\Fonts\arial.ttf",
  50. ]
  51. for font_path in font_paths:
  52. if os.path.exists(font_path):
  53. try:
  54. pdfmetrics.registerFont(TTFont('UnicodeFont', font_path))
  55. return 'UnicodeFont'
  56. except Exception as e:
  57. print(f"Erreur lors de l'enregistrement de {font_path}: {e}")
  58. # Si aucune police spéciale trouvée, utilise Helvetica par défaut
  59. print("Aucune police Unicode trouvée, utilisation d'Helvetica")
  60. return 'Helvetica'
  61. def create_pdf_from_results(results, output_path):
  62. """Crée un PDF à partir des résultats de traduction."""
  63. doc = SimpleDocTemplate(output_path, pagesize=letter, topMargin=inch, bottomMargin=inch)
  64. story = []
  65. # Style personnalisé
  66. styles = getSampleStyleSheet()
  67. title_style = ParagraphStyle(
  68. 'CustomTitle',
  69. parent=styles['Heading1'],
  70. fontSize=16,
  71. textColor='#1f4788',
  72. spaceAfter=0.3*inch,
  73. alignment=TA_JUSTIFY
  74. )
  75. page_style = ParagraphStyle(
  76. 'PageHeading',
  77. parent=styles['Heading2'],
  78. fontSize=12,
  79. textColor='#1f4788',
  80. spaceAfter=0.2*inch,
  81. spaceBefore=0.2*inch
  82. )
  83. body_style = ParagraphStyle(
  84. 'CustomBody',
  85. parent=styles['BodyText'],
  86. fontSize=11,
  87. alignment=TA_JUSTIFY,
  88. spaceAfter=0.2*inch
  89. )
  90. # Titre
  91. story.append(Paragraph("Traduction - Ukrainien vers Français", title_style))
  92. story.append(Spacer(1, 0.2*inch))
  93. # Contenu
  94. for page_num, translation in results.items():
  95. # Préserver la mise en page en convertissant les sauts de ligne
  96. formatted_text = translation.replace("\n", "<br/>")
  97. story.append(Paragraph(formatted_text, body_style))
  98. story.append(Spacer(1, 0.1*inch))
  99. # Construction du PDF
  100. doc.build(story)
  101. print(f"PDF généré avec succès : {output_path}")
  102. def main():
  103. # Extraction du texte
  104. pages = extract_text_from_pdf(PDF_PATH)
  105. print(f"Nombre de pages extraites : {len(pages)}")
  106. # Dictionnaire pour stocker les résultats
  107. results = {}
  108. # Traitement page par page
  109. for i, page_text in enumerate(pages, start=1):
  110. if( i > 3) : # Limite le nombre de pages pour les tests
  111. break
  112. print(f"{15 * '-'} Traduction de la page {i}/{len(pages)}...")
  113. prompt = f"Traduis le texte suivant de l'ukrainien vers le français : {page_text}"
  114. try:
  115. result = send_to_ollama(prompt)
  116. print(f"{result}.")
  117. results[i] = result
  118. except Exception as e:
  119. print(f"Erreur lors du traitement de la page {i} : {e}")
  120. results[i] = f"Erreur lors du traitement de la page {i} : {e}"
  121. # Création du PDF avec tous les résultats
  122. create_pdf_from_results(results, OUTPUT_PDF_PATH)
  123. if __name__ == "__main__":
  124. main()