Files
AutonetSellCar/temp_content_video_schema.py

138 lines
3.9 KiB
Python

from pydantic import BaseModel, field_validator
from typing import Optional
from datetime import datetime
import re
class ContentVideoBase(BaseModel):
youtube_id: str
title_ko: str
title_en: Optional[str] = None
title_ja: Optional[str] = None
title_zh: Optional[str] = None
description_ko: Optional[str] = None
description_en: Optional[str] = None
description_ja: Optional[str] = None
description_zh: Optional[str] = None
entity_type: str # "project", "solution", "product"
entity_id: int
display_order: int = 0
is_active: bool = True
@field_validator('youtube_id', mode='before')
@classmethod
def extract_youtube_id(cls, v):
"""Extract YouTube ID from various URL formats or plain ID"""
if not v:
return v
# Already a plain ID (11 characters)
if re.match(r'^[a-zA-Z0-9_-]{11}$', v):
return v
# Extract from various YouTube URL formats
patterns = [
r'(?:youtube\.com/watch\?v=|youtu\.be/|youtube\.com/embed/)([a-zA-Z0-9_-]{11})',
r'youtube\.com/watch\?.*v=([a-zA-Z0-9_-]{11})',
]
for pattern in patterns:
match = re.search(pattern, v)
if match:
return match.group(1)
# Return as-is if no pattern matches
return v
@field_validator('entity_type')
@classmethod
def validate_entity_type(cls, v):
allowed = ['project', 'solution', 'product']
if v not in allowed:
raise ValueError(f'entity_type must be one of: {allowed}')
return v
class ContentVideoCreate(ContentVideoBase):
pass
class ContentVideoUpdate(BaseModel):
youtube_id: Optional[str] = None
title_ko: Optional[str] = None
title_en: Optional[str] = None
title_ja: Optional[str] = None
title_zh: Optional[str] = None
description_ko: Optional[str] = None
description_en: Optional[str] = None
description_ja: Optional[str] = None
description_zh: Optional[str] = None
display_order: Optional[int] = None
is_active: Optional[bool] = None
@field_validator('youtube_id', mode='before')
@classmethod
def extract_youtube_id(cls, v):
if not v:
return v
if re.match(r'^[a-zA-Z0-9_-]{11}$', v):
return v
patterns = [
r'(?:youtube\.com/watch\?v=|youtu\.be/|youtube\.com/embed/)([a-zA-Z0-9_-]{11})',
r'youtube\.com/watch\?.*v=([a-zA-Z0-9_-]{11})',
]
for pattern in patterns:
match = re.search(pattern, v)
if match:
return match.group(1)
return v
class ContentVideoResponse(BaseModel):
id: int
youtube_id: str
title_ko: str
title_en: Optional[str] = None
title_ja: Optional[str] = None
title_zh: Optional[str] = None
description_ko: Optional[str] = None
description_en: Optional[str] = None
description_ja: Optional[str] = None
description_zh: Optional[str] = None
entity_type: str
entity_id: int
display_order: int
is_active: bool
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
# Computed fields
youtube_url: str = ""
youtube_embed_url: str = ""
thumbnail_url: str = ""
class Config:
from_attributes = True
def __init__(self, **data):
super().__init__(**data)
youtube_id = data.get('youtube_id', '')
self.youtube_url = f"https://www.youtube.com/watch?v={youtube_id}"
self.youtube_embed_url = f"https://www.youtube.com/embed/{youtube_id}"
self.thumbnail_url = f"https://img.youtube.com/vi/{youtube_id}/maxresdefault.jpg"
class ContentVideoPublic(BaseModel):
"""Public response with language-specific fields"""
id: int
youtube_id: str
title: str
description: Optional[str] = None
youtube_url: str
youtube_embed_url: str
thumbnail_url: str
display_order: int
class Config:
from_attributes = True