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