diff --git a/lib/nntp/tiny/message.py b/lib/nntp/tiny/message.py index 146b579..025ba65 100644 --- a/lib/nntp/tiny/message.py +++ b/lib/nntp/tiny/message.py @@ -43,6 +43,7 @@ class MessageState(enum.Enum): class Message(DatabaseTable): __slots__ = ( + '_cache', 'id', 'newsgroup_id', 'state', @@ -68,10 +69,11 @@ class Message(DatabaseTable): RE_HEADER = re.compile(r'^([A-Za-z0-9\-]+): (.*)$') def __init__(self): + self._cache = dict() self.id = None self.newsgroup_id = None self.state = MessageState.EMPTY - self.headers = dict() + self.headers = None self.line = None self.content = '' self.body = None @@ -80,7 +82,14 @@ class Message(DatabaseTable): @staticmethod def __from_row__(row): message = Message() - message.id = row['id'] + message.headers = dict() + message.id = row['id'] + message.newsgroup_id = row['newsgroup_id'] + message.created_on = row['created_on'] + message.message_id = row['message_id'] + message.parent_id = row['parent_id'] + message.sender = row['sender'] + message.read(row['content']) return message @@ -88,35 +97,76 @@ class Message(DatabaseTable): def __values__(self) -> tuple: return ( self.newsgroup_id, - self.date(), - self.unique_id(), - self.header('references'), - self.sender(), - self.subject(), + self.created_on, + self.message_id, + self.parent_id, + self.sender, + self.subject, self.content ) def header(self, key: str): + if self.headers is None: + self.read(self.content) + return self.headers.get(key.lower()) - def unique_id(self) -> str: + @property + def created_on(self): + try: + value = self._cache.get('created_on') + + if value is not None: + ret = datetime.datetime.fromisoformat(value) + else: + value = self.header('Date') + + if value is None: + ret = search_dates(value)[0][1] + + self._cache['created_on'] = str(ret) + except: + ret = datetime.datetime.fromtimestamp(0) + + return ret + + @created_on.setter + def created_on(self, value): + self.headers['date'] = str(value) + self._cache['created_on'] = str(value) + + @property + def message_id(self) -> str: return self.header('Message-ID') + @message_id.setter + def message_id(self, value): + self.headers['message-id'] = value + + @property def parent_id(self) -> str: return self.header('References') - def date(self): - try: - return search_dates(self.headers['date'])[0][1] - except: - return datetime.datetime.fromtimestamp(0) + @parent_id.setter + def parent_id(self, value): + self.headers['references'] = value - def sender(self): + @property + def sender(self) -> str: return self.headers.get('from', 'Unknown') - def subject(self): + @sender.setter + def sender(self, value): + self.headers['from'] = value + + @property + def subject(self) -> str: return self.headers.get('subject', '(no subject)') + @subject.setter + def subject(self, value): + self.headers['subject'] = value + def is_first_line(self): return len(self.headers) == 1 and (self.body == '' or self.body is None) @@ -125,7 +175,8 @@ class Message(DatabaseTable): self.content += self.line if self.state is MessageState.EMPTY: - self.state = MessageState.HEADER + self.state = MessageState.HEADER + self.headers = dict() if self.state is MessageState.HEADER: if line == '\n' or line == '\r\n':