import gradio as gr import pypdf import os import zipfile import shutil # --- Yardımcı Fonksiyonlar --- def create_temp_dir(): """Geçici bir çıktı klasörü oluşturur ve eskisini (varsa) temizler.""" temp_dir = "temp_output_files" if os.path.exists(temp_dir): shutil.rmtree(temp_dir) os.makedirs(temp_dir) return temp_dir def zip_output_files(directory_path, zip_filename="sonuc.zip"): """Belirtilen klasördeki dosyaları bir ZIP arşivine ekler.""" shutil.make_archive(zip_filename.replace('.zip', ''), 'zip', directory_path) return zip_filename def cleanup(directory_path): """Geçici klasörü ve içeriğini temizler.""" if os.path.exists(directory_path): shutil.rmtree(directory_path) # --- Ana İşlem Fonksiyonları --- def process_split_by_chunk(pdf_file, pages_per_split): """PDF'i sabit boyutlu parçalara böler.""" if not pdf_file: return None, "Lütfen önce bir PDF dosyası yükleyin." if not isinstance(pages_per_split, int) or pages_per_split <= 0: return None, "Lütfen 'Her dosyada kaç sayfa olsun?' alanı için pozitif bir tam sayı girin." temp_dir = create_temp_dir() try: input_pdf = pypdf.PdfReader(pdf_file.name) total_pages = len(input_pdf.pages) original_filename = os.path.splitext(os.path.basename(pdf_file.name))[0] for i in range(0, total_pages, pages_per_split): pdf_writer = pypdf.PdfWriter() end_page = min(i + pages_per_split, total_pages) for page_num in range(i, end_page): pdf_writer.add_page(input_pdf.pages[page_num]) part_num = (i // pages_per_split) + 1 output_filename = os.path.join(temp_dir, f"{original_filename}_bolum_{part_num}.pdf") with open(output_filename, "wb") as out_pdf: pdf_writer.write(out_pdf) num_files_created = len(os.listdir(temp_dir)) if num_files_created == 0: return None, "Hiçbir dosya oluşturulmadı. Lütfen girdilerinizi kontrol edin." zip_path = zip_output_files(temp_dir, "bolunmus_pdfler.zip") success_message = f"Başarılı! PDF'iniz toplam {num_files_created} parçaya bölündü." return zip_path, success_message except Exception as e: return None, f"Bir hata oluştu: {str(e)}" finally: cleanup(temp_dir) def process_split_by_ranges(pdf_file, ranges_text): """PDF'i kullanıcının belirttiği özel aralıklara göre böler.""" if not pdf_file: return None, "Lütfen önce bir PDF dosyası yükleyin." if not ranges_text or not ranges_text.strip(): return None, "Lütfen bölmek istediğiniz sayfa aralıklarını girin." temp_dir = create_temp_dir() try: input_pdf = pypdf.PdfReader(pdf_file.name) total_pages = len(input_pdf.pages) original_filename = os.path.splitext(os.path.basename(pdf_file.name))[0] # Kullanıcının girdiği metni işle range_parts = [r.strip() for r in ranges_text.split(',')] for part in range_parts: pdf_writer = pypdf.PdfWriter() # Aralığı veya tek sayfayı işle if '-' in part: start_str, end_str = part.split('-') start = int(start_str) end = int(end_str) else: start = end = int(part) # Girdi doğrulaması if start > end: raise ValueError(f"Geçersiz aralık: '{part}'. Başlangıç sayfası, bitiş sayfasından büyük olamaz.") if start < 1 or end > total_pages: raise ValueError(f"Geçersiz sayfa numarası: '{part}'. Sayfalar 1 ile {total_pages} arasında olmalıdır.") # Sayfaları ekle (kullanıcı 1'den başlar, pypdf 0'dan) for page_num in range(start - 1, end): pdf_writer.add_page(input_pdf.pages[page_num]) # Çıktı dosyasını kaydet output_filename = os.path.join(temp_dir, f"{original_filename}_sayfalar_{start}-{end}.pdf") with open(output_filename, "wb") as out_pdf: pdf_writer.write(out_pdf) num_files_created = len(os.listdir(temp_dir)) if num_files_created == 0: return None, "Hiçbir dosya oluşturulmadı. Lütfen girdiğiniz aralıkları kontrol edin." zip_path = zip_output_files(temp_dir, "ozel_bolunmus_pdfler.zip") success_message = f"Başarılı! Belirttiğiniz {num_files_created} aralık için PDF'ler oluşturuldu." return zip_path, success_message except ValueError as ve: # Sayı formatı veya aralık hataları için return None, f"Giriş Hatası: {str(ve)}" except Exception as e: return None, f"Genel bir hata oluştu: {str(e)}" finally: cleanup(temp_dir) # --- Gradio Arayüzü --- with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown("# 📄 Gelişmiş PDF Sayfa Bölücü") # Ortak alanlar: Dosya yükleme ve çıktılar with gr.Row(): pdf_input = gr.File(label="Bölünecek PDF Dosyasını Yükleyin", file_types=[".pdf"], scale=1) with gr.Column(scale=2): status_output = gr.Textbox(label="İşlem Durumu", interactive=False, lines=2) output_zip_file = gr.File(label="Sonucu İndir (ZIP)", interactive=False) gr.Markdown("---") # Farklı bölme metodları için sekmeler with gr.Tabs(): # Sekme 1: Sabit Boyuta Göre Bölme with gr.TabItem("Bölüm Boyutuna Göre Böl"): gr.Markdown("PDF'i sabit sayıda sayfa içeren eşit parçalara ayırır.") with gr.Row(): pages_per_split_input = gr.Number(label="Her dosyada kaç sayfa olsun?", value=5, minimum=1, step=1) chunk_button = gr.Button("🚀 Böl ve Zip'le (Boyuta Göre)", variant="primary") # Sekme 2: Özel Aralıklara Göre Bölme with gr.TabItem("Özel Sayfa Aralığına Göre Böl"): gr.Markdown("Yalnızca belirttiğiniz sayfa aralıklarını ayrı PDF'ler olarak alır. Virgülle ayırarak birden çok aralık girebilirsiniz.") with gr.Row(): ranges_input = gr.Textbox(label="Sayfa Aralıkları (Örn: 2-12, 15-25, 30)", placeholder="2-12, 15-25, 30") ranges_button = gr.Button("🚀 Böl ve Zip'le (Aralığa Göre)", variant="primary") # Buton tıklama olaylarını ilgili fonksiyonlara bağlama chunk_button.click( fn=process_split_by_chunk, inputs=[pdf_input, pages_per_split_input], outputs=[output_zip_file, status_output] ) ranges_button.click( fn=process_split_by_ranges, inputs=[pdf_input, ranges_input], outputs=[output_zip_file, status_output] ) demo.launch()