lab4 / app /api /topics /views.py
brestok's picture
init
a08f988
from typing import List
from uuid import UUID
from fastapi import APIRouter
from app.api.messages.schemas import Message
from app.api.messages.services import MessageService
from app.api.participants.schemas import Participant
from app.api.participants.services import ParticipantService
from app.api.topics.schemas import (
AddMessageRequest,
Topic,
TopicCreate,
TopicMessageResponse,
TopicResponse,
)
from app.api.topics.services import TopicService
from app.core.config import (
HTTP_STATUS_CREATED,
MESSAGES_FILE,
PARTICIPANTS_FILE,
TOPICS_FILE,
UNKNOWN_PARTICIPANT_NAME,
)
from app.core.file_manager import FileManager
from app.core.link import Link, TopicLink
router = APIRouter()
message_service = MessageService(FileManager(MESSAGES_FILE), FileManager(TOPICS_FILE), FileManager(PARTICIPANTS_FILE))
topic_service = TopicService(FileManager(TOPICS_FILE), message_service=message_service)
participant_service = ParticipantService(FileManager(PARTICIPANTS_FILE))
def _resolve_participant_name(participant_id: Link, participants: List[Participant]) -> str:
for participant in participants:
if participant.id == participant_id.value:
return f"{participant.first_name} {participant.last_name}".strip()
return UNKNOWN_PARTICIPANT_NAME
def _topic_to_response(topic: Topic, participants: List[Participant], messages: List[Message]) -> TopicResponse:
message_responses = []
for message in sorted(messages, key=lambda item: item.order_in_topic):
message_responses.append(
TopicMessageResponse(
participant_id=message.participant_id,
content=message.content,
participant_name=_resolve_participant_name(message.participant_id, participants),
order_in_topic=message.order_in_topic,
)
)
return TopicResponse(
id=topic.id,
title=topic.title,
description=topic.description,
created_at=topic.created_at,
participants=topic.participants,
messages=message_responses,
)
@router.get("/", response_model=List[TopicResponse])
async def list_topics() -> List[TopicResponse]:
topics = topic_service.list_topics()
participants = participant_service.list_participants()
messages = message_service.list_messages()
messages_by_topic: dict[UUID, List[Message]] = {}
for message in messages:
messages_by_topic.setdefault(message.topic_id.value, []).append(message)
return [
_topic_to_response(topic, participants, messages_by_topic.get(topic.id, []))
for topic in topics
]
@router.get("/{topic_id}", response_model=TopicResponse)
async def get_topic(topic_id: UUID) -> TopicResponse:
topic_link = TopicLink(value=topic_id)
topic = topic_service.get_topic(topic_link)
participants = participant_service.list_participants()
topic_messages = message_service.list_messages_by_topic(topic_link)
return _topic_to_response(topic, participants, topic_messages)
@router.post("/", response_model=TopicResponse, status_code=HTTP_STATUS_CREATED)
async def create_topic(payload: TopicCreate) -> TopicResponse:
topic = topic_service.create_topic(payload)
participants = participant_service.list_participants()
topic_messages = message_service.list_messages_by_topic(TopicLink(value=topic.id))
return _topic_to_response(topic, participants, topic_messages)
@router.post("/{topic_id}/messages", response_model=TopicResponse, status_code=HTTP_STATUS_CREATED)
async def add_message(topic_id: UUID, payload: AddMessageRequest) -> TopicResponse:
topic_link = TopicLink(value=topic_id)
topic = topic_service.add_message(topic_link, payload)
participants = participant_service.list_participants()
topic_messages = message_service.list_messages_by_topic(topic_link)
return _topic_to_response(topic, participants, topic_messages)
@router.get("/{topic_id}/download")
async def download_topic(topic_id: UUID) -> dict:
topic_link = TopicLink(value=topic_id)
topic = topic_service.get_topic(topic_link)
participants = participant_service.list_participants()
topic_messages = message_service.list_messages_by_topic(topic_link)
response = _topic_to_response(topic, participants, topic_messages)
return {
"id": str(response.id),
"title": response.title,
"description": response.description,
"created_at": response.created_at.isoformat(),
"participants": [{"table": p.table, "value": str(p.value)} for p in response.participants],
"messages": [
{
"participant_id": {"table": m.participant_id.table, "value": str(m.participant_id.value)},
"content": m.content,
"participant_name": m.participant_name,
"order_in_topic": m.order_in_topic,
}
for m in response.messages
],
}