diff options
Diffstat (limited to 'mail2news.py')
-rw-r--r-- | mail2news.py | 178 |
1 files changed, 92 insertions, 86 deletions
diff --git a/mail2news.py b/mail2news.py index d340432..3011a4e 100644 --- a/mail2news.py +++ b/mail2news.py @@ -3,7 +3,7 @@ Author: Cosimo Alfarano Date: September 16 2000 -mail2news.py - Copyright 2000 by Cosimo Alfarano <Alfarano@Students.CS.UniBo.It> +mail2news.py - (C) 2000 by Cosimo Alfarano <Alfarano@Students.CS.UniBo.It> You can use this software under the terms of the GPL. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return. @@ -16,19 +16,17 @@ class mail2news is hopefully conform to rfc850. """ import sys -from os import unlink, getpid +from os import getpid from socket import gethostbyaddr, gethostname import string from re import findall -import time import nntplib import pyginfo -import tempfile + class mail2news: """news to mail gateway class""" - reader = None # mode reader # newsgroups = None # Newsgroups: local.test,local.moderated... # approved = None # Approved: kame@aragorn.lorien.org @@ -42,20 +40,25 @@ class mail2news: heads_dict, smtpheads, nntpheads = {}, {}, {} email, headers, body = [], [], [] - - def readfile(self): + def readfile(self, opt): for line in sys.stdin.readlines(): self.email.append(line) - + if(len(self.email) == 1 and self.email[0][0] == '/'): file = self.email[0][:-1] del self.email[0] - for line in open(file,'r').readlines(): + for line in open(file, 'r').readlines(): self.email.append(line) - - return 1 + # introduce nntpheads + if opt.newsgroup != '': + # TODO put it directly to self.message when we have it + self.nntpheads['Newsgroups:'] = opt.newsgroup + '\n' + if opt.approver != '': + self.nntpheads['Approved:'] = opt.approver + '\n' + + return 1 def parseemail(self): """get news email from file or stdin and separate heads from body @@ -66,7 +69,7 @@ class mail2news: try: body = 0 # are we in body or in headers? - + for line in self.email: if not body and len(line) == 1: body = 1 # starts email body section @@ -74,7 +77,7 @@ class mail2news: if not body: try: # if it is a multi-line header like Received: - if not line[0] in [' ','\t']: + if line[0] not in [' ', '\t']: try: head, value = string.split(line, ' ', 1) except string.index_error: @@ -84,17 +87,18 @@ class mail2news: self.smtpheads[head] = '%s%s' % \ (self.smtpheads[head], line) except (string.index_error), message: - print 'line: %s' % line - print '(probably missing couple "Header: value" in %s)' % line + print('line: %s' % line) + print('(probably missing couple "Header: value" in %s)' + % line) sys.exit(1) - + elif len(line) > 0 and body: self.body.append(line) - + except (string.index_error), message: print message sys.exit(1) - + return self.smtpheads, self.body def puthead(self, dict, list, key): @@ -102,7 +106,7 @@ class mail2news: Appends key of dict to list, deleting it from dict. """ - if dict.has_key(key): + if key in dict: list.append(key + ' ' + dict.get(key)) del dict[key] else: @@ -110,39 +114,42 @@ class mail2news: return 1 def sortheads(self): - """make list sorted by heads: From: To: Subject: first, others, X-*, X-Resent-* last""" + """make list sorted by heads: From: To: Subject: first, + others, X-*, X-Resent-* last""" - set = ('Newsgroups:','From:','To:','X-To:','Cc:','Subject:','Date:','Approved:','References:','Message-Id:') # put at top + # put at top + set = ('Newsgroups:', 'From:', 'To:', 'X-To:', 'Cc:', 'Subject:', + 'Date:', 'Approved:', 'References:', 'Message-Id:') for k in set: - self.puthead(self.heads_dict,self.headers,k) + self.puthead(self.heads_dict, self.headers, k) for k in self.heads_dict.keys(): if k[:2] != 'X-' and k[:9] != 'X-Resent-' and k not in set: - self.puthead(self.heads_dict,self.headers,k) + self.puthead(self.heads_dict, self.headers, k) for k in self.heads_dict.keys(): if k[:2] == 'X-': - self.puthead(self.heads_dict,self.headers,k) - + self.puthead(self.heads_dict, self.headers, k) + for k in self.heads_dict.keys(): if k[:9] == 'X-Resent-': - self.puthead(self.heads_dict,self.headers,k) - + self.puthead(self.heads_dict, self.headers, k) + return self.headers - - + def mergeheads(self): - """make a unique headers dictionary from NNTP and SMTP + """make a unique headers dictionary from NNTP and SMTP single headers dictionaries.""" - + self.heads_dict = {} try: - for header in self.smtpheads.keys(): # fill it w/ smtp old heads + for header in self.smtpheads.keys(): # fill it w/ smtp old heads self.heads_dict[header] = self.smtpheads[header] - - for header in self.nntpheads.keys(): # and replace them w/ nntp new heads + + # and replace them w/ nntp new heads + for header in self.nntpheads.keys(): self.heads_dict[header] = self.nntpheads[header] except KeyError, message: @@ -151,7 +158,7 @@ class mail2news: return self.heads_dict def addheads(self): - """add new header like X-Gateway: + """add new header like X-Gateway: """ info = pyginfo.pygsinfo() @@ -163,10 +170,10 @@ class mail2news: # it is nntpheads stuff # if(self.newsgroups): # self.heads_dict['Newsgroups:'] = self.newsgroups - + # if(self.approved): # self.heads_dict['Approved:'] = self.approved - + except KeyError, message: print message @@ -180,45 +187,46 @@ class mail2news: """ try: -### test -# if(post): -# if(self.heads_dict.has_key(post)): -# self.heads_dict['X-Original-' + post] = self.heads_dict[post] +### test +# if(post): +# if(post in self.heads_dict): +# self.heads_dict['X-Original-' + post] = self.heads_dict[post] # -# self.heads_dict[post] = self.heads_dict[pre] -# del(self.heads_dict[pre]) -# -# else: -# if(pre[0:2] == 'X-' and self.heads_dict.has_key(pre)): -# self.heads_dict['X-Original-' + pre] = self.heads_dict[pre] -# elif(not pre[0:2] == 'X-' and self.heads_dict.has_key('X-' + pre)): -# self.heads_dict['X-' + pre] = self.heads_dict[pre] -# del(self.heads_dict[pre]) +# self.heads_dict[post] = self.heads_dict[pre] +# del(self.heads_dict[pre]) +# +# else: +# if(pre[0:2] == 'X-' and pre in self.heads_dict): +# self.heads_dict['X-Original-' + pre] = self.heads_dict[pre] +# elif(not pre[0:2] == 'X-' and 'X-' + pre in self.heads_dict): +# self.heads_dict['X-' + pre] = self.heads_dict[pre] +# del(self.heads_dict[pre]) ### end test for key in self.heads_dict.keys(): if(key[:7] in ['Resent-']): - if(self.heads_dict.has_key('X-' + key)): - self.heads_dict[ 'X-Original-' + key ] = self.heads_dict['X-' + key] - self.heads_dict[ 'X-' + key ] = self.heads_dict[key] + if ('X-' + key) in self.heads_dict: + self.heads_dict['X-Original-' + key] = \ + self.heads_dict['X-' + key] + self.heads_dict['X-' + key] = self.heads_dict[key] del self.heads_dict[key] - # In rfc822 References: is considered, but many MUA doen't put it. - if(not self.heads_dict.has_key('References:') and self.heads_dict.has_key('In-Reply-To:')): + if ('References:' not in self.heads_dict) and \ + ('In-Reply-To:' in self.heads_dict): print self.heads_dict['In-Reply-To:'] # some MUA uses msgid without '<' '>' # ref = findall('([^\s<>\']+@[^\s<>;:\']+)', \ # but I prefer use RFC standards - ref = findall('(<[^<>]+@[^<>]+>)', \ - self.heads_dict['In-Reply-To:']) + ref = findall('(<[^<>]+@[^<>]+>)', + self.heads_dict['In-Reply-To:']) # if found, keep first element that seems a Msg-ID. if(ref and len(ref)): - self.heads_dict['References:'] = '%s\n' % ref[0] - -# if(self.heads_dict.has_key('To:')): + self.heads_dict['References:'] = '%s\n' % ref[0] + +# if('To:' in self.heads_dict): # self.heads_dict['X-To:'] = self.heads_dict['To:'] # del self.heads_dict['To:'] @@ -227,48 +235,46 @@ class mail2news: return self.heads_dict - - def removeheads(self, heads = None): + def removeheads(self, heads=None): """remove headers like Xref: Path: Lines: """ try: # removing some others useless headers .... (From is not From:) - rmheads = ['Received:', 'From', 'NNTP-Posting-Host:', \ - 'X-Trace:', 'X-Compliants-To:', 'NNTP-Posting-Date:'] + rmheads = ['Received:', 'From', 'NNTP-Posting-Host:', + 'X-Trace:', 'X-Compliants-To:', 'NNTP-Posting-Date:'] if(heads): rmheads.append(heads) - + for head in rmheads: - if self.heads_dict.has_key(head): + if head in self.heads_dict: del self.heads_dict[head] - -# if self.heads_dict.has_key('From'): # neither 'From ' nor 'From:' + +# if 'From' in self.heads_dict: # neither 'From ' nor 'From:' # del self.heads_dict['From'] -# if self.heads_dict.has_key('NNTP-Posting-Host:'): # neither 'From ' nor 'From:' +# # neither 'From ' nor 'From:' +# if 'NNTP-Posting-Host:' in self.heads_dict: # del self.heads_dict[''] - -# if self.heads_dict.has_key('Lines:'): +# if 'Lines:' in self.heads_dict: # del self.heads_dict['Lines:'] # it is usually set by INN, if ng is moderated... -# if self.heads_dict.has_key('Sender:'): +# if 'Sender:' in self.heads_dict: # del self.heads_dict['Sender:'] - - if self.heads_dict.has_key('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 self.heads_dict.has_key('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 not self.heads_dict.has_key('Message-Id:'): + if 'Message-Id:' not in self.heads_dict: msgid = '<pyg.%d@tuchailepuppapera.org>\n' % (getpid()) self.heads_dict['Message-Id:'] = msgid @@ -280,19 +286,18 @@ class mail2news: def sendemail(self): """Talk to NNTP server and try to send email.""" try: - msglist = [] - - n = nntplib.NNTP(self.newsserver, self.port, self.user, self.password) + n = nntplib.NNTP(self.newsserver, self.port, self.user, + self.password) if(self.reader): n.putline('mode reader') resp = n.getline() print resp - + resp = n.shortcmd('POST') - # sett RFC977 2.4.2 - if resp[0] <> '3': + # sett RFC977 2.4.2 + if resp[0] != '3': raise n.error_reply, str(resp) for line in self.headers: @@ -316,5 +321,6 @@ class mail2news: n.putline('.') n.quit() return None - except (nntplib.error_reply, nntplib.error_temp, nntplib.error_perm, nntplib.error_proto, nntplib.error_data), message: - return 'NNTP: ' + str(message) + except (nntplib.error_reply, nntplib.error_temp, nntplib.error_perm, + nntplib.error_proto, nntplib.error_data), message: + return 'NNTP: ' + str(message) |