Skip to content

Instantly share code, notes, and snippets.

@me-suzy
Created May 7, 2025 02:53
Show Gist options
  • Save me-suzy/27ed5a40ef3df62c68cd412f34c250d1 to your computer and use it in GitHub Desktop.
Save me-suzy/27ed5a40ef3df62c68cd412f34c250d1 to your computer and use it in GitHub Desktop.
convert all to pdf GROK 2.py
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