Implement method to fetch message summaries from newsgroups

This commit is contained in:
XANTRONIX Development 2024-12-05 12:44:24 -05:00
parent 616e767c0c
commit 7824c8e47b
2 changed files with 52 additions and 7 deletions

View file

@ -2,15 +2,19 @@ import re
import socket
import ssl
import datetime
import email.utils
from typing import Optional
from nntp.tiny.socket import Connection
from nntp.tiny.host import Host
from nntp.tiny.response import Response, ResponseCode
from nntp.tiny.remote import RemoteNewsgroup
from nntp.tiny.message import MessageRange
from nntp.tiny.remote import (
RemoteException, RemoteNewsgroup, RemoteMessage
)
class ClientException(Exception):
pass
@ -62,7 +66,12 @@ class Client(Connection):
def request(self, *args):
self.print(' '.join(args))
return self._read_response()
response = self._read_response()
if response.code.value >= 400:
raise RemoteException(response)
return response
def each_response_line(self):
while True:
@ -88,9 +97,33 @@ class Client(Connection):
parts = self.RE_SPLIT.split(line)
if len(parts) != 4:
raise ClientException('Unexpected result from NEWGROUPS')
raise RemoteException('Unexpected result from NEWGROUPS')
yield RemoteNewsgroup(parts[0],
int(parts[1]),
int(parts[2]),
parts[3] == 'y')
def each_newsgroup_message(self, newsgroup: RemoteNewsgroup, msgrange: Optional[MessageRange]):
self.request('GROUP', newsgroup.name)
self.request('OVER', str(msgrange))
for line in self.each_response_line():
message = RemoteMessage()
parts = line.split('\t')
message.id = int(parts[0])
message.subject = parts[1]
message.sender = parts[2]
message.created_on = email.utils.parsedate_to_datetime(parts[3])
message.message_id = parts[4]
message.references = parts[5]
message.size = int(parts[6])
message.lines = int(parts[7])
for part in parts[8:]:
key, value = part.split(': ')
message.headers[key] = value
yield message

View file

@ -1,11 +1,14 @@
class RemoteException(Exception):
pass
class RemoteNewsgroup():
__slots__ = 'name', 'low', 'high', 'post',
def __init__(self, name: str, low: int, high: int, post: bool):
self.name = name
self.low = low
self.high = high
self.post = post
self.name: str = name
self.low: int = low
self.high: int = high
self.post: bool = post
def __str__(self):
return "%s %d %d %s" % (
@ -14,3 +17,12 @@ class RemoteNewsgroup():
self.high,
'y' if self.post else 'n'
)
class RemoteMessage():
__slots__ = (
'id', 'subject', 'sender', 'created_on', 'message_id',
'references', 'size', 'lines', 'headers'
)
def __init__(self):
self.headers = dict()