File size: 6,645 Bytes
735d401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import requests
import pandas as pd
import io
from PIL import Image
import os

API_URL = "http://localhost:7860"

def get_preview():
    try:
        response = requests.post(f"{API_URL}/preview")
        if response.status_code == 200:
            return Image.open(io.BytesIO(response.content))
        else:
            return None
    except Exception as e:
        print(f"Error getting preview: {e}")
        return None

def update_config(cert_type, name_x, name_y, name_size, award_text, award_x, award_y, award_size, award_width):
    # Update Certificate Type
    requests.post(f"{API_URL}/config/certificate-type", data={"certificate_type": cert_type})
    
    # Update Name Settings
    requests.post(f"{API_URL}/config/name-settings", json={
        "position": {"x": int(name_x), "y": int(name_y)},
        "font_size": int(name_size),
        "font_path": "DancingScript-Regular.ttf",
        "color": "black"
    })
    
    # Update Award Text
    requests.post(f"{API_URL}/config/award-text", json={
        "text": award_text,
        "position": {"x": int(award_x), "y": int(award_y)},
        "font_size": int(award_size),
        "max_width": int(award_width),
        "font_path": "times.ttf",
        "color": "black"
    })
    
    return get_preview()

def upload_assets(template_part, template_ach, logo_l, logo_r, sig_l, sig_r):
    status = []
    if template_part:
        with open(template_part, "rb") as f:
            requests.post(f"{API_URL}/upload-template", files={"file": f}, data={"template_type": "participation"})
            status.append("Participation Template Uploaded")
    if template_ach:
        with open(template_ach, "rb") as f:
            requests.post(f"{API_URL}/upload-template", files={"file": f}, data={"template_type": "achievement"})
            status.append("Achievement Template Uploaded")
    if logo_l:
        with open(logo_l, "rb") as f:
            requests.post(f"{API_URL}/upload-logo", files={"file": f}, data={"logo_type": "left"})
            status.append("Left Logo Uploaded")
    if logo_r:
        with open(logo_r, "rb") as f:
            requests.post(f"{API_URL}/upload-logo", files={"file": f}, data={"logo_type": "right"})
            status.append("Right Logo Uploaded")
    if sig_l:
        with open(sig_l, "rb") as f:
            requests.post(f"{API_URL}/upload-signature", files={"file": f}, data={"signature_type": "left"})
            status.append("Left Signature Uploaded")
    if sig_r:
        with open(sig_r, "rb") as f:
            requests.post(f"{API_URL}/upload-signature", files={"file": f}, data={"signature_type": "right"})
            status.append("Right Signature Uploaded")
    
    return ", ".join(status) if status else "No files uploaded", get_preview()

def generate_bulk(csv_file):
    if csv_file is None:
        return None, "Please upload a CSV file"
    
    try:
        df = pd.read_csv(csv_file.name)
        if "name" not in df.columns and "Name" not in df.columns:
            return None, "CSV must have a 'name' or 'Name' column"
        
        name_col = "name" if "name" in df.columns else "Name"
        names = df[name_col].dropna().tolist()
        
        response = requests.post(f"{API_URL}/generate-zip", json={"names": names})
        if response.status_code == 200:
            zip_path = "certificates.zip"
            with open(zip_path, "wb") as f:
                f.write(response.content)
            return zip_path, f"Successfully generated {len(names)} certificates"
        else:
            return None, f"Error: {response.text}"
    except Exception as e:
        return None, f"Processing Error: {str(e)}"

# Define Gradio Interface
with gr.Blocks(title="Certificate Generator UI") as demo:
    gr.Markdown("# 🏆 Certificate Generator Professional")
    gr.Markdown("Configure your certificate template and generate bulk certificates.")
    
    with gr.Tab("1. Asset Upload"):
        with gr.Row():
            with gr.Column():
                templ_p = gr.File(label="Participation Template (PNG)")
                templ_a = gr.File(label="Achievement Template (PNG)")
            with gr.Column():
                l_logo = gr.File(label="Left Logo (PNG)")
                r_logo = gr.File(label="Right Logo (PNG)")
            with gr.Column():
                l_sig = gr.File(label="Left Signature (PNG)")
                r_sig = gr.File(label="Right Signature (PNG)")
        
        upload_btn = gr.Button("Upload & Refresh Preview", variant="primary")
        upload_status = gr.Textbox(label="Upload Status")

    with gr.Tab("2. Layout Customization"):
        with gr.Row():
            with gr.Column():
                c_type = gr.Dropdown(["participation", "achievement"], label="Certificate Type", value="participation")
                gr.Markdown("### Name Settings")
                n_x = gr.Slider(0, 2000, value=810, label="Name X")
                n_y = gr.Slider(0, 2000, value=596, label="Name Y")
                n_size = gr.Slider(10, 200, value=85, label="Name Font Size")
                
                gr.Markdown("### Award Text Settings")
                a_text = gr.Textbox(label="Award Text", value="For outstanding participation in the CSI Workshop 2025")
                a_x = gr.Slider(0, 2000, value=810, label="Award X")
                a_y = gr.Slider(0, 2000, value=720, label="Award Y")
                a_size = gr.Slider(10, 100, value=45, label="Award Font Size")
                a_width = gr.Slider(200, 1500, value=1000, label="Max Width")
                
                refresh_btn = gr.Button("Update Layout & Preview", variant="primary")
            
            with gr.Column():
                preview_img = gr.Image(label="Live Preview")

    with gr.Tab("3. Bulk Generation"):
        gr.Markdown("Upload a CSV file with a **name** column to generate certificates in bulk.")
        csv_input = gr.File(label="Recipients CSV")
        gen_btn = gr.Button("Generate Certificates (ZIP)", variant="primary")
        gen_status = gr.Textbox(label="Generation Status")
        zip_output = gr.File(label="Download ZIP")

    # Event Handlers
    upload_btn.click(upload_assets, inputs=[templ_p, templ_a, l_logo, r_logo, l_sig, r_sig], outputs=[upload_status, preview_img])
    refresh_btn.click(update_config, inputs=[c_type, n_x, n_y, n_size, a_text, a_x, a_y, a_size, a_width], outputs=[preview_img])
    gen_btn.click(generate_bulk, inputs=[csv_input], outputs=[zip_output, gen_status])

if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=7861) # Run on different port if standalone