Spaces:
Sleeping
Sleeping
| """ | |
| Definition of Space-related DTOs (Data Transfer Objects) | |
| """ | |
| from typing import List, Optional, ClassVar | |
| from datetime import datetime | |
| from pydantic import BaseModel, Field, validator | |
| import re | |
| from typing import Optional | |
| class CreateSpaceDTO(BaseModel): | |
| """Request DTO for creating a Space""" | |
| title: str = Field(..., description="Topic of the Space") | |
| objective: str = Field(..., description="Objective of the Space") | |
| host: str = Field(..., description="Host's endpoint") | |
| participants: List[str] = Field(default_factory=list, description="List of other participants' endpoints") | |
| def validate_host(cls, v): | |
| pattern = r'^https?://[^\s/$.?#].[^\s]*$' | |
| if not re.match(pattern, v): | |
| raise ValueError(f"Invalid host endpoint format: {v}, must be a valid http(s) address") | |
| return v | |
| def validate_participants(cls, v): | |
| pattern = r'^https?://[^\s/$.?#].[^\s]*$' | |
| invalid_endpoints = [] | |
| for endpoint in v: | |
| if not re.match(pattern, endpoint): | |
| invalid_endpoints.append(endpoint) | |
| if invalid_endpoints: | |
| raise ValueError(f"The following participant endpoints are invalid: {', '.join(invalid_endpoints)}, must be valid http(s) addresses") | |
| return v | |
| class SpaceMessageDTO(BaseModel): | |
| """DTO for Space messages""" | |
| id: str = Field(..., description="Message ID") | |
| space_id: str = Field(..., description="ID of the Space this message belongs to") | |
| sender_endpoint: str = Field(..., description="Sender's endpoint") | |
| content: str = Field(..., description="Message content") | |
| message_type: str = Field(..., description="Message type, such as opening, discussion, summary, etc.") | |
| round: int = Field(0, description="Discussion round, 0 indicates a non-discussion message (such as opening or summary)") | |
| create_time: datetime = Field(..., description="Message creation time") | |
| role: str = Field("participant", description="Role of the message sender, such as host or participant") | |
| def from_db(cls, db_message) -> "SpaceMessageDTO": | |
| """Create DTO from database model""" | |
| return cls( | |
| id=db_message.id, | |
| space_id=db_message.space_id, | |
| sender_endpoint=db_message.sender_endpoint, | |
| content=db_message.content, | |
| message_type=getattr(db_message, "message_type", "unknown"), | |
| round=getattr(db_message, "round", 0), | |
| create_time=db_message.create_time, | |
| role=getattr(db_message, "role", "participant") | |
| ) | |
| def to_dict(self) -> dict: | |
| """Convert DTO to dictionary""" | |
| return { | |
| "id": self.id, | |
| "space_id": self.space_id, | |
| "sender_endpoint": self.sender_endpoint, | |
| "content": self.content, | |
| "message_type": self.message_type, | |
| "round": self.round, | |
| "create_time": self.create_time.isoformat(), | |
| "role": self.role | |
| } | |
| class SpaceDTO(BaseModel): | |
| """Response DTO for Space""" | |
| # Status constant definitions | |
| STATUS_INITIALIZED: ClassVar[int] = 1 # Initialized | |
| STATUS_DISCUSSING: ClassVar[int] = 2 # In discussion | |
| STATUS_INTERRUPTED: ClassVar[int] = 3 # Discussion interrupted | |
| STATUS_FINISHED: ClassVar[int] = 4 # Discussion finished | |
| id: str | |
| title: str | |
| objective: str | |
| participants: List[str] | |
| host: str | |
| create_time: datetime | |
| messages: List[SpaceMessageDTO] = Field(default_factory=list, description="List of messages in the Space") | |
| conclusion: Optional[str] = Field(default=None, description="Final conclusion of the discussion") | |
| status: int = Field(STATUS_INITIALIZED, description="Discussion status: 1-Initialized, 2-In discussion, 3-Discussion interrupted, 4-Discussion finished") | |
| space_share_id: Optional[str] = Field(default=None, description="Share ID for the Space, used for sharing with others") | |
| def get_all_participants(self) -> List[str]: | |
| """ | |
| Get the list of endpoints for all participants (including the host) | |
| Returns: | |
| List[str]: List of endpoints for all participants | |
| """ | |
| # Ensure the host is in the list and not duplicated | |
| all_participants = set(self.participants) | |
| all_participants.add(self.host) | |
| return list(all_participants) | |
| def add_message(self, message_dto: SpaceMessageDTO) -> None: | |
| """ | |
| Add a message to the Space | |
| Args: | |
| message_dto: The message DTO to be added | |
| """ | |
| self.messages.append(message_dto) | |
| def from_db(cls, db_space) -> "SpaceDTO": | |
| """Create DTO from database model""" | |
| # Get message list | |
| messages = [] | |
| if hasattr(db_space, "messages") and db_space.messages: | |
| messages = [SpaceMessageDTO.from_db(msg) for msg in db_space.messages] | |
| return cls( | |
| id=db_space.id, | |
| space_share_id=db_space.space_share_id, | |
| title=db_space.title, | |
| objective=db_space.objective, | |
| participants=db_space.participants, | |
| host=db_space.host, | |
| create_time=db_space.create_time, | |
| messages=messages, | |
| conclusion=db_space.conclusion, | |
| status=getattr(db_space, "status", 1) | |
| ) | |
| def to_dict(self) -> dict: | |
| """Convert DTO to dictionary""" | |
| return { | |
| "id": self.id, | |
| "space_share_id": self.space_share_id, | |
| "title": self.title, | |
| "objective": self.objective, | |
| "participants": self.participants, | |
| "host": self.host, | |
| "create_time": self.create_time.isoformat(), | |
| "messages": [msg.to_dict() for msg in self.messages], | |
| "conclusion": self.conclusion, | |
| "status": self.status | |
| } | |