diff options
author | Matěj Cepl <mcepl@cepl.eu> | 2014-12-28 01:31:08 +0100 |
---|---|---|
committer | Matěj Cepl <mcepl@cepl.eu> | 2014-12-28 01:31:08 +0100 |
commit | 7627c1faabce8398845d0687338cc8e052fcd0dc (patch) | |
tree | fcb8bcb09f7a2351cef21b96754ee69e8f115265 | |
parent | 8e8a89e3dc6d6da2e9f230e316f4c3372013bb85 (diff) | |
download | pyg-7627c1faabce8398845d0687338cc8e052fcd0dc.tar.gz |
Switch news2mail to pure email.Message based system.
Fixes #10
Fixes #3
-rw-r--r-- | news2mail.py | 178 | ||||
-rwxr-xr-x | pygn2m | 10 |
2 files changed, 62 insertions, 126 deletions
diff --git a/news2mail.py b/news2mail.py index 71e0d17..49825fb 100644 --- a/news2mail.py +++ b/news2mail.py @@ -24,7 +24,6 @@ normal (what pygs does) operations flow is: """ from collections import OrderedDict import email -import logging import smtplib from socket import gethostbyaddr, gethostname import sys @@ -37,76 +36,32 @@ from mail2news import VERSION, DESC class news2mail(object): """news to mail gateway class""" - wlfile = None - logfile = None + def __init__(self): + self.wlfile = None + self.logfile = None - sender = '' - rcpt = '' - envelope = '' + self.sender = '' + self.rcpt = '' + self.envelope = '' - smtpserver = 'localhost' + self.smtpserver = 'localhost' - hostname = gethostbyaddr(gethostname())[0] + self.hostname = gethostbyaddr(gethostname())[0] - heads_dict, smtpheads, nntpheads = {}, {}, {} - article, headers, body = [], [], [] - message = None + self.heads_dict = {} + self.article, self.headers, self.body = [], [], [] + self.message = None - debug = 1 + self.debug = 1 def readfile(self): self.message = email.message_from_file(sys.stdin) - self.nntpheads = OrderedDict(self.message) - - @staticmethod - def puthead(from_dict, out_list, key): - """private, x-form dict entries in out_list entries""" - if key in from_dict: - out_list.append(key + ' ' + from_dict.get(key)) - else: - return 0 - return 1 - - def sortheads(self): - """make list sorting heads, Received: From: To: Subject: first, - others, X-*, Resent-* last""" - - # put at top - header_set = ('Received', 'From', 'To', 'Subject', 'Date') - - for k in header_set: - self.puthead(self.heads_dict, self.headers, k) - - for k in self.heads_dict.keys(): - if not k.startswith('X-') and not k.startswith('Resent-') \ - and k not in header_set: - self.puthead(self.heads_dict, self.headers, k) - - for k in self.heads_dict.keys(): - if k.startswith('X-'): - self.puthead(self.heads_dict, self.headers, k) - - for k in self.heads_dict.keys(): - if k.startswith('Resent-'): - self.puthead(self.heads_dict, self.headers, k) - - logging.debug('self.headers = %s', self.headers) - return self.headers - - def mergeheads(self): - """make a unique headers dictionary from NNTP and SMTP - single headers dictionaries.""" - - self.heads_dict = OrderedDict(self.nntpheads) - self.heads_dict.update(self.smtpheads) - - return self.heads_dict def addheads(self): """add new header like X-Gateway: Received: """ - self.heads_dict['X-Gateway'] = 'pyg {0} {1}'.format(VERSION, DESC) + self.message['X-Gateway'] = 'pyg {0} {1}'.format(VERSION, DESC) # to make Received: header t = time.ctime(time.time()) @@ -127,9 +82,7 @@ class news2mail(object): '\n\tfor <' + self.rcpt + '> ; ' + \ t + ' (' + tzone + ')\n' - self.heads_dict['Received'] = tmp - - return self.heads_dict + self.message['Received'] = tmp def renameheads(self): """rename headers such as Newsgroups: to X-Newsgroups: @@ -137,19 +90,17 @@ class news2mail(object): 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'] - except KeyError, message: - print message - - return self.heads_dict + if 'Newsgroups' in self.message: + self.message['X-Newsgroups'] = \ + self.message['Newsgroups'] + del self.message['Newsgroups'] + + if 'NNTP-Posting-Host' in self.message: + self.message['X-NNTP-Posting-Host'] = \ + self.message['NNTP-Posting-Host'] + del self.message['NNTP-Posting-Host'] + except KeyError as ex: + print(ex) def removeheads(self): """remove headers like Xref: Path: Lines: @@ -160,63 +111,52 @@ class news2mail(object): # 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 '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 key in self.message: + del self.message[key] + + if 'Message-id' in self.message: + msgid = self.message['Message-id'] + del self.message['Message-id'] + self.message['Message-Id'] = msgid + else: # It should put a real user@domain self.heads_dict['Message-Id'] = 'pyg@puppapera.org' except KeyError, message: print message - return self.heads_dict - - def sendarticle(self): - """Talk to SMTP server and try to send email.""" - try: - raise NotImplementedError( - 'sendarticle does not use email.Message yet') + def sortheads(self): + """make list sorting heads, Received: From: To: Subject: first, + others, X-*, Resent-* last""" - msglist = [] + # put at top + header_set = ('Received', 'From', 'To', 'Subject', 'Date') - s = smtplib.SMTP(self.smtpserver) + heads_dict = OrderedDict(self.message) + for hdr in self.message.keys(): + del self.message[hdr] - # put real locahost domain name. - s.helo(self.hostname) - if s.helo_resp is None and s.ehlo_resp is None: - print 'No helo resp' - sys.exit(1) + for k in header_set: + if k in heads_dict: + self.message[k] = heads_dict[k] - resp = s.mail(self.envelope) - if resp[0] != 250: - print 'SMTP error during MAIL cmd: %s %s' % (resp[0], resp[1]) - print 'envelope %s gave problem?' % self.envelope - sys.exit(1) - resp = s.rcpt(self.rcpt) - if resp[0] != 250: - print 'SMTP error during MAIL cmd: %s %s' % (resp[0], resp[1]) - sys.exit(1) + for k in heads_dict: + if not k.startswith('X-') and not k.startswith('Resent-') \ + and k not in header_set: + self.message[k] = heads_dict[k] - msglist.append(''.join(self.headers)) + for k in heads_dict: + if k.startswith('X-'): + self.message[k] = heads_dict[k] - msglist.append(''.join(self.body)) - msg = ''.join(msglist) + for k in heads_dict: + if k.startswith('Resent-'): + self.message[k] = heads_dict[k] - s.data(msg) - s.quit() + def sendarticle(self): + """Talk to SMTP server and try to send email.""" + s = smtplib.SMTP(self.smtpserver) - return 1 + s.sendmail(self.envelope, self.rcpt, self.message.as_string()) - except (smtplib.SMTPException), messaggio: - print messaggio - sys.exit(1) + s.quit() @@ -100,17 +100,16 @@ try: # reads stdin and parses article separating head from body n2m.readfile() -# n2m.parsearticle() """phase 2: check whitelist for user's permission """ # make a first check of From: address - owner = wl.checkfrom(n2m.nntpheads['From']) + owner = wl.checkfrom(n2m.message['From']) if owner is None: if sys.stdin.isatty() == 1 or args.test: - print ('"%s" is not in whitelist!' % (n2m.nntpheads['From'][:-1])) + print ('"%s" is not in whitelist!' % (n2m.message['From'][:-1])) else: wl.logmsg(n2m.nntpheads, wl.DENY) @@ -123,8 +122,6 @@ try: format rfc 822 headers from input article """ - n2m.mergeheads() # make unique dict from NNTP and SMTP dicts - n2m.addheads() # add some important heads n2m.renameheads() # rename useless heads n2m.removeheads() # remove other heads @@ -133,8 +130,7 @@ try: # prints formatted email message only (without send) if user wants if args.verbose: - for line in n2m.headers: - print(line) + print(n2m.message.as_string()) if owner is None: sys.exit(1) |