Revision: 8064
          http://svn.sourceforge.net/mailman/?rev=8064&view=rev
Author:   bwarsaw
Date:     2006-10-15 15:04:16 -0700 (Sun, 15 Oct 2006)

Log Message:
-----------
More work on the WSGI support.  So far, I've tested most of the admin.py links
and some of the admindb.py links.  There may still be breakage in other parts
of the interface and I haven't gone back to verify that traditional CGI still
works.

Changes:

- Add wsgiref-0.1.2-py2.4.egg so that we can still do WSGI in Python 2.4,
  which doesn't come with wsgiref.  Of course this means we /also/ have to add
  setuptools-0.5c3 because eggs require setuptools.

- Style cleanups in HTTPRunner.py and wsgi_app.py.  Also, use cStringIO
  instead of StringIO.

- All internal links within the listinfo and admin pages are (or at least
  should be ;) relative now.  This should make other things better, such as
  running Mailman over https or alternative ports.  It does kind of mean that
  web_page_url is obsolete, but I haven't looked at whether we can completely
  eradicate it.

- ValidateEmail(): Use ' ' in s instead of s.count(' ') > 0.

- GetPathPieces(): When path is false, return the empty list instead of None,
  so we can still len() it.

- ScriptURL(): Much simpler.  To support relative urls as the default, we
  change the API so that it only takes a 'target' argument (i.e. the script we
  want to link to).  It no longer takes 'absolute' or 'web_page_url', and it
  constructs its link from GetPathPieces(), the target, and the cgi extension.

- GetRequestURI(): code style updates.

- Mailman/bin/show_config.py: De-DOS-line-ending-ification.

- export.py: A few modifications, although this is likely still not final (I'm
  still working on the import script).  First, for <option> elements, don't
  put the value in an attribute, put it in the text body of the element.
  Second, put the list <option> tags in a <configuration> element.  Third, put
  the preferred language on an <option> tag with a 'preferred_language'
  name attribute value.

- SecurityManager: Make sure that MakeCookie() and ZapCookie() use the same
  'path' cookie value by refactoring that into a separate method.  That method
   now returns just the SCRIPT_NAME and the full listname.  web_page_url
   doesn't enter into it.

- loginit.py: Add a 'debug' logger since it's just too useful to have :)

- admin.py: Remove the extra / right before the query string in ?VARHELP
  urls.  That extra / turns out to be problematic with the relative url scheme
  we're using now.

- Auth.py: whitespace normalization and copyright years update.  Also, remove
  a couple of unnecessary imports.  Also, make sure that the actionurl is
  relative.

- create.py: Typo.

- private.py: mm_cfg -> config object

- In MailList.py: GetScriptURL() can be written in terms of Utils.ScriptURL()
  now.

Modified Paths:
--------------
    trunk/mailman/Mailman/Archiver/Archiver.py
    trunk/mailman/Mailman/Cgi/Auth.py
    trunk/mailman/Mailman/Cgi/admin.py
    trunk/mailman/Mailman/Cgi/admindb.py
    trunk/mailman/Mailman/Cgi/create.py
    trunk/mailman/Mailman/Cgi/private.py
    trunk/mailman/Mailman/Cgi/wsgi_app.py
    trunk/mailman/Mailman/Defaults.py.in
    trunk/mailman/Mailman/Gui/Privacy.py
    trunk/mailman/Mailman/HTMLFormatter.py
    trunk/mailman/Mailman/MailList.py
    trunk/mailman/Mailman/Queue/HTTPRunner.py
    trunk/mailman/Mailman/SecurityManager.py
    trunk/mailman/Mailman/Utils.py
    trunk/mailman/Mailman/bin/export.py
    trunk/mailman/Mailman/bin/show_config.py
    trunk/mailman/Mailman/configuration.py
    trunk/mailman/Mailman/loginit.py
    trunk/mailman/bin/Makefile.in
    trunk/mailman/misc/Makefile.in

Added Paths:
-----------
    trunk/mailman/misc/setuptools-0.6c3.tar.gz
    trunk/mailman/misc/wsgiref-0.1.2-py2.4.egg

Property Changed:
----------------
    trunk/mailman/misc/

Modified: trunk/mailman/Mailman/Archiver/Archiver.py
===================================================================
--- trunk/mailman/Mailman/Archiver/Archiver.py  2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/Archiver/Archiver.py  2006-10-15 22:04:16 UTC (rev 
8064)
@@ -117,7 +117,7 @@
                 fp.write(Utils.maketext(
                     'emptyarchive.html',
                     {'listname': self.real_name,
-                     'listinfo': self.GetScriptURL('listinfo', absolute=1),
+                     'listinfo': self.GetScriptURL('listinfo'),
                      }, mlist=self))
             if fp:
                 fp.close()
@@ -135,19 +135,17 @@
                             self.internal_name() + '.mbox')
 
     def GetBaseArchiveURL(self):
