import enum import socket import re from nntp.tiny.server import Server, ServerCapability from nntp.tiny.response import Response class SessionState(enum.Flag): NONE = 0 AUTH_OK = enum.auto() AUTH_POST = enum.auto() from nntp.tiny.buffer import LineBuffer, BufferOverflow class Session(): RE_SPLIT = re.compile(r'\s+') NNTP_VERSION = 2 NNTP_CAPABILITIES = [ 'VERSION %d' % (self.NNTP_VERSION), 'READER', 'HDR', 'NEWNEWS', 'LIST ACTIVE NEWSGROUP OVERVIEW.FMT SUBSCRIPTIONS', 'OVER MSGID' ] COMMANDS = { 'capabilities': } def __init__(self, server: Server, sock: socket.socket): self.server: Server = server self.state: SessionState = SessionState.NONE self.sock: socket.socket = sock self.buf: LineBuffer = LineBuffer() def readline(self): return self.buf.readline(self.sock) def print(self, text: str, end: str="\r\n"): return self.sock.send(bytes(text + end, 'ascii')) def end(self): return self.print('.') def respond(self, code: ResponseCode, message: str=None, body=None): response = Response(code, message, body) return self.print(str(response)) def _cmd_capabilities(self, *args): self.respond(ResponseCode.NNTP_CAPABILITIES_FOLLOW) if self.state & SessionState.AUTH_POST: self.print('POST') if self.state & SessionState.AUTH_OK: self.print('AUTHUSER INFO') for item in self.NNTP_CAPABILITIES: self.print(item) self.end() def handle(self): line = self.readline() if line == '': return command, args = self.RE_SPLIT.split(line.rstrip())