lab4 / app /api /messages /parser.py
brestok's picture
init
a08f988
Raw History Blame Contribute Delete
2.12 kB
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),
]
)