|
|
import base64 |
|
|
from datetime import datetime |
|
|
from uuid import UUID |
|
|
|
|
|
from app.api.messages.schemas import Message |
|
|
from app.api.participants.schemas import Participant |
|
|
from app.core.config import ( |
|
|
ENCODING_ASCII, |
|
|
ENCODING_UTF8, |
|
|
MESSAGE_EXPECTED_PARTS, |
|
|
MESSAGE_PARSE_EMPTY_ERROR, |
|
|
MESSAGE_PARSE_INVALID_ERROR, |
|
|
MESSAGE_SEPARATOR, |
|
|
TABLE_PARTICIPANTS, |
|
|
TABLE_TOPICS, |
|
|
) |
|
|
from app.core.link import Link, TopicLink, ParticipantLink |
|
|
|
|
|
|
|
|
class MessageLineParser: |
|
|
SEPARATOR = MESSAGE_SEPARATOR |
|
|
EXPECTED_PARTS = MESSAGE_EXPECTED_PARTS |
|
|
|
|
|
@staticmethod |
|
|
def _decode_content(encoded: str) -> str: |
|
|
return base64.b64decode(encoded.encode(ENCODING_ASCII)).decode(ENCODING_UTF8) |
|
|
|
|
|
@staticmethod |
|
|
def _encode_content(value: str) -> str: |
|
|
return base64.b64encode(value.encode(ENCODING_UTF8)).decode(ENCODING_ASCII) |
|
|
|
|
|
@classmethod |
|
|
def parse(cls, line: str) -> Message: |
|
|
raw = line.strip() |
|
|
if not raw: |
|
|
raise ValueError(MESSAGE_PARSE_EMPTY_ERROR) |
|
|
|
|
|
parts = raw.split(cls.SEPARATOR) |
|
|
if len(parts) != cls.EXPECTED_PARTS: |
|
|
raise ValueError(MESSAGE_PARSE_INVALID_ERROR) |
|
|
|
|
|
( |
|
|
message_id, |
|
|
topic_raw, |
|
|
order_in_topic, |
|
|
participant_raw, |
|
|
created_at_value, |
|
|
encoded_content, |
|
|
) = parts |
|
|
|
|
|
return Message( |
|
|
id=UUID(message_id), |
|
|
topic_id=Link.from_raw(topic_raw), |
|
|
order_in_topic=int(order_in_topic), |
|
|
participant_id=Link.from_raw(participant_raw), |
|
|
created_at=datetime.fromisoformat(created_at_value), |
|
|
content=cls._decode_content(encoded_content), |
|
|
) |
|
|
|
|
|
@classmethod |
|
|
def serialize(cls, message: Message) -> str: |
|
|
return cls.SEPARATOR.join( |
|
|
[ |
|
|
str(message.id), |
|
|
message.topic_id.as_path(), |
|
|
str(message.order_in_topic), |
|
|
message.participant_id.as_path(), |
|
|
message.created_at.isoformat(), |
|
|
cls._encode_content(message.content), |
|
|
] |
|
|
) |
|
|
|
|
|
|