lab4 / app /api /messages /parser.py
brestok's picture
init
a08f988
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),
]
)