diff options
| -rw-r--r-- | .bzrignore | 25 | ||||
| -rw-r--r-- | Mailman/data/Elixir-0.3.0.tar.gz | bin | 99715 -> 0 bytes | |||
| -rw-r--r-- | Mailman/data/Makefile.in | 118 | ||||
| -rw-r--r-- | Mailman/data/SQLAlchemy-0.3.3.tar.gz | bin | 737019 -> 0 bytes | |||
| -rw-r--r-- | Mailman/data/munepy-1.1-py2.5.egg | bin | 8192 -> 0 bytes | |||
| -rw-r--r-- | Mailman/data/pysqlite-2.3.2.tar.gz | bin | 79532 -> 0 bytes | |||
| -rw-r--r-- | Mailman/data/setuptools-0.6c3.tar.gz | bin | 238544 -> 0 bytes | |||
| -rw-r--r-- | Mailman/data/wsgiref-0.1.2-py2.4.egg | bin | 39890 -> 0 bytes | |||
| -rw-r--r-- | Mailman/data/zope.interface-3.3.0.1.tar.gz | bin | 105075 -> 0 bytes | |||
| -rw-r--r-- | Mailman/messages/Makefile.in | 155 | ||||
| -rw-r--r-- | Mailman/queue/Runner.py | 244 | ||||
| -rw-r--r-- | Mailman/queue/Switchboard.py | 190 | ||||
| -rw-r--r-- | Mailman/queue/sbcache.py | 27 | ||||
| -rw-r--r-- | Mailman/templates/Makefile.in | 83 | ||||
| -rw-r--r-- | Mailman/tests/Makefile.in | 82 | ||||
| -rw-r--r-- | Mailman/tests/base.py | 81 | ||||
| -rw-r--r-- | Mailman/tests/bounces/Makefile.in | 66 | ||||
| -rwxr-xr-x | data/__init__.py | 0 | ||||
| -rw-r--r-- | src/mailman/bouncers/Compuserve.py | 46 |
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 Binary files differdeleted file mode 100644 index fd61be97e..000000000 --- a/Mailman/data/Elixir-0.3.0.tar.gz +++ /dev/null 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 Binary files differdeleted file mode 100644 index 5732923fd..000000000 --- a/Mailman/data/SQLAlchemy-0.3.3.tar.gz +++ /dev/null diff --git a/Mailman/data/munepy-1.1-py2.5.egg b/Mailman/data/munepy-1.1-py2.5.egg Binary files differdeleted file mode 100644 index 00ed8ccfe..000000000 --- a/Mailman/data/munepy-1.1-py2.5.egg +++ /dev/null diff --git a/Mailman/data/pysqlite-2.3.2.tar.gz b/Mailman/data/pysqlite-2.3.2.tar.gz Binary files differdeleted file mode 100644 index 52f5711e9..000000000 --- a/Mailman/data/pysqlite-2.3.2.tar.gz +++ /dev/null diff --git a/Mailman/data/setuptools-0.6c3.tar.gz b/Mailman/data/setuptools-0.6c3.tar.gz Binary files differdeleted file mode 100644 index 30a4a464a..000000000 --- a/Mailman/data/setuptools-0.6c3.tar.gz +++ /dev/null diff --git a/Mailman/data/wsgiref-0.1.2-py2.4.egg b/Mailman/data/wsgiref-0.1.2-py2.4.egg Binary files differdeleted file mode 100644 index b38cb8321..000000000 --- a/Mailman/data/wsgiref-0.1.2-py2.4.egg +++ /dev/null diff --git a/Mailman/data/zope.interface-3.3.0.1.tar.gz b/Mailman/data/zope.interface-3.3.0.1.tar.gz Binary files differdeleted file mode 100644 index c95bf0698..000000000 --- a/Mailman/data/zope.interface-3.3.0.1.tar.gz +++ /dev/null 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 |
