summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2015-04-28 18:57:43 -0400
committerBarry Warsaw2015-04-28 18:57:43 -0400
commitd52a7f13baccecadd5d298d5f12190fae474024f (patch)
tree0e849c2f9f552586751257933c4d5a5b32f8481c
parent5bd0f593724f9a696bbefc91ea9c2127b66fa231 (diff)
downloadmailman-d52a7f13baccecadd5d298d5f12190fae474024f.tar.gz
mailman-d52a7f13baccecadd5d298d5f12190fae474024f.tar.zst
mailman-d52a7f13baccecadd5d298d5f12190fae474024f.zip
-rw-r--r--.bzrignore25
-rw-r--r--Mailman/data/Elixir-0.3.0.tar.gzbin99715 -> 0 bytes
-rw-r--r--Mailman/data/Makefile.in118
-rw-r--r--Mailman/data/SQLAlchemy-0.3.3.tar.gzbin737019 -> 0 bytes
-rw-r--r--Mailman/data/munepy-1.1-py2.5.eggbin8192 -> 0 bytes
-rw-r--r--Mailman/data/pysqlite-2.3.2.tar.gzbin79532 -> 0 bytes
-rw-r--r--Mailman/data/setuptools-0.6c3.tar.gzbin238544 -> 0 bytes
-rw-r--r--Mailman/data/wsgiref-0.1.2-py2.4.eggbin39890 -> 0 bytes
-rw-r--r--Mailman/data/zope.interface-3.3.0.1.tar.gzbin105075 -> 0 bytes
-rw-r--r--Mailman/messages/Makefile.in155
-rw-r--r--Mailman/queue/Runner.py244
-rw-r--r--Mailman/queue/Switchboard.py190
-rw-r--r--Mailman/queue/sbcache.py27
-rw-r--r--Mailman/templates/Makefile.in83
-rw-r--r--Mailman/tests/Makefile.in82
-rw-r--r--Mailman/tests/base.py81
-rw-r--r--Mailman/tests/bounces/Makefile.in66
-rwxr-xr-xdata/__init__.py0
-rw-r--r--src/mailman/bouncers/Compuserve.py46
19 files changed, 0 insertions, 1117 deletions
diff --git a/.bzrignore b/.bzrignore
deleted file mode 100644
index b687d7d83..000000000
--- a/.bzrignore
+++ /dev/null
@@ -1,25 +0,0 @@
-*.mo
-.bzrignore
-build/
-bzr-*.egg/
-cron/crontab.in
-dist/
-mailman.egg-info
-misc/mailman
-setuptools*
-TAGS
-var/
-.shelf
-bin
-.installed.cfg
-develop-eggs
-parts
-./bin
-eggs
-diff.txt
-distribute-*.egg
-distribute-*.tar.gz
-.coverage
-htmlcov
-.tox
-__pycache__
diff --git a/Mailman/data/Elixir-0.3.0.tar.gz b/Mailman/data/Elixir-0.3.0.tar.gz
deleted file mode 100644
index fd61be97e..000000000
--- a/Mailman/data/Elixir-0.3.0.tar.gz
+++ /dev/null
Binary files differ
diff --git a/Mailman/data/Makefile.in b/Mailman/data/Makefile.in
deleted file mode 100644
index 24f0f3a85..000000000
--- a/Mailman/data/Makefile.in
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright (C) 1998-2007 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.
-
-# NOTE: Makefile.in is converted into Makefile by the configure script
-# in the parent directory. Once configure has run, you can recreate
-# the Makefile by running just config.status.
-
-# Variables set by configure
-
-VPATH= @srcdir@
-srcdir= @srcdir@
-bindir= @bindir@
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-var_prefix= @VAR_PREFIX@
-DESTDIR=
-
-CC= @CC@
-CHMOD= @CHMOD@
-INSTALL= @INSTALL@
-PYTHON= @PYTHON@
-
-DEFS= @DEFS@
-
-# Customizable but not set by configure
-
-OPT= @OPT@
-CFLAGS= $(OPT) $(DEFS)
-PACKAGEDIR= $(prefix)/Mailman
-DATADIR= $(var_prefix)/data
-ETCDIR= $(var_prefix)/etc
-ICONDIR= $(prefix)/icons
-SCRIPTSDIR= $(prefix)/scripts
-
-SHELL= /bin/sh
-PYTHONLIBDIR= $(prefix)/pythonlib
-PYTHONPATHDIR= $(PYTHONLIBDIR)/lib/python
-
-# Traditional distutils packages
-SETUPINSTOPTS= --home $(DESTDIR)$(PYTHONLIBDIR)
-SETUPCMD= setup.py --quiet install $(SETUPINSTOPTS)
-
-SETUPTOOLS= setuptools-0.6c3
-SQLALCHEMY= SQLAlchemy-0.3.3
-ZOPEIFACE= zope.interface-3.3.0.1
-ELIXIR= Elixir-0.3.0
-SETUPPKGS= $(SETUPTOOLS) $(SQLALCHEMY) $(ZOPEIFACE) $(ELIXIR)
-
-EZINSTOPTS= --install-dir $(DESTDIR)$(PYTHONPATHDIR)
-EZCMD= $(PYTHONLIBDIR)/bin/easy_install $(EZINSTOPTS)
-
-WSGIREF= wsgiref-0.1.2-py2.4.egg
-MUNEPY= munepy-1.1-py2.5.egg
-EZPKGS= $(WSGIREF) $(MUNEPY)
-
-# Modes for directories and executables created by the install
-# process. Default to group-writable directories but
-# user-only-writable for executables.
-DIRMODE= 775
-EXEMODE= 755
-FILEMODE= 644
-DATAMODE= 664
-INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
-
-PATHSDIRS= bin cron scripts tests
-ICONS= $(srcdir)/*.jpg $(srcdir)/*.png
-
-# Rules
-
-all:
-
-install: install-other install-packages
-
-install-other:
- $(INSTALL) -m $(FILEMODE) $(ICONS) $(DESTDIR)$(ICONDIR)
- for d in $(PATHSDIRS); \
- do \
- dir=$(DESTDIR)$(prefix)/$$d; \
- $(INSTALL) -m $(FILEMODE) paths.py $$dir; \
- done
- $(INSTALL) -m $(EXEMODE) mailman $(DESTDIR)$(SCRIPTSDIR)
- $(INSTALL) -m $(FILEMODE) mailman.cfg.sample $(DESTDIR)$(ETCDIR)
-
-install-packages:
- mkdir -p $(PYTHONPATHDIR)
- for p in $(SETUPPKGS); \
- do \
- gunzip -c $(srcdir)/$$p.tar.gz | tar xf -; \
- (cd $$p ; umask 02 ; \
- PYTHONPATH=$(PYTHONPATHDIR) $(PYTHON) $(SETUPCMD)); \
- done
- for p in $(EZPKGS); \
- do \
- (umask 02 ; PYTHONPATH=$(PYTHONPATHDIR) $(EZCMD) $$p); \
- done
- $(INSTALL) -m $(FILEMODE) coverage.py $(PYTHONPATHDIR)
-
-finish:
-
-clean:
-
-distclean:
- -rm Makefile paths.py mailman
- -rm -rf $(PACKAGES)
diff --git a/Mailman/data/SQLAlchemy-0.3.3.tar.gz b/Mailman/data/SQLAlchemy-0.3.3.tar.gz
deleted file mode 100644
index 5732923fd..000000000
--- a/Mailman/data/SQLAlchemy-0.3.3.tar.gz
+++ /dev/null
Binary files differ
diff --git a/Mailman/data/munepy-1.1-py2.5.egg b/Mailman/data/munepy-1.1-py2.5.egg
deleted file mode 100644
index 00ed8ccfe..000000000
--- a/Mailman/data/munepy-1.1-py2.5.egg
+++ /dev/null
Binary files differ
diff --git a/Mailman/data/pysqlite-2.3.2.tar.gz b/Mailman/data/pysqlite-2.3.2.tar.gz
deleted file mode 100644
index 52f5711e9..000000000
--- a/Mailman/data/pysqlite-2.3.2.tar.gz
+++ /dev/null
Binary files differ
diff --git a/Mailman/data/setuptools-0.6c3.tar.gz b/Mailman/data/setuptools-0.6c3.tar.gz
deleted file mode 100644
index 30a4a464a..000000000
--- a/Mailman/data/setuptools-0.6c3.tar.gz
+++ /dev/null
Binary files differ
diff --git a/Mailman/data/wsgiref-0.1.2-py2.4.egg b/Mailman/data/wsgiref-0.1.2-py2.4.egg
deleted file mode 100644
index b38cb8321..000000000
--- a/Mailman/data/wsgiref-0.1.2-py2.4.egg
+++ /dev/null
Binary files differ
diff --git a/Mailman/data/zope.interface-3.3.0.1.tar.gz b/Mailman/data/zope.interface-3.3.0.1.tar.gz
deleted file mode 100644
index c95bf0698..000000000
--- a/Mailman/data/zope.interface-3.3.0.1.tar.gz
+++ /dev/null
Binary files differ
diff --git a/Mailman/messages/Makefile.in b/Mailman/messages/Makefile.in
deleted file mode 100644
index dd2b1a610..000000000
--- a/Mailman/messages/Makefile.in
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright (C) 2001-2007 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.
-
-# NOTE: Makefile.in is converted into Makefile by the configure script
-# in the parent directory. Once configure has run, you can recreate
-# the Makefile by running just config.status.
-#
-# NOTE: You should ordinarily never need to run "make catalogs", but
-# if you find you do, you will need GNU make, and the GNU gettext
-# suite (e.g. msgfmt, msgmerge).
-
-# Variables set by configure
-
-VPATH= @srcdir@
-srcdir= @srcdir@
-bindir= @bindir@
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-DESTDIR=
-
-CC= @CC@
-CHMOD= @CHMOD@
-INSTALL= @INSTALL@
-
-DEFS= @DEFS@
-
-# Customizable but not set by configure
-
-OPT= @OPT@
-CFLAGS= $(OPT) $(DEFS)
-PACKAGEDIR= $(prefix)/messages
-SHELL= /bin/sh
-DIRSETGID= chmod g+s
-MSGFMT= @PYTHON@ ../build/bin/msgfmt.py
-MSGMERGE= msgmerge
-
-# Languages from configure script
-LANGUAGES= @LANGUAGES@
-LANGDIRS= $(LANGUAGES:%=messages/%/LC_MESSAGES)
-# Human readable po file
-POFILES= $(LANGUAGES:%=%/LC_MESSAGES/mailman.po)
-# Binary generated mo file
-MOFILES= $(LANGUAGES:%=%/LC_MESSAGES/mailman.mo)
-TARGETS= $(MOFILES)
-
-# Modes for directories and executables created by the install
-# process. Default to group-writable directories but
-# user-only-writable for executables.
-DIRMODE= 775
-EXEMODE= 755
-FILEMODE= 644
-INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
-PROG= @PYTHON@ build/bin/pygettext.py
-TEMPL2POT= @PYTHON@ build/bin/templ2pot.py
-
-.SUFFIXES: .po .mo
-.po.mo:
- -$(MSGFMT) -o $@ $<
-
-# Rules
-
-all: mofiles
-
-catalogs: $(TARGETS)
-
-check:
- @for file in $(POFILES); \
- do \
- echo "Checking $$file"; \
- msgfmt -o /dev/null --statistics -v $$file; \
- done
-
-install: doinstall
-
-doinstall: mofiles
- @for d in $(LANGDIRS); \
- do \
- dir=$(DESTDIR)$(prefix)/$$d; \
- echo "Creating language directory $$dir"; \
- $(srcdir)/../mkinstalldirs $$dir; \
- chmod $(DIRMODE) $$dir; \
- $(DIRSETGID) $$dir; \
- done
- @for d in $(LANGUAGES); \
- do \
- readme=$(srcdir)/$$d/README.$$d; \
- if test -f $$readme; \
- then \
- $(INSTALL) -m $(FILEMODE) $$readme $(DESTDIR)$(prefix)/messages/$$d; \
- fi; \
- done
- @for d in $(LANGUAGES); \
- do \
- po=$(srcdir)/$$d/LC_MESSAGES/mailman.po; \
- mo=$(srcdir)/$$d/LC_MESSAGES/mailman.mo; \
- dir=$(DESTDIR)$(prefix)/messages/$$d/LC_MESSAGES; \
- $(INSTALL) -m $(FILEMODE) $$po $$dir; \
- $(INSTALL) -m $(FILEMODE) $$mo $$dir; \
- done
-
-mofiles: $(MOFILES)
-
-finish:
-
-clean:
- -rm -f */LC_MESSAGES/mailman.mo
-
-fileclean:
- -rm -f marked.files docstring.files template.files
-
-potclean: fileclean
- -rm -f Makefile $(POTFILE)
-
-distclean: clean potclean
- -rm -f Makefile
-
-marked.files:
- @echo "Calculating marked input files for pygettext"
- (cd ..; find Mailman -path '*pythonlib' -prune -o -path '*Commands/cmd_*.py' -prune -o -name '*.py' -print >| messages/$@)
-
-docstring.files:
- @echo "Calculating script input files for pygettext"
- (cd ..; grep -d skip -l -i '^#! .*python.*' `find bin cron scripts -name ".#*" -prune -o -print` | grep -v pygettext >| messages/$@)
- (cd ..; ls Mailman/Commands/cmd_*.py >> messages/$@)
-
-template.files:
- @echo "Calculating template input files for templ2pot"
- (cd ..; ls templates/en/*.* >| messages/$@)
-
-potfile: marked.files docstring.files template.files
- @echo "Running pygettext on $@; this make take a while."
- (cd ..; $(PROG) -p messages -d mailman -D -X messages/marked.files `cat messages/marked.files messages/docstring.files`)
- (cd ..; $(TEMPL2POT) `cat messages/template.files` >> messages/mailman.pot)
-
-# Update the individual mailman.po files with the new changes to the
-# .pot file
-%/LC_MESSAGES/mailman.po: mailman.pot
- @echo "Merging new template file with existing translations"
- $(MSGMERGE) -U $@ mailman.pot || touch $@
-
-
-FORCE:
diff --git a/Mailman/queue/Runner.py b/Mailman/queue/Runner.py
deleted file mode 100644
index 958e11e6c..000000000
--- a/Mailman/queue/Runner.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Copyright (C) 1998-2007 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.
-
-"""Generic queue runner class."""
-
-from __future__ import with_statement
-
-import time
-import weakref
-import logging
-import traceback
-import email.Errors
-
-from cStringIO import StringIO
-
-from Mailman import Errors
-from Mailman import Utils
-from Mailman import i18n
-from Mailman.Queue.Switchboard import Switchboard
-from Mailman.configuration import config
-
-log = logging.getLogger('mailman.error')
-
-
-
-class Runner:
- QDIR = None
- SLEEPTIME = config.QRUNNER_SLEEP_TIME
-
- def __init__(self, slice=None, numslices=1):
- self._kids = {}
- # Create our own switchboard. Don't use the switchboard cache because
- # we want to provide slice and numslice arguments.
- self._switchboard = Switchboard(self.QDIR, slice, numslices, True)
- # Create the shunt switchboard
- self._shunt = Switchboard(config.SHUNTQUEUE_DIR)
- self._stop = False
-
- def __repr__(self):
- return '<%s at %s>' % (self.__class__.__name__, id(self))
-
- def stop(self):
- self._stop = True
-
- def run(self):
- # Start the main loop for this queue runner.
- try:
- try:
- while True:
- # Once through the loop that processes all the files in
- # the queue directory.
- filecnt = self._oneloop()
- # Do the periodic work for the subclass. BAW: this
- # shouldn't be called here. There should be one more
- # _doperiodic() call at the end of the _oneloop() loop.
- self._doperiodic()
- # If the stop flag is set, we're done.
- if self._stop:
- break
- # Give the runner an opportunity to snooze for a while,
- # but pass it the file count so it can decide whether to
- # do more work now or not.
- self._snooze(filecnt)
- except KeyboardInterrupt:
- pass
- finally:
- # We've broken out of our main loop, so we want to reap all the
- # subprocesses we've created and do any other necessary cleanups.
- self._cleanup()
-
- def _oneloop(self):
- # First, list all the files in our queue directory.
- # Switchboard.files() is guaranteed to hand us the files in FIFO
- # order. Return an integer count of the number of files that were
- # available for this qrunner to process.
- files = self._switchboard.files
- for filebase in files:
- try:
- # Ask the switchboard for the message and metadata objects
- # associated with this filebase.
- msg, msgdata = self._switchboard.dequeue(filebase)
- except Exception, e:
- # This used to just catch email.Errors.MessageParseError,
- # but other problems can occur in message parsing, e.g.
- # ValueError, and exceptions can occur in unpickling too.
- # We don't want the runner to die, so we just log and skip
- # this entry, but preserve it for analysis.
- self._log(e)
- log.error('Skipping and preserving unparseable message: %s',
- filebase)
- self._switchboard.finish(filebase, preserve=True)
- continue
- try:
- self._onefile(msg, msgdata)
- self._switchboard.finish(filebase)
- except Exception, e:
- # All runners that implement _dispose() must guarantee that
- # exceptions are caught and dealt with properly. Still, there
- # may be a bug in the infrastructure, and we do not want those
- # to cause messages to be lost. Any uncaught exceptions will
- # cause the message to be stored in the shunt queue for human
- # intervention.
- self._log(e)
- # Put a marker in the metadata for unshunting
- msgdata['whichq'] = self._switchboard.queue_directory
- # It is possible that shunting can throw an exception, e.g. a
- # permissions problem or a MemoryError due to a really large
- # message. Try to be graceful.
- try:
- new_filebase = self._shunt.enqueue(msg, msgdata)
- log.error('SHUNTING: %s', new_filebase)
- self._switchboard.finish(filebase)
- except Exception, e:
- # The message wasn't successfully shunted. Log the
- # exception and try to preserve the original queue entry
- # for possible analysis.
- self._log(e)
- log.error('SHUNTING FAILED, preserving original entry: %s',
- filebase)
- self._switchboard.finish(filebase, preserve=True)
- # Other work we want to do each time through the loop
- Utils.reap(self._kids, once=True)
- self._doperiodic()
- if self._shortcircuit():
- break
- return len(files)
-
- def _onefile(self, msg, msgdata):
- # Do some common sanity checking on the message metadata. It's got to
- # be destined for a particular mailing list. This switchboard is used
- # to shunt off badly formatted messages. We don't want to just trash
- # them because they may be fixable with human intervention. Just get
- # them out of our site though.
- #
- # Find out which mailing list this message is destined for.
- listname = msgdata.get('listname')
- mlist = config.db.list_manager.get(listname)
- if not mlist:
- log.error('Dequeuing message destined for missing list: %s',
- listname)
- self._shunt.enqueue(msg, msgdata)
- return
- # Now process this message, keeping track of any subprocesses that may
- # have been spawned. We'll reap those later.
- #
- # We also want to set up the language context for this message. The
- # context will be the preferred language for the user if a member of
- # the list, or the list's preferred language. However, we must take
- # special care to reset the defaults, otherwise subsequent messages
- # may be translated incorrectly. BAW: I'm not sure I like this
- # approach, but I can't think of anything better right now.
- sender = msg.get_sender()
- member = mlist.members.get_member(sender)
- if member:
- lang = member.preferred_language
- else:
- lang = mlist.preferred_language
- with i18n.using_language(lang):
- msgdata['lang'] = lang
- keepqueued = self._dispose(mlist, msg, msgdata)
- # Keep tabs on any child processes that got spawned.
- kids = msgdata.get('_kids')
- if kids:
- self._kids.update(kids)
- if keepqueued:
- self._switchboard.enqueue(msg, msgdata)
-
- def _log(self, exc):
- log.error('Uncaught runner exception: %s', exc)
- s = StringIO()
- traceback.print_exc(file=s)
- log.error('%s', s.getvalue())
-
- #
- # Subclasses can override these methods.
- #
- def _cleanup(self):
- """Clean up upon exit from the main processing loop.
-
- Called when the Runner's main loop is stopped, this should perform
- any necessary resource deallocation. Its return value is irrelevant.
- """
- Utils.reap(self._kids)
-
- def _dispose(self, mlist, msg, msgdata):
- """Dispose of a single message destined for a mailing list.
-
- Called for each message that the Runner is responsible for, this is
- the primary overridable method for processing each message.
- Subclasses, must provide implementation for this method.
-
- mlist is the IMailingList instance this message is destined for.
-
- msg is the Message object representing the message.
-
- msgdata is a dictionary of message metadata.
- """
- raise NotImplementedError
-
- def _doperiodic(self):
- """Do some processing `every once in a while'.
-
- Called every once in a while both from the Runner's main loop, and
- from the Runner's hash slice processing loop. You can do whatever
- special periodic processing you want here, and the return value is
- irrelevant.
- """
- pass
-
- def _snooze(self, filecnt):
- """Sleep for a little while.
-
- filecnt is the number of messages in the queue the last time through.
- Sub-runners can decide to continue to do work, or sleep for a while
- based on this value. By default, we only snooze if there was nothing
- to do last time around.
- """
- if filecnt or float(self.SLEEPTIME) <= 0:
- return
- time.sleep(float(self.SLEEPTIME))
-
- def _shortcircuit(self):
- """Return a true value if the individual file processing loop should
- exit before it's finished processing each message in the current slice
- of hash space. A false value tells _oneloop() to continue processing
- until the current snapshot of hash space is exhausted.
-
- You could, for example, implement a throttling algorithm here.
- """
- return self._stop
diff --git a/Mailman/queue/Switchboard.py b/Mailman/queue/Switchboard.py
deleted file mode 100644
index 2c8672f57..000000000
--- a/Mailman/queue/Switchboard.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright (C) 2001-2007 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.
-
-"""Queing and dequeuing message/metadata pickle files.
-
-Messages are represented as email.message.Message objects (or an instance ofa
-subclass). Metadata is represented as a Python dictionary. For every
-message/metadata pair in a queue, a single file containing two pickles is
-written. First, the message is written to the pickle, then the metadata
-dictionary is written.
-"""
-
-from __future__ import with_statement
-
-import os
-import sha
-import time
-import email
-import errno
-import cPickle
-import logging
-import marshal
-
-from zope.interface import implements
-
-from Mailman import Message
-from Mailman import Utils
-from Mailman.configuration import config
-from Mailman.interfaces import ISwitchboard
-
-# 20 bytes of all bits set, maximum sha.digest() value
-shamax = 0xffffffffffffffffffffffffffffffffffffffffL
-
-# Small increment to add to time in case two entries have the same time. This
-# prevents skipping one of two entries with the same time until the next pass.
-DELTA = .0001
-
-elog = logging.getLogger('mailman.error')
-
-
-
-class Switchboard:
- implements(ISwitchboard)
-
- def __init__(self, whichq, slice=None, numslices=1, recover=False):
- self._whichq = whichq
- # Create the directory if it doesn't yet exist.
- Utils.makedirs(self._whichq, 0770)
- # Fast track for no slices
- self._lower = None
- self._upper = None
- # BAW: test performance and end-cases of this algorithm
- if numslices <> 1:
- self._lower = ((shamax + 1) * slice) / numslices
- self._upper = (((shamax + 1) * (slice + 1)) / numslices) - 1
- if recover:
- self.recover_backup_files()
-
- @property
- def queue_directory(self):
- return self._whichq
-
- def enqueue(self, _msg, _metadata=None, **_kws):
- if _metadata is None:
- _metadata = {}
- # Calculate the SHA hexdigest of the message to get a unique base
- # filename. We're also going to use the digest as a hash into the set
- # of parallel qrunner processes.
- data = _metadata.copy()
- data.update(_kws)
- listname = data.get('listname', '--nolist--')
- # Get some data for the input to the sha hash.
- now = time.time()
- if not data.get('_plaintext'):
- protocol = 1
- msgsave = cPickle.dumps(_msg, protocol)
- else:
- protocol = 0
- msgsave = cPickle.dumps(str(_msg), protocol)
- # listname is unicode but the input to the hash function must be an
- # 8-bit string (eventually, a bytes object).
- hashfood = msgsave + listname.encode('utf-8') + repr(now)
- # Encode the current time into the file name for FIFO sorting. The
- # file name consists of two parts separated by a '+': the received
- # time for this message (i.e. when it first showed up on this system)
- # and the sha hex digest.
- rcvtime = data.setdefault('received_time', now)
- filebase = repr(rcvtime) + '+' + sha.new(hashfood).hexdigest()
- filename = os.path.join(self._whichq, filebase + '.pck')
- tmpfile = filename + '.tmp'
- # Always add the metadata schema version number
- data['version'] = config.QFILE_SCHEMA_VERSION
- # Filter out volatile entries
- for k in data:
- if k.startswith('_'):
- del data[k]
- # We have to tell the dequeue() method whether to parse the message
- # object or not.
- data['_parsemsg'] = (protocol == 0)
- # Write to the pickle file the message object and metadata.
- with open(tmpfile, 'w') as fp:
- fp.write(msgsave)
- cPickle.dump(data, fp, protocol)
- fp.flush()
- os.fsync(fp.fileno())
- os.rename(tmpfile, filename)
- return filebase
-
- def dequeue(self, filebase):
- # Calculate the filename from the given filebase.
- filename = os.path.join(self._whichq, filebase + '.pck')
- backfile = os.path.join(self._whichq, filebase + '.bak')
- # Read the message object and metadata.
- with open(filename) as fp:
- # Move the file to the backup file name for processing. If this
- # process crashes uncleanly the .bak file will be used to
- # re-instate the .pck file in order to try again. XXX what if
- # something caused Python to constantly crash? Is it possible
- # that we'd end up mail bombing recipients or crushing the
- # archiver? How would we defend against that?
- os.rename(filename, backfile)
- msg = cPickle.load(fp)
- data = cPickle.load(fp)
- if data.get('_parsemsg'):
- msg = email.message_from_string(msg, Message.Message)
- return msg, data
-
- def finish(self, filebase, preserve=False):
- bakfile = os.path.join(self._whichq, filebase + '.bak')
- try:
- if preserve:
- psvfile = os.path.join(config.SHUNTQUEUE_DIR,
- filebase + '.psv')
- # Create the directory if it doesn't yet exist.
- Utils.makedirs(config.SHUNTQUEUE_DIR, 0770)
- os.rename(bakfile, psvfile)
- else:
- os.unlink(bakfile)
- except EnvironmentError, e:
- elog.exception('Failed to unlink/preserve backup file: %s',
- bakfile)
-
- @property
- def files(self):
- return self.get_files()
-
- def get_files(self, extension='.pck'):
- times = {}
- lower = self._lower
- upper = self._upper
- for f in os.listdir(self._whichq):
- # By ignoring anything that doesn't end in .pck, we ignore
- # tempfiles and avoid a race condition.
- filebase, ext = os.path.splitext(f)
- if ext <> extension:
- continue
- when, digest = filebase.split('+', 1)
- # Throw out any files which don't match our bitrange. BAW: test
- # performance and end-cases of this algorithm. MAS: both
- # comparisons need to be <= to get complete range.
- if lower is None or (lower <= long(digest, 16) <= upper):
- key = float(when)
- while key in times:
- key += DELTA
- times[key] = filebase
- # FIFO sort
- return [times[key] for key in sorted(times)]
-
- def recover_backup_files(self):
- # Move all .bak files in our slice to .pck. It's impossible for both
- # to exist at the same time, so the move is enough to ensure that our
- # normal dequeuing process will handle them.
- for filebase in self.get_files('.bak'):
- src = os.path.join(self._whichq, filebase + '.bak')
- dst = os.path.join(self._whichq, filebase + '.pck')
- os.rename(src, dst)
diff --git a/Mailman/queue/sbcache.py b/Mailman/queue/sbcache.py
deleted file mode 100644
index 8689bf083..000000000
--- a/Mailman/queue/sbcache.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2001-2007 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.
-
-"""A factory of Switchboards with caching."""
-
-from Mailman.Queue.Switchboard import Switchboard
-
-# a mapping from queue directory to Switchboard instance
-_sbcache = {}
-
-def get_switchboard(qdir):
- switchboard = _sbcache.setdefault(qdir, Switchboard(qdir))
- return switchboard
diff --git a/Mailman/templates/Makefile.in b/Mailman/templates/Makefile.in
deleted file mode 100644
index a69e558f4..000000000
--- a/Mailman/templates/Makefile.in
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (C) 1998-2007 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.
-
-# NOTE: Makefile.in is converted into Makefile by the configure script
-# in the parent directory. Once configure has run, you can recreate
-# the Makefile by running just config.status.
-
-# Variables set by configure
-
-VPATH= @srcdir@
-srcdir= @srcdir@
-bindir= @bindir@
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-DESTDIR=
-
-CC= @CC@
-CHMOD= @CHMOD@
-INSTALL= @INSTALL@
-TRUE= @TRUE@
-
-DEFS= @DEFS@
-
-# Customizable but not set by configure
-
-OPT= @OPT@
-CFLAGS= $(OPT) $(DEFS)
-TEMPLATEDIR= $(prefix)/templates
-
-SHELL= /bin/sh
-
-LANGUAGES= en @LANGUAGES@
-MAKELANGS= @LANGUAGES@
-
-# Modes for directories and executables created by the install
-# process. Default to group-writable directories but
-# user-only-writable for executables.
-DIRMODE= 775
-EXEMODE= 755
-FILEMODE= 644
-INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
-PO2TEMPL= @PYTHON@ build/bin/po2templ.py
-
-
-# Rules
-
-all:
- for d in $(MAKELANGS); \
- do \
- (mkdir -p $$d; cd ..; $(PO2TEMPL) $$d) \
- done
-
-install: all
- for d in $(LANGUAGES); \
- do \
- $(srcdir)/../mkinstalldirs $(DESTDIR)$(TEMPLATEDIR)/$$d; \
- for f in $(srcdir)/$$d/*.html $(srcdir)/$$d/*.txt; \
- do \
- $(INSTALL) -m $(FILEMODE) $$f $(DESTDIR)$(TEMPLATEDIR)/$$d; \
- done; \
- done
-
-finish:
-
-clean:
- -rm -rf $(MAKELANGS)
-
-distclean:
- -rm -f Makefile
- -rm -rf $(MAKELANGS)
diff --git a/Mailman/tests/Makefile.in b/Mailman/tests/Makefile.in
deleted file mode 100644
index 1326f67e5..000000000
--- a/Mailman/tests/Makefile.in
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 1998-2007 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.
-
-# NOTE: Makefile.in is converted into Makefile by the configure script
-# in the parent directory. Once configure has run, you can recreate
-# the Makefile by running just config.status.
-
-# Variables set by configure
-
-VPATH= @srcdir@
-srcdir= @srcdir@
-bindir= @bindir@
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-DESTDIR=
-
-CC= @CC@
-CHMOD= @CHMOD@
-INSTALL= @INSTALL@
-
-DEFS= @DEFS@
-
-# Customizable but not set by configure
-
-OPT= @OPT@
-CFLAGS= $(OPT) $(DEFS)
-PACKAGEDIR= $(prefix)/Mailman/testing
-SHELL= /bin/sh
-
-MODULES= *.py
-OTHERFILES= testing.cfg.in
-
-# Modes for directories and executables created by the install
-# process. Default to group-writable directories but
-# user-only-writable for executables.
-DIRMODE= 775
-EXEMODE= 755
-FILEMODE= 644
-INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
-
-# Directories make should decend into
-SUBDIRS= bounces
-
-# Rules
-
-all:
-
-install:
- for f in $(MODULES) $(OTHERFILES); \
- do \
- $(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
- done
- for d in $(SUBDIRS); \
- do \
- (cd $$d; $(MAKE) DESTDIR=$(DESTDIR) install); \
- done
-
-finish:
-
-clean:
-
-distclean:
- -rm *.pyc
- -rm Makefile
- @for d in $(SUBDIRS); \
- do \
- (cd $$d; $(MAKE) distclean); \
- done
diff --git a/Mailman/tests/base.py b/Mailman/tests/base.py
deleted file mode 100644
index 562443b1e..000000000
--- a/Mailman/tests/base.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (C) 2001-2007 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.
-
-"""Test base class which handles creating and deleting a test list."""
-
-import os
-import grp
-import new
-import pwd
-import sys
-import stat
-import shutil
-import difflib
-import tempfile
-import unittest
-
-from cStringIO import StringIO
-from sqlalchemy.orm import clear_mappers
-
-from Mailman import MailList
-from Mailman import Utils
-from Mailman.bin import rmlist
-from Mailman.configuration import config
-from Mailman.database.dbcontext import dbcontext
-
-NL = '\n'
-
-
-
-class TestBase(unittest.TestCase):
- def ndiffAssertEqual(self, first, second):
- """Like failUnlessEqual except use ndiff for readable output."""
- if first <> second:
- sfirst = str(first)
- ssecond = str(second)
- diff = difflib.ndiff(sfirst.splitlines(), ssecond.splitlines())
- fp = StringIO()
- print >> fp, NL, NL.join(diff)
- raise self.failureException(fp.getvalue())
-
- def setUp(self):
- # Be sure to close the connection to the current database, and then
- # reconnect to the new temporary SQLite database. Otherwise we end up
- # with turds in the main database and our qrunner subprocesses won't
- # find the mailing list. Because our global config object's
- # SQLALCHEMY_ENGINE_URL variable has already been updated, the
- # connect() call will open the database file the qrunners will be
- # rendezvousing on.
- dbcontext.close()
- clear_mappers()
- dbcontext.connect()
- mlist = MailList.MailList()
- mlist.Create('_xtest@example.com', 'owner@example.com', 'xxxxx')
- mlist.Save()
- # This leaves the list in a locked state
- self._mlist = mlist
-
- def tearDown(self):
- self._mlist.Unlock()
- rmlist.delete_list(self._mlist.fqdn_listname, self._mlist,
- archives=True, quiet=True)
- # Clear out any site locks, which can be left over if tests fail.
- for filename in os.listdir(config.LOCK_DIR):
- if filename.startswith('<site>'):
- path = os.path.join(config.LOCK_DIR, filename)
- print >> sys.stderr, '@@@@@ removing:', path
- os.unlink(path)
diff --git a/Mailman/tests/bounces/Makefile.in b/Mailman/tests/bounces/Makefile.in
deleted file mode 100644
index 0c9b2759b..000000000
--- a/Mailman/tests/bounces/Makefile.in
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2001-2007 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 Licenseo
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-# USA.
-
-# Variables set by configure
-
-VPATH= @srcdir@
-srcdir= @srcdir@
-bindir= @bindir@
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-DESTDIR=
-
-CC= @CC@
-CHMOD= @CHMOD@
-INSTALL= @INSTALL@
-
-DEFS= @DEFS@
-
-# Customizable but not set by configure
-
-OPT= @OPT@
-CFLAGS= $(OPT) $(DEFS)
-BOUNCEDIR= $(prefix)/Mailman/testing/bounces
-SHELL= /bin/sh
-
-BOUNCE_FILES= $(srcdir)/*.txt
-
-
-# Modes for directories and executables created by the install
-# process. Default to group-writable directories but
-# user-only-writable for executables.
-DIRMODE= 775
-EXEMODE= 755
-FILEMODE= 644
-INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
-
-# Rules
-all:
-
-install:
- for f in $(BOUNCE_FILES); \
- do \
- $(INSTALL) -m $(FILEMODE) $$f $(DESTDIR)$(BOUNCEDIR); \
- done
-
-finish:
-
-clean:
-
-distclean:
- -rm *.pyc
- -rm Makefile
diff --git a/data/__init__.py b/data/__init__.py
deleted file mode 100755
index e69de29bb..000000000
--- a/data/__init__.py
+++ /dev/null
diff --git a/src/mailman/bouncers/Compuserve.py b/src/mailman/bouncers/Compuserve.py
deleted file mode 100644
index 13052b68e..000000000
--- a/src/mailman/bouncers/Compuserve.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 1998-2010 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Compuserve has its own weird format for bounces."""
-
-import re
-import email
-
-dcre = re.compile(r'your message could not be delivered', re.IGNORECASE)
-acre = re.compile(r'Invalid receiver address: (?P<addr>.*)')
-
-
-
-def process(msg):
- # simple state machine
- # 0 = nothing seen yet
- # 1 = intro line seen
- state = 0
- addrs = []
- for line in email.Iterators.body_line_iterator(msg):
- if state == 0:
- mo = dcre.search(line)
- if mo:
- state = 1
- elif state == 1:
- mo = dcre.search(line)
- if mo:
- break
- mo = acre.search(line)
- if mo:
- addrs.append(mo.group('addr'))
- return addrs