#!/usr/bin/env python3 """ Generate plugin icons using Gemini 2.5 Flash Image API. Based on: https://ai.google.dev/gemini-api/docs/image-generation """ from google import genai from PIL import Image import os import time # API Key client = genai.Client(api_key="AIzaSyBF3_KnttSerq2BK2CaRKSTJHN8BoXp6Hw") OUTPUT_DIR = os.path.dirname(os.path.abspath(__file__)) # Plugin configurations with improved prompts plugins = [ { 'filename': 'daily-appointment-summary.png', 'prompt': '''Generate a professional app icon, 512x512 pixels, square with rounded corners. Style: Modern gradient background transitioning from deep indigo (#4338ca) to vibrant blue (#3b82f6). Central element: A stylized white clipboard or document with 3 horizontal lines representing a list, and a small clock or sun symbol in the top right corner indicating "daily". Design principles: Minimalist, clean lines, no text, suitable for a scheduling/calendar application. The icon should be instantly recognizable as "daily summary" or "daily report" at small sizes like 32x32.''' }, { 'filename': 'no-show-tracker.png', 'prompt': '''Generate a professional app icon, 512x512 pixels, square with rounded corners. Style: Modern gradient background from deep red (#b91c1c) to coral red (#ef4444). Central element: A white calendar or appointment card with a prominent empty circle or "absent" symbol - perhaps a chair silhouette with a question mark, or a clock with a slash through it indicating a missed appointment. Design principles: Minimalist, clean lines, no text. The icon should clearly communicate "missed" or "no-show" at a glance. Professional warning aesthetic without being alarming.''' }, { 'filename': 'birthday-greetings.png', 'prompt': '''Generate a professional app icon, 512x512 pixels, square with rounded corners. Style: Modern gradient background from magenta (#c026d3) to pink (#ec4899). Central element: A white birthday cake with 2-3 simple candles, or a wrapped gift box with a ribbon bow. Add subtle confetti dots or small stars around it for a celebratory feel. Design principles: Minimalist, cheerful but professional, clean lines, no text. Should feel warm and celebratory while still fitting a business application aesthetic.''' }, { 'filename': 'monthly-revenue-report.png', 'prompt': '''Generate a professional app icon, 512x512 pixels, square with rounded corners. Style: Modern gradient background from emerald green (#059669) to teal (#14b8a6). Central element: A white line chart showing an upward trend with 3-4 data points connected by lines, or ascending bar chart with dollar sign integrated subtly. The graph should clearly show growth/success. Design principles: Minimalist, professional finance/analytics aesthetic, clean lines, no text. Should instantly communicate "revenue" and "growth" at small sizes.''' }, { 'filename': 'appointment-reminder-24hr.png', 'prompt': '''Generate a professional app icon, 512x512 pixels, square with rounded corners. Style: Modern gradient background from amber (#d97706) to orange (#f97316). Central element: A white notification bell with a small circular badge, combined with a "24" numeral or a clock face showing time. The bell should be the primary focus with the time element secondary. Design principles: Minimalist, attention-grabbing but professional, clean lines, no text except possibly "24". Should clearly indicate "reminder" and "advance notice" at small sizes.''' }, { 'filename': 'inactive-customer-reengagement.png', 'prompt': '''Generate a professional app icon, 512x512 pixels, square with rounded corners. Style: Modern gradient background from violet (#7c3aed) to purple (#a855f7). Central element: A white person silhouette or user icon with a curved "return" arrow circling back to them, or a magnet symbol attracting a small person icon. Should convey "bringing customers back". Design principles: Minimalist, warm and welcoming professional aesthetic, clean lines, no text. Should communicate "re-engagement" or "win back" at a glance.''' } ] def generate_logo(prompt: str, filename: str) -> bool: """Generate a logo using Gemini 2.5 Flash Image (per official docs)""" print(f"\nGenerating {filename}...") try: # Using the exact format from Google's documentation response = client.models.generate_content( model='gemini-2.5-flash-image', contents=[prompt], ) # Process response per docs for part in response.parts: if part.inline_data is not None: # Get the raw image data and convert to PIL from io import BytesIO image_data = part.inline_data.data pil_image = Image.open(BytesIO(image_data)) # Resize to 256x256 for consistency if pil_image.size != (256, 256): pil_image = pil_image.resize((256, 256), Image.Resampling.LANCZOS) output_path = os.path.join(OUTPUT_DIR, filename) pil_image.save(output_path, 'PNG') print(f" ✓ Saved: {output_path}") return True elif part.text is not None: print(f" Model text: {part.text[:100]}...") print(" ✗ No image in response") return False except Exception as e: error_msg = str(e) if "RESOURCE_EXHAUSTED" in error_msg or "quota" in error_msg.lower(): print(f" ✗ Quota exceeded - try again later") else: print(f" ✗ Error: {type(e).__name__}: {error_msg[:300]}") return False def main(): print("=" * 60) print("Generating Plugin Icons with Gemini 2.5 Flash Image") print("=" * 60) success_count = 0 for i, plugin in enumerate(plugins): if i > 0: print("\nWaiting 5 seconds...") time.sleep(5) if generate_logo(plugin['prompt'], plugin['filename']): success_count += 1 print("\n" + "=" * 60) print(f"Complete: {success_count}/{len(plugins)} icons generated") print("=" * 60) if __name__ == "__main__": main()