From f07bb981e9616a8ffab85a022f5b1e2046e71ecf Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Sat, 23 Nov 2024 22:40:06 -0500 Subject: [PATCH] More slog --- lib/nntp/tiny/session.py | 75 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/lib/nntp/tiny/session.py b/lib/nntp/tiny/session.py index db63b65..a07ca2c 100644 --- a/lib/nntp/tiny/session.py +++ b/lib/nntp/tiny/session.py @@ -1,9 +1,12 @@ +import re import enum import socket -import re +import datetime +import fnmatch from typing import Optional +from nntp.tiny.buffer import LineBuffer, BufferOverflow from nntp.tiny.db import Database from nntp.tiny.server import Server, ServerCapability from nntp.tiny.response import Response, ResponseCode @@ -15,8 +18,6 @@ class SessionState(enum.Flag): AUTH_OK = enum.auto() AUTH_POST = enum.auto() -from nntp.tiny.buffer import LineBuffer, BufferOverflow - class MessageRange(): __slots__ = 'id', 'min', 'max', @@ -226,6 +227,74 @@ class Session(): return self.end() + def _cmd_list(self, *args): + pass + + RE_DATE_SHORT = re.compile(r'^(\d{2})(\d{2})(\d{2})$') + RE_DATE_LONG = re.compile(r'^(\d{4})(\d{2})(\d{2})$') + RE_TIME = re.compile(r'^(\d{2})(\d{2})(\d{2})$') + + def _parse_date_time(self, datestr: str, timestr: str): + yyyy, mm, dd = None, None, None, + hh, MM, ss = None, None, None + + match = self.RE_DATE_SHORT.match(datestr) + if match: + yy, mm, dd = map(int, match[1:3]) + + if yy >= 70: + yyyy = 1900 + yy + else: + yyyy = 2000 + yy + + match = self.RE_DATE_LONG.match(datestr) + if match: + yyyy, mm, dd = map(int, match[1:3]) + + if yyyy is None: + return + + match = self.RE_TIME.match(timestr) + if match is None: + return + + hh, mm, ss = map(int, match[1:3]) + + return datetime.datetime(yyyy, mm, dd, hh, MM, ss) + + def _cmd_newnews(self, wildmat, datestr, timestr, *args): + gmt = False + + if len(args) == 1: + if args[0] == "GMT": + gmt = True + else: + return self.send_response(ResponseCode.NNTP_SYNTAX_ERROR, "Only optional 'GMT' allowed") + elif len(args) > 1: + return self.send_response(ResponseCode.NNTP_SYNTAX_ERROR, "Too many arguments") + + timestamp = self._parse_date_time(datestr, timestr) + + if timestamp is None: + return self.send_response(ResponseCode.NNTP_SYNTAX_ERROR, "Invalid date or time") + + self.respond(ResponseCode.NNTP_ARTICLE_LISTING_ID_FOLLOWS) + + sql = """ + select message_id from newsgroup_message where newsgroup_id = ? and created_on >= ? + """ + + for name in self.server.newsgroups: + if fnmatch.fnmatch(name, wildmat): + newsgroup = self.server.newsgroups[name] + + cr = self.db.execute(sql, (newsgroup.id, timestamp.isoformat())) + + for row in cr.each(): + self.print(row[0]) + + return self.end() + def handle(self): line = self.readline()