File size: 7,452 Bytes
beb8990 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | """
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 |