lab4 / app /api /messages /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, 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,
}