|
|
import gradio as gr |
|
|
import json |
|
|
from datetime import datetime |
|
|
import base64 |
|
|
import tempfile |
|
|
import os |
|
|
from fpdf import FPDF |
|
|
from PIL import Image |
|
|
|
|
|
|
|
|
TEMPLATE_PRESETS = { |
|
|
"Weekly Planner": "A4 weekly planner, portrait orientation, Monday start, 7 columns, notes section", |
|
|
"Monthly Calendar": "A4 monthly calendar, landscape orientation, large date boxes, clean design", |
|
|
"Daily Schedule": "A4 daily planner, hourly time slots, priority tasks section", |
|
|
"Habit Tracker": "A4 habit tracker, 30-day grid, progress tracking", |
|
|
"Study Planner": "A4 study schedule, subject blocks, assignment tracker" |
|
|
} |
|
|
|
|
|
|
|
|
COLOR_SCHEMES = { |
|
|
"Professional Blue": {"primary": "#2563EB", "secondary": "#1E40AF", "accent": "#3B82F6"}, |
|
|
"Forest Green": {"primary": "#059669", "secondary": "#047857", "accent": "#10B981"}, |
|
|
"Sunset Orange": {"primary": "#EA580C", "secondary": "#C2410C", "accent": "#FB923C"}, |
|
|
"Royal Purple": {"primary": "#7C3AED", "secondary": "#5B21B6", "accent": "#8B5CF6"} |
|
|
} |
|
|
|
|
|
class SimplePDF(FPDF): |
|
|
def __init__(self, title="My Planner", colors=None): |
|
|
super().__init__() |
|
|
self.title_text = title |
|
|
self.colors = colors or COLOR_SCHEMES["Professional Blue"] |
|
|
|
|
|
def header(self): |
|
|
self.set_font('Arial', 'B', 16) |
|
|
|
|
|
primary_rgb = tuple(int(self.colors["primary"][1:][i:i+2], 16) for i in (0, 2, 4)) |
|
|
self.set_text_color(*primary_rgb) |
|
|
self.cell(0, 10, self.title_text, 0, 1, 'C') |
|
|
self.ln(10) |
|
|
|
|
|
def footer(self): |
|
|
self.set_y(-15) |
|
|
self.set_font('Arial', 'I', 8) |
|
|
self.set_text_color(128, 128, 128) |
|
|
self.cell(0, 10, f'Generated on {datetime.now().strftime("%Y-%m-%d")}', 0, 0, 'C') |
|
|
|
|
|
def create_simple_template(prompt, title, color_scheme): |
|
|
"""Create a simple template based on user input""" |
|
|
try: |
|
|
|
|
|
colors = COLOR_SCHEMES.get(color_scheme, COLOR_SCHEMES["Professional Blue"]) |
|
|
|
|
|
|
|
|
html_content = f""" |
|
|
<!DOCTYPE html> |
|
|
<html> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<title>{title}</title> |
|
|
<style> |
|
|
body {{ |
|
|
font-family: Arial, sans-serif; |
|
|
margin: 20px; |
|
|
color: #333; |
|
|
}} |
|
|
.header {{ |
|
|
text-align: center; |
|
|
color: {colors['primary']}; |
|
|
border-bottom: 3px solid {colors['primary']}; |
|
|
padding-bottom: 15px; |
|
|
margin-bottom: 30px; |
|
|
}} |
|
|
.title {{ |
|
|
font-size: 24px; |
|
|
font-weight: bold; |
|
|
margin: 0; |
|
|
}} |
|
|
.subtitle {{ |
|
|
font-size: 14px; |
|
|
color: {colors['secondary']}; |
|
|
margin: 5px 0; |
|
|
}} |
|
|
.grid {{ |
|
|
display: grid; |
|
|
grid-template-columns: repeat(7, 1fr); |
|
|
gap: 2px; |
|
|
border: 2px solid {colors['primary']}; |
|
|
margin: 20px 0; |
|
|
}} |
|
|
.grid-header {{ |
|
|
background: {colors['primary']}; |
|
|
color: white; |
|
|
padding: 10px; |
|
|
text-align: center; |
|
|
font-weight: bold; |
|
|
}} |
|
|
.grid-cell {{ |
|
|
border: 1px solid {colors['accent']}; |
|
|
min-height: 80px; |
|
|
padding: 8px; |
|
|
background: #fafafa; |
|
|
}} |
|
|
.notes {{ |
|
|
margin-top: 30px; |
|
|
padding: 20px; |
|
|
background: #f8f9fa; |
|
|
border-left: 5px solid {colors['accent']}; |
|
|
}} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="header"> |
|
|
<h1 class="title">{title}</h1> |
|
|
<p class="subtitle">Generated on {datetime.now().strftime('%B %d, %Y')}</p> |
|
|
</div> |
|
|
|
|
|
<div class="grid"> |
|
|
""" |
|
|
|
|
|
|
|
|
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] |
|
|
for day in days: |
|
|
html_content += f'<div class="grid-header">{day}</div>' |
|
|
|
|
|
|
|
|
for i in range(28): |
|
|
html_content += f'<div class="grid-cell"><strong>{i+1}</strong></div>' |
|
|
|
|
|
html_content += f""" |
|
|
</div> |
|
|
|
|
|
<div class="notes"> |
|
|
<h3 style="color: {colors['primary']}; margin-top: 0;">Notes & Reminders</h3> |
|
|
<div style="height: 100px; background: white; border: 1px solid #ddd; padding: 10px;"></div> |
|
|
</div> |
|
|
</body> |
|
|
</html> |
|
|
""" |
|
|
|
|
|
|
|
|
pdf = SimplePDF(title=title, colors=colors) |
|
|
pdf.add_page() |
|
|
|
|
|
|
|
|
pdf.set_font('Arial', '', 12) |
|
|
pdf.set_text_color(0, 0, 0) |
|
|
|
|
|
|
|
|
y_start = 50 |
|
|
cell_width = 25 |
|
|
cell_height = 20 |
|
|
|
|
|
|
|
|
for row in range(5): |
|
|
for col in range(7): |
|
|
x = 10 + (col * cell_width) |
|
|
y = y_start + (row * cell_height) |
|
|
pdf.rect(x, y, cell_width, cell_height) |
|
|
|
|
|
if row == 0: |
|
|
pdf.set_xy(x + 1, y + 1) |
|
|
pdf.set_font('Arial', 'B', 8) |
|
|
pdf.cell(cell_width-2, cell_height-2, days[col][:3], 0, 0, 'C') |
|
|
pdf.set_font('Arial', '', 8) |
|
|
|
|
|
|
|
|
pdf.set_xy(10, y_start + 120) |
|
|
pdf.set_font('Arial', 'B', 14) |
|
|
primary_rgb = tuple(int(colors["primary"][1:][i:i+2], 16) for i in (0, 2, 4)) |
|
|
pdf.set_text_color(*primary_rgb) |
|
|
pdf.cell(0, 10, 'Notes & Important Reminders', 0, 1, 'L') |
|
|
|
|
|
|
|
|
temp_dir = "temp_outputs" |
|
|
os.makedirs(temp_dir, exist_ok=True) |
|
|
pdf_path = os.path.join(temp_dir, f"template_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf") |
|
|
pdf.output(pdf_path) |
|
|
|
|
|
success_msg = f""" |
|
|
<div style='padding: 20px; background: #f0f9ff; border-left: 4px solid {colors['primary']};'> |
|
|
<h3 style='color: {colors['primary']}; margin-top: 0;'>â
Template Generated Successfully!</h3> |
|
|
<p><strong>Title:</strong> {title}</p> |
|
|
<p><strong>Description:</strong> {prompt}</p> |
|
|
<p><strong>Color Scheme:</strong> {color_scheme}</p> |
|
|
<p><strong>Generated at:</strong> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p> |
|
|
</div> |
|
|
""" |
|
|
|
|
|
return html_content, pdf_path, success_msg |
|
|
|
|
|
except Exception as e: |
|
|
error_msg = f"<div style='color: red; padding: 20px;'>â Error: {str(e)}</div>" |
|
|
return error_msg, None, f"Error details: {str(e)}" |
|
|
|
|
|
|
|
|
with gr.Blocks(title="ð¨ AI Template Generator", theme=gr.themes.Default()) as demo: |
|
|
gr.Markdown(""" |
|
|
# ð¨ AI Template Generator |
|
|
### Create Beautiful Planners & Templates with AI |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=2): |
|
|
gr.Markdown("### ð Template Description") |
|
|
|
|
|
template_preset = gr.Dropdown( |
|
|
choices=["Custom"] + list(TEMPLATE_PRESETS.keys()), |
|
|
value="Weekly Planner", |
|
|
label="ð§ Quick Presets" |
|
|
) |
|
|
|
|
|
prompt_input = gr.Textbox( |
|
|
label="ð Describe Your Template", |
|
|
placeholder="Describe what kind of planner you need...", |
|
|
lines=3, |
|
|
value=TEMPLATE_PRESETS["Weekly Planner"] |
|
|
) |
|
|
|
|
|
def update_prompt(preset): |
|
|
if preset and preset != "Custom": |
|
|
return TEMPLATE_PRESETS[preset] |
|
|
return "" |
|
|
|
|
|
template_preset.change(update_prompt, template_preset, prompt_input) |
|
|
|
|
|
with gr.Column(scale=1): |
|
|
gr.Markdown("### ð¨ Customization") |
|
|
|
|
|
title_input = gr.Textbox( |
|
|
label="ð Template Title", |
|
|
placeholder="My Planner", |
|
|
value="My Weekly Planner" |
|
|
) |
|
|
|
|
|
color_scheme = gr.Dropdown( |
|
|
choices=list(COLOR_SCHEMES.keys()), |
|
|
value="Professional Blue", |
|
|
label="ð Color Scheme" |
|
|
) |
|
|
|
|
|
generate_btn = gr.Button("ð Generate Template", variant="primary", size="lg") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=2): |
|
|
preview_output = gr.HTML(label="ð Template Preview") |
|
|
|
|
|
with gr.Column(scale=1): |
|
|
download_output = gr.File(label="ð¥ Download PDF") |
|
|
status_output = gr.HTML(label="ð Generation Status") |
|
|
|
|
|
|
|
|
generate_btn.click( |
|
|
create_simple_template, |
|
|
inputs=[prompt_input, title_input, color_scheme], |
|
|
outputs=[preview_output, download_output, status_output] |
|
|
) |
|
|
|
|
|
gr.Markdown(""" |
|
|
--- |
|
|
### ð¡ Tips: |
|
|
- **Be specific**: Mention size (A4), orientation (portrait/landscape) |
|
|
- **Include details**: Time ranges, number of columns, special sections |
|
|
- **Try presets**: Use quick presets as starting points |
|
|
""") |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |