Update app.py
Browse files
app.py
CHANGED
|
@@ -6,7 +6,7 @@ from reportlab.pdfgen import canvas
|
|
| 6 |
from reportlab.lib.pagesizes import A4
|
| 7 |
from reportlab.lib import colors
|
| 8 |
|
| 9 |
-
# --- हेल्पर फ़ंक्शन 1: सभी PDF से पेजों की सूची बनाने के लिए
|
| 10 |
def list_all_pages(main_pdf, additional_pdfs):
|
| 11 |
if not main_pdf:
|
| 12 |
return None, gr.update(visible=False), "कृपया पहले मुख्य PDF अपलोड करें."
|
|
@@ -17,7 +17,6 @@ def list_all_pages(main_pdf, additional_pdfs):
|
|
| 17 |
|
| 18 |
try:
|
| 19 |
for file_index, pdf_file in enumerate(all_files):
|
| 20 |
-
# PyPDF2 का उपयोग करके पेजों की संख्या प्राप्त करें
|
| 21 |
reader = PyPDF2.PdfReader(pdf_file.name)
|
| 22 |
num_pages = len(reader.pages)
|
| 23 |
total_page_count += num_pages
|
|
@@ -25,12 +24,11 @@ def list_all_pages(main_pdf, additional_pdfs):
|
|
| 25 |
page_labels.append(f"File{file_index+1}-Page{page_index+1}")
|
| 26 |
|
| 27 |
status = f"{total_page_count} पेज {len(all_files)} फाइलों से पाए गए. जिन पेजों को रखना है, उन्हें चुनें."
|
| 28 |
-
# केवल चेकबॉक्स ग्रुप और सेक्शन को अपडेट करें
|
| 29 |
return gr.update(choices=page_labels, value=page_labels), gr.update(visible=True), status
|
| 30 |
except Exception as e:
|
| 31 |
return None, gr.update(visible=False), f"फ़ाइल पढ़ने में त्रुटि: {e}. क्या यह एक वैध PDF है?"
|
| 32 |
|
| 33 |
-
# --- मुख्य PDF प्रोसेसिंग फ़ंक्शन (
|
| 34 |
def process_pdf(main_pdf, additional_pdfs, selected_pages, split_pdf, style, custom_left, custom_right, x_pos, y_pos):
|
| 35 |
if not main_pdf:
|
| 36 |
raise gr.Error("मुख्य PDF फ़ाइल गायब है!")
|
|
@@ -41,27 +39,29 @@ def process_pdf(main_pdf, additional_pdfs, selected_pages, split_pdf, style, cus
|
|
| 41 |
all_files = [main_pdf] + (additional_pdfs if additional_pdfs else [])
|
| 42 |
readers = [PyPDF2.PdfReader(f.name) for f in all_files]
|
| 43 |
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
| 45 |
for label in selected_pages:
|
|
|
|
|
|
|
|
|
|
| 46 |
parts = label.replace("File", "").split("-Page")
|
| 47 |
file_idx, page_idx = int(parts[0]) - 1, int(parts[1]) - 1
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
-
|
| 52 |
-
filtered_pdf_stream = io.BytesIO()
|
| 53 |
-
filtered_writer.write(filtered_pdf_stream)
|
| 54 |
-
filtered_pdf_stream.seek(0)
|
| 55 |
-
|
| 56 |
-
filtered_reader = PyPDF2.PdfReader(filtered_pdf_stream)
|
| 57 |
-
for i, page in enumerate(filtered_reader.pages):
|
| 58 |
-
new_page_number = i + 1
|
| 59 |
packet = io.BytesIO()
|
| 60 |
can = canvas.Canvas(packet, pagesize=A4)
|
| 61 |
if style == "Custom...":
|
| 62 |
-
page_num_text = f"{custom_left}{
|
| 63 |
else:
|
| 64 |
-
page_num_text = style.replace("1", str(
|
| 65 |
|
| 66 |
can.setFont("Helvetica-Bold", 12)
|
| 67 |
can.setFillColor(colors.black)
|
|
@@ -69,23 +69,28 @@ def process_pdf(main_pdf, additional_pdfs, selected_pages, split_pdf, style, cus
|
|
| 69 |
can.save()
|
| 70 |
packet.seek(0)
|
| 71 |
|
| 72 |
-
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
| 74 |
final_writer.add_page(page)
|
| 75 |
|
|
|
|
| 76 |
original_filename = os.path.basename(getattr(main_pdf, 'orig_name', main_pdf.name))
|
| 77 |
-
final_numbered_path = f"
|
| 78 |
with open(final_numbered_path, "wb") as f:
|
| 79 |
final_writer.write(f)
|
| 80 |
|
|
|
|
| 81 |
if split_pdf:
|
| 82 |
-
|
| 83 |
odd_writer, even_writer = PyPDF2.PdfWriter(), PyPDF2.PdfWriter()
|
| 84 |
-
for i, page in enumerate(
|
| 85 |
(odd_writer if (i + 1) % 2 != 0 else even_writer).add_page(page)
|
| 86 |
|
| 87 |
-
odd_path = f"
|
| 88 |
-
even_path = f"
|
| 89 |
if odd_path:
|
| 90 |
with open(odd_path, "wb") as f: odd_writer.write(f)
|
| 91 |
if even_path:
|
|
@@ -98,23 +103,20 @@ def process_pdf(main_pdf, additional_pdfs, selected_pages, split_pdf, style, cus
|
|
| 98 |
except Exception as e:
|
| 99 |
raise gr.Error(f"एक गंभीर त्रुटि हुई: {e}")
|
| 100 |
|
| 101 |
-
# --- Gradio इंटरफ़ेस (UI में बदलाव) ---
|
| 102 |
with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
|
| 103 |
-
gr.Markdown("# 🚀 PDF वर्कफ़्लो स्टेशन
|
| 104 |
|
| 105 |
-
# चरण 1: अपलोड
|
| 106 |
gr.Markdown("### 1. अपनी PDF फाइलें अपलोड करें")
|
| 107 |
main_pdf_input = gr.File(label="मुख्य PDF", file_types=[".pdf"])
|
| 108 |
additional_pdfs_input = gr.File(label="(वैकल्पिक) जोड़ने के लिए और PDF", file_count="multiple", file_types=[".pdf"])
|
| 109 |
list_pages_button = gr.Button("📂 सभी पेजों की सूची जेनरेट करें")
|
| 110 |
|
| 111 |
-
# चरण 2: चयन (बिना इमेज के)
|
| 112 |
with gr.Column(visible=False) as selection_section:
|
| 113 |
gr.Markdown("### 2. अंतिम PDF में रखने के लिए पेज चुनें")
|
| 114 |
gr.Markdown("<p style='color:red;'>ध्यान दें: जिन पेजों को आप अनचेक करेंगे, वे अंतिम फ़ाइल से हटा दिए जाएंगे.</p>")
|
| 115 |
page_selector = gr.CheckboxGroup(label="पेज चुनें")
|
| 116 |
|
| 117 |
-
# चरण 3: सेटिंग्स और प्रोसेसिंग
|
| 118 |
gr.Markdown("### 3. नंबरिंग स्टाइल और अंतिम आउटपुट")
|
| 119 |
split_checkbox = gr.Checkbox(label="अंतिम PDF को सम/विषम पेजों में विभाजित करें", value=False)
|
| 120 |
with gr.Accordion("Page Numbering Studio", open=True):
|
|
@@ -129,14 +131,12 @@ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
|
|
| 129 |
process_button = gr.Button("🚀 PDF प्रोसेस करें", variant="primary")
|
| 130 |
status_output = gr.Textbox(label="स्थिति", interactive=False)
|
| 131 |
|
| 132 |
-
# चरण 4: आउटपुट
|
| 133 |
with gr.Column():
|
| 134 |
pdf_output_final = gr.File(label="अंतिम PDF डाउनलोड करें")
|
| 135 |
with gr.Row():
|
| 136 |
pdf_output_odd = gr.File(label="विषम पेज (Odd) डाउनलोड करें")
|
| 137 |
pdf_output_even = gr.File(label="सम पेज (Even) डाउनलोड करें")
|
| 138 |
|
| 139 |
-
# --- UI Logic ---
|
| 140 |
list_pages_button.click(
|
| 141 |
fn=list_all_pages,
|
| 142 |
inputs=[main_pdf_input, additional_pdfs_input],
|
|
|
|
| 6 |
from reportlab.lib.pagesizes import A4
|
| 7 |
from reportlab.lib import colors
|
| 8 |
|
| 9 |
+
# --- हेल्पर फ़ंक्शन 1: सभी PDF से पेजों की सूची बनाने के लिए ---
|
| 10 |
def list_all_pages(main_pdf, additional_pdfs):
|
| 11 |
if not main_pdf:
|
| 12 |
return None, gr.update(visible=False), "कृपया पहले मुख्य PDF अपलोड करें."
|
|
|
|
| 17 |
|
| 18 |
try:
|
| 19 |
for file_index, pdf_file in enumerate(all_files):
|
|
|
|
| 20 |
reader = PyPDF2.PdfReader(pdf_file.name)
|
| 21 |
num_pages = len(reader.pages)
|
| 22 |
total_page_count += num_pages
|
|
|
|
| 24 |
page_labels.append(f"File{file_index+1}-Page{page_index+1}")
|
| 25 |
|
| 26 |
status = f"{total_page_count} पेज {len(all_files)} फाइलों से पाए गए. जिन पेजों को रखना है, उन्हें चुनें."
|
|
|
|
| 27 |
return gr.update(choices=page_labels, value=page_labels), gr.update(visible=True), status
|
| 28 |
except Exception as e:
|
| 29 |
return None, gr.update(visible=False), f"फ़ाइल पढ़ने में त्रुटि: {e}. क्या यह एक वैध PDF है?"
|
| 30 |
|
| 31 |
+
# --- मुख्य PDF प्रोसेसिंग फ़ंक्शन (पूरी तरह से नया और बेहतर तर्क) ---
|
| 32 |
def process_pdf(main_pdf, additional_pdfs, selected_pages, split_pdf, style, custom_left, custom_right, x_pos, y_pos):
|
| 33 |
if not main_pdf:
|
| 34 |
raise gr.Error("मुख्य PDF फ़ाइल गायब है!")
|
|
|
|
| 39 |
all_files = [main_pdf] + (additional_pdfs if additional_pdfs else [])
|
| 40 |
readers = [PyPDF2.PdfReader(f.name) for f in all_files]
|
| 41 |
|
| 42 |
+
final_writer = PyPDF2.PdfWriter()
|
| 43 |
+
new_page_counter = 0
|
| 44 |
+
|
| 45 |
+
# एक ही चरण में फ़िल्टर और नंबर करें (यह अधिक मेमोरी-कुशल है)
|
| 46 |
for label in selected_pages:
|
| 47 |
+
new_page_counter += 1 # नई PDF के लिए पेज नंबर 1 से शुरू करें
|
| 48 |
+
|
| 49 |
+
# लेबल से मूल पेज प्राप्त करें
|
| 50 |
parts = label.replace("File", "").split("-Page")
|
| 51 |
file_idx, page_idx = int(parts[0]) - 1, int(parts[1]) - 1
|
| 52 |
+
|
| 53 |
+
if not (0 <= file_idx < len(readers) and 0 <= page_idx < len(readers[file_idx].pages)):
|
| 54 |
+
continue # अमान्य लेबल को छोड़ दें
|
| 55 |
+
|
| 56 |
+
page = readers[file_idx].pages[page_idx]
|
| 57 |
|
| 58 |
+
# इस पेज के लिए वॉटरमार्क बनाएं
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
packet = io.BytesIO()
|
| 60 |
can = canvas.Canvas(packet, pagesize=A4)
|
| 61 |
if style == "Custom...":
|
| 62 |
+
page_num_text = f"{custom_left}{new_page_counter}{custom_right}"
|
| 63 |
else:
|
| 64 |
+
page_num_text = style.replace("1", str(new_page_counter))
|
| 65 |
|
| 66 |
can.setFont("Helvetica-Bold", 12)
|
| 67 |
can.setFillColor(colors.black)
|
|
|
|
| 69 |
can.save()
|
| 70 |
packet.seek(0)
|
| 71 |
|
| 72 |
+
# वॉटरमार्क को सीधे पेज पर मर्ज करें
|
| 73 |
+
watermark_reader = PyPDF2.PdfReader(packet)
|
| 74 |
+
page.merge_page(watermark_reader.pages[0])
|
| 75 |
+
|
| 76 |
+
# संशोधित पेज को अंतिम राइटर में जोड़ें
|
| 77 |
final_writer.add_page(page)
|
| 78 |
|
| 79 |
+
# अंतिम PDF को सहेजें
|
| 80 |
original_filename = os.path.basename(getattr(main_pdf, 'orig_name', main_pdf.name))
|
| 81 |
+
final_numbered_path = f"Final_Output_{original_filename}"
|
| 82 |
with open(final_numbered_path, "wb") as f:
|
| 83 |
final_writer.write(f)
|
| 84 |
|
| 85 |
+
# यदि चुना गया है तो विभाजित करें
|
| 86 |
if split_pdf:
|
| 87 |
+
# हम final_writer का उपयोग कर सकते हैं, फाइल को फिर से पढ़ने की जरूरत नहीं है
|
| 88 |
odd_writer, even_writer = PyPDF2.PdfWriter(), PyPDF2.PdfWriter()
|
| 89 |
+
for i, page in enumerate(final_writer.pages):
|
| 90 |
(odd_writer if (i + 1) % 2 != 0 else even_writer).add_page(page)
|
| 91 |
|
| 92 |
+
odd_path = f"odd_output_{original_filename}" if odd_writer.pages else None
|
| 93 |
+
even_path = f"even_output_{original_filename}" if even_writer.pages else None
|
| 94 |
if odd_path:
|
| 95 |
with open(odd_path, "wb") as f: odd_writer.write(f)
|
| 96 |
if even_path:
|
|
|
|
| 103 |
except Exception as e:
|
| 104 |
raise gr.Error(f"एक गंभीर त्रुटि हुई: {e}")
|
| 105 |
|
| 106 |
+
# --- Gradio इंटरफ़ेस (UI में कोई बदलाव नहीं) ---
|
| 107 |
with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
|
| 108 |
+
gr.Markdown("# 🚀 PDF वर्कफ़्लो स्टेशन (स्थिर और तेज) 🚀\nPDF जोड़ें, पेज हटाएं, पुनः-नंबर करें और विभाजित करें!")
|
| 109 |
|
|
|
|
| 110 |
gr.Markdown("### 1. अपनी PDF फाइलें अपलोड करें")
|
| 111 |
main_pdf_input = gr.File(label="मुख्य PDF", file_types=[".pdf"])
|
| 112 |
additional_pdfs_input = gr.File(label="(वैकल्पिक) जोड़ने के लिए और PDF", file_count="multiple", file_types=[".pdf"])
|
| 113 |
list_pages_button = gr.Button("📂 सभी पेजों की सूची जेनरेट करें")
|
| 114 |
|
|
|
|
| 115 |
with gr.Column(visible=False) as selection_section:
|
| 116 |
gr.Markdown("### 2. अंतिम PDF में रखने के लिए पेज चुनें")
|
| 117 |
gr.Markdown("<p style='color:red;'>ध्यान दें: जिन पेजों को आप अनचेक करेंगे, वे अंतिम फ़ाइल से हटा दिए जाएंगे.</p>")
|
| 118 |
page_selector = gr.CheckboxGroup(label="पेज चुनें")
|
| 119 |
|
|
|
|
| 120 |
gr.Markdown("### 3. नंबरिंग स्टाइल और अंतिम आउटपुट")
|
| 121 |
split_checkbox = gr.Checkbox(label="अंतिम PDF को सम/विषम पेजों में विभाजित करें", value=False)
|
| 122 |
with gr.Accordion("Page Numbering Studio", open=True):
|
|
|
|
| 131 |
process_button = gr.Button("🚀 PDF प्रोसेस करें", variant="primary")
|
| 132 |
status_output = gr.Textbox(label="स्थिति", interactive=False)
|
| 133 |
|
|
|
|
| 134 |
with gr.Column():
|
| 135 |
pdf_output_final = gr.File(label="अंतिम PDF डाउनलोड करें")
|
| 136 |
with gr.Row():
|
| 137 |
pdf_output_odd = gr.File(label="विषम पेज (Odd) डाउनलोड करें")
|
| 138 |
pdf_output_even = gr.File(label="सम पेज (Even) डाउनलोड करें")
|
| 139 |
|
|
|
|
| 140 |
list_pages_button.click(
|
| 141 |
fn=list_all_pages,
|
| 142 |
inputs=[main_pdf_input, additional_pdfs_input],
|