From 94f926135065255b9b94665220ecfb3eb324ad82 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sun, 10 Nov 2024 10:05:26 -0500 Subject: [PATCH] Use property wrappers to defer parsing content --- lib/nntp/tiny/message.py | 42 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/nntp/tiny/message.py b/lib/nntp/tiny/message.py index 64d396f..08dbb5a 100644 --- a/lib/nntp/tiny/message.py +++ b/lib/nntp/tiny/message.py @@ -44,14 +44,14 @@ class MessageState(enum.Enum): class Message(DatabaseTable): __slots__ = ( '_cache', + '_headers', + '_body', + '_key', 'id', 'newsgroup_id', 'state', - 'headers', 'line', 'content', - 'body', - '_key' ) name = 'newsgroup_message' @@ -71,19 +71,19 @@ class Message(DatabaseTable): def __init__(self): self._cache = dict() + self._headers = None + self._body = None + self._key = None self.id = None self.newsgroup_id = None self.state = MessageState.EMPTY - self.headers = None self.line = None self.content = '' - self.body = None - self._key = None @staticmethod def __from_row__(row): message = Message() - message.headers = dict() + message._headers = dict() message.id = row['id'] message.newsgroup_id = row['newsgroup_id'] message.created_on = row['created_on'] @@ -91,7 +91,11 @@ class Message(DatabaseTable): message.parent_id = row['parent_id'] message.sender = row['sender'] - message.read(row['content']) + # + # Defer parsing the message content until a specific header not already + # assigned to a dedcicated property, or the message body, is required. + # + message.content = row['content'] return message @@ -106,6 +110,20 @@ class Message(DatabaseTable): self.content ) + @property + def headers(self): + if self._headers is None: + self.read(self.content) + + return self._headers + + @property + def body(self): + if self._body is None: + self.read(self.content) + + return self._body + def header(self, key: str): if self.headers is None: self.read(self.content) @@ -176,21 +194,21 @@ class Message(DatabaseTable): self.content += self.line if self.state is MessageState.EMPTY: - self.state = MessageState.HEADER - self.headers = dict() + self.state = MessageState.HEADER + self._headers = dict() if self.state is MessageState.HEADER: if line == '\n' or line == '\r\n': self.state = MessageState.BODY elif line[0] == ' ' or line[0] == '\t': - self.headers[self._key] += ' ' + decode(line.strip()) + self._headers[self._key] += ' ' + decode(line.strip()) else: match = self.RE_HEADER.match(line) if match: self._key = match[1].lower() - self.headers[self._key] = decode(match[2].rstrip()) + self._headers[self._key] = decode(match[2].rstrip()) elif self.state is MessageState.BODY: if self.body is None: self.body = ''