From 5b25c51d3a02d49db2c7e33f9b65fad5432219f4 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Mon, 22 Dec 2014 00:26:30 +0100 Subject: pygn2m and news2mail.py use stdlib email parser. Instead of doing it on their own (poorly). --- news2mail.py | 139 ++++++++++++++++++----------------------------------------- 1 file changed, 43 insertions(+), 96 deletions(-) (limited to 'news2mail.py') diff --git a/news2mail.py b/news2mail.py index bfd6fd1..4dd83fc 100644 --- a/news2mail.py +++ b/news2mail.py @@ -9,7 +9,6 @@ and you think this stuff is worth it, you can buy me a beer in return. Thanks to md for this useful formula. Beer is beer. - Gets news article and sends it via SMTP. class news2mail is hopefully conform to rfc822. @@ -23,18 +22,17 @@ normal (what pygs does) operations flow is: Date:, normal headers ending with X-* and Resent-* headers. """ +import email import sys import smtplib import time from socket import gethostbyaddr, gethostname -import tempfile import pyginfo -class news2mail: +class news2mail(object): """news to mail gateway class""" - TMPFILE = tempfile.mktemp() wlfile = None logfile = None @@ -48,62 +46,21 @@ class news2mail: heads_dict, smtpheads, nntpheads = {}, {}, {} article, headers, body = [], [], [] + message = None debug = 1 def readfile(self): + self.message = email.message_from_file(sys.stdin) + self.nntpheads = dict(((key, value) + for (key, value) in self.message.items())) - for line in sys.stdin.readlines(): - self.article.append(line) - - if (len(self.article) == 1 and self.article[0][0] == '/'): - file = self.article[0][:-1] - del self.article[0] - for line in open(file, 'r').readlines(): - self.article.append(line) - - def parsearticle(self): - """get news article from file or stdin and separate heads from body - - REMEBER: headers value has '\n' as last char. - Use string[:-1] to ignore newline. - """ - - try: - body = 0 # are we in body or in headers? - -# voidline = compile('^$') # I need '\n', ^$ matches anything -# spaceending = compile('\s*\n$') - - for line in self.article: - if not body and len(line) == 1: - body = 1 # starts article body section - - if not body: - try: - head, value = line.split(' ', 1) - self.nntpheads[head] = value - except (ValueError), message: - print('string error: %s' % message) - print('(probably missing couple "Header: value" in %s)' - % line) - sys.exit(1) - - elif len(line) > 0 and body: - self.body.append(line) - - return self.nntpheads, self.body + @staticmethod + def puthead(from_dict, out_list, key): + """private, x-form dict entries in out_list entries""" -# except (re.error, ValueError), message: - except (ValueError), message: - print message - sys.exit(1) - - def puthead(self, dict, list, key): - """private, x-form dict entries in list entries""" - - if key in dict: - list.append(key + ' ' + dict.get(key)) + if key in from_dict: + out_list.append(key + ' ' + from_dict.get(key)) else: return 0 return 1 @@ -112,13 +69,14 @@ class news2mail: """make list sorting heads, Received: From: To: Subject: first, others, X-*, Resent-* last""" - set = ('Received:', 'From:', 'To:', 'Subject:', 'Date:') # put at top + # put at top + header_set = ('Received', 'From', 'To', 'Subject', 'Date') - for k in set: + for k in header_set: self.puthead(self.heads_dict, self.headers, k) for k in self.heads_dict.keys(): - if k[:2] != 'X-' and k[:7] != 'Resent-' and k not in set: + if k[:2] != 'X-' and k[:7] != 'Resent-' and k not in header_set: self.puthead(self.heads_dict, self.headers, k) for k in self.heads_dict.keys(): @@ -157,10 +115,10 @@ class news2mail: info = pyginfo.pygsinfo() try: - self.heads_dict['X-Gateway:'] = info.PROGNAME + ' ' + \ + self.heads_dict['X-Gateway'] = info.PROGNAME + ' ' + \ info.__doc__ + '\n' - ##self.heads_dict['X-Gateway:'] = '%s %s\n' % + ##self.heads_dict['X-Gateway'] = '%s %s\n' % ## (info.PROGNAME, info.__doc__) # to make Received: header @@ -182,7 +140,7 @@ class news2mail: '\n\tfor <' + self.rcpt + '> ; ' + \ t + ' (' + tzone + ')\n' - self.heads_dict['Received:'] = tmp + self.heads_dict['Received'] = tmp except KeyError, message: print message @@ -194,15 +152,15 @@ class news2mail: headers renamed are useless or not rfc 822 copliant """ try: - if 'Newsgroups:' in self.heads_dict: - self.heads_dict['X-Newsgroups:'] = \ - self.heads_dict['Newsgroups:'] - del self.heads_dict['Newsgroups:'] - - if 'NNTP-Posting-Host:' in self.heads_dict: - self.heads_dict['X-NNTP-Posting-Host:'] = \ - self.heads_dict['NNTP-Posting-Host:'] - del self.heads_dict['NNTP-Posting-Host:'] + if 'Newsgroups' in self.heads_dict: + self.heads_dict['X-Newsgroups'] = \ + self.heads_dict['Newsgroups'] + del self.heads_dict['Newsgroups'] + + if 'NNTP-Posting-Host' in self.heads_dict: + self.heads_dict['X-NNTP-Posting-Host'] = \ + self.heads_dict['NNTP-Posting-Host'] + del self.heads_dict['NNTP-Posting-Host'] except KeyError, message: print message @@ -214,38 +172,24 @@ class news2mail: try: # removing some others useless headers .... + # that includes BOTH 'From ' and 'From' + # 'Sender is usually set by INN, if ng is moderated... + for key in ('Approved', 'From', 'Xref', 'Path', 'Lines', 'Sender'): + if key in self.heads_dict: + del self.heads_dict[key] - if 'Approved:' in self.heads_dict: - del self.heads_dict['Approved:'] - - if 'From' in self.heads_dict: # neither 'From ' nor 'From:' - del self.heads_dict['From'] - - if 'Xref:' in self.heads_dict: - del self.heads_dict['Xref:'] + if 'Message-id' in self.heads_dict: + self.heads_dict['Message-Id'] = self.heads_dict['Message-id'] + del self.heads_dict['Message-id'] - if 'Path:' in self.heads_dict: - del self.heads_dict['Path:'] - - if 'Lines:' in self.heads_dict: - del self.heads_dict['Lines:'] - - # it is usually set by INN, if ng is moderated... - if 'Sender:' in self.heads_dict: - del self.heads_dict['Sender:'] - - if 'Message-id:' in self.heads_dict: - self.heads_dict['Message-Id:'] = self.heads_dict['Message-id'] - del(self.heads_dict['Message-id']) - - if 'Message-ID:' in self.heads_dict: - self.heads_dict['Message-Id:'] = self.heads_dict['Message-ID'] - del(self.heads_dict['Message-ID']) + if 'Message-ID' in self.heads_dict: + self.heads_dict['Message-Id'] = self.heads_dict['Message-ID'] + del self.heads_dict['Message-ID'] # If message-id is not present, I generate it - if 'Message-Id:' not in self.heads_dict: + if 'Message-Id' not in self.heads_dict: # It should put a real user@domain - msgid = 'pyg@puppapera.org' # FIXME unused variable + self.heads_dict['Message-Id'] = 'pyg@puppapera.org' except KeyError, message: print message @@ -255,6 +199,9 @@ class news2mail: def sendarticle(self): """Talk to SMTP server and try to send email.""" try: + raise NotImplementedError( + 'sendarticle does not use email.Message yet') + msglist = [] s = smtplib.SMTP(self.smtpserver) -- cgit