import os import tempfile import math from typing import List, Tuple import gradio as gr from PyPDF2 import PdfReader, PdfWriter # Load custom CSS try: with open(os.path.join(os.path.dirname(__file__), "fancy.css")) as f: custom_css = f.read() except FileNotFoundError: custom_css = "" # Maximum upload size (1 GB) MAX_SIZE_BYTES = 1 * 1024 * 1024 * 1024 def split_pdf_into_chunks(file, num_chunks: int) -> Tuple[List[str], str]: """ Teilt eine PDF-Datei in X möglichst gleich große Teile auf. Gibt eine Liste der temporären Dateipfade und eine Fehlermeldung (falls vorhanden) zurück. """ if file is None: return [], "Bitte lade zuerst eine PDF-Datei hoch." # Validate file size file_size = os.path.getsize(file.name) if file_size > MAX_SIZE_BYTES: return [], f"Datei überschreitet das 1 GB Limit ({file_size / (1024*1024*1024):.2f} GB)." if num_chunks < 1: return [], "Die Anzahl der Teile muss mindestens 1 betragen." try: reader = PdfReader(file.name) total_pages = len(reader.pages) if total_pages == 0: return [], "Die PDF-Datei enthält keine Seiten." # Wenn mehr Teile gefordert sind als Seiten da sind, begrenzen wir es auf die Seitenzahl chunks = min(num_chunks, total_pages) # Berechne die Basis-Seitenanzahl pro Teil und den Rest pages_per_chunk = total_pages // chunks remainder = total_pages % chunks output_files = [] current_page = 0 for i in range(chunks): writer = PdfWriter() # Verteile den Rest auf die ersten Chunks actual_pages = pages_per_chunk + (1 if i < remainder else 0) for _ in range(actual_pages): writer.add_page(reader.pages[current_page]) current_page += 1 # Temporäre Datei für diesen Teil erstellen # Verwende ein Muster im Namen, damit man die Reihenfolge erkennt out_path = tempfile.NamedTemporaryFile(delete=False, suffix=f"_teil_{i+1}.pdf").name with open(out_path, "wb") as f_out: writer.write(f_out) output_files.append(out_path) return output_files, "" except Exception as e: return [], f"Fehler beim Aufteilen der PDF: {str(e)}" def merge_pdfs(files): # Merge multiple PDFs in upload order if not files: return None, "Bitte lade mindestens zwei PDF-Dateien zum Zusammenführen hoch." # Validate total size total_size = sum(os.path.getsize(f.name) for f in files) if total_size > MAX_SIZE_BYTES: return None, f"Gesamtgröße überschreitet das 1 GB Limit ({total_size / (1024*1024*1024):.2f} GB)." writer = PdfWriter() try: for f in files: reader = PdfReader(f.name) for page in reader.pages: writer.add_page(page) except Exception as e: return None, f"Fehler beim Lesen der PDFs: {e}" out_path = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf").name with open(out_path, "wb") as f_out: writer.write(f_out) return out_path, None # Build Gradio interface with gr.Blocks(css=custom_css) as demo: gr.HTML("