File size: 4,959 Bytes
69f2337 a08f988 69f2337 a08f988 69f2337 a08f988 69f2337 a08f988 69f2337 a08f988 | 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 | 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
],
}
|