from typing import List from uuid import UUID from fastapi import APIRouter from app.api.messages.schemas import Message, MessageResponse 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 Topic from app.core.config import ( MESSAGES_FILE, PARTICIPANTS_FILE, TABLE_PARTICIPANTS, TABLE_TOPICS, TOPICS_FILE, UNKNOWN_PARTICIPANT_NAME, UNKNOWN_TOPIC_TITLE, ) from app.core.file_manager import FileManager from app.core.link import Link, ParticipantLink, TopicLink router = APIRouter() message_service = MessageService( FileManager(MESSAGES_FILE), FileManager(TOPICS_FILE), FileManager(PARTICIPANTS_FILE) ) participant_service = ParticipantService(FileManager(PARTICIPANTS_FILE)) topic_file_manager = FileManager(TOPICS_FILE) def _resolve_link_value(link: Link, participants: List[Participant], topics: List[Topic]) -> str: resolvers = { TABLE_PARTICIPANTS: lambda identifier: next( ( f"{participant.first_name} {participant.last_name}".strip() for participant in participants if participant.id == identifier ), UNKNOWN_PARTICIPANT_NAME, ), TABLE_TOPICS: lambda identifier: next( (topic.title for topic in topics if topic.id == identifier), UNKNOWN_TOPIC_TITLE, ), } return link.resolve(resolvers) def _list_topics() -> List[Topic]: from app.api.topics.parser import TopicLineParser topics: List[Topic] = [] for line in topic_file_manager.read_lines(): try: topics.append(TopicLineParser.parse(line)) except ValueError: continue return topics def _message_to_response( message: Message, participants: List[Participant], topics: List[Topic] ) -> MessageResponse: return MessageResponse( id=message.id, topic_id=message.topic_id, order_in_topic=message.order_in_topic, participant_id=message.participant_id, created_at=message.created_at, content=message.content, participant_name=_resolve_link_value(message.participant_id, participants, topics), topic_title=_resolve_link_value(message.topic_id, participants, topics), ) @router.get("/", response_model=List[MessageResponse]) async def list_messages() -> List[MessageResponse]: messages = message_service.list_messages() participants = participant_service.list_participants() topics = _list_topics() messages.sort(key=lambda message: (message.topic_id.value, message.order_in_topic)) return [_message_to_response(message, participants, topics) for message in messages] @router.get("/topic/{topic_id}", response_model=List[MessageResponse]) async def list_messages_by_topic(topic_id: UUID) -> List[MessageResponse]: topic_link = TopicLink(value=topic_id) message_service.get_topic(topic_link) messages = message_service.list_messages_by_topic(topic_link) participants = participant_service.list_participants() topics = _list_topics() return [_message_to_response(message, participants, topics) for message in messages] @router.get("/{message_id}/download") async def download_message(message_id: UUID) -> dict: message = message_service.get_message(message_id) participants = participant_service.list_participants() topics = _list_topics() response = _message_to_response(message, participants, topics) return { "id": str(response.id), "topic_id": {"table": response.topic_id.table, "value": str(response.topic_id.value)}, "participant_id": {"table": response.participant_id.table, "value": str(response.participant_id.value)}, "content": response.content, "order_in_topic": response.order_in_topic, "created_at": response.created_at.isoformat(), "participant_name": response.participant_name, "topic_title": response.topic_title, }