Refactor OVER, HDR

Refactor OVER, HDR to be simpler, using a single convenience method to
implement similar semantics for commands which operate on both single
and ranges of messages
This commit is contained in:
XANTRONIX Development 2024-11-26 14:53:16 -05:00
parent 72a4fd2230
commit 65a60d33fd

View file

@ -518,17 +518,62 @@ class Session():
return self.end() return self.end()
def _message_by_id(self, identifier: str): def _each_message_by_id(self, identifier: str):
if identifier[0] == '<': if identifier is None:
return self.db.get(Message, { if self.newsgroup is None:
'newsgroup_id': self.newsgroup.id, self.respond(ResponseCode.NNTP_NEWSGROUP_NOT_SELECTED)
'message_id': identifier return
})
if self.article_id is None:
self.respond(ResponseCode.NNTP_ARTICLE_INVALID_NUMBER)
return
message = self.db.get(Message, self.article_id)
if message is None:
self.respond(ResponseCode.NNTP_ARTICLE_INVALID_NUMBER)
return
self.respond(ResponseCode.NNTP_INFORMATION_FOLLOWS)
yield message
elif identifier[0] == '<':
message = self.db.query(Message, {
'message_id': identifier
}).fetchone()
if message is None:
self.respond(ResponseCode.NNTP_ARTICLE_NOT_FOUND_ID)
return
self.respond(ResponseCode.NNTP_INFORMATION_FOLLOWS)
yield message
else: else:
return self.db.get(Message, { if self.newsgroup is None:
'newsgroup_id': self.newsgroup.id, self.respond(ResponseCode.NNTP_NEWSGROUP_NOT_SELECTED)
'id': int(identifier) return
})
msgrange = MessageRange.parse(identifier)
sql = f"select * from {Message.name} where "
sql += " newsgroup_id = ? and " + msgrange.where()
cr = self.db.query_sql(Message, sql, (self.newsgroup.id,))
first = True
for message in cr.each():
if first:
first = False
self.respond(ResponseCode.NNTP_INFORMATION_FOLLOWS)
yield message
if first:
self.respond(ResponseCode.NNTP_ARTICLE_NOT_FOUND_RANGE)
self.end()
def _send_message_headers(self, message: Message): def _send_message_headers(self, message: Message):
for name in message.headers: for name in message.headers:
@ -587,39 +632,9 @@ class Session():
message.id, message.headers.get(name, '') message.id, message.headers.get(name, '')
)) ))
def _cmd_hdr(self, name: str, msg: Optional[str]=None): def _cmd_hdr(self, name: str, identifier: Optional[str]=None):
if self.newsgroup is None: for message in self._each_message_by_id(identifier):
return self.respond(ResponseCode.NNTP_NEWSGROUP_NOT_SELECTED)
if msg is None:
if self.article_id is None:
return self.respond(ResponseCode.NNTP_ARTICLE_INVALID_NUMBER)
message = self.db.get(Message, self.article_id)
self.respond(ResponseCode.NNTP_HEADERS_FOLLOW)
self._send_message_header(message, name) self._send_message_header(message, name)
else:
msgrange = MessageRange.parse(msg)
sql = f"select * from {Message.name} where "
sql += " newsgroup_id = ? and " + msgrange.where()
cr = self.db.query_sql(Message, sql, (self.newsgroup.id,))
first = True
for message in cr.each():
if first:
first = False
self.respond(ResponseCode.NNTP_HEADERS_FOLLOW)
self._send_message_header(message, name)
if first:
return self.respond(ResponseCode.NNTP_ARTICLE_NOT_FOUND_RANGE)
return self.end()
def _message_overview(self, message: Message) -> dict: def _message_overview(self, message: Message) -> dict:
return map(lambda s: s.replace('\t', ' '), [ return map(lambda s: s.replace('\t', ' '), [
@ -634,48 +649,10 @@ class Session():
]) ])
def _cmd_over(self, identifier: Optional[str]=None): def _cmd_over(self, identifier: Optional[str]=None):
if identifier is None: for message in self._each_message_by_id(identifier):
if self.newsgroup is None: overview = self._message_overview(message)
return self.respond(ResponseCode.NNTP_NEWSGROUP_NOT_SELECTED)
if self.article_id is None: self.print('|'.join(overview))
return self.respond(ResponseCode.NNTP_ARTICLE_INVALID_NUMBER)
message = self.db.get(Message, self.article_id)
if message is None:
return self.respond(ResponseCode.NNTP_ARTICLE_INVALID_NUMBER)
elif identifier[0] == '<':
message = self.db.query(Message, {
'message_id': identifier
}).fetchone()
if message is None:
return self.respond(ResponseCode.NNTP_ARTICLE_NOT_FOUND_ID)
else:
if self.newsgroup is None:
return self.respond(ResponseCode.NNTP_NEWSGROUP_NOT_SELECTED)
msgrange = MessageRange.parse(identifier)
sql = f"select * from {Message.name} where "
sql += " newsgroup_id = ? and " + msgrange.where()
cr = self.db.query_sql(Message, sql, (self.newsgroup.id,))
first = True
for message in cr.each():
if first:
first = False
self.respond(ResponseCode.NNTP_OVERVIEW_FOLLOWS)
overview = self._message_overview(message)
self.print('|'.join(overview))
if first:
return self.respond(ResponseCode.NNTP_ARTICLE_NOT_FOUND_RANGE)
def _cmd_stat(self, identifier: Optional[str]=None): def _cmd_stat(self, identifier: Optional[str]=None):
if self.newsgroup is None: if self.newsgroup is None: