Files
smoothschedule/frontend/public/plugin-logos/generate_daily_summary.py
poduck 9b106bf129 feat: Add plugin configuration editing with template variable parsing
## Backend Changes:
- Enhanced PluginTemplate.save() to auto-parse template variables from plugin code
- Updated PluginInstallationSerializer to expose template metadata (description, category, version, author, logo, template_variables)
- Fixed template variable parser to handle nested {{ }} braces in default values
- Added brace-counting algorithm to properly extract variables with insertion codes
- Fixed explicit type parameter detection (textarea, text, email, etc.)
- Made scheduled_task optional on PluginInstallation model
- Added EventPlugin through model for event-plugin relationships
- Added Event.execute_plugins() method for plugin automation

## Frontend Changes:
- Created Tasks.tsx page for managing scheduled tasks
- Enhanced MyPlugins page with clickable plugin cards
- Added edit configuration modal with dynamic form generation
- Implemented escape sequence handling (convert \n, \', etc. for display)
- Added plugin logos to My Plugins page
- Updated type definitions for PluginInstallation interface
- Added insertion code documentation to Plugin Docs

## Plugin System:
- All platform plugins now have editable email templates with textarea support
- Template variables properly parsed with full default values
- Insertion codes ({{CUSTOMER_NAME}}, {{BUSINESS_NAME}}, etc.) documented
- Plugin logos displayed in marketplace and My Plugins

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 23:45:55 -05:00

78 lines
2.7 KiB
Python

import os
import sys
try:
from PIL import Image, ImageDraw
except ImportError:
print("Error: Pillow library not found.")
print("Please install it using: pip install Pillow")
sys.exit(1)
# Configuration
OUTPUT_PATH = "/home/poduck/Desktop/smoothschedule2/frontend/public/plugin-logos/daily-appointment-summary.png"
SIZE = (144, 144) # Generated at 3x resolution (144px) for high quality on 48px displays
BG_COLOR = "#4f46e5" # Indigo/Blue
ICON_COLOR = "white"
def create_logo():
# Create a new image with a transparent background
img = Image.new('RGBA', SIZE, (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
# 1. Draw Background (Rounded Square)
radius = 30
rect_bounds = [0, 0, SIZE[0], SIZE[1]]
draw.rounded_rectangle(rect_bounds, radius=radius, fill=BG_COLOR)
# 2. Draw Envelope Icon (Email concept)
# Centered, slightly offset up to make room for calendar
env_w = 90
env_h = 60
env_x = (SIZE[0] - env_w) // 2
env_y = (SIZE[1] - env_h) // 2 - 10
# Envelope body
draw.rectangle([env_x, env_y, env_x + env_w, env_y + env_h], outline=ICON_COLOR, width=5)
# Envelope flap (V shape)
draw.line([env_x, env_y, env_x + env_w // 2, env_y + env_h // 2 + 5], fill=ICON_COLOR, width=5)
draw.line([env_x + env_w, env_y, env_x + env_w // 2, env_y + env_h // 2 + 5], fill=ICON_COLOR, width=5)
# 3. Draw Calendar Badge (Scheduling concept)
# Bottom right corner
cal_size = 50
cal_x = env_x + env_w - (cal_size // 2)
cal_y = env_y + env_h - (cal_size // 2)
# Clear background behind calendar for separation
border = 4
draw.rounded_rectangle(
[cal_x - border, cal_y - border, cal_x + cal_size + border, cal_y + cal_size + border],
radius=10, fill=BG_COLOR
)
# Calendar body
draw.rounded_rectangle([cal_x, cal_y, cal_x + cal_size, cal_y + cal_size], radius=8, fill="white")
# Calendar red header (using a lighter indigo/blue to match theme)
header_h = 14
draw.rounded_rectangle(
[cal_x, cal_y, cal_x + cal_size, cal_y + header_h],
radius=8, corners=(True, True, False, False), fill="#818cf8"
)
# Calendar 'lines'
line_x = cal_x + 10
line_w = cal_size - 20
draw.line([line_x, cal_y + 22, line_x + line_w, cal_y + 22], fill=BG_COLOR, width=3)
draw.line([line_x, cal_y + 32, line_x + line_w, cal_y + 32], fill=BG_COLOR, width=3)
draw.line([line_x, cal_y + 42, line_x + line_w * 0.6, cal_y + 42], fill=BG_COLOR, width=3)
# Save the file
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
img.save(OUTPUT_PATH)
print(f"Success! Logo saved to: {OUTPUT_PATH}")
if __name__ == "__main__":
create_logo()