summaryrefslogtreecommitdiff
path: root/Mailman/GatewayManager.py
diff options
context:
space:
mode:
Diffstat (limited to 'Mailman/GatewayManager.py')
-rw-r--r--Mailman/GatewayManager.py168
1 files changed, 8 insertions, 160 deletions
diff --git a/Mailman/GatewayManager.py b/Mailman/GatewayManager.py
index 7952f9833..931a67dec 100644
--- a/Mailman/GatewayManager.py
+++ b/Mailman/GatewayManager.py
@@ -14,19 +14,17 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-'''Mixin class for gatewaying mail to news, and news to mail.'''
+"""Mixin class for configuring Usenet gateway.
-# All these things should already be imported, so might as well do them here
-# at the top level
-import os
-import string
-import re
-import time
-import mm_cfg
+All the actual functionality is in Handlers/ToUsenet.py for the mail->news
+gateway and cron/gate_news for the news->mail gateway.
-# XXX: Bogus, but might as we do it `legally'
-QuickEscape = 'QuickEscape'
+"""
+from Mailman import mm_cfg
+
+
+
class GatewayManager:
def InitVars(self):
# Configurable
@@ -54,153 +52,3 @@ class GatewayManager:
'Should newsgroup posts not sent from the list be resent '
'to the list?')
]
-
- # This function is called from cron/gate_news and assumes the following
- # have been asserted:
- # - that the list gates from news to mail
- # - that list has an nntp_host and linked_newsgroup
- # - that the connection has been opened
- # - that this method is run in a child process
- # - that the watermark is non-zero
- def PollNewsGroup(self, conn, wm, first, last):
- import nntplib
- # NEWNEWS is not portable and has synchronization issues... Use a
- # watermark system instead.
- for num in range(max(wm+1, first), last+1):
- try:
- headers = conn.head(`num`)[3]
- found_to = 0
- for header in headers:
- i = string.find(header, ':')
- if i > 0 and string.lower(header[:i]) == 'to':
- found_to = 1
- if header[:i] <> 'X-BeenThere':
- continue
- if header[i:] == ': %s' % self.GetListEmail():
- raise QuickEscape
- body = conn.body(`num`)[3]
- # Create the pipe to the Mail posting script. Note that it is
- # not installed executable, so we'll tack on the path to
- # Python we discovered when we configured Mailman. The extra
- # argument to `post' informs the system that the message is
- # originating from Usenet and so should not get posted back to
- # Usenet. I think this is mostly redundent with the
- # X-BeenThere header, but I'm a little afraid to muck with
- # that.
- cmd = '%s %s %s fromusenet' % (
- mm_cfg.PYTHON,
- os.path.join(mm_cfg.SCRIPTS_DIR, 'post'),
- self._internal_name)
- file = os.popen(cmd, 'w')
- # Usenet originated messages will not have a Unix envelope
- # (i.e. "From " header). This breaks Pipermail archiving, so
- # we will synthesize one. Be sure to use the format searched
- # for by mailbox.UnixMailbox._isrealfromline()
- timehdr = time.asctime(time.localtime(time.time()))
- envhdr = 'From ' + self.GetAdminEmail() + ' ' + timehdr
- file.write(envhdr + '\n')
- file.write(string.join(headers,'\n'))
- # If there wasn't already a TO: header, add one.
- if not found_to:
- file.write("\nTo: %s" % self.GetListEmail())
- file.write('\n\n')
- file.write(string.join(body,'\n'))
- file.write('\n')
- file.close()
- except nntplib.error_temp:
- pass # Probably canceled, etc...
- except QuickEscape:
- pass # We gated this TO news, don't repost it!
-
- def SendMailToNewsGroup(self, mail_msg):
- import Message
- error = []
- if not self.linked_newsgroup:
- error.append('no newsgroup')
- if not self.nntp_host:
- error.append('no NNTP host')
- if error:
- msg = 'NNTP gateway improperly configured: ' + \
- string.join(error, ', ')
- self.LogMsg('error', msg)
- return
- if hasattr(mail_msg, 'fromusenet') and mail_msg.fromusenet:
- # This message originated on Usenet; don't re-post it.
- return
- # Fork in case the nntp connection hangs.
- if not os.fork():
- # child
- import nntplib
- # Now make the news message...
- msg = Message.NewsMessage(mail_msg)
- # Ok, munge headers, etc.
- subj = msg.getheader('subject')
- if subj:
- subjpref = self.subject_prefix
- if not re.match('(re:? *)?' + re.escape(subjpref), subj, re.I):
- msg.SetHeader('Subject', '%s%s' % (subjpref, subj))
- else:
- msg.SetHeader('Subject', '%s(no subject)' % subjpref)
- if self.reply_goes_to_list:
- del msg['reply-to']
- msg.headers.append('Reply-To: %s\n' % self.GetListEmail())
- # if we already have a sender header, don't add another one; use
- # the header that's already there.
- if not msg.getheader('sender'):
- msg.headers.append('Sender: %s\n' % self.GetAdminEmail())
- msg.headers.append('Errors-To: %s\n' % self.GetAdminEmail())
- msg.headers.append('X-BeenThere: %s\n' % self.GetListEmail())
- ngheader = msg.getheader('newsgroups')
- if ngheader is not None:
- # see if the Newsgroups: header already contains our
- # linked_newsgroup. If so, don't add it again. If not,
- # append our linked_newsgroup to the end of the header list
- ngroups = map(string.strip, string.split(ngheader, ','))
- if self.linked_newsgroup not in ngroups:
- ngroups.append(self.linked_newsgroup)
- ngheader = string.join(ngroups, ',')
- # subtitute our new header for the old one. XXX Message
- # class should have a __setitem__()
- del msg['newsgroups']
- msg.headers.append('Newsgroups: %s\n' % ngroups)
- else:
- # Newsgroups: isn't in the message
- msg.headers.append('Newsgroups: %s\n' % self.linked_newsgroup)
- # Note: Need to be sure 2 messages aren't ever sent to the same
- # list in the same process, since message ID's need to be unique.
- # Could make the ID be mm.listname.postnum instead if that happens
- if msg.getheader('Message-ID') is None:
- msg.headers.append('Message-ID: <mm.%s.%s@%s>\n' %
- (time.time(), os.getpid(), self.host_name))
- if msg.getheader('Lines') is None:
- msg.headers.append('Lines: %s\n' %
- len(string.split(msg.body,"\n")))
- del msg['received']
-
- # TBD: Gross hack to ensure that we have only one
- # content-transfer-encoding header. More than one barfs NNTP. I
- # don't know why we sometimes have more than one such header, and
- # it probably isn't correct to take the value of just the first
- # one. What if there are conflicting headers???
- #
- # This relies on the new interface for getaddrlist() returning
- # values for all present headers, and the fact that the legal
- # values are usually not parseable as addresses. Yes this is
- # another bogosity.
- cteheaders = msg.getaddrlist('content-transfer-encoding')
- if cteheaders:
- ctetuple = cteheaders[0]
- ctevalue = ctetuple[1]
- del msg['content-transfer-encoding']
- msg['content-transfer-encoding'] = ctevalue
-
- # NNTP is strict about spaces after the colon in headers.
- for n in range(len(msg.headers)):
- line = msg.headers[n]
- i = string.find(line,":")
- if i <> -1 and line[i+1] <> ' ':
- msg.headers[n] = line[:i+1] + ' ' + line[i+1:]
- con = nntplib.NNTP(self.nntp_host)
- con.post(msg)
- con.quit()
- os._exit(0)