|
|
import gradio as gr |
|
|
import pypdf |
|
|
import os |
|
|
import zipfile |
|
|
import shutil |
|
|
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
|
|
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] |
|
|
|
|
|
|
|
|
range_parts = [r.strip() for r in ranges_text.split(',')] |
|
|
|
|
|
for part in range_parts: |
|
|
pdf_writer = pypdf.PdfWriter() |
|
|
|
|
|
|
|
|
if '-' in part: |
|
|
start_str, end_str = part.split('-') |
|
|
start = int(start_str) |
|
|
end = int(end_str) |
|
|
else: |
|
|
start = end = int(part) |
|
|
|
|
|
|
|
|
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.") |
|
|
|
|
|
|
|
|
for page_num in range(start - 1, end): |
|
|
pdf_writer.add_page(input_pdf.pages[page_num]) |
|
|
|
|
|
|
|
|
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: |
|
|
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) |
|
|
|
|
|
|
|
|
with gr.Blocks(theme=gr.themes.Soft()) as demo: |
|
|
gr.Markdown("# 📄 Gelişmiş PDF Sayfa Bölücü") |
|
|
|
|
|
|
|
|
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("---") |
|
|
|
|
|
|
|
|
with gr.Tabs(): |
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
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() |