[Mailman-Developers] post messages from the web
Steven Hazel
cherub@azrael.dyn.cheapnet.net
Wed, 25 Aug 1999 03:07:29 -0500 (CDT)
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)
============================================================