Created
May 7, 2025 02:53
-
-
Save me-suzy/27ed5a40ef3df62c68cd412f34c250d1 to your computer and use it in GitHub Desktop.
convert all to pdf GROK 2.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import subprocess | |
import win32com.client | |
from PyPDF2 import PdfReader, PdfWriter | |
import pikepdf | |
import logging | |
import tempfile | |
import shutil | |
import threading | |
import json | |
import glob | |
import time | |
# Configurare logging | |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
# Specificați căile complete pentru utilitarele externe | |
WKHTMLTOPDF_PATH = r"c:\Program Files (x86)\wkhtmltopdf\bin\wkhtmltopdf.exe" | |
EBOOK_CONVERT_PATH = r"C:\Program Files\Calibre2\ebook-convert.exe" | |
DDJVU_PATH = r"c:\Program Files (x86)\DjVuLibre\ddjvu.exe" | |
LIBREOFFICE_PATH = r"D:\Program Files\LibreOffice\program\soffice.exe" | |
# Creare lock pentru conversiile LibreOffice | |
libreoffice_conversion_lock = threading.Lock() | |
def check_output_dir_permissions(output_dir): | |
"""Verifică dacă scriptul are permisiuni de scriere în directorul de ieșire.""" | |
try: | |
test_file = os.path.join(output_dir, "test_permissions.txt") | |
with open(test_file, 'w') as f: | |
f.write("Test") | |
os.remove(test_file) | |
print(f"Permisiuni de scriere confirmate în {output_dir}") | |
except Exception as e: | |
print(f"Eroare: Nu se poate scrie în {output_dir}. Detalii: {str(e)}") | |
raise | |
def clean_temp_files(output_dir, base_filename): | |
"""Șterge fișierele temporare și lock-urile din directorul de ieșire.""" | |
try: | |
# Șterge fișierele temporare (ex. *.tmp) | |
temp_files = glob.glob(os.path.join(output_dir, "*.tmp")) | |
for temp_file in temp_files: | |
try: | |
os.remove(temp_file) | |
logging.info(f"Fișier temporar șters: {temp_file}") | |
except Exception as e: | |
logging.warning(f"Nu s-a putut șterge fișierul temporar {temp_file}: {str(e)}") | |
# Șterge fișierele de lock (ex. .~lock.*.pdf#) | |
lock_files = glob.glob(os.path.join(output_dir, f".~lock.{base_filename}.pdf#")) | |
for lock_file in lock_files: | |
try: | |
os.remove(lock_file) | |
logging.info(f"Fișier lock șters: {lock_file}") | |
except Exception as e: | |
logging.warning(f"Nu s-a putut șterge fișierul lock {lock_file}: {str(e)}") | |
except Exception as e: | |
logging.error(f"Eroare la curățarea fișierelor temporare: {str(e)}") | |
def test_libreoffice_installation(output_dir): | |
"""Testează dacă LibreOffice poate crea un fișier PDF simplu.""" | |
try: | |
# Creează un fișier RTF temporar simplu | |
temp_rtf_path = os.path.join(output_dir, "test_libreoffice.rtf") | |
with open(temp_rtf_path, 'w', encoding='utf-8') as f: | |
f.write("{\\rtf1\\ansi Test document}") | |
# Încearcă să convertești fișierul RTF în PDF | |
command = [ | |
LIBREOFFICE_PATH, | |
"--headless", | |
"--convert-to", "pdf", | |
"--outdir", output_dir, | |
temp_rtf_path | |
] | |
print(f"Testez LibreOffice cu comanda: {' '.join(command)}") | |
result = subprocess.run(command, capture_output=True, text=True, check=True, timeout=60) | |
print(f"Test stdout: {result.stdout}") | |
print(f"Test stderr: {result.stderr}") | |
# Verifică dacă fișierul PDF a fost creat | |
temp_pdf_path = os.path.join(output_dir, "test_libreoffice.pdf") | |
if os.path.exists(temp_pdf_path): | |
print("Test LibreOffice reușit: fișierul PDF a fost creat.") | |
os.remove(temp_pdf_path) | |
else: | |
print("Test LibreOffice eșuat: fișierul PDF nu a fost creat.") | |
os.remove(temp_rtf_path) | |
except Exception as e: | |
print(f"Eroare la testarea LibreOffice: {str(e)}") | |
raise | |
def convert_with_libreoffice(input_file, output_file, conversion_type): | |
""" | |
Funcție unificată pentru conversiile LibreOffice (DOC, DOCX, RTF) | |
""" | |
with libreoffice_conversion_lock: # Asigură procesare secvențială | |
# Curăță fișierele temporare și lock-urile înainte de conversie | |
base_filename = os.path.splitext(os.path.basename(input_file))[0] | |
clean_temp_files(os.path.dirname(output_file), base_filename) | |
print(f"Încep conversia pentru {input_file} cu LibreOffice la {LIBREOFFICE_PATH}") | |
try: | |
# Verifică dacă LibreOffice este disponibil | |
if not os.path.exists(LIBREOFFICE_PATH): | |
print(f"Eroare: LibreOffice nu a fost găsit la {LIBREOFFICE_PATH}") | |
logging.error(f"LibreOffice nu a fost găsit la {LIBREOFFICE_PATH}") | |
raise Exception("LibreOffice nu este instalat sau calea este incorectă") | |
# Construiește comanda pentru conversie | |
command = [ | |
LIBREOFFICE_PATH, | |
"--headless", | |
"--convert-to", "pdf", | |
"--outdir", os.path.dirname(output_file), | |
input_file | |
] | |
print(f"Comanda construită: {' '.join(command)}") | |
logging.info(f"Începe conversia {conversion_type}: {input_file} -> {output_file}") | |
start_time = time.time() | |
result = subprocess.run(command, capture_output=True, text=True, check=True, timeout=300) | |
print(f"Timp de execuție: {time.time() - start_time:.2f} secunde") | |
print(f"Ieșire stdout: {result.stdout}") | |
print(f"Ieșire stderr: {result.stderr}") | |
logging.info(f"Conversia finalizată în {time.time() - start_time:.2f} secunde") | |
logging.info(f"Ieșire comandă: {result.stdout}") | |
if result.stderr: | |
logging.warning(f"Erori comandă: {result.stderr}") | |
# Verifică dacă fișierul PDF a fost creat | |
temp_pdf_name = os.path.splitext(os.path.basename(input_file))[0] + ".pdf" | |
temp_pdf_path = os.path.join(os.path.dirname(output_file), temp_pdf_name) | |
print(f"Căutăm fișierul PDF temporar la: {temp_pdf_path}") | |
if os.path.exists(temp_pdf_path) and temp_pdf_path != output_file: | |
print(f"Mutăm {temp_pdf_path} la {output_file}") | |
shutil.move(temp_pdf_path, output_file) | |
if os.path.exists(output_file): | |
print(f"Conversie reușită: {output_file} creat cu succes") | |
logging.info(f"Conversie {conversion_type} reușită: {input_file} -> {output_file}") | |
else: | |
print(f"Eroare: Fișierul PDF {output_file} nu a fost creat") | |
raise Exception(f"Fișierul PDF nu a fost creat pentru {input_file}") | |
except subprocess.TimeoutExpired as e: | |
print(f"Timeout după {e.timeout} secunde pentru {input_file}") | |
logging.error(f"Timeout la conversia {conversion_type}: {input_file}. Detalii: {str(e)}") | |
raise | |
except subprocess.CalledProcessError as e: | |
print(f"Eroare de proces: {str(e)} pentru {input_file}") | |
logging.error(f"Eroare la conversia {conversion_type}: {input_file}. Detalii: {e.stderr}") | |
raise | |
except Exception as e: | |
print(f"Eroare neașteptată: {str(e)} pentru {input_file}") | |
logging.error(f"Eroare neașteptată la conversia {conversion_type}: {input_file}. Detalii: {str(e)}") | |
raise | |
finally: | |
# Curăță fișierele temporare și lock-urile după conversie | |
clean_temp_files(os.path.dirname(output_file), base_filename) | |
def convert_doc_to_pdf(input_file, output_file): | |
convert_with_libreoffice(input_file, output_file, "DOC") | |
def convert_docx_to_pdf(input_file, output_file): | |
convert_with_libreoffice(input_file, output_file, "DOCX") | |
def convert_rtf_to_pdf(input_file, output_file): | |
convert_with_libreoffice(input_file, output_file, "RTF") | |
def convert_epub_to_pdf(input_file, output_file): | |
try: | |
subprocess.run([EBOOK_CONVERT_PATH, input_file, output_file], check=True, capture_output=True, text=True) | |
logging.info(f"Conversia EPUB la PDF reușită: {input_file} -> {output_file}") | |
except subprocess.CalledProcessError as e: | |
logging.error(f"Eroare la conversia EPUB la PDF: {input_file}. Detalii: {e.stderr}") | |
raise | |
except Exception as e: | |
logging.error(f"Eroare neașteptată la conversia EPUB la PDF: {input_file}. Detalii: {str(e)}") | |
raise | |
def convert_mobi_to_pdf(input_file, output_file): | |
try: | |
subprocess.run([EBOOK_CONVERT_PATH, input_file, output_file, | |
"--pdf-page-numbers", | |
"--paper-size", "a4", | |
"--pdf-add-toc", | |
"--margin-top", "72", | |
"--margin-right", "72", | |
"--margin-bottom", "72", | |
"--margin-left", "72"], | |
check=True, capture_output=True, text=True) | |
logging.info(f"Conversia MOBI la PDF reușită: {input_file} -> {output_file}") | |
except subprocess.CalledProcessError as e: | |
logging.error(f"Eroare la conversia MOBI la PDF: {input_file}. Detalii: {e.stderr}") | |
raise | |
except Exception as e: | |
logging.error(f"Eroare neașteptată la conversia MOBI la PDF: {input_file}. Detalii: {str(e)}") | |
raise | |
def convert_djvu_to_pdf(input_file, output_file): | |
try: | |
subprocess.run([DDJVU_PATH, '-format=pdf', input_file, output_file], check=True, capture_output=True, text=True) | |
logging.info(f"Conversia DJVU la PDF reușită: {input_file} -> {output_file}") | |
except subprocess.CalledProcessError as e: | |
logging.error(f"Eroare la conversia DJVU la PDF: {input_file}. Detalii: {e.stderr}") | |
raise | |
except Exception as e: | |
logging.error(f"Eroare neașteptată la conversia DJVU la PDF: {input_file}. Detalii: {str(e)}") | |
raise | |
def convert_lit_to_pdf(input_file, output_file): | |
try: | |
epub_file = tempfile.mktemp(suffix='.epub') | |
subprocess.run([EBOOK_CONVERT_PATH, input_file, epub_file], check=True, capture_output=True, text=True) | |
subprocess.run([EBOOK_CONVERT_PATH, epub_file, output_file, | |
"--pdf-page-numbers", | |
"--paper-size", "a4", | |
"--pdf-add-toc", | |
"--margin-top", "72", | |
"--margin-right", "72", | |
"--margin-bottom", "72", | |
"--margin-left", "72"], | |
check=True, capture_output=True, text=True) | |
os.remove(epub_file) | |
logging.info(f"Conversia LIT la PDF reușită: {input_file} -> {output_file}") | |
except subprocess.CalledProcessError as e: | |
logging.error(f"Eroare la conversia LIT la PDF: {input_file}. Detalii: {e.stderr}") | |
raise | |
except Exception as e: | |
logging.error(f"Eroare neașteptată la conversia LIT la PDF: {input_file}. Detalii: {str(e)}") | |
raise | |
def convert_txt_to_pdf(input_file, output_file): | |
try: | |
with open(input_file, 'r', encoding='utf-8') as file: | |
content = file.read() | |
html_content = f""" | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<style> | |
body {{ font-family: Arial, sans-serif; font-size: 12px; line-height: 1.6; }} | |
pre {{ white-space: pre-wrap; }} | |
</style> | |
</head> | |
<body> | |
<pre>{content}</pre> | |
</body> | |
</html> | |
""" | |
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.html', encoding='utf-8') as temp_html: | |
temp_html.write(html_content) | |
temp_html_path = temp_html.name | |
subprocess.run([WKHTMLTOPDF_PATH, temp_html_path, output_file], check=True, capture_output=True, text=True) | |
os.remove(temp_html_path) | |
logging.info(f"Conversia TXT la PDF reușită: {input_file} -> {output_file}") | |
except subprocess.CalledProcessError as e: | |
logging.error(f"Eroare la conversia TXT la PDF: {input_file}. Detalii: {e.stderr}") | |
raise | |
except Exception as e: | |
logging.error(f"Eroare neașteptată la conversia TXT la PDF: {input_file}. Detalii: {str(e)}") | |
raise | |
def repair_and_reconvert_pdf(input_file, output_file): | |
try: | |
with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_file: | |
temp_path = temp_file.name | |
with pikepdf.open(input_file, allow_overwriting_input=True) as pdf: | |
pdf.save(temp_path) | |
shutil.move(temp_path, output_file) | |
logging.info(f"PDF reparat cu succes folosind pikepdf: {input_file} -> {output_file}") | |
except Exception as e: | |
logging.error(f"Eroare la repararea PDF-ului cu pikepdf {input_file}: {str(e)}") | |
try: | |
reader = PdfReader(input_file) | |
writer = PdfWriter() | |
for page in reader.pages: | |
writer.add_page(page) | |
with open(temp_path, 'wb') as f: | |
writer.write(f) | |
shutil.move(temp_path, output_file) | |
logging.info(f"PDF reparat cu succes folosind PyPDF2: {input_file} -> {output_file}") | |
except Exception as e2: | |
logging.error(f"Eroare la repararea PDF-ului {input_file} cu PyPDF2: {str(e2)}") | |
raise | |
def pdf_exists(input_file, output_dir): | |
file_name = os.path.basename(input_file) | |
file_name_without_ext = os.path.splitext(file_name)[0] | |
pdf_file = os.path.join(output_dir, file_name_without_ext + '.pdf') | |
exists = os.path.exists(pdf_file) | |
return exists | |
def try_alternative_conversion(input_file, output_file, conversion_type): | |
""" | |
Încercă metoda alternativă de conversie folosind LibreOffice pentru fișierele problematice. | |
""" | |
print(f"Încep metoda alternativă de conversie pentru {input_file}") | |
try: | |
# Creăm un fișier temporar pentru a evita probleme cu fișierele blocate | |
temp_dir = tempfile.mkdtemp() | |
temp_file_name = os.path.basename(input_file) | |
temp_file_path = os.path.join(temp_dir, temp_file_name) | |
# Copiem fișierul în locația temporară | |
shutil.copy2(input_file, temp_file_path) | |
print(f"Fișier copiat în locația temporară: {temp_file_path}") | |
# Metoda alternativă: Folosește LibreOffice | |
libreoffice_path = LIBREOFFICE_PATH | |
if os.path.exists(libreoffice_path): | |
print(f"Încep conversia cu LibreOffice pentru {temp_file_path}") | |
cmd = [ | |
libreoffice_path, | |
"--headless", | |
"--convert-to", "pdf", | |
"--outdir", os.path.dirname(output_file), | |
temp_file_path | |
] | |
print(f"Comanda alternativă: {' '.join(cmd)}") | |
result = subprocess.run(cmd, capture_output=True, text=True, check=True, timeout=300) | |
print(f"Ieșire stdout alternativă: {result.stdout}") | |
print(f"Ieșire stderr alternativă: {result.stderr}") | |
# Verifică dacă s-a creat PDF-ul și redenumește-l dacă este necesar | |
temp_pdf_name = os.path.splitext(temp_file_name)[0] + ".pdf" | |
temp_pdf_path = os.path.join(os.path.dirname(output_file), temp_pdf_name) | |
print(f"Căutăm fișierul PDF temporar la: {temp_pdf_path}") | |
if os.path.exists(temp_pdf_path) and temp_pdf_path != output_file: | |
print(f"Mutăm {temp_pdf_path} la {output_file}") | |
shutil.move(temp_pdf_path, output_file) | |
if os.path.exists(output_file): | |
print(f"Conversie alternativă reușită: {output_file} creat") | |
logging.info(f"Conversie alternativă reușită cu LibreOffice: {input_file} -> {output_file}") | |
return True | |
else: | |
print(f"Eroare: LibreOffice nu a fost găsit la {libreoffice_path}") | |
logging.error(f"LibreOffice nu a fost găsit la {libreoffice_path}") | |
return False | |
# Curățare | |
try: | |
shutil.rmtree(temp_dir) | |
print(f"Director temporar {temp_dir} șters") | |
except: | |
print(f"Eroare la ștergerea directorului temporar {temp_dir}") | |
return False | |
except Exception as e: | |
print(f"Eroare la conversia alternativă: {str(e)} pentru {input_file}") | |
logging.error(f"Eroare la conversia alternativă pentru {input_file}: {str(e)}") | |
return False | |
def convert_file(input_file, output_dir, problematic_files): | |
file_name = os.path.basename(input_file) | |
file_name_without_ext = os.path.splitext(file_name)[0] | |
output_file = os.path.join(output_dir, file_name_without_ext + '.pdf') | |
if pdf_exists(input_file, output_dir): | |
return | |
_, extension = os.path.splitext(input_file) | |
extension = extension.lower() | |
try: | |
success = False | |
if extension == '.docx': | |
convert_docx_to_pdf(input_file, output_file) | |
success = True | |
elif extension == '.doc': | |
try: | |
convert_doc_to_pdf(input_file, output_file) | |
success = True | |
except Exception as e: | |
print(f"Prima încercare de conversie a eșuat: {str(e)} pentru {input_file}") | |
success = try_alternative_conversion(input_file, output_file, "DOC") | |
elif extension == '.rtf': | |
try: | |
convert_rtf_to_pdf(input_file, output_file) | |
success = True | |
except Exception as e: | |
print(f"Prima încercare de conversie a eșuat: {str(e)} pentru {input_file}") | |
success = try_alternative_conversion(input_file, output_file, "RTF") | |
elif extension == '.epub': | |
convert_epub_to_pdf(input_file, output_file) | |
success = True | |
elif extension == '.mobi': | |
convert_mobi_to_pdf(input_file, output_file) | |
success = True | |
elif extension == '.djvu': | |
convert_djvu_to_pdf(input_file, output_file) | |
success = True | |
elif extension == '.pdf': | |
repair_and_reconvert_pdf(input_file, output_file) | |
success = True | |
elif extension == '.lit': | |
convert_lit_to_pdf(input_file, output_file) | |
success = True | |
elif extension == '.txt': | |
convert_txt_to_pdf(input_file, output_file) | |
success = True | |
else: | |
print(f"Format nesuportat: {extension} pentru {input_file}") | |
return | |
if success and os.path.exists(output_file): | |
print(f"Conversie reușită: {input_file} -> {output_file}") | |
else: | |
print(f"Conversie eșuată: {input_file} nu a fost procesat") | |
problematic_files[input_file] = "Conversia nu a reușit - fișier PDF nu a fost creat" | |
except Exception as e: | |
print(f"Eroare la procesare: {str(e)} pentru {input_file}") | |
problematic_files[input_file] = str(e) | |
def process_directory(input_dir, output_dir): | |
supported_extensions = ['.docx', '.doc', '.rtf', '.epub', '.mobi', '.djvu', '.pdf', '.lit', '.txt'] | |
processed_files = [] | |
problematic_files = {} | |
# Verifică permisiunile | |
check_output_dir_permissions(output_dir) | |
# Testează instalarea LibreOffice | |
test_libreoffice_installation(output_dir) | |
# Obține doar fișierele din directorul curent (fără recursivitate) | |
files = [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f))] | |
total_files = len(files) | |
print(f"Total fișiere de procesat: {total_files}") | |
# Procesează mai întâi fișierele non-Office | |
for file_index, file in enumerate(files): | |
input_file = os.path.join(input_dir, file) | |
_, extension = os.path.splitext(file) | |
if extension.lower() not in supported_extensions: | |
continue | |
if pdf_exists(input_file, output_dir): | |
continue | |
print(f"[{file_index+1}/{total_files}] Procesare {file}") | |
if any(file.lower().endswith(ext) for ext in ['.epub', '.mobi', '.djvu', '.pdf', '.lit', '.txt']): | |
try: | |
convert_file(input_file, output_dir, problematic_files) | |
processed_files.append(file) | |
except Exception as e: | |
print(f"Eroare la procesarea {file}: {str(e)}") | |
problematic_files[input_file] = str(e) | |
# Apoi procesează fișierele Office | |
for file_index, file in enumerate(files): | |
if any(file.lower().endswith(ext) for ext in ['.doc', '.docx', '.rtf']): | |
input_file = os.path.join(input_dir, file) | |
if pdf_exists(input_file, output_dir): | |
continue | |
print(f"[{file_index+1}/{total_files}] Procesare {file}") | |
try: | |
convert_file(input_file, output_dir, problematic_files) | |
processed_files.append(file) | |
except Exception as e: | |
print(f"Eroare la procesarea {file}: {str(e)}") | |
problematic_files[input_file] = str(e) | |
time.sleep(5) # Mărire pauză la 5 secunde | |
# Salvează fișierele problematice în JSON | |
if problematic_files: | |
json_path = os.path.join(output_dir, "fisiere_problematice.json") | |
with open(json_path, 'w', encoding='utf-8') as json_file: | |
json.dump(problematic_files, json_file, ensure_ascii=False, indent=4) | |
print(f"Fișierele problematice au fost salvate în: {json_path}") | |
# Afișează sumarul | |
print("\n=== SUMAR CONVERSIE ===") | |
print(f"Total fișiere: {total_files}") | |
print(f"Fișiere procesate cu succes: {len(processed_files)}") | |
print(f"Fișiere cu erori: {len(problematic_files)}") | |
if problematic_files: | |
print("\nFișiere care nu au putut fi procesate:") | |
for file in problematic_files: | |
print(f"- {file}") | |
def disable_registry_file_block_settings(): | |
pass | |
# Dezactivăm setările de registru global (nu mai este necesar) | |
disable_registry_file_block_settings() | |
# Directorul de intrare și ieșire | |
input_dir = "D:\\3" | |
output_dir = "D:\\3\\Input" | |
# Ne asigurăm că directorul de ieșire există | |
os.makedirs(output_dir, exist_ok=True) | |
# Procesăm toate fișierele din directorul de intrare | |
process_directory(input_dir, output_dir) | |
print("Procesarea tuturor fișierelor a fost finalizată.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment