TNCSC_Odoo/scripts/generate_module_assets.py
Alaguraj0361 0f462ad21a
Some checks failed
CI / Brand-leak check (push) Has been cancelled
CI / flake8 / pylint-odoo / manifest completeness (push) Has been cancelled
CI / Install all modules with --test-enable (push) Has been cancelled
add TNCSC deployment module, community add-ons, role guides, and website navigation overrides
2026-09-28 19:43:48 +05:30

176 lines
5.9 KiB
Python

#!/usr/bin/env python3
"""Generate professional icon.png and banner.png assets for Community OS modules."""
import os
from PIL import Image, ImageDraw, ImageFont
MODULES = [
{
'dir': 'community_membership',
'title': 'Community Membership',
'subtitle': 'Tiers, Terms, Expiry, Family Plans & Digital Cards',
'color_primary': (18, 7, 53), # Deep Navy
'color_secondary': (229, 169, 60), # Gold
'badge': 'MEMBERSHIP',
},
{
'dir': 'community_school',
'title': 'Community School',
'subtitle': 'Classrooms, Tamil School Rosters, Attendance & Teachers',
'color_primary': (15, 60, 45), # Deep Emerald
'color_secondary': (229, 169, 60), # Gold
'badge': 'TAMIL SCHOOL',
},
{
'dir': 'event_qr_ticketing',
'title': 'Event QR Ticketing',
'subtitle': 'Fast QR Code Check-in, Attendee Badges & Scanner',
'color_primary': (40, 15, 80), # Deep Violet
'color_secondary': (243, 198, 105),# Light Gold
'badge': 'EVENTS & QR',
},
{
'dir': 'community_portal',
'title': 'Community Portal',
'subtitle': 'Self-Service Member Portal, Digital Cards & School Roster',
'color_primary': (20, 30, 75), # Deep Indigo
'color_secondary': (70, 190, 200), # Teal
'badge': 'PORTAL',
},
{
'dir': 'community_benefits',
'title': 'Community Benefits',
'subtitle': 'Member Discounts, Partner Perks & Entitlement Verification',
'color_primary': (25, 45, 100), # Royal Blue
'color_secondary': (229, 169, 60), # Gold
'badge': 'BENEFITS',
},
{
'dir': 'community_classifieds',
'title': 'Community Classifieds',
'subtitle': 'Community Marketplace, Volunteer Listings & Housing',
'color_primary': (20, 70, 70), # Dark Teal
'color_secondary': (255, 140, 60), # Tangerine
'badge': 'CLASSIFIEDS',
},
{
'dir': 'community_interac',
'title': 'Community Interac',
'subtitle': 'Canadian Interac e-Transfer Direct Payment Provider',
'color_primary': (80, 50, 10), # Dark Bronze
'color_secondary': (255, 190, 40), # Amber
'badge': 'INTERAC CAD',
},
{
'dir': 'community_theme_base',
'title': 'Community Theme Base',
'subtitle': 'Unified Theme Tokens, Typography, Colors & Branding',
'color_primary': (35, 25, 60), # Deep Slate Purple
'color_secondary': (180, 140, 230),# Lavender
'badge': 'THEME BASE',
},
{
'dir': 'tncsc_deployment',
'title': 'TNCSC Deployment',
'subtitle': 'Tamil Nadu Cultural Society of Canada Production Platform',
'color_primary': (18, 7, 53), # TNCSC Navy
'color_secondary': (229, 169, 60), # TNCSC Gold
'badge': 'TNCSC CANADA',
},
]
def make_gradient(width, height, color1, color2):
base = Image.new('RGB', (width, height), color1)
top = Image.new('RGB', (width, height), color2)
mask = Image.new('L', (width, height))
mask_data = []
for y in range(height):
for x in range(width):
mask_data.append(int(255 * (x / width * 0.5 + y / height * 0.5)))
mask.putdata(mask_data)
base.paste(top, (0, 0), mask)
return base
def generate_icon(mod, target_dir):
width, height = 128, 128
c1 = mod['color_primary']
c2 = tuple(min(255, c + 35) for c in c1)
im = make_gradient(width, height, c1, c2)
draw = ImageDraw.Draw(im)
# Gold accent border
gold = mod['color_secondary']
draw.rounded_rectangle([4, 4, width - 4, height - 4], radius=24, outline=gold, width=3)
# Center monogram/symbol
words = mod['badge'].split()
monogram = "".join(w[0] for w in words[:3])
# Inner badge pill
draw.rounded_rectangle([20, 46, width - 20, 82], radius=8, fill=gold)
draw.text((width // 2, 64), monogram, fill=c1, anchor="mm")
# Bottom bar
draw.line([30, 100, width - 30, 100], fill=gold, width=2)
os.makedirs(target_dir, exist_ok=True)
icon_path = os.path.join(target_dir, 'icon.png')
im.save(icon_path, 'PNG')
print(f"Generated {icon_path}")
def generate_banner(mod, target_dir):
width, height = 800, 400
c1 = mod['color_primary']
c2 = tuple(min(255, c + 25) for c in c1)
im = make_gradient(width, height, c1, c2)
draw = ImageDraw.Draw(im)
gold = mod['color_secondary']
# Elegant decorative borders
draw.rectangle([0, 0, width, 8], fill=gold)
draw.rectangle([0, height - 8, width, height], fill=gold)
# Subtle geometric grid / card background
draw.rounded_rectangle([40, 40, width - 40, height - 40], radius=16, outline=gold, width=2)
draw.rounded_rectangle([48, 48, width - 48, height - 48], radius=12, outline=(60, 60, 80), width=1)
# Badge Pill at top
badge_text = f"★ {mod['badge']} MODULE ★"
draw.rounded_rectangle([280, 70, 520, 102], radius=16, fill=gold)
draw.text((400, 86), badge_text, fill=c1, anchor="mm")
# Main Title
draw.text((400, 170), mod['title'], fill=(255, 255, 255), anchor="mm")
# Gold separator line
draw.line([250, 220, 550, 220], fill=gold, width=3)
# Subtitle
draw.text((400, 260), mod['subtitle'], fill=(210, 215, 230), anchor="mm")
# Footer attribution
draw.text((400, 330), "Community OS • Odoo 19 Edition", fill=gold, anchor="mm")
os.makedirs(target_dir, exist_ok=True)
banner_path = os.path.join(target_dir, 'banner.png')
im.save(banner_path, 'PNG')
print(f"Generated {banner_path}")
def main():
if os.path.exists('/mnt/extra-addons'):
root = '/mnt/extra-addons'
else:
root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'addons'))
for mod in MODULES:
desc_dir = os.path.join(root, mod['dir'], 'static', 'description')
generate_icon(mod, desc_dir)
generate_banner(mod, desc_dir)
if __name__ == '__main__':
main()