calendar-gym / server /utils /validation.py
santosh-iima's picture
Upload 91 files
beb8990 verified
"""
Validation utilities for Calendar API
Provides common validation functions used across different API endpoints
"""
from typing import Optional, Tuple
from database.managers.color_manager import ColorManager
from apis.colors.data import CALENDAR_COLORS, EVENT_COLORS
def validate_calendar_color_id(color_id: Optional[str], database_id: str) -> Optional[str]:
"""
Validate calendar colorId against database
Args:
color_id: The color ID to validate (can be None)
database_id: Database ID for color manager
Returns:
None if validation passes, error message if invalid
"""
if color_id is None:
return None # Optional field, None is valid
if not isinstance(color_id, str):
return "colorId must be a string"
try:
color_manager = ColorManager(database_id)
if not color_manager.validate_color_id("calendar", color_id):
return f"Invalid calendar colorId: '{color_id}'. Check available colorId with GET /colors"
except Exception:
# Fallback validation if database fails
return f"Could not validate colorId: '{color_id}'. Database may not be initialized"
return None
def validate_event_color_id(color_id: Optional[str], database_id: str) -> Optional[str]:
"""
Validate event colorId against database
Args:
color_id: The color ID to validate (can be None)
database_id: Database ID for color manager
Returns:
None if validation passes, error message if invalid
"""
if color_id is None:
return None # Optional field, None is valid
if not isinstance(color_id, str):
return "colorId must be a string"
try:
color_manager = ColorManager(database_id)
if not color_manager.validate_color_id("event", color_id):
return f"Invalid event colorId: '{color_id}'. Check available colors with GET /colors"
except Exception:
# Fallback validation if database fails
return f"Could not validate colorId: '{color_id}'. Database may not be initialized"
return None
def validate_request_colors(data: dict, color_type: str, database_id: str) -> Optional[str]:
"""
Validate colorId in request data against database
Args:
data: Request data dictionary
color_type: Either 'calendar' or 'event'
database_id: Database ID for color manager
Returns:
None if validation passes, error message if invalid
"""
if "colorId" not in data:
return None # No colorId in request, that's fine
color_id = data.get("colorId")
if color_type == "calendar":
return validate_calendar_color_id(color_id, database_id)
elif color_type == "event":
return validate_event_color_id(color_id, database_id)
else:
return f"Unknown color type: {color_type}"
def validate_color_combination(background_color: str, foreground_color: str, color_type: str) -> Optional[str]:
"""
Validate that backgroundColor and foregroundColor combination exists in color data
Args:
background_color: Background color in hex format (e.g., "#ac725e")
foreground_color: Foreground color in hex format (e.g., "#1d1d1d")
color_type: Either 'calendar' or 'event'
Returns:
None if combination is valid, error message if invalid
"""
if color_type == "calendar":
colors = CALENDAR_COLORS
elif color_type == "event":
colors = EVENT_COLORS
else:
return f"Unknown color type: {color_type}"
# Check if the combination exists in the color data
for color_id, color_data in colors.items():
if (color_data["background"].lower() == background_color.lower() and
color_data["foreground"].lower() == foreground_color.lower()):
return None # Valid combination found
return f"Invalid color combination: backgroundColor='{background_color}' and foregroundColor='{foreground_color}' is not a valid {color_type} color combination"
def find_color_id_by_combination(background_color: str, foreground_color: str, color_type: str) -> Optional[str]:
"""
Find the colorId that matches the given backgroundColor and foregroundColor combination
Args:
background_color: Background color in hex format (e.g., "#ac725e")
foreground_color: Foreground color in hex format (e.g., "#1d1d1d")
color_type: Either 'calendar' or 'event'
Returns:
colorId if combination is found, None if not found
"""
if color_type == "calendar":
colors = CALENDAR_COLORS
elif color_type == "event":
colors = EVENT_COLORS
else:
return None
# Find the colorId that matches the combination
for color_id, color_data in colors.items():
if (color_data["background"].lower() == background_color.lower() and
color_data["foreground"].lower() == foreground_color.lower()):
return color_id
return None
def set_colors_from_color_id(data: dict, color_type: str) -> Optional[str]:
"""
Set backgroundColor and foregroundColor from colorId if they are not provided
Args:
data: Request data dictionary (will be modified to add colors if colorId is valid)
color_type: Either 'calendar' or 'event'
Returns:
None if successful, error message if colorId is invalid
"""
color_id = data.get("colorId")
# Only process if colorId is provided and RGB colors are not provided
if not color_id:
return None
# Skip if RGB colors are already provided
if data.get("backgroundColor") or data.get("foregroundColor"):
return None
if color_type == "calendar":
colors = CALENDAR_COLORS
elif color_type == "event":
colors = EVENT_COLORS
else:
return f"Unknown color type: {color_type}"
# Validate colorId and get colors
if color_id not in colors:
return f"Invalid {color_type} colorId: '{color_id}'. Check available colorId with GET /colors"
# Set the colors from the colorId
color_data = colors[color_id]
data["backgroundColor"] = color_data["background"]
data["foregroundColor"] = color_data["foreground"]
return None
def validate_and_set_color_id(data: dict, color_type: str) -> Optional[str]:
"""
Validate RGB color combination and set appropriate colorId if valid combination exists
Args:
data: Request data dictionary (will be modified to add colorId if found)
color_type: Either 'calendar' or 'event'
Returns:
None if validation passes, error message if invalid combination
"""
background_color = data.get("backgroundColor")
foreground_color = data.get("foregroundColor")
# Only validate if both colors are provided
if not (background_color and foreground_color):
return None
# Validate the combination exists
validation_error = validate_color_combination(background_color, foreground_color, color_type)
if validation_error:
return validation_error
# Find and set the matching colorId
color_id = find_color_id_by_combination(background_color, foreground_color, color_type)
if color_id:
data["colorId"] = color_id
return None