Use property wrappers to defer parsing content

This commit is contained in:
XANTRONIX Development 2024-11-10 10:05:26 -05:00
parent 71de86fdae
commit 94f9261350

View file

@ -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 = ''