Well, my previous mailing inquiring about how to best submit code got no reponse, so I'm submitting as I see fit: namely, via attached files and generous context diffs. Attached are mailman/Mailman/Cgi/postmsg.py, a basic web interface for posting messages, and Message.diff, a 30-line context diff of some minor changes to IncomingMessage which allow postmsg.py to work properly. This is still all very early code, so your beautifcations and suggestions are appriciated. Patches to make the postmsg script accessable via a replacement tag are pending. User accounts are in progress, but further off.
-S
===File ~/projects/mailman/Mailman/Cgi/postmsg.py=========== #! /usr/bin/env python # # Copyright (C) 1999 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Allows user to log in, setting authentication cookies """
# No lock needed in this script, because we don't change data.
from Mailman import auth import Cookie import sys import os, string, cgi from regsub import gsub from Mailman import Utils, MailList, Message, Errors from Mailman import mm_cfg from Mailman.htmlformat import *
def main(): global user try: path = os.environ['PATH_INFO'] except KeyError: path = ""
list_info = Utils.GetPathPieces(path)
list_name = string.lower(list_info[0])
try:
list = MailList.MailList(list_name, lock=0)
except:
list = None
if not (list and list._ready):
FormatPostmsgStatus(error="List <em>%s</em> not found." % list_name)
return
if len(list_info) == 0:
FormatPostmsgStatus()
return
global cgi_data
cgi_data = cgi.FieldStorage()
message = None
if cgi_data.has_key('message'):
imsg = Message.IncomingMessage('');
fromaddr = cgi_data['from'].value
is_auth = 0
try:
# admin uses cookies with -admin name suffix
is_auth = list.WebAuthenticate(user=fromaddr,
password=
cgi_data['password'].value)
except Errors.MMNotAMemberError:
errormsg = 'Incorrect user name or password.'
except Errors.MMBadPasswordError:
errormsg = 'Incorrect user name or password.'
except Errors.MMExpiredCookieError:
errormsg = 'Your cookie has gone stale, ' \
'enter password to get a new one.',
except Errors.MMInvalidCookieError:
errormsg = 'Error decoding authorization cookie.'
except Errors.MMAuthenticationError:
errormsg = 'Authentication error.'
if (is_auth):
imsg.SetHeader('from', fromaddr)
else:
FormatPostmsgStatus(errormsg)
return
imsg.SetHeader('subject', cgi_data['subject'].value)
imsg.SetHeader('to', list.GetListEmail())
message = cgi_data['message'].value
if message[len(message)-1]!='\n':
message = "%s\n" % message
imsg.SetBody(message)
list.Post(imsg)
FormatPostmsgStatus('Message Posted')
else:
doc = Document()
doc.SetTitle('Post Message')
doc.AddItem('Fill out the form below to post a message to the ')
doc.AddItem(list_name)
doc.AddItem(' mailing list.<br><br>')
form = Form(list.GetRelativeScriptURL('postmsg'))
doc.AddItem(form)
form.AddItem('Email Address: ')
form.AddItem(TextBox(name='from', size=30))
form.AddItem('<br>Password: ')
form.AddItem(PasswordBox(name='password'))
form.AddItem('<br>')
form.AddItem('<br><br>Subject: ')
form.AddItem(TextBox(name='subject', size=30))
form.AddItem('<br><br>Post<br>')
form.AddItem(TextArea(name='message', rows=24, cols=80, wrap='soft'))
form.AddItem('<br>')
form.AddItem(SubmitButton('Post','Post Message'))
print doc.Format()
def FormatPostmsgStatus(error=None): "Simple message posting overview"
# XXX We need a portable way to determine the host by which we are being
# visited! An absolute URL would do...
http_host = os.environ.get('HTTP_HOST') or\
os.environ.get('SERVER_NAME')
port = os.environ.get('SERVER_PORT')
# strip off the port if there is one
if port and http_host[-len(port)-1:] == ':'+port:
http_host = http_host[:-len(port)-1]
if mm_cfg.VIRTUAL_HOST_OVERVIEW and http_host:
host_name = http_host
else:
host_name = mm_cfg.DEFAULT_HOST_NAME
doc = Document()
doc.SetTitle(error)
table = Table(border=0, width="100%")
table.AddRow([Center(Header(2, error))])
table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0,
colspan=2, bgcolor="#99ccff")
advertised = []
names = Utils.list_names()
names.sort()
for n in names:
l = MailList.MailList(n, lock = 0)
if l.advertised:
if (mm_cfg.VIRTUAL_HOST_OVERVIEW
and http_host
and (string.find(http_host, l.web_page_url) == -1
and string.find(l.web_page_url, http_host) == -1)):
# List is for different identity of this host - skip it.
continue
else:
advertised.append(l)
doc.AddItem(table)
doc.AddItem('<hr>')
doc.AddItem(MailmanLogo())
print doc.Format(bgcolor="#ffffff")
if __name__ == "__main__": main()
===File ~/Message.diff====================================== Index: Message.py
RCS file: /home/cherub/cvs/mailman/Mailman/Message.py,v retrieving revision 1.1 retrieving revision 1.4 diff -c -3 -0 -r1.1 -r1.4 *** Message.py 1999/07/28 20:42:33 1.1 --- Message.py 1999/08/25 07:58:32 1.4
*** 76,135 **** --- 76,141 ----
# We know the message is gonna come in on stdin or from text for our purposes. class IncomingMessage(rfc822.Message): def __init__(self, text=None): if not text: rfc822.Message.__init__(self, sys.stdin, 0) self.body = self.fp.read() else: rfc822.Message.__init__(self, FakeFile(text), 0) self.body = self.fp.read() self.file_count = None
def readlines(self):
if self.file_count <> None:
x = self.file_count
self.file_count = len(self.file_data)
return self.file_data[x:]
return map(RemoveNewline, self.headers) + [''] + \
string.split(self.body,'\n')
def readline(self):
if self.file_count == None:
self.file_count = 0
self.file_data = map(RemoveNewline, self.headers) + [''] + \
string.split(self.body,'\n')
if self.file_count >= len(self.file_data):
return ''
self.file_count = self.file_count + 1
return self.file_data[self.file_count-1] + '\n'
def SetBody(self, body):
self.body = body
def AppendToBody(self, text):
self.body = self.body + text
def GetSender(self):
# Look for a Sender field. sender = self.getheader('sender') if sender: realname, mail_address = self.getaddr('sender') else: try: realname, mail_address = self.getaddr('from') except: real_name = mail_address = None
# We can't trust that any of the headers really contained an address if mail_address and type(mail_address) == type(""): return string.lower(mail_address) else: # The unix from line is all we have left... if self.unixfrom: return string.lower(string.split(self.unixfrom)[1]) def GetEnvelopeSender(self): # # look for unix from line and attain address # from it, return None if there is no unix from line # this function is used to get the envelope sender # when mail is sent to a <listname>-admin address # if not self.unixfrom: return None # XXX assumes no whitespace in address parts = string.split(self.unixfrom)
============================================================
participants (1)
-
Steven Hazel