File size: 9,279 Bytes
f6ea8c9
 
 
d5dcd86
 
a6d8181
 
f6ea8c9
08c3f6a
2255202
4a5e8d2
2255202
5232a03
4a5e8d2
2255202
 
4a5e8d2
444003a
4a5e8d2
2255202
 
 
 
4a5e8d2
444003a
4a5e8d2
2255202
444003a
2255202
444003a
08c3f6a
4a5e8d2
 
 
444003a
 
 
 
4a5e8d2
 
444003a
08c3f6a
 
 
 
4a5e8d2
08c3f6a
 
 
4a5e8d2
 
08c3f6a
 
 
 
 
444003a
08c3f6a
9387339
 
 
08c3f6a
9387339
08c3f6a
5232a03
444003a
9387339
 
 
 
444003a
08c3f6a
 
 
 
 
444003a
f6ea8c9
08c3f6a
4a5e8d2
08c3f6a
444003a
 
 
08c3f6a
a6d8181
08c3f6a
5232a03
08c3f6a
5232a03
444003a
08c3f6a
 
5232a03
 
 
 
a6d8181
444003a
c450bc2
4a5e8d2
444003a
f6ea8c9
5232a03
 
08c3f6a
5232a03
08c3f6a
f6ea8c9
4a5e8d2
 
 
2255202
f6ea8c9
2255202
4a5e8d2
2255202
9387339
 
4a5e8d2
444003a
9387339
 
5232a03
9387339
 
5232a03
9387339
 
5232a03
9387339
d5dcd86
f6ea8c9
a6d8181
2255202
a6d8181
 
 
5232a03
2255202
 
4a5e8d2
2255202
4a5e8d2
f6ea8c9
4a5e8d2
5232a03
 
a6d8181
 
4a5e8d2
 
f6ea8c9
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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()