File size: 2,115 Bytes
69f2337 a08f988 69f2337 a08f988 69f2337 a08f988 69f2337 a08f988 69f2337 |
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 |
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),
]
)
|