Files
Kunthawat Greethong c35fa52117 Base code
2026-01-08 22:39:53 +07:00

556 lines
22 KiB
Python

"""Template system for Image Studio with platform-specific presets."""
from dataclasses import dataclass
from typing import Dict, List, Optional, Literal
from enum import Enum
class Platform(str, Enum):
"""Supported social media platforms."""
INSTAGRAM = "instagram"
FACEBOOK = "facebook"
TWITTER = "twitter"
LINKEDIN = "linkedin"
YOUTUBE = "youtube"
PINTEREST = "pinterest"
TIKTOK = "tiktok"
BLOG = "blog"
EMAIL = "email"
WEBSITE = "website"
class TemplateCategory(str, Enum):
"""Template categories."""
SOCIAL_MEDIA = "social_media"
BLOG_CONTENT = "blog_content"
AD_CREATIVE = "ad_creative"
PRODUCT = "product"
BRAND_ASSETS = "brand_assets"
EMAIL_MARKETING = "email_marketing"
@dataclass
class AspectRatio:
"""Aspect ratio configuration."""
ratio: str # e.g., "1:1", "16:9"
width: int
height: int
label: str # e.g., "Square", "Widescreen"
@dataclass
class ImageTemplate:
"""Image generation template."""
id: str
name: str
category: TemplateCategory
platform: Optional[Platform]
aspect_ratio: AspectRatio
description: str
recommended_provider: str
style_preset: str
quality: Literal["draft", "standard", "premium"]
prompt_template: Optional[str] = None
negative_prompt_template: Optional[str] = None
use_cases: List[str] = None
class PlatformTemplates:
"""Platform-specific template definitions."""
# Aspect Ratios
SQUARE_1_1 = AspectRatio("1:1", 1080, 1080, "Square")
PORTRAIT_4_5 = AspectRatio("4:5", 1080, 1350, "Portrait")
STORY_9_16 = AspectRatio("9:16", 1080, 1920, "Story/Reel")
LANDSCAPE_16_9 = AspectRatio("16:9", 1920, 1080, "Landscape")
WIDE_21_9 = AspectRatio("21:9", 2560, 1080, "Ultra Wide")
TWITTER_2_1 = AspectRatio("2:1", 1200, 600, "Twitter Card")
TWITTER_3_1 = AspectRatio("3:1", 1500, 500, "Twitter Header")
FACEBOOK_1_91_1 = AspectRatio("1.91:1", 1200, 630, "Facebook Feed")
LINKEDIN_1_91_1 = AspectRatio("1.91:1", 1200, 628, "LinkedIn Feed")
LINKEDIN_2_1 = AspectRatio("2:1", 1200, 627, "LinkedIn Article")
LINKEDIN_4_1 = AspectRatio("4:1", 1128, 191, "LinkedIn Cover")
PINTEREST_2_3 = AspectRatio("2:3", 1000, 1500, "Pinterest Pin")
YOUTUBE_16_9 = AspectRatio("16:9", 1280, 720, "YouTube Thumbnail")
FACEBOOK_COVER_16_9 = AspectRatio("16:9", 820, 312, "Facebook Cover")
@classmethod
def get_platform_templates(cls) -> Dict[Platform, List[ImageTemplate]]:
"""Get all platform-specific templates."""
return {
Platform.INSTAGRAM: cls._instagram_templates(),
Platform.FACEBOOK: cls._facebook_templates(),
Platform.TWITTER: cls._twitter_templates(),
Platform.LINKEDIN: cls._linkedin_templates(),
Platform.YOUTUBE: cls._youtube_templates(),
Platform.PINTEREST: cls._pinterest_templates(),
Platform.TIKTOK: cls._tiktok_templates(),
Platform.BLOG: cls._blog_templates(),
Platform.EMAIL: cls._email_templates(),
Platform.WEBSITE: cls._website_templates(),
}
@classmethod
def _instagram_templates(cls) -> List[ImageTemplate]:
"""Instagram templates."""
return [
ImageTemplate(
id="instagram_feed_square",
name="Instagram Feed Post (Square)",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.INSTAGRAM,
aspect_ratio=cls.SQUARE_1_1,
description="Perfect for Instagram feed posts with maximum visibility",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Product showcase", "Lifestyle posts", "Brand content"]
),
ImageTemplate(
id="instagram_feed_portrait",
name="Instagram Feed Post (Portrait)",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.INSTAGRAM,
aspect_ratio=cls.PORTRAIT_4_5,
description="Vertical format for maximum feed real estate",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Fashion", "Food", "Product photography"]
),
ImageTemplate(
id="instagram_story",
name="Instagram Story",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.INSTAGRAM,
aspect_ratio=cls.STORY_9_16,
description="Full-screen vertical stories",
recommended_provider="ideogram",
style_preset="digital-art",
quality="standard",
use_cases=["Behind-the-scenes", "Announcements", "Quick updates"]
),
ImageTemplate(
id="instagram_reel_cover",
name="Instagram Reel Cover",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.INSTAGRAM,
aspect_ratio=cls.STORY_9_16,
description="Eye-catching reel cover images",
recommended_provider="ideogram",
style_preset="cinematic",
quality="premium",
use_cases=["Video covers", "Thumbnails", "Highlights"]
),
]
@classmethod
def _facebook_templates(cls) -> List[ImageTemplate]:
"""Facebook templates."""
return [
ImageTemplate(
id="facebook_feed",
name="Facebook Feed Post",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.FACEBOOK,
aspect_ratio=cls.FACEBOOK_1_91_1,
description="Optimized for Facebook news feed",
recommended_provider="ideogram",
style_preset="photographic",
quality="standard",
use_cases=["Page posts", "Shared content", "Community posts"]
),
ImageTemplate(
id="facebook_feed_square",
name="Facebook Feed Post (Square)",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.FACEBOOK,
aspect_ratio=cls.SQUARE_1_1,
description="Square format for feed posts",
recommended_provider="ideogram",
style_preset="photographic",
quality="standard",
use_cases=["Page posts", "Product highlights"]
),
ImageTemplate(
id="facebook_story",
name="Facebook Story",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.FACEBOOK,
aspect_ratio=cls.STORY_9_16,
description="Full-screen vertical stories",
recommended_provider="ideogram",
style_preset="digital-art",
quality="standard",
use_cases=["Quick updates", "Promotions", "Events"]
),
ImageTemplate(
id="facebook_cover",
name="Facebook Cover Photo",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.FACEBOOK,
aspect_ratio=cls.FACEBOOK_COVER_16_9,
description="Wide cover photo for pages",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Page branding", "Events", "Seasonal updates"]
),
]
@classmethod
def _twitter_templates(cls) -> List[ImageTemplate]:
"""Twitter/X templates."""
return [
ImageTemplate(
id="twitter_post",
name="Twitter/X Post",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.TWITTER,
aspect_ratio=cls.LANDSCAPE_16_9,
description="Optimized for Twitter feed",
recommended_provider="ideogram",
style_preset="photographic",
quality="standard",
use_cases=["Tweets", "News", "Updates"]
),
ImageTemplate(
id="twitter_card",
name="Twitter Card",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.TWITTER,
aspect_ratio=cls.TWITTER_2_1,
description="Twitter card with link preview",
recommended_provider="ideogram",
style_preset="digital-art",
quality="standard",
use_cases=["Link sharing", "Articles", "Blog posts"]
),
ImageTemplate(
id="twitter_header",
name="Twitter Header",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.TWITTER,
aspect_ratio=cls.TWITTER_3_1,
description="Profile header image",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Profile branding", "Personal brand", "Business identity"]
),
]
@classmethod
def _linkedin_templates(cls) -> List[ImageTemplate]:
"""LinkedIn templates."""
return [
ImageTemplate(
id="linkedin_post",
name="LinkedIn Post",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.LINKEDIN,
aspect_ratio=cls.LINKEDIN_1_91_1,
description="Professional feed posts",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Professional content", "Industry news", "Thought leadership"]
),
ImageTemplate(
id="linkedin_post_square",
name="LinkedIn Post (Square)",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.LINKEDIN,
aspect_ratio=cls.SQUARE_1_1,
description="Square format for LinkedIn feed",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Quick tips", "Infographics", "Quotes"]
),
ImageTemplate(
id="linkedin_article",
name="LinkedIn Article Header",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.LINKEDIN,
aspect_ratio=cls.LINKEDIN_2_1,
description="Article header images",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Long-form content", "Articles", "Newsletters"]
),
ImageTemplate(
id="linkedin_cover",
name="LinkedIn Company Cover",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.LINKEDIN,
aspect_ratio=cls.LINKEDIN_4_1,
description="Company page cover photo",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Company branding", "Recruitment", "Brand identity"]
),
]
@classmethod
def _youtube_templates(cls) -> List[ImageTemplate]:
"""YouTube templates."""
return [
ImageTemplate(
id="youtube_thumbnail",
name="YouTube Thumbnail",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.YOUTUBE,
aspect_ratio=cls.YOUTUBE_16_9,
description="Eye-catching video thumbnails",
recommended_provider="ideogram",
style_preset="cinematic",
quality="premium",
use_cases=["Video thumbnails", "Channel branding", "Playlists"]
),
ImageTemplate(
id="youtube_channel_art",
name="YouTube Channel Art",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.YOUTUBE,
aspect_ratio=cls.LANDSCAPE_16_9,
description="Channel banner art",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Channel branding", "Personal brand", "Business identity"]
),
]
@classmethod
def _pinterest_templates(cls) -> List[ImageTemplate]:
"""Pinterest templates."""
return [
ImageTemplate(
id="pinterest_pin",
name="Pinterest Pin",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.PINTEREST,
aspect_ratio=cls.PINTEREST_2_3,
description="Vertical pin format",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Product pins", "DIY guides", "Recipes", "Inspiration"]
),
ImageTemplate(
id="pinterest_story",
name="Pinterest Story Pin",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.PINTEREST,
aspect_ratio=cls.STORY_9_16,
description="Full-screen story pins",
recommended_provider="ideogram",
style_preset="digital-art",
quality="standard",
use_cases=["Step-by-step guides", "Tutorials", "Quick tips"]
),
]
@classmethod
def _tiktok_templates(cls) -> List[ImageTemplate]:
"""TikTok templates."""
return [
ImageTemplate(
id="tiktok_video_cover",
name="TikTok Video Cover",
category=TemplateCategory.SOCIAL_MEDIA,
platform=Platform.TIKTOK,
aspect_ratio=cls.STORY_9_16,
description="Vertical video cover",
recommended_provider="ideogram",
style_preset="cinematic",
quality="premium",
use_cases=["Video covers", "Thumbnails", "Profile highlights"]
),
]
@classmethod
def _blog_templates(cls) -> List[ImageTemplate]:
"""Blog content templates."""
return [
ImageTemplate(
id="blog_header",
name="Blog Header",
category=TemplateCategory.BLOG_CONTENT,
platform=Platform.BLOG,
aspect_ratio=cls.LANDSCAPE_16_9,
description="Blog post featured image",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Featured images", "Article headers", "Post thumbnails"]
),
ImageTemplate(
id="blog_header_wide",
name="Blog Header (Wide)",
category=TemplateCategory.BLOG_CONTENT,
platform=Platform.BLOG,
aspect_ratio=cls.WIDE_21_9,
description="Ultra-wide blog header",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Hero sections", "Wide headers", "Landing pages"]
),
]
@classmethod
def _email_templates(cls) -> List[ImageTemplate]:
"""Email marketing templates."""
return [
ImageTemplate(
id="email_banner",
name="Email Banner",
category=TemplateCategory.EMAIL_MARKETING,
platform=Platform.EMAIL,
aspect_ratio=cls.LANDSCAPE_16_9,
description="Email header banner",
recommended_provider="ideogram",
style_preset="photographic",
quality="standard",
use_cases=["Email headers", "Newsletter banners", "Promotions"]
),
ImageTemplate(
id="email_product",
name="Email Product Image",
category=TemplateCategory.EMAIL_MARKETING,
platform=Platform.EMAIL,
aspect_ratio=cls.SQUARE_1_1,
description="Product showcase for emails",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Product highlights", "Promotions", "Offers"]
),
]
@classmethod
def _website_templates(cls) -> List[ImageTemplate]:
"""Website templates."""
return [
ImageTemplate(
id="website_hero",
name="Website Hero Image",
category=TemplateCategory.BRAND_ASSETS,
platform=Platform.WEBSITE,
aspect_ratio=cls.WIDE_21_9,
description="Hero section background",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Hero sections", "Landing pages", "Home page banners"]
),
ImageTemplate(
id="website_banner",
name="Website Banner",
category=TemplateCategory.BRAND_ASSETS,
platform=Platform.WEBSITE,
aspect_ratio=cls.LANDSCAPE_16_9,
description="Section banners",
recommended_provider="ideogram",
style_preset="photographic",
quality="premium",
use_cases=["Section headers", "Category pages", "Feature sections"]
),
]
class TemplateManager:
"""Manager for image templates with search and recommendation."""
def __init__(self):
"""Initialize template manager."""
self.templates = PlatformTemplates.get_platform_templates()
self._all_templates: Optional[List[ImageTemplate]] = None
def get_all_templates(self) -> List[ImageTemplate]:
"""Get all templates across all platforms."""
if self._all_templates is None:
self._all_templates = []
for platform_templates in self.templates.values():
self._all_templates.extend(platform_templates)
return self._all_templates
def get_by_platform(self, platform: Platform) -> List[ImageTemplate]:
"""Get templates for a specific platform."""
return self.templates.get(platform, [])
def get_by_category(self, category: TemplateCategory) -> List[ImageTemplate]:
"""Get templates by category."""
all_templates = self.get_all_templates()
return [t for t in all_templates if t.category == category]
def get_by_id(self, template_id: str) -> Optional[ImageTemplate]:
"""Get template by ID."""
all_templates = self.get_all_templates()
for template in all_templates:
if template.id == template_id:
return template
return None
def search(self, query: str) -> List[ImageTemplate]:
"""Search templates by query."""
query = query.lower()
all_templates = self.get_all_templates()
results = []
for template in all_templates:
# Search in name, description, and use cases
searchable = (
template.name.lower() + " " +
template.description.lower() + " " +
" ".join(template.use_cases or []).lower()
)
if query in searchable:
results.append(template)
return results
def recommend_for_use_case(self, use_case: str, platform: Optional[Platform] = None) -> List[ImageTemplate]:
"""Recommend templates based on use case and platform."""
use_case_lower = use_case.lower()
all_templates = self.get_all_templates()
# Filter by platform if specified
if platform:
all_templates = [t for t in all_templates if t.platform == platform]
# Find matching templates
matches = []
for template in all_templates:
if template.use_cases:
for case in template.use_cases:
if use_case_lower in case.lower():
matches.append(template)
break
return matches
def get_aspect_ratio_options(self) -> List[AspectRatio]:
"""Get all available aspect ratios."""
return [
PlatformTemplates.SQUARE_1_1,
PlatformTemplates.PORTRAIT_4_5,
PlatformTemplates.STORY_9_16,
PlatformTemplates.LANDSCAPE_16_9,
PlatformTemplates.WIDE_21_9,
PlatformTemplates.TWITTER_2_1,
PlatformTemplates.TWITTER_3_1,
PlatformTemplates.FACEBOOK_1_91_1,
PlatformTemplates.LINKEDIN_1_91_1,
PlatformTemplates.LINKEDIN_2_1,
PlatformTemplates.LINKEDIN_4_1,
PlatformTemplates.PINTEREST_2_3,
PlatformTemplates.YOUTUBE_16_9,
PlatformTemplates.FACEBOOK_COVER_16_9,
]