-        url = self.GetScriptURL('private', absolute=1) + '/'
         if self.archive_private:
-            return url
+            url = self.GetScriptURL('private')
         else:
-            hostname = re.match('[^:]*://([^/]*)/.*', url).group(1)\
-                       or mm_cfg.DEFAULT_URL_HOST
-            url = mm_cfg.PUBLIC_ARCHIVE_URL % {
+            web_host = config.domains.get(self.host_name, self.host_name)
+            url = config.PUBLIC_ARCHIVE_URL % {
                 'listname': self.internal_name(),
-                'hostname': hostname
+                'hostname': web_host,
                 }
-            if not url.endswith('/'):
-                url += '/'
-            return url
+        if not url.endswith('/'):
+            url += '/'
+        return url
 
     def __archive_file(self, afn):
         """Open (creating, if necessary) the named archive file."""

Modified: trunk/mailman/Mailman/Cgi/Auth.py
===================================================================
--- trunk/mailman/Mailman/Cgi/Auth.py   2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/Mailman/Cgi/Auth.py   2006-10-15 22:04:16 UTC (rev 8064)
@@ -1,26 +1,25 @@
-# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 
USA.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
 
 """Common routines for logging in and logging out of the list administrator
 and list moderator interface.
 """
 
-from Mailman import mm_cfg
 from Mailman import Utils
-from Mailman import Errors
 from Mailman.htmlformat import FontAttr
 from Mailman.i18n import _
 
@@ -34,12 +33,14 @@
 
 
 
-def loginpage(mlist, scriptname, msg='', frontpage=None):
+def loginpage(mlist, scriptname, msg='', frontpage=False):
     url = mlist.GetScriptURL(scriptname)
     if frontpage:
         actionurl = url
     else:
-        actionurl = Utils.GetRequestURI(url)
+        request = Utils.GetRequestURI(url)
+        up = '../' * request.count('/')
+        actionurl = up + request
     if msg:
         msg = FontAttr(msg, color='#ff0000', size='+1').Format()
     if scriptname == 'admindb':

Modified: trunk/mailman/Mailman/Cgi/admin.py
===================================================================
--- trunk/mailman/Mailman/Cgi/admin.py  2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/Mailman/Cgi/admin.py  2006-10-15 22:04:16 UTC (rev 8064)
@@ -99,7 +99,7 @@
     # Is this a log-out request?
     if category == 'logout':
         print mlist.ZapCookie(mm_cfg.AuthListAdmin)
-        Auth.loginpage(mlist, 'admin', frontpage=1)
+        Auth.loginpage(mlist, 'admin', frontpage=True)
         return
 
     # Sanity check
@@ -795,9 +795,9 @@
     # the details page!
     if detailsp:
         if subcat:
-            varhelp = '/?VARHELP=%s/%s/%s' % (category, subcat, varname)
+            varhelp = '?VARHELP=%s/%s/%s' % (category, subcat, varname)
         else:
-            varhelp = '/?VARHELP=%s/%s' % (category, varname)
+            varhelp = '?VARHELP=%s/%s' % (category, varname)
         if descr == elaboration:
             linktext = _('<br>(Edit <b>%(varname)s</b>)')
         else:
@@ -817,7 +817,7 @@
 
 def membership_options(mlist, subcat, cgidata, doc, form):
     # Show the main stuff
-    adminurl = mlist.GetScriptURL('admin', absolute=1)
+    adminurl = mlist.GetScriptURL('admin')
     container = Container()
     header = Table(width="100%")
     # If we're in the list subcategory, show the membership list
@@ -1200,7 +1200,7 @@
 
 
 def password_inputs(mlist):
-    adminurl = mlist.GetScriptURL('admin', absolute=1)
+    adminurl = mlist.GetScriptURL('admin')
     table = Table(cellspacing=3, cellpadding=4)
     table.AddRow([Center(Header(2, _('Change list ownership passwords')))])
     table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2,

Modified: trunk/mailman/Mailman/Cgi/admindb.py
===================================================================
--- trunk/mailman/Mailman/Cgi/admindb.py        2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/Cgi/admindb.py        2006-10-15 22:04:16 UTC (rev 
8064)
@@ -172,7 +172,7 @@
             doc.AddItem(Header(2, title))
             doc.AddItem(_('There are no pending requests.'))
             doc.AddItem(' ')
-            doc.AddItem(Link(mlist.GetScriptURL('admindb', absolute=1),
+            doc.AddItem(Link(mlist.GetScriptURL('admindb'),
                              _('Click here to reload this page.')))
             doc.AddItem(mlist.GetMailmanFooter())
             print doc.Format()

Modified: trunk/mailman/Mailman/Cgi/create.py
===================================================================
--- trunk/mailman/Mailman/Cgi/create.py 2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/Mailman/Cgi/create.py 2006-10-15 22:04:16 UTC (rev 8064)
@@ -154,7 +154,7 @@
     url_host = Utils.get_request_domain()
     email_host = config.get_email_host(url_host)
     if not email_host:
-        safehostname = Utils.websafe(email_host)
+        safehostname = Utils.websafe(url_host)
         request_creation(doc, cgidata,
                          _('Unknown virtual host: $safehostname'))
         return

Modified: trunk/mailman/Mailman/Cgi/private.py
===================================================================
--- trunk/mailman/Mailman/Cgi/private.py        2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/Cgi/private.py        2006-10-15 22:04:16 UTC (rev 
8064)
@@ -23,18 +23,17 @@
 import logging
 import mimetypes
 
-from Mailman import mm_cfg
-from Mailman import Utils
-from Mailman import MailList
 from Mailman import Errors
+from Mailman import MailList
+from Mailman import Utils
 from Mailman import i18n
-from Mailman.htmlformat import *
 from Mailman.configuration import config
+from Mailman.htmlformat import *
 
 # Set up i18n.  Until we know which list is being requested, we use the
 # server's default.
 _ = i18n._
-i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
+i18n.set_language(config.DEFAULT_SERVER_LANGUAGE)
 
 SLASH = '/'
 
@@ -61,7 +60,7 @@
 
 def main():
     doc = Document()
-    doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
+    doc.set_language(config.DEFAULT_SERVER_LANGUAGE)
 
     parts = Utils.GetPathPieces()
     if not parts:
@@ -127,10 +126,10 @@
     realname = mlist.real_name
     message = ''
 
-    if not mlist.WebAuthenticate((mm_cfg.AuthUser,
-                                  mm_cfg.AuthListModerator,
-                                  mm_cfg.AuthListAdmin,
-                                  mm_cfg.AuthSiteAdmin),
+    if not mlist.WebAuthenticate((config.AuthUser,
+                                  config.AuthListModerator,
+                                  config.AuthListAdmin,
+                                  config.AuthSiteAdmin),
                                  password, username):
         if cgidata.has_key('submit'):
             # This is a re-authorization attempt

Modified: trunk/mailman/Mailman/Cgi/wsgi_app.py
===================================================================
--- trunk/mailman/Mailman/Cgi/wsgi_app.py       2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/Cgi/wsgi_app.py       2006-10-15 22:04:16 UTC (rev 
8064)
@@ -1,5 +1,3 @@
-# -*- python -*-
-
 # Copyright (C) 2006 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
@@ -17,30 +15,36 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 # USA.
 
+import os
 import sys
+
+from cStringIO import StringIO
+from email import message_from_string
+
+from Mailman.configuration import config
+
+# XXX Should this be configurable in Defaults.py?
 STEALTH_MODE = False
-# Shoul this be configurable in Defaults.py?
 
+
+
 def websafe(s):
     return s
 
-import os
-import StringIO
-from email import message_from_string
-from Mailman.configuration import config
 
 SCRIPTS = ['admin', 'admindb', 'confirm', 'create',
            'edithtml', 'listinfo', 'options', 'private',
            'rmlist', 'roster', 'subscribe']
-SLASH = '/'
-NL2 = '\n\n'
-CRLF2 = '\r\n\r\n'
 
+SLASH   = '/'
+NL2     = '\n\n'
+CRLF2   = '\r\n\r\n'
+
+
+
 # WSGI to CGI wrapper.  Mostly copied from scripts/driver.
-
 def mailman_app(environ, start_response):
-    """wrapper to *.py cgi commands"""
-
+    """Wrapper to *.py CGI commands"""
     global STEALTH_MODE, websafe
     try:
         try:
@@ -65,7 +69,7 @@
                 environ['PATH_INFO'] = SLASH + SLASH.join(paths[2:])
             else:
                 environ['PATH_INFO'] = ''
-           # reverse proxy environment.
+            # Reverse proxy environment.
             if environ.has_key('HTTP_X_FORWARDED_HOST'):
                 environ['HTTP_HOST'] = environ['HTTP_X_FORWARDED_HOST']
             if environ.has_key('HTTP_X_FORWARDED_FOR'):
@@ -75,14 +79,14 @@
             os.environ['HTTP_COOKIE'] = ''
             for k, v in environ.items():
                 os.environ[k] = str(v)
-            # Prepare for redirection.
+            # Prepare for redirection
             save_stdin = sys.stdin
             # CGI writes its output to sys.stdout, while wsgi app should
             # return (list of) strings.
             save_stdout = sys.stdout
             save_stderr = sys.stderr
-            tmpstdout = StringIO.StringIO()
-            tmpstderr = StringIO.StringIO()
+            tmpstdout = StringIO()
+            tmpstderr = StringIO()
             response = ''
             try:
                 try:
@@ -117,7 +121,7 @@
     except:
         start_response('200 OK', [('Content-Type', 'text/html')])
         retstring = print_traceback(log)
-        retstring +=print_environment(log)
+        retstring += print_environment(log)
         return retstring
 
 
@@ -133,13 +137,13 @@
     except ImportError:
         traceback = None
     try:
-        from Mailman.mm_cfg import VERSION
+        from Mailman.Version import VERSION
     except ImportError:
         VERSION = '&lt;undetermined&gt;'
 
     # Write to the log file first.
     if log:
-        outfp = StringIO.StringIO()
+        outfp = StringIO()
 
         print >> outfp, '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
         print >> outfp, '[----- Mailman Version: %s -----]' % VERSION
@@ -155,7 +159,7 @@
         log.error('%s', outfp.getvalue())
 
     # return HTML sink.
-    htfp = StringIO.StringIO()
+    htfp = StringIO()
     print >> htfp, """\
 <head><title>Bug in Mailman version %(VERSION)s</title></head>
 <body bgcolor=#ffffff><h2>Bug in Mailman version %(VERSION)s</h2>
@@ -192,7 +196,7 @@
         os = None
 
     if log:
-        outfp = StringIO.StringIO()
+        outfp = StringIO()
 
         # Write some information about our Python executable to the log file.
         print >> outfp, '[----- Python Information -----]'
@@ -204,20 +208,20 @@
         print >> outfp, 'sys.platform    =', sys.platform
 
     # Write the same information to the HTML sink.
-    htfp = StringIO.StringIO()
+    htfp = StringIO()
     if not STEALTH_MODE:
-        print >> htfp, '''\
+        print >> htfp, """\
 <p><hr><h4>Python information:</h4>
 
 <p><table>
 <tr><th>Variable</th><th>Value</th></tr>
 <tr><td><tt>sys.version</tt></td><td> %s </td></tr>
 <tr><td><tt>sys.executable</tt></td><td> %s </td></tr>
-<tr><td><tt>sys.prefix</tt></td><td> %s </td></tr>'
+<tr><td><tt>sys.prefix</tt></td><td> %s </td></tr>
 <tr><td><tt>sys.exec_prefix</tt></td><td> %s </td></tr>
 <tr><td><tt>sys.path</tt></td><td> %s </td></tr>
 <tr><td><tt>sys.platform</tt></td><td> %s </td></tr>
-</table>''' % (sys.version, sys.executable, sys.prefix,
+</table>""" % (sys.version, sys.executable, sys.prefix,
                sys.exec_prefix, sys.path, sys.platform)
 
     # Write environment variables to the log file.
@@ -231,12 +235,12 @@
 
     # Write environment variables to the HTML sink.
     if not STEALTH_MODE:
-        print >> htfp, '''\
+        print >> htfp, """\
 <p><hr><h4>Environment variables:</h4>
 
 <p><table>
 <tr><th>Variable</th><th>Value</th></tr>
-'''
+"""
         if os:
             for k, v in os.environ.items():
                 print >> htfp, '<tr><td><tt>' + websafe(k) + \

Modified: trunk/mailman/Mailman/Defaults.py.in
===================================================================
--- trunk/mailman/Mailman/Defaults.py.in        2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/Defaults.py.in        2006-10-15 22:04:16 UTC (rev 
8064)
@@ -716,7 +716,7 @@
 #
 # NOTE: LMTP delivery is experimental for Mailman 2.2.
 USE_LMTP = No
-# NOTE: If you set USE_LMTP = Yes, add the following line to your mailman.cfg 
+# NOTE: If you set USE_LMTP = Yes, add the following line to your mailman.cfg
 # file (uncommented of course!)
 # QRUNNERS.append(('LMTPRunner', 1))
 
@@ -727,8 +727,10 @@
 LMTP_PORT = 8025
 
 # Experimental WSGI Server.
-# You must enable PROXY of Apache httpd server and configure to pass
-# mailman CGI requests to this WSGI Server:
+#
+# You must enable PROXY of Apache httpd server and configure to pass Mailman
+# CGI requests to this WSGI Server:
+#
 #     ProxyPass /mailman/ http://localhost:2580/
 HTTP_HOST = 'localhost'
 HTTP_PORT = 2580

Modified: trunk/mailman/Mailman/Gui/Privacy.py
===================================================================
--- trunk/mailman/Mailman/Gui/Privacy.py        2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/Gui/Privacy.py        2006-10-15 22:04:16 UTC (rev 
8064)
@@ -160,7 +160,7 @@
              spammers.""")),
             ]
 
-        adminurl = mlist.GetScriptURL('admin', absolute=1)
+        adminurl = mlist.GetScriptURL('admin')
         sender_rtn = [
             _("""When a message is posted to the list, a series of
             moderation steps are take to decide whether the a moderator must

Modified: trunk/mailman/Mailman/HTMLFormatter.py
===================================================================
--- trunk/mailman/Mailman/HTMLFormatter.py      2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/HTMLFormatter.py      2006-10-15 22:04:16 UTC (rev 
8064)
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2006 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
@@ -12,19 +12,18 @@
 #
 # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 
USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
 
-
 """Routines for presentation of list-specific HTML text."""
 
+import re
 import time
-import re
 
+from Mailman import MemberAdaptor
+from Mailman import Utils
 from Mailman import mm_cfg
-from Mailman import Utils
-from Mailman import MemberAdaptor
 from Mailman.htmlformat import *
-
 from Mailman.i18n import _
 
 
@@ -42,7 +41,8 @@
         # Remove the .Format() when htmlformat conversion is done.
         realname = self.real_name
         hostname = self.host_name
-        listinfo_link  = Link(self.GetScriptURL('listinfo'), realname).Format()
+        listinfo_link  = Link(self.GetScriptURL('listinfo'),
+                              realname).Format()
         owner_link = Link('mailto:' + self.GetOwnerEmail(), ownertext).Format()
         innertext = _('%(listinfo_link)s list run by %(owner_link)s')
         return Container(

Modified: trunk/mailman/Mailman/MailList.py
===================================================================
--- trunk/mailman/Mailman/MailList.py   2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/Mailman/MailList.py   2006-10-15 22:04:16 UTC (rev 8064)
@@ -262,12 +262,10 @@
             acct, host = tuple(member.split('@'))
             return "[EMAIL PROTECTED]" % (acct, self.umbrella_member_suffix, 
host)
 
-    def GetScriptURL(self, scriptname, absolute=False):
-        return '%s/%s' % (
-            Utils.ScriptURL(scriptname, self.web_page_url, absolute),
-            self.fqdn_listname)
+    def GetScriptURL(self, target):
+        return Utils.ScriptURL(target) + '/' + self.fqdn_listname
 
-    def GetOptionsURL(self, user, obscure=0, absolute=False):
+    def GetOptionsURL(self, user, obscure=False, absolute=False):
         url = self.GetScriptURL('options', absolute)
         if obscure:
             user = Utils.ObscureEmail(user)
@@ -299,8 +297,7 @@
                                                    name + '@' +
                                                    self.host_name)
                 else:
-                    self._full_path = os.path.join(config.LIST_DATA_DIR,
-                                                   name)
+                    self._full_path = os.path.join(config.LIST_DATA_DIR, name)
         else:
             self._full_path = ''
         # Only one level of mixin inheritance allowed

Modified: trunk/mailman/Mailman/Queue/HTTPRunner.py
===================================================================
--- trunk/mailman/Mailman/Queue/HTTPRunner.py   2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/Queue/HTTPRunner.py   2006-10-15 22:04:16 UTC (rev 
8064)
@@ -15,25 +15,24 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 # USA.
 
-"""Mailman HTTP runner (server).
+"""Mailman HTTP runner (server)."""
 
-"""
-
 import sys
 import logging
-import StringIO
 
+from cStringIO import StringIO
 from wsgiref.simple_server import make_server, WSGIRequestHandler
 
+from Mailman.Cgi.wsgi_app import mailman_app
 from Mailman.Queue.Runner import Runner
 from Mailman.configuration import config
-from Mailman.Cgi.wsgi_app import mailman_app
 
 hlog = logging.getLogger('mailman.http')
 qlog = logging.getLogger('mailman.qrunner')
 
+
+
 class HTTPRunner(Runner):
-
     def __init__(self, slice=None, numslices=1):
         pass
 
@@ -41,23 +40,27 @@
         pass
 
 
+
 class MailmanWSGIRequestHandler(WSGIRequestHandler):
-
     def handle(self):
         """Handle a single HTTP request with error output to elog"""
-        stderr = StringIO.StringIO()
-        save_stderr = sys.stderr
+        stderr = StringIO()
+        saved_stderr = sys.stderr
         sys.stderr = stderr
-        WSGIRequestHandler.handle(self)
-        sys.stderr = save_stderr
+        try:
+            WSGIRequestHandler.handle(self)
+        finally:
+            sys.stderr = saved_stderr
         hlog.info(stderr.getvalue().strip())
 
 
+
 server = make_server(config.HTTP_HOST, config.HTTP_PORT,
                      mailman_app,
                      handler_class=MailmanWSGIRequestHandler)
+
+
 qlog.info('HTTPRunner qrunner started.')
 server.serve_forever()
 # We'll never get here, but just in case...
 qlog.info('HTTPRunner qrunner exiting.')
-

Modified: trunk/mailman/Mailman/SecurityManager.py
===================================================================
--- trunk/mailman/Mailman/SecurityManager.py    2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/SecurityManager.py    2006-10-15 22:04:16 UTC (rev 
8064)
@@ -57,8 +57,6 @@
 import marshal
 import binascii
 
-from urlparse import urlparse
-
 from Mailman import Errors
 from Mailman import mm_cfg
 from Mailman import Utils
@@ -225,6 +223,9 @@
             return True
         return False
 
+    def _cookie_path(self):
+        return '/%s/%s' % (os.environ['SCRIPT_NAME'], self.fqdn_listname)
+
     def MakeCookie(self, authcontext, user=None):
         key, secret = self.AuthContextInfo(authcontext, user)
         if key is None or secret is None or not isinstance(secret, str):
@@ -236,10 +237,7 @@
         # Create the cookie object.
         c = Cookie.SimpleCookie()
         c[key] = binascii.hexlify(marshal.dumps((issued, mac)))
-        # The path to all Mailman stuff, minus the scheme and host,
-        # i.e. usually the string `/mailman'
-        path = urlparse(self.web_page_url)[2]
-        c[key]['path'] = path
+        c[key]['path'] = self._cookie_path()
         # We use session cookies, so don't set `expires' or `max-age' keys.
         # Set the RFC 2109 required header.
         c[key]['version'] = 1
@@ -253,10 +251,7 @@
         # string.
         c = Cookie.SimpleCookie()
         c[key] = ''
-        # The path to all Mailman stuff, minus the scheme and host,
-        # i.e. usually the string `/mailman'
-        path = urlparse(self.web_page_url)[2]
-        c[key]['path'] = path
+        c[key]['path'] = self._cookie_path()
         c[key]['max-age'] = 0
         # Don't set expires=0 here otherwise it'll force a persistent cookie
         c[key]['version'] = 1

Modified: trunk/mailman/Mailman/Utils.py
===================================================================
--- trunk/mailman/Mailman/Utils.py      2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/Mailman/Utils.py      2006-10-15 22:04:16 UTC (rev 8064)
@@ -202,7 +202,7 @@
 def ValidateEmail(s):
     """Verify that the an email address isn't grossly evil."""
     # Pretty minimal, cheesy check.  We could do better...
-    if not s or s.count(' ') > 0:
+    if not s or ' ' in s:
         raise Errors.MMBadEmailError
     if _badchars.search(s) or s[0] == '-':
         raise Errors.MMHostileAddress, s
@@ -226,36 +226,13 @@
             path = CRNLpat.split(path)[0]
             log.error('Warning: Possible malformed path attack.')
         return [p for p in path.split('/') if p]
-    return None
+    return []
 
 
 
-def ScriptURL(target, web_page_url=None, absolute=False):
-    """target - scriptname only, nothing extra
-    web_page_url - the list's configvar of the same name
-    absolute - a flag which if set, generates an absolute url
-    """
-    if web_page_url is None:
-        web_page_url = config.DEFAULT_URL_PATTERN % get_request_domain()
-        if web_page_url[-1] <> '/':
-            web_page_url = web_page_url + '/'
-    fullpath = os.environ.get('REQUEST_URI')
-    if fullpath is None:
-        fullpath = os.environ.get('SCRIPT_NAME', '') + \
-                   os.environ.get('PATH_INFO', '')
-    baseurl = urlparse.urlparse(web_page_url)[2]
-    if not absolute and fullpath.endswith(baseurl):
-        # Use relative addressing
-        fullpath = fullpath[len(baseurl):]
-        i = fullpath.find('?')
-        if i > 0:
-            count = fullpath.count('/', 0, i)
-        else:
-            count = fullpath.count('/')
-        path = ('../' * count) + target
-    else:
-        path = web_page_url + target
-    return path + config.CGIEXT
+def ScriptURL(target):
+    up = '../' * len(GetPathPieces())
+    return '%s%s' % (up, target + config.CGIEXT)
 
 
 
@@ -630,9 +607,9 @@
     unless `escape' is set to 0.
     """
     url = fallback
-    if os.environ.has_key('REQUEST_URI'):
+    if 'REQUEST_URI' in os.environ:
         url = os.environ['REQUEST_URI']
-    elif os.environ.has_key('SCRIPT_NAME') and os.environ.has_key('PATH_INFO'):
+    elif 'SCRIPT_NAME' in os.environ and 'PATH_INFO' in os.environ:
         url = os.environ['SCRIPT_NAME'] + os.environ['PATH_INFO']
     if escape:
         return websafe(url)

Modified: trunk/mailman/Mailman/bin/export.py
===================================================================
--- trunk/mailman/Mailman/bin/export.py 2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/Mailman/bin/export.py 2006-10-15 22:04:16 UTC (rev 8064)
@@ -156,12 +156,15 @@
                     self._element('value', v)
                 self._pop_element('option')
             else:
-                self._element('option', name=varname, value=value)
+                self._element('option', value, name=varname)
 
     def _dump_list(self, mlist, with_passwords):
         # Write list configuration values
         self._push_element('list', name=mlist.fqdn_listname)
-        self._element('language', mlist.preferred_language)
+        self._push_element('configuration')
+        self._element('option',
+                      mlist.preferred_language,
+                      name='preferred_language')
         for k in config.ADMIN_CATEGORIES:
             subcats = mlist.GetConfigSubCategories(k)
             if subcats is None:
@@ -169,6 +172,7 @@
             else:
                 for subcat in [t[0] for t in subcats]:
                     self._do_list_categories(mlist, k, subcat)
+        self._pop_element('configuration')
         # Write membership
         self._push_element('roster')
         digesters = set(mlist.getDigestMemberKeys())
@@ -206,14 +210,12 @@
                 when = datetime.datetime.fromtimestamp(changed)
                 attrs['changed'] = when.isoformat()
             self._element('delivery', **attrs)
-            self._push_element('options')
             for option, flag in Defaults.OPTINFO.items():
                 # Digest/Regular delivery flag must be handled separately
                 if option in ('digest', 'plain'):
                     continue
                 value = mlist.getMemberOption(member, flag)
                 self._element(option, value)
-            self._pop_element('options')
             topics = mlist.getMemberTopics(member)
             if not topics:
                 self._element('topics')

Modified: trunk/mailman/Mailman/bin/show_config.py
===================================================================
--- trunk/mailman/Mailman/bin/show_config.py    2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/bin/show_config.py    2006-10-15 22:04:16 UTC (rev 
8064)
@@ -1,99 +1,98 @@
-# Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-# USA.
-
-import re
-import sys
-import pprint
-import optparse
-
-from Mailman import Version
-from Mailman.configuration import config
-from Mailman.i18n import _
-
-__i18_templates__ = True
-
-# List of names never to show even if --verbose
-NEVER_SHOW = ['__builtins__', '__doc__']
-
-
-
-def parseargs():
-    parser = optparse.OptionParser(version=Version.MAILMAN_VERSION,
-                                   usage=_("""\
-%%prog [options] [pattern ...]
-
-Show the values of various Defaults.py/mailman.cfg variables.
-If one or more patterns are given, show only those variables
-whose names match a pattern"""))
-    parser.add_option('-v', '--verbose',
-                      default=False, action='store_true',
-                      help=_(
-"Show all configuration names, not just 'settings'."))
-    parser.add_option('-i', '--ignorecase',
-                      default=False, action='store_true',
-                      help=_("Match patterns case-insensitively."))
-    parser.add_option('-C', '--config',
-                      help=_('Alternative configuration file to use'))
-    opts, args = parser.parse_args()
-    return parser, opts, args
-
-
-
-def main():
-    parser, opts, args = parseargs()
-
-    patterns = []
-    if opts.ignorecase:
-        flag = re.IGNORECASE
-    else:
-        flag = 0
-    for pattern in args:
-        patterns.append(re.compile(pattern, flag))
-
-    pp = pprint.PrettyPrinter(indent=4)
-    config.load(opts.config)
-    names = config.__dict__.keys()
-    names.sort()
-    for name in names:
-        if name in NEVER_SHOW:
-            continue
-        if not opts.verbose:
-            if name.startswith('_') or re.search('[a-z]', name):
-                continue
-        if patterns:
-            hit = False
-            for pattern in patterns:
-                if pattern.search(name):
-                    hit = True
-                    break
-            if not hit:
-                continue
-        value = config.__dict__[name]
-        if isinstance(value, str):
-            if re.search('\n', value):
-                print '%s = """%s"""' %(name, value)
-            else:
-                print "%s = '%s'" % (name, value)
-        else:
-            print '%s = ' % name,
-            pp.pprint(value)
-
-
-
-if __name__ == '__main__':
-    main()
-
+# Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+import re
+import sys
+import pprint
+import optparse
+
+from Mailman import Version
+from Mailman.configuration import config
+from Mailman.i18n import _
+
+__i18_templates__ = True
+
+# List of names never to show even if --verbose
+NEVER_SHOW = ['__builtins__', '__doc__']
+
+
+
+def parseargs():
+    parser = optparse.OptionParser(version=Version.MAILMAN_VERSION,
+                                   usage=_("""\
+%%prog [options] [pattern ...]
+
+Show the values of various Defaults.py/mailman.cfg variables.
+If one or more patterns are given, show only those variables
+whose names match a pattern"""))
+    parser.add_option('-v', '--verbose',
+                      default=False, action='store_true',
+                      help=_(
+"Show all configuration names, not just 'settings'."))
+    parser.add_option('-i', '--ignorecase',
+                      default=False, action='store_true',
+                      help=_("Match patterns case-insensitively."))
+    parser.add_option('-C', '--config',
+                      help=_('Alternative configuration file to use'))
+    opts, args = parser.parse_args()
+    return parser, opts, args
+
+
+
+def main():
+    parser, opts, args = parseargs()
+
+    patterns = []
+    if opts.ignorecase:
+        flag = re.IGNORECASE
+    else:
+        flag = 0
+    for pattern in args:
+        patterns.append(re.compile(pattern, flag))
+
+    pp = pprint.PrettyPrinter(indent=4)
+    config.load(opts.config)
+    names = config.__dict__.keys()
+    names.sort()
+    for name in names:
+        if name in NEVER_SHOW:
+            continue
+        if not opts.verbose:
+            if name.startswith('_') or re.search('[a-z]', name):
+                continue
+        if patterns:
+            hit = False
+            for pattern in patterns:
+                if pattern.search(name):
+                    hit = True
+                    break
+            if not hit:
+                continue
+        value = config.__dict__[name]
+        if isinstance(value, str):
+            if re.search('\n', value):
+                print '%s = """%s"""' %(name, value)
+            else:
+                print "%s = '%s'" % (name, value)
+        else:
+            print '%s = ' % name,
+            pp.pprint(value)
+
+
+
+if __name__ == '__main__':
+    main()

Modified: trunk/mailman/Mailman/configuration.py
===================================================================
--- trunk/mailman/Mailman/configuration.py      2006-10-14 21:48:37 UTC (rev 
8063)
+++ trunk/mailman/Mailman/configuration.py      2006-10-15 22:04:16 UTC (rev 
8064)
@@ -29,7 +29,7 @@
 
 class Configuration(object):
     def __init__(self):
-        self.domains = {}
+        self.domains = {}       # email host -> web host
         self._reverse = None
 
     def load(self, filename=None):

Modified: trunk/mailman/Mailman/loginit.py
===================================================================
--- trunk/mailman/Mailman/loginit.py    2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/Mailman/loginit.py    2006-10-15 22:04:16 UTC (rev 8064)
@@ -31,6 +31,7 @@
 LOGGERS = (
     'bounce',
     'config',
+    'debug',
     'error',
     'http',
     'locks',

Modified: trunk/mailman/bin/Makefile.in
===================================================================
--- trunk/mailman/bin/Makefile.in       2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/bin/Makefile.in       2006-10-15 22:04:16 UTC (rev 8064)
@@ -54,7 +54,7 @@
                reset_pw.py templ2pot.py po2templ.py
 
 LN_SCRIPTS=    add_members arch change_pw check_perms config_list \
-               export find_member genaliases inject list_lists \
+               export find_member genaliases import inject list_lists \
                list_members list_owners mailmanctl mmsitepass newlist \
                qrunner rmlist show_config show_qfiles testall unshunt \
                update version


Property changes on: trunk/mailman/misc
___________________________________________________________________
Name: svn:ignore
   - Makefile
paths.py
mailman
email-?.?.?


   + Makefile
paths.py
mailman
email-?.?.?

setuptools-0.6c3


Modified: trunk/mailman/misc/Makefile.in
===================================================================
--- trunk/mailman/misc/Makefile.in      2006-10-14 21:48:37 UTC (rev 8063)
+++ trunk/mailman/misc/Makefile.in      2006-10-15 22:04:16 UTC (rev 8064)
@@ -48,15 +48,24 @@
 
 SHELL=         /bin/sh
 PYTHONLIBDIR=  $(prefix)/pythonlib
+
+# Traditional distutils packages
 SETUPINSTOPTS= --install-lib $(DESTDIR)$(PYTHONLIBDIR) \
                --install-purelib $(DESTDIR)$(PYTHONLIBDIR) \
                --install-data $(DESTDIR)$(PYTHONLIBDIR)
 SETUPCMD=      setup.py --quiet install $(SETUPINSTOPTS)
 
-EMAILPKG=      email-4.0.1
+EMAIL=         email-4.0.1
+SETUPTOOLS=    setuptools-0.6c3
+SETUPPKGS=     $(EMAIL) $(SETUPTOOLS)
 
-PACKAGES= $(EMAILPKG)
+EZINSTOPTS=    --install-dir $(DESTDIR)$(PYTHONLIBDIR)
+EZCMD=         $(PYTHONLIBDIR)/$(SETUPTOOLS)-py2.4.egg/easy_install.py \
+               $(EZINSTALLOPTS)
 
+WSGIREF=       wsgiref-0.1.2-py2.4.egg
+EZPKGS=                $(WSGIREF)
+
 # Modes for directories and executables created by the install
 # process.  Default to group-writable directories but
 # user-only-writable for executables.
@@ -86,11 +95,16 @@
        $(INSTALL) -m $(FILEMODE) mailman.cfg.sample $(DESTDIR)$(ETCDIR)
 
 install-packages:
-       for p in $(PACKAGES); \
+       for p in $(SETUPPKGS); \
        do \
            gunzip -c $(srcdir)/$$p.tar.gz | tar xf -; \
-           (cd $$p ; umask 02 ; PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) 
$(SETUPCMD)); \
+           (cd $$p ; umask 02 ; \
+            PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
        done
+       for p in $(EZPKGS); \
+       do \
+           (umask 02 ; PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(EZCMD) $$p); \
+       done
 
 finish:
 

Added: trunk/mailman/misc/setuptools-0.6c3.tar.gz
===================================================================
(Binary files differ)


Property changes on: trunk/mailman/misc/setuptools-0.6c3.tar.gz
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/mailman/misc/wsgiref-0.1.2-py2.4.egg
===================================================================
(Binary files differ)


Property changes on: trunk/mailman/misc/wsgiref-0.1.2-py2.4.egg
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to