Pdfbol / app.py
Zatimm's picture
Update app.py
854ee83 verified
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()