bk939448's picture
Update app.py
08c3f6a verified
import gradio as gr
import PyPDF2
import os
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
# --- हेल्पर फ़ंक्शन 1: सभी PDF से पेजों की सूची बनाने के लिए ---
def list_all_pages(main_pdf, additional_pdfs):
if not main_pdf:
return None, gr.update(visible=False), "कृपया पहले मुख्य PDF अपलोड करें."
all_files = [main_pdf] + (additional_pdfs if additional_pdfs else [])
page_labels = []
total_page_count = 0
try:
for file_index, pdf_file in enumerate(all_files):
reader = PyPDF2.PdfReader(pdf_file.name)
num_pages = len(reader.pages)
total_page_count += num_pages
for page_index in range(num_pages):
page_labels.append(f"File{file_index+1}-Page{page_index+1}")
status = f"{total_page_count} पेज {len(all_files)} फाइलों से पाए गए. जिन पेजों को रखना है, उन्हें चुनें."
return gr.update(choices=page_labels, value=page_labels), gr.update(visible=True), status
except Exception as e:
return None, gr.update(visible=False), f"फ़ाइल पढ़ने में त्रुटि: {e}. क्या यह एक वैध PDF है?"
# --- मुख्य PDF प्रोसेसिंग फ़ंक्शन (पूरी तरह से नया और बेहतर तर्क) ---
def process_pdf(main_pdf, additional_pdfs, selected_pages, split_pdf, style, custom_left, custom_right, x_pos, y_pos):
if not main_pdf:
raise gr.Error("मुख्य PDF फ़ाइल गायब है!")
if not selected_pages:
raise gr.Error("आपने कोई भी पेज नहीं चुना है! कृपया रखने के लिए कम से कम एक पेज चुनें.")
try:
all_files = [main_pdf] + (additional_pdfs if additional_pdfs else [])
readers = [PyPDF2.PdfReader(f.name) for f in all_files]
final_writer = PyPDF2.PdfWriter()
new_page_counter = 0
# एक ही चरण में फ़िल्टर और नंबर करें (यह अधिक मेमोरी-कुशल है)
for label in selected_pages:
new_page_counter += 1 # नई PDF के लिए पेज नंबर 1 से शुरू करें
# लेबल से मूल पेज प्राप्त करें
parts = label.replace("File", "").split("-Page")
file_idx, page_idx = int(parts[0]) - 1, int(parts[1]) - 1
if not (0 <= file_idx < len(readers) and 0 <= page_idx < len(readers[file_idx].pages)):
continue # अमान्य लेबल को छोड़ दें
page = readers[file_idx].pages[page_idx]
# इस पेज के लिए वॉटरमार्क बनाएं
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=A4)
if style == "Custom...":
page_num_text = f"{custom_left}{new_page_counter}{custom_right}"
else:
page_num_text = style.replace("1", str(new_page_counter))
can.setFont("Helvetica-Bold", 12)
can.setFillColor(colors.black)
can.drawCentredString(x_pos, y_pos, page_num_text)
can.save()
packet.seek(0)
# वॉटरमार्क को सीधे पेज पर मर्ज करें
watermark_reader = PyPDF2.PdfReader(packet)
page.merge_page(watermark_reader.pages[0])
# संशोधित पेज को अंतिम राइटर में जोड़ें
final_writer.add_page(page)
# अंतिम PDF को सहेजें
original_filename = os.path.basename(getattr(main_pdf, 'orig_name', main_pdf.name))
final_numbered_path = f"Final_Output_{original_filename}"
with open(final_numbered_path, "wb") as f:
final_writer.write(f)
# यदि चुना गया है तो विभाजित करें
if split_pdf:
# हम final_writer का उपयोग कर सकते हैं, फाइल को फिर से पढ़ने की जरूरत नहीं है
odd_writer, even_writer = PyPDF2.PdfWriter(), PyPDF2.PdfWriter()
for i, page in enumerate(final_writer.pages):
(odd_writer if (i + 1) % 2 != 0 else even_writer).add_page(page)
odd_path = f"odd_output_{original_filename}" if odd_writer.pages else None
even_path = f"even_output_{original_filename}" if even_writer.pages else None
if odd_path:
with open(odd_path, "wb") as f: odd_writer.write(f)
if even_path:
with open(even_path, "wb") as f: even_writer.write(f)
return final_numbered_path, odd_path, even_path, "प्रोसेसिंग सफल रही!"
else:
return final_numbered_path, None, None, "पेज सफलतापूर्वक बनाए और नंबर किए गए!"
except Exception as e:
raise gr.Error(f"एक गंभीर त्रुटि हुई: {e}")
# --- Gradio इंटरफ़ेस (UI में कोई बदलाव नहीं) ---
with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
gr.Markdown("# 🚀 PDF वर्कफ़्लो स्टेशन (स्थिर और तेज) 🚀\nPDF जोड़ें, पेज हटाएं, पुनः-नंबर करें और विभाजित करें!")
gr.Markdown("### 1. अपनी PDF फाइलें अपलोड करें")
main_pdf_input = gr.File(label="मुख्य PDF", file_types=[".pdf"])
additional_pdfs_input = gr.File(label="(वैकल्पिक) जोड़ने के लिए और PDF", file_count="multiple", file_types=[".pdf"])
list_pages_button = gr.Button("📂 सभी पेजों की सूची जेनरेट करें")
with gr.Column(visible=False) as selection_section:
gr.Markdown("### 2. अंतिम PDF में रखने के लिए पेज चुनें")
gr.Markdown("<p style='color:red;'>ध्यान दें: जिन पेजों को आप अनचेक करेंगे, वे अंतिम फ़ाइल से हटा दिए जाएंगे.</p>")
page_selector = gr.CheckboxGroup(label="पेज चुनें")
gr.Markdown("### 3. नंबरिंग स्टाइल और अंतिम आउटपुट")
split_checkbox = gr.Checkbox(label="अंतिम PDF को सम/विषम पेजों में विभाजित करें", value=False)
with gr.Accordion("Page Numbering Studio", open=True):
style_dropdown = gr.Dropdown(["- 1 -", "[ 1 ]", "★ 1 ★", "* 1 *", "Page 1", "Custom..."], label="स्टाइल टेम्पलेट", value="- 1 -")
with gr.Row(visible=False) as custom_style_row:
custom_left = gr.Textbox(label="कस्टम बायां टेक्स्ट")
custom_right = gr.Textbox(label="कस्टम दायां टेक्स्ट")
x_pos = gr.Slider(0, 595, value=297, label="X-Position (बाएं से दूरी)")
y_pos = gr.Slider(0, 842, value=825, label="Y-Position (नीचे से दूरी)")
process_button = gr.Button("🚀 PDF प्रोसेस करें", variant="primary")
status_output = gr.Textbox(label="स्थिति", interactive=False)
with gr.Column():
pdf_output_final = gr.File(label="अंतिम PDF डाउनलोड करें")
with gr.Row():
pdf_output_odd = gr.File(label="विषम पेज (Odd) डाउनलोड करें")
pdf_output_even = gr.File(label="सम पेज (Even) डाउनलोड करें")
list_pages_button.click(
fn=list_all_pages,
inputs=[main_pdf_input, additional_pdfs_input],
outputs=[page_selector, selection_section, status_output]
)
def toggle_custom_style(style): return gr.update(visible=(style == "Custom..."))
style_dropdown.change(fn=toggle_custom_style, inputs=style_dropdown, outputs=custom_style_row)
process_button.click(
fn=process_pdf,
inputs=[main_pdf_input, additional_pdfs_input, page_selector, split_checkbox, style_dropdown, custom_left, custom_right, x_pos, y_pos],
outputs=[pdf_output_final, pdf_output_odd, pdf_output_even, status_output]
)
demo.launch()