[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-06-22 Thread noreply

revno: 979
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-06-22 08:16:40 -0400
message:
  testing bzr commit messages
added:
  test.txt

=== added file 'test.txt'
--- a/test.txt  1970-01-01 00:00:00 +
+++ b/test.txt  2007-06-22 12:16:40 +
@@ -0,0 +1,1 @@
+Please ignore me; I'm just testing bzr commits



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-06-22 Thread noreply

revno: 980
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-06-22 08:34:40 -0400
message:
  remove test file
removed:
  test.txt

=== removed file 'test.txt'
--- a/test.txt  2007-06-22 12:16:40 +
+++ b/test.txt  1970-01-01 00:00:00 +
@@ -1,1 +0,0 @@
-Please ignore me; I'm just testing bzr commits



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-22 Thread noreply

revno: 6508
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Fri 2007-06-22 11:53:02 -0700
message:
  Scrubber.py - Malformed RFC 2047 encoded filename= parameter can have
a null byte or other garbage in the extension. Cleaned this.
  - Improved handling of None payloads.
  - Cleaned up a few charset coercions.
  OutgoingRunner.py - Made probe bounce processing and queuing of bounces
  conditional on having some permanent failure(s).
modified:
  Mailman/Handlers/Scrubber.py
  Mailman/Queue/OutgoingRunner.py

=== modified file 'Mailman/Handlers/Scrubber.py'
--- a/Mailman/Handlers/Scrubber.py  2007-05-28 20:21:41 +
+++ b/Mailman/Handlers/Scrubber.py  2007-06-22 18:53:02 +
@@ -277,6 +277,7 @@
 size = len(payload)
 url = save_attachment(mlist, part, dir)
 desc = part.get('content-description', _('not available'))
+desc = Utils.oneline(desc, lcset)
 filename = part.get_filename(_('not available'))
 filename = Utils.oneline(filename, lcset)
 replace_payload_by_text(part, _(\
@@ -318,23 +319,23 @@
 text.append(_('Skipped content of type %(partctype)s\n'))
 continue
 try:
-t = part.get_payload(decode=True)
+t = part.get_payload(decode=True) or ''
 # MAS: TypeError exception can occur if payload is None. This
 # was observed with a message that contained an attached
 # message/delivery-status part. Because of the special parsing
 # of this type, this resulted in a text/plain sub-part with a
 # null body. See bug 1430236.
 except (binascii.Error, TypeError):
-t = part.get_payload()
+t = part.get_payload() or ''
 # Email problem was solved by Mark Sapiro. (TK)
 partcharset = part.get_content_charset('us-ascii')
 try:
 t = unicode(t, partcharset, 'replace')
 except (UnicodeError, LookupError, ValueError, TypeError,
 AssertionError):
-# What is the cause to come this exception now ?
+# We can get here if partcharset is bogus in come way.
 # Replace funny characters.  We use errors='replace'.
-u = unicode(t, 'ascii', 'replace')
+t = unicode(t, 'ascii', 'replace')
 # Separation is useful
 if isinstance(t, basestring):
 if not t.endswith('\n'):
@@ -344,12 +345,11 @@
 charsets.append(partcharset)
 # Now join the text and set the payload
 sep = _('-- next part --\n')
-# The i18n separator is in the list's charset. Coerce it to the
-# message charset.
+# The i18n separator is in the list's charset. Coerce to unicode.
 try:
-s = unicode(sep, lcset, 'replace')
-sep = s.encode(charset, 'replace')
+sep = unicode(sep, lcset, 'replace')
 except (UnicodeError, LookupError, ValueError):
+# This shouldn't occur.
 pass
 rept = sep.join(text)
 # Replace entire message with text and scrubbed notice.
@@ -360,7 +360,9 @@
 try:
 replace_payload_by_text(msg, rept, charset)
 break
-except UnicodeError:
+# Bogus charset can throw several exceptions
+except (UnicodeError, LookupError, ValueError, TypeError,
+AssertionError):
 pass
 if format:
 msg.set_param('format', format)
@@ -396,7 +398,7 @@
 # i18n file name is encoded
 lcset = Utils.GetCharSet(mlist.preferred_language)
 filename = Utils.oneline(msg.get_filename(''), lcset)
-fnext = os.path.splitext(filename)[1]
+filename, fnext = os.path.splitext(filename)
 # For safety, we should confirm this is valid ext for content-type
 # but we can use fnext if we introduce fnext filtering
 if config.SCRUBBER_USE_ATTACHMENT_FILENAME_EXTENSION:
@@ -404,6 +406,8 @@
 ext = fnext or guess_extension(ctype, fnext)
 else:
 ext = guess_extension(ctype, fnext)
+# Allow only alphanumerics, dash, underscore, and dot
+ext = sre.sub('', ext)
 if not ext:
 # We don't know what it is, so assume it's just a shapeless
 # application/octet-stream, unless the Content-Type: is
@@ -421,7 +425,6 @@
 try:
 # Now base the filename on what's in the attachment, uniquifying it if
 # necessary.
-filename = msg.get_filename()
 if not filename or config.SCRUBBER_DONT_USE_ATTACHMENT_FILENAME:
 filebase = 'attachment'
 else:
@@ -436,7 +439,8 @@
 # which one should we go 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-22 Thread noreply
1 revision was removed from the branch.


--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-22 Thread noreply

revno: 6509
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Fri 2007-06-22 17:15:03 -0400
message:
  Refactor tests to get consistent clean up behavior.  The clean up sections
  have been removed from the .txt files and instead added to the test harness,
  which all doctests now use.
modified:
  Mailman/docs/ack-headers.txt
  Mailman/docs/acknowledge.txt
  Mailman/docs/addresses.txt
  Mailman/docs/after-delivery.txt
  Mailman/docs/avoid-duplicates.txt
  Mailman/docs/calc-recips.txt
  Mailman/docs/cleanse.txt
  Mailman/docs/cook-headers.txt
  Mailman/docs/membership.txt
  Mailman/docs/mlist-addresses.txt
  Mailman/docs/reply-to.txt
  Mailman/docs/replybot.txt
  Mailman/docs/subject-munging.txt
  Mailman/docs/usermanager.txt
  Mailman/docs/users.txt
  Mailman/testing/base.py
  Mailman/testing/test_acknowledge.py
  Mailman/testing/test_address.py
  Mailman/testing/test_after_delivery.py
  Mailman/testing/test_avoid_duplicates.py
  Mailman/testing/test_calc_recips.py
  Mailman/testing/test_cleanse.py
  Mailman/testing/test_cook_headers.py
  Mailman/testing/test_decorate.py
  Mailman/testing/test_listmanager.py
  Mailman/testing/test_membership.py
  Mailman/testing/test_mlist_addresses.py
  Mailman/testing/test_replybot.py
  Mailman/testing/test_user.py
  Mailman/testing/test_usermanager.py

=== modified file 'Mailman/docs/ack-headers.txt'
--- a/Mailman/docs/ack-headers.txt  2007-06-21 14:23:40 +
+++ b/Mailman/docs/ack-headers.txt  2007-06-22 21:15:03 +
@@ -53,13 +53,3 @@
 BLANKLINE
 A message of great import.
 BLANKLINE
-
-
-Clean up
-
-
- for mlist in config.list_manager.mailing_lists:
-... config.list_manager.delete(mlist)
- flush()
- list(config.list_manager.mailing_lists)
-[]

=== modified file 'Mailman/docs/acknowledge.txt'
--- a/Mailman/docs/acknowledge.txt  2007-06-18 18:53:34 +
+++ b/Mailman/docs/acknowledge.txt  2007-06-22 21:15:03 +
@@ -174,13 +174,3 @@
 List info page: http://lists.example.com/listinfo/[EMAIL PROTECTED]
 Your preferences: http://example.com/[EMAIL PROTECTED]
 BLANKLINE
-
-
-Clean up
-
-
- for mlist in config.list_manager.mailing_lists:
-... config.list_manager.delete(mlist)
- flush()
- list(config.list_manager.mailing_lists)
-[]

=== modified file 'Mailman/docs/addresses.txt'
--- a/Mailman/docs/addresses.txt2007-06-10 23:14:10 +
+++ b/Mailman/docs/addresses.txt2007-06-22 21:15:03 +
@@ -174,21 +174,3 @@
   [EMAIL PROTECTED] as MemberRole.member]
  sorted(mlist.digest_members.members)
 []
-
-
-Clean up
-
-
- for mlist in config.list_manager.mailing_lists:
-... config.list_manager.delete(mlist)
- for user in mgr.users:
-... mgr.delete_user(user)
- for address in mgr.addresses:
-... mgr.delete_address(address)
- flush()
- sorted(config.list_manager.names)
-[]
- sorted(mgr.users)
-[]
- sorted(mgr.addresses)
-[]

=== modified file 'Mailman/docs/after-delivery.txt'
--- a/Mailman/docs/after-delivery.txt   2007-06-18 18:53:34 +
+++ b/Mailman/docs/after-delivery.txt   2007-06-22 21:15:03 +
@@ -31,13 +31,3 @@
 True
  mlist.post_id
 11
-
-
-Clean up
-
-
- for mlist in config.list_manager.mailing_lists:
-... config.list_manager.delete(mlist)
- flush()
- list(config.list_manager.mailing_lists)
-[]

=== modified file 'Mailman/docs/avoid-duplicates.txt'
--- a/Mailman/docs/avoid-duplicates.txt 2007-06-21 23:46:27 +
+++ b/Mailman/docs/avoid-duplicates.txt 2007-06-22 21:15:03 +
@@ -171,13 +171,3 @@
 BLANKLINE
 Something of great import.
 BLANKLINE
-
-
-Clean up
-
-
- for mlist in config.list_manager.mailing_lists:
-... config.list_manager.delete(mlist)
- flush()
- list(config.list_manager.mailing_lists)
-[]

=== modified file 'Mailman/docs/calc-recips.txt'
--- a/Mailman/docs/calc-recips.txt  2007-06-19 15:13:09 +
+++ b/Mailman/docs/calc-recips.txt  2007-06-22 21:15:03 +
@@ -105,26 +105,3 @@
 * test_urgent_moderator()
 * test_urgent_admin()
 * test_urgent_reject()
-
-
-Clean up
-
-
- for member in mlist.members.members:
-... member.unsubscribe()
- flush()
- list(mlist.members.members)
-[]
- for user in config.user_manager.users:
-... config.user_manager.delete_user(user)
- for address in config.user_manager.addresses:
-... config.user_manager.delete_address(address)
- for mlist in config.list_manager.mailing_lists:
-... config.list_manager.delete(mlist)
- flush()
- list(config.user_manager.users)
-[]
- list(config.user_manager.addresses)
-[]
- list(config.list_manager.mailing_lists)
-[]

=== modified file 'Mailman/docs/cleanse.txt'
--- a/Mailman/docs/cleanse.txt  

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-22 Thread noreply

revno: 6508
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Fri 2007-06-22 15:32:57 -0400
message:
  Merge temporary Elixir model branch to the 3.0 trunk.  Some tests are failing
  now so I have to fix these before pushing the branch up.
removed:
  Mailman/database/model/rosterset.py
  Mailman/docs/mlist-rosters.txt
  Mailman/interfaces/rosterset.py
  Mailman/testing/test_mlist_rosters.py
added:
  .bzrignore
  Mailman/database/model/member.py
  Mailman/docs/ack-headers.txt
  Mailman/docs/acknowledge.txt
  Mailman/docs/after-delivery.txt
  Mailman/docs/avoid-duplicates.txt
  Mailman/docs/calc-recips.txt
  Mailman/docs/cleanse.txt
  Mailman/docs/cook-headers.txt
  Mailman/docs/membership.txt
  Mailman/docs/reply-to.txt
  Mailman/docs/subject-munging.txt
  Mailman/interfaces/member.py
  Mailman/testing/test_acknowledge.py
  Mailman/testing/test_after_delivery.py
  Mailman/testing/test_avoid_duplicates.py
  Mailman/testing/test_calc_recips.py
  Mailman/testing/test_cleanse.py
  Mailman/testing/test_cook_headers.py
renamed:
  Mailman/database/model/profile.py = Mailman/database/model/preferences.py
  Mailman/interfaces/profile.py = Mailman/interfaces/preferences.py
modified:
  Mailman/Defaults.py.in
  Mailman/Handlers/Acknowledge.py
  Mailman/Handlers/AfterDelivery.py
  Mailman/Handlers/AvoidDuplicates.py
  Mailman/Handlers/CalcRecips.py
  Mailman/Handlers/Cleanse.py
  Mailman/Handlers/CookHeaders.py
  Mailman/MailList.py
  Mailman/Utils.py
  Mailman/constants.py
  Mailman/database/listmanager.py
  Mailman/database/model/__init__.py
  Mailman/database/model/address.py
  Mailman/database/model/language.py
  Mailman/database/model/mailinglist.py
  Mailman/database/model/roster.py
  Mailman/database/model/user.py
  Mailman/database/model/version.py
  Mailman/database/types.py
  Mailman/database/usermanager.py
  Mailman/docs/addresses.txt
  Mailman/docs/listmanager.txt
  Mailman/docs/usermanager.txt
  Mailman/docs/users.txt
  Mailman/interfaces/address.py
  Mailman/interfaces/mlistrosters.py
  Mailman/interfaces/mlistweb.py
  Mailman/interfaces/roster.py
  Mailman/interfaces/user.py
  Mailman/interfaces/usermanager.py
  Mailman/testing/test_handlers.py
  Mailman/testing/test_membership.py
  Mailman/testing/test_user.py
  docs/NEWS.txt
  Mailman/database/model/preferences.py
  Mailman/interfaces/preferences.py

revno: 6504.1.13
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: model
timestamp: Thu 2007-06-21 19:46:27 -0400
message:
  Convert the AvoidDuplicates handler tests to a doctest.  Well,
  actually there /was/ no separate AvoidDuplicates test, but now there
  is, even though it may not be full coverage.
  
  Update the AvoidDuplicates handler to use more modern Python idioms.

revno: 6504.1.12
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: model
timestamp: Thu 2007-06-21 10:23:40 -0400
message:
  Convert the CookHeaders tests in test_handlers to using doctests, split up
  into several sub-documents.
  
  Defaults.py.in: Removed OLD_STYLE_PREFIXING.  So-called 'new style' 
prefixing
  is the default and only option now.
  
  CookHeaders.py is updated to the new API and some (but not all) of the 
code
  has been updated to more modern Python idioms.
  
  reply_goes_to_list attribute has been changed from a strict integer to a
  munepy enum called ReplyToMunging.
  
  RFC 2369 headers List-Subscribe and List-Unsubscribe now use the preferred
  -join and -leave addresses instead of the -request address with a subject
  value.

revno: 6504.1.11
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: model
timestamp: Tue 2007-06-19 18:42:27 -0400
message:
  Convert the Cleanse handler tests to doctest style.

revno: 6504.1.10
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: model
timestamp: Tue 2007-06-19 11:13:09 -0400
message:
  Convert the tests for the CalcRecips handler to doc tests.  There are
  some XXX's in the doc test because digest recipients aren't tested
  (though those may go in a different doctest), and neither are urgent
  messages.  This latter is for the same reason that the Approved
  handler is not yet tested; which password do you use in that header?
  
  The CalcRecips tests would also seem the natural place to test the
  receive_list_copy preference, but that actually gets processed in the
  AvoidDuplicates handler, so it isn't tested here.
  
  Add delivery_status (of type enum DeliveryStatus) to preferences.  I'm
  not entirely 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-23 Thread noreply

revno: 6511
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sat 2007-06-23 08:38:45 -0400
message:
  Simplify doctests by having just a single test_documentation.py module in
  Mailman/testing.  This introspects the Mailman/docs directory and adds
  DocFileSuites for all .txt files found there.
removed:
  Mailman/testing/test_acknowledge.py
  Mailman/testing/test_address.py
  Mailman/testing/test_after_delivery.py
  Mailman/testing/test_avoid_duplicates.py
  Mailman/testing/test_calc_recips.py
  Mailman/testing/test_cleanse.py
  Mailman/testing/test_cook_headers.py
  Mailman/testing/test_decorate.py
  Mailman/testing/test_listmanager.py
  Mailman/testing/test_mlist_addresses.py
  Mailman/testing/test_replybot.py
  Mailman/testing/test_user.py
  Mailman/testing/test_usermanager.py
added:
  Mailman/testing/test_documentation.py
modified:
  Mailman/testing/base.py
  Mailman/testing/test_membership.py

=== removed file 'Mailman/testing/test_acknowledge.py'
--- a/Mailman/testing/test_acknowledge.py   2007-06-22 21:15:03 +
+++ b/Mailman/testing/test_acknowledge.py   1970-01-01 00:00:00 +
@@ -1,27 +0,0 @@
-# Copyright (C) 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.
-
-Doctest harness for testing message acknowledgment.
-
-import unittest
-from Mailman.testing.base import make_docfile_suite
-
-
-def test_suite():
-suite = unittest.TestSuite()
-suite.addTest(make_docfile_suite('../docs/acknowledge.txt'))
-return suite

=== removed file 'Mailman/testing/test_address.py'
--- a/Mailman/testing/test_address.py   2007-06-22 21:15:03 +
+++ b/Mailman/testing/test_address.py   1970-01-01 00:00:00 +
@@ -1,27 +0,0 @@
-# Copyright (C) 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.
-
-Doctest harness for testing IAddress interface.
-
-import unittest
-from Mailman.testing.base import make_docfile_suite
-
-
-def test_suite():
-suite = unittest.TestSuite()
-suite.addTest(make_docfile_suite('../docs/addresses.txt'))
-return suite

=== removed file 'Mailman/testing/test_after_delivery.py'
--- a/Mailman/testing/test_after_delivery.py2007-06-22 21:15:03 +
+++ b/Mailman/testing/test_after_delivery.py1970-01-01 00:00:00 +
@@ -1,28 +0,0 @@
-# Copyright (C) 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.
-
-Doctest harness for testing bookkeeping done after message delivery.
-
-import unittest
-
-from Mailman.testing.base import make_docfile_suite
-
-
-def test_suite():
-suite = unittest.TestSuite()
-suite.addTest(make_docfile_suite('../docs/after-delivery.txt'))
-return suite

=== removed file 'Mailman/testing/test_avoid_duplicates.py'
--- a/Mailman/testing/test_avoid_duplicates.py  2007-06-22 21:15:03 +
+++ b/Mailman/testing/test_avoid_duplicates.py  

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-27 Thread noreply

revno: 6512
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-06-27 17:33:42 -0400
message:
  Convert the Switchboard test in test_runners.py to a doctest.  Add an
  ISwitchboard interface and modernize the Python code in the Switchboard.py
  implementation.
  
  The SAVE_MSGS_AS_PICKLES option is removed.  Messages are always saved as
  pickles unless the metadata '_plaintext' key is present, though this should
  eventually go away too.
  
  In testall.py, put the entire VAR_PREFIX in a temporary directory.  This helps
  the switchboard tests by not mixing their data with the installation's queue
  directories.  The Configuration object now also ensures that all the queue and
  log directories exist -- one more step on the road to getting rid of the
  autoconf mess.
added:
  Mailman/docs/switchboard.txt
  Mailman/interfaces/switchboard.py
modified:
  Mailman/Queue/Runner.py
  Mailman/Queue/Switchboard.py
  Mailman/Queue/tests/test_runners.py
  Mailman/bin/testall.py
  Mailman/configuration.py
  Mailman/initialize.py

=== added file 'Mailman/docs/switchboard.txt'
--- a/Mailman/docs/switchboard.txt  1970-01-01 00:00:00 +
+++ b/Mailman/docs/switchboard.txt  2007-06-27 21:33:42 +
@@ -0,0 +1,151 @@
+The switchboard
+===
+
+The switchboard is subsystem that moves messages between queues.  Each
+instance of a switchboard is responsible for one queue directory.
+
+ from email import message_from_string
+ from Mailman.Message import Message
+ from Mailman.Queue.Switchboard import Switchboard
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... To: [EMAIL PROTECTED]
+...
+... A test message.
+... , Message)
+
+Create a switchboard by giving its queue directory.
+
+ import os
+ from Mailman.configuration import config
+ queue_directory = os.path.join(config.QUEUE_DIR, 'test')
+ switchboard = Switchboard(queue_directory)
+ switchboard.queue_directory == queue_directory
+True
+
+Here's a helper function for ensuring things work correctly.
+
+ def check_qfiles():
+... files = {}
+... for qfile in os.listdir(queue_directory):
+... root, ext = os.path.splitext(qfile)
+... files[ext] = files.get(ext, 0) + 1
+... return sorted(files.items())
+
+
+Enqueing and dequeing
+-
+
+The message can be enqueued with metadata specified in the passed in
+dictionary.
+
+ filebase = switchboard.enqueue(msg)
+ check_qfiles()
+[('.pck', 1)]
+
+To read the contents of a queue file, dequeue it.
+
+ msg, msgdata = switchboard.dequeue(filebase)
+ print msg.as_string()
+From: [EMAIL PROTECTED]
+To: [EMAIL PROTECTED]
+BLANKLINE
+A test message.
+BLANKLINE
+ sorted(msgdata.items())
+[('_parsemsg', False), ('received_time', ...), ('version', 3)]
+ check_qfiles()
+[('.bak', 1)]
+
+To complete the dequeing process, removing all traces of the message file,
+finish it (without preservation).
+
+ switchboard.finish(filebase)
+ check_qfiles()
+[]
+
+When enqueing a file, you can provide additional metadata keys by using
+keyword arguments.
+
+ filebase = switchboard.enqueue(msg, {'foo': 1}, bar=2)
+ msg, msgdata = switchboard.dequeue(filebase)
+ switchboard.finish(filebase)
+ sorted(msgdata.items())
+[('_parsemsg', False),
+('bar', 2), ('foo', 1),
+('received_time', ...), ('version', 3)]
+
+Keyword arguments override keys from the metadata dictionary.
+
+ filebase = switchboard.enqueue(msg, {'foo': 1}, foo=2)
+ msg, msgdata = switchboard.dequeue(filebase)
+ switchboard.finish(filebase)
+ sorted(msgdata.items())
+[('_parsemsg', False),
+('foo', 2),
+('received_time', ...), ('version', 3)]
+
+
+Iterating over files
+
+
+There are two ways to iterate over all the files in a switchboard's queue.
+Normally, queue files end in .pck (for 'pickle') and the easiest way to
+iterate over just these files is to use the .files attribute.
+
+ filebase_1 = switchboard.enqueue(msg, foo=1)
+ filebase_2 = switchboard.enqueue(msg, foo=2)
+ filebase_3 = switchboard.enqueue(msg, foo=3)
+ filebases = sorted((filebase_1, filebase_2, filebase_3))
+ sorted(switchboard.files) == filebases
+True
+ check_qfiles()
+[('.pck', 3)]
+
+You can also use the .get_files() method if you want to iterate over all the
+file bases for some other extension.
+
+ for filebase in switchboard.get_files():
+... msg, msgdata = switchboard.dequeue(filebase)
+ bakfiles = sorted(switchboard.get_files('.bak'))
+ bakfiles == filebases
+True
+ check_qfiles()
+[('.bak', 3)]
+ for filebase in switchboard.get_files('.bak'):
+... switchboard.finish(filebase)
+ check_qfiles()
+[]
+
+
+Recovering files
+
+
+Calling 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-27 Thread noreply

revno: 6513
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-06-27 23:01:56 -0400
message:
  Repair docfiles broken with the new ISwitchboard interface.  Mostly these were
  due to the change from the method Switchboard.files() to the generator
  property Switchboard.files.
  
  Add support in cleaning_teardown() for the doctests for removing all queue
  files leftover after a test is complete.  This way, failures in one test that
  queues files won't break all subsequent such tests.
  
  Update the 2.1.9 section of the NEWS.txt file from the Mailman 2.1 branch.
modified:
  Mailman/docs/acknowledge.txt
  Mailman/docs/replybot.txt
  Mailman/testing/test_documentation.py
  docs/NEWS.txt

=== modified file 'Mailman/docs/acknowledge.txt'
--- a/Mailman/docs/acknowledge.txt  2007-06-22 21:15:03 +
+++ b/Mailman/docs/acknowledge.txt  2007-06-28 03:01:56 +
@@ -21,7 +21,7 @@
  # for new auto-response messages.
  from Mailman.Queue.sbcache import get_switchboard
  virginq = get_switchboard(config.VIRGINQUEUE_DIR)
- virginq.files()
+ list(virginq.files)
 []
 
 Subscribe a user to the mailing list.
@@ -44,7 +44,7 @@
 ...
 ... , Message)
  process(mlist, msg, {})
- virginq.files()
+ list(virginq.files)
 []
 
 We can also specify the original sender in the message's metadata.  If that
@@ -55,7 +55,7 @@
 ...
 ... , Message)
  process(mlist, msg, dict(original_sender='[EMAIL PROTECTED]'))
- virginq.files()
+ list(virginq.files)
 []
 
 
@@ -69,7 +69,7 @@
 ...
 ... , Message)
  process(mlist, msg, {})
- virginq.files()
+ list(virginq.files)
 []
 
 Similarly if the original sender is specified in the message metadata, and
@@ -83,7 +83,7 @@
  flush()
 
  process(mlist, msg, dict(original_sender='[EMAIL PROTECTED]'))
- virginq.files()
+ list(virginq.files)
 []
 
 
@@ -104,11 +104,11 @@
 ...
 ... , Message)
  process(mlist, msg, {})
-
- len(virginq.files())
+ files = list(virginq.files)
+ len(files)
 1
- qmsg, qdata = virginq.dequeue(virginq.files()[0])
- virginq.files()
+ qmsg, qdata = virginq.dequeue(files[0])
+ list(virginq.files)
 []
  # Print only some of the meta data.  The rest is uninteresting.
  qdata['listname']
@@ -143,11 +143,11 @@
 ...
 ... , Message)
  process(mlist, msg, {})
-
- len(virginq.files())
+ files = list(virginq.files)
+ len(files)
 1
- qmsg, qdata = virginq.dequeue(virginq.files()[0])
- virginq.files()
+ qmsg, qdata = virginq.dequeue(files[0])
+ list(virginq.files)
 []
  # Print only some of the meta data.  The rest is uninteresting.
  qdata['listname']

=== modified file 'Mailman/docs/replybot.txt'
--- a/Mailman/docs/replybot.txt 2007-06-22 21:15:03 +
+++ b/Mailman/docs/replybot.txt 2007-06-28 03:01:56 +
@@ -19,7 +19,7 @@
  # for new auto-response messages.
  from Mailman.Queue.sbcache import get_switchboard
  virginq = get_switchboard(config.VIRGINQUEUE_DIR)
- virginq.files()
+ list(virginq.files)
 []
 
 
@@ -43,9 +43,10 @@
 ... help
 ... , Message)
  process(mlist, msg, dict(toowner=True))
- len(virginq.files())
+ files = list(virginq.files)
+ len(files)
 1
- qmsg, qdata = virginq.dequeue(virginq.files()[0])
+ qmsg, qdata = virginq.dequeue(files[0])
  # Print only some of the meta data.  The rest is uninteresting.
  qdata['listname']
 '[EMAIL PROTECTED]'
@@ -66,7 +67,7 @@
 Precedence: bulk
 BLANKLINE
 admin autoresponse text
- virginq.files()
+ list(virginq.files)
 []
 
 
@@ -84,7 +85,7 @@
 ... help me
 ... , Message)
  process(mlist, msg, dict(toowner=True))
- virginq.files()
+ list(virginq.files)
 []
 
 Mailman itself can suppress autoresponses for certain types of internally
@@ -96,7 +97,7 @@
 ... help for you
 ... , Message)
  process(mlist, msg, dict(noack=True, toowner=True))
- virginq.files()
+ list(virginq.files)
 []
 
 If there is a Precedence: header with any of the values 'bulk', 'junk', or
@@ -109,16 +110,16 @@
 ... hey!
 ... , Message)
  process(mlist, msg, dict(toowner=True))
- virginq.files()
+ list(virginq.files)
 []
 
  msg.replace_header('precedence', 'junk')
  process(mlist, msg, dict(toowner=True))
- virginq.files()
+ list(virginq.files)
 []
  msg.replace_header('precedence', 'list')
  process(mlist, msg, dict(toowner=True))
- virginq.files()
+ list(virginq.files)
 []
 
 Unless the X-Ack: header has a value of yes, in which case, the Precedence
@@ -126,9 +127,10 @@
 
  msg['X-Ack'] = 'yes'
  process(mlist, msg, dict(toowner=True))
- len(virginq.files())
+ files = list(virginq.files)
+ len(files)
 1
- qmsg, qdata 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-27 Thread noreply

revno: 6514
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Thu 2007-06-28 01:11:50 -0400
message:
  Convert the rest of test_runners.py to doctests; even though incomplete, they
  test everything the old unit tests tested.  There are XXX's left in the
  doctests as reminders to flesh them out.
  
  Change the NNTP_REWRITE_DUPLICATE_HEADERS to use proper capitalization.
  
  Revert a change I made in the conversion of the Switchboard class:
  Switchboard.files is no longer a generator.  The Runner implementation is
  cleaner if this returns a concrete list, so that's what it does now.  Update
  the tests to reflect that.
  
  The Runner simplifies now too because it no longer needs _open_files() or the
  _listcache WeakValueDictionary.  The standard list manager handles all this
  now, so just use it directly.
  
  Also change the way the Runner sets the language context in _onefile().  It
  still tries to set it to the preferred language of the sender, if the sender
  is a member of the list.  Otherwise it sets it to the list's preferred
  language, not the system's preferred language.  Removed a conditional that
  can't possibly happen.
removed:
  Mailman/Queue/tests/test_runners.py
added:
  Mailman/docs/news-runner.txt
  Mailman/docs/runner.txt
modified:
  Mailman/Defaults.py.in
  Mailman/Queue/Runner.py
  Mailman/Queue/Switchboard.py
  Mailman/docs/acknowledge.txt
  Mailman/docs/replybot.txt
  Mailman/docs/switchboard.txt

=== removed file 'Mailman/Queue/tests/test_runners.py'
--- a/Mailman/Queue/tests/test_runners.py   2007-06-27 21:33:42 +
+++ b/Mailman/Queue/tests/test_runners.py   1970-01-01 00:00:00 +
@@ -1,163 +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.
-
-Unit tests for the various Mailman qrunner modules.
-
-import os
-import email
-import shutil
-import tempfile
-import unittest
-
-from Mailman.Message import Message
-from Mailman.Queue.NewsRunner import prepare_message
-from Mailman.Queue.Runner import Runner
-from Mailman.Queue.Switchboard import Switchboard
-from Mailman.testing.base import TestBase
-
-
-
-class TestPrepMessage(TestBase):
-def test_remove_unacceptables(self):
-eq = self.assertEqual
-msg = email.message_from_string(\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-NNTP-Posting-Host: news.dom.ain
-NNTP-Posting-Date: today
-X-Trace: blah blah
-X-Complaints-To: [EMAIL PROTECTED]
-Xref: blah blah
-Xref: blah blah
-Date-Received: yesterday
-Posted: tomorrow
-Posting-Version: 99.99
-Relay-Version: 88.88
-Received: blah blah
-
-A message
-)
-msgdata = {}
-prepare_message(self._mlist, msg, msgdata)
-eq(msgdata.get('prepped'), 1)
-eq(msg['from'], '[EMAIL PROTECTED]')
-eq(msg['to'], '[EMAIL PROTECTED]')
-eq(msg['nntp-posting-host'], None)
-eq(msg['nntp-posting-date'], None)
-eq(msg['x-trace'], None)
-eq(msg['x-complaints-to'], None)
-eq(msg['xref'], None)
-eq(msg['date-received'], None)
-eq(msg['posted'], None)
-eq(msg['posting-version'], None)
-eq(msg['relay-version'], None)
-eq(msg['received'], None)
-
-def test_munge_duplicates_no_duplicates(self):
-eq = self.assertEqual
-msg = email.message_from_string(\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-Cc: [EMAIL PROTECTED]
-Content-Transfer-Encoding: yes
-
-A message
-)
-msgdata = {}
-prepare_message(self._mlist, msg, msgdata)
-eq(msgdata.get('prepped'), 1)
-eq(msg['from'], '[EMAIL PROTECTED]')
-eq(msg['to'], '[EMAIL PROTECTED]')
-eq(msg['cc'], '[EMAIL PROTECTED]')
-eq(msg['content-transfer-encoding'], 'yes')
-
-def test_munge_duplicates(self):
-eq = self.assertEqual
-msg = email.message_from_string(\
-From: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-To: [EMAIL PROTECTED]
-Cc: [EMAIL PROTECTED]
-Cc: [EMAIL PROTECTED]
-Cc: [EMAIL PROTECTED]
-Content-Transfer-Encoding: yes
-Content-Transfer-Encoding: no
-Content-Transfer-Encoding: maybe
-
-A message
-)
-msgdata = {}
-prepare_message(self._mlist, msg, msgdata)
-eq(msgdata.get('prepped'), 1)

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-06-28 Thread noreply

revno: 983
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-06-28 12:20:50 -0700
message:
  Cleaned up a couple of style issues.  No actual code changes.
modified:
  bin/check_perms

=== modified file 'bin/check_perms'
--- a/bin/check_perms   2007-06-28 17:26:13 +
+++ b/bin/check_perms   2007-06-28 19:20:50 +
@@ -135,12 +135,13 @@
 # 'group' permissions are checked here.  Their 'other' permissions
 # aren't checked.
 private = mm_cfg.PRIVATE_ARCHIVE_FILE_DIR
-if path == private or \
-  (os.path.commonprefix((path, private)) == private
-   and os.path.split(path)[1] == 'database'):
+if path == private or (
+os.path.commonprefix((path, private)) == private
+and os.path.split(path)[1] == 'database'):
+# then...
 targetperms = PRIVATEPERMS
-elif os.path.commonprefix((path, mm_cfg.QUEUE_DIR)) \
-  == mm_cfg.QUEUE_DIR:
+elif (os.path.commonprefix((path, mm_cfg.QUEUE_DIR))
+  == mm_cfg.QUEUE_DIR):
 targetperms = QFILEPERMS
 else:
 targetperms = DIRPERMS



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-06-28 Thread noreply

revno: 6516
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Thu 2007-06-28 12:23:25 -0700
message:
  Cleaned up a couple of style issues.  No actual code changes.
modified:
  Mailman/bin/check_perms.py

=== modified file 'Mailman/bin/check_perms.py'
--- a/Mailman/bin/check_perms.py2007-06-28 17:23:27 +
+++ b/Mailman/bin/check_perms.py2007-06-28 19:23:25 +
@@ -110,12 +110,13 @@
 # 'group' permissions are checked here.  Their 'other' permissions
 # aren't checked.
 private = config.PRIVATE_ARCHIVE_FILE_DIR
-if path == private or \
-  (os.path.commonprefix((path, private)) == private
-   and os.path.split(path)[1] == 'database'):
+if path == private or (
+os.path.commonprefix((path, private)) == private
+and os.path.split(path)[1] == 'database'):
+# then...
 targetperms = PRIVATEPERMS
-elif os.path.commonprefix((path, config.QUEUE_DIR)) \
-  == config.QUEUE_DIR:
+elif (os.path.commonprefix((path, config.QUEUE_DIR))
+  == config.QUEUE_DIR):
 targetperms = QFILEPERMS
 else:
 targetperms = DIRPERMS
@@ -402,7 +403,7 @@
 else:
 print _('Problems found:'), STATE.ERRORS
 print _('Re-run as $MAILMAN_USER (or root) with -f flag to fix')
-
+
 
 if __name__ == '__main__':
 main()



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-06-29 Thread noreply

revno: 984
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-06-29 14:24:32 -0700
message:
  There is a bug in email 2.5.8 and possibly others, but not in 4.0.1 or
  4.0.2 that causes email.Utils.getaddresses() to return a spurious (name,
  address) tuple if the supplied argument is multi-line.  The actual bug is
  in email.Utils.parseaddr(), but the manifestation in Message.py is in
  the use of getaddresses() in get_sender() and get_senders().
  This fix works around the bug by passing the header field values through
  Mailman.Utils.oneline().
modified:
  Mailman/Message.py

=== modified file 'Mailman/Message.py'
--- a/Mailman/Message.py2006-03-06 18:21:52 +
+++ b/Mailman/Message.py2007-06-29 21:24:32 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
+# 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
@@ -127,6 +127,10 @@
 fieldval = self[h]
 if not fieldval:
 continue
+# Work around bug in email 2.5.8 (and ?) involving getaddresses()
+# from multi-line header values.  Note that cset='us-ascii' is OK
+# since the address itself can't be RFC 2047 encoded.
+fieldval = Utils.oneline(fieldval, 'us-ascii')
 addrs = email.Utils.getaddresses([fieldval])
 try:
 realname, address = addrs[0]
@@ -180,6 +184,10 @@
 else:
 fieldvals = self.get_all(h)
 if fieldvals:
+# See comment above in get_sender() regarding
+# getaddresses() and multi-line headers
+fieldvals = [Utils.oneline(fv, 'us-ascii')
+ for fv in fieldvals]
 pairs.extend(email.Utils.getaddresses(fieldvals))
 authors = []
 for pair in pairs:



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-01 Thread noreply

revno: 6517
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-07-01 11:51:09 -0400
message:
  Support for case-preserving addresses.  When an Address is given an email
  address that is not lower cased, the original, case-preserved version is store
  on the '_original' attribute.  The lower-cased version is always used as the
  key and thus always stored on the 'address' attribute.  The IAddress interface
  is given a new 'original_address' property which returns the case-preserved
  version.
  
  Address's __str__() and __repr__() are similarly modified.  The former always
  includes the case-preserved address; the latter does too, but now also
  includes the lower-cased 'key' email address (along with the object's id).
  
  Searching for an address always does so on the lower-cased version.
  
  Test suite is updated as necessary.  Also, I'm adding the
  REPORT_ONLY_FIRST_FAILURE doctest flag so that it's easier to debug doctest
  failures without having pages of problems to scroll through.
modified:
  Mailman/database/model/address.py
  Mailman/database/usermanager.py
  Mailman/docs/addresses.txt
  Mailman/docs/users.txt
  Mailman/interfaces/address.py
  Mailman/testing/test_documentation.py

=== modified file 'Mailman/database/model/address.py'
--- a/Mailman/database/model/address.py 2007-06-16 02:37:33 +
+++ b/Mailman/database/model/address.py 2007-07-01 15:51:09 +
@@ -31,6 +31,7 @@
 implements(IAddress)
 
 has_field('address',Unicode)
+has_field('_original',  Unicode)
 has_field('real_name',  Unicode)
 has_field('verified',   Boolean)
 has_field('registered_on',  DateTime)
@@ -41,12 +42,26 @@
 # Options
 using_options(shortnames=True)
 
+def __init__(self, address, real_name):
+super(Address, self).__init__()
+lower_case = address.lower()
+self.address = lower_case
+self.real_name = real_name
+self._original = (None if lower_case == address else address)
+
 def __str__(self):
-return formataddr((self.real_name, self.address))
+addr = (self.address if self._original is None else self._original)
+return formataddr((self.real_name, addr))
 
 def __repr__(self):
-return 'Address: %s [%s]' % (
-str(self), ('verified' if self.verified else 'not verified'))
+verified = ('verified' if self.verified else 'not verified')
+address_str = str(self)
+if self._original is None:
+return 'Address: %s [%s] at %#x' % (
+address_str, verified, id(self))
+else:
+return 'Address: %s [%s] key: %s at %#x' % (
+address_str, verified, self.address, id(self))
 
 def subscribe(self, mlist, role):
 from Mailman.database.model import Member
@@ -57,3 +72,7 @@
 address=self)
 member.preferences = Preferences()
 return member
+
+@property
+def original_address(self):
+return (self.address if self._original is None else self._original)

=== modified file 'Mailman/database/usermanager.py'
--- a/Mailman/database/usermanager.py   2007-06-16 02:37:33 +
+++ b/Mailman/database/usermanager.py   2007-07-01 15:51:09 +
@@ -39,7 +39,7 @@
 user = User()
 user.real_name = (real_name if real_name is not None else '')
 if address:
-addrobj = Address(address=address, real_name=user.real_name)
+addrobj = Address(address, user.real_name)
 addrobj.preferences = Preferences()
 user.link(addrobj)
 user.preferences = Preferences()
@@ -54,16 +54,16 @@
 yield user
 
 def get_user(self, address):
-found = Address.get_by(address=address)
+found = Address.get_by(address=address.lower())
 return found and found.user
 
 def create_address(self, address, real_name=None):
-found = Address.get_by(address=address)
+found = Address.get_by(address=address.lower())
 if found:
-raise Errors.ExistingAddressError(address)
+raise Errors.ExistingAddressError(found.original_address)
 if real_name is None:
 real_name = ''
-address = Address(address=address, real_name=real_name)
+address = Address(address, real_name)
 address.preferences = Preferences()
 return address
 
@@ -75,7 +75,7 @@
 address.delete()
 
 def get_address(self, address):
-return Address.get_by(address=address)
+return Address.get_by(address=address.lower())
 
 @property
 def addresses(self):

=== modified file 'Mailman/docs/addresses.txt'
--- a/Mailman/docs/addresses.txt2007-06-22 21:15:03 +
+++ b/Mailman/docs/addresses.txt2007-07-01 15:51:09 +
@@ -41,6 +41,14 @@
  sorted(address.real_name for address in mgr.addresses)
   

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-01 Thread noreply

revno: 6518
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-07-01 21:49:34 -0400
message:
  Add support for code coverage with 'testall --coverage'.  However, I'm not
  convinced this is totally accurate as a full test run shows almost no coverage
  in the Mailman.database.model modules even though I /know/ they're getting
  executed.
  
  I'll need to figure this out, but eventually we'll convert fully to setuptools
  and then we'll use the nosetests to do testing and coverage.
added:
  misc/coverage.py
modified:
  Mailman/bin/testall.py
  misc/Makefile.in

=== added file 'misc/coverage.py'
--- a/misc/coverage.py  1970-01-01 00:00:00 +
+++ b/misc/coverage.py  2007-07-02 01:49:34 +
@@ -0,0 +1,952 @@
+#!/usr/bin/python
+#
+# Perforce Defect Tracking Integration Project
+#  http://www.ravenbrook.com/project/p4dti/
+#
+#   COVERAGE.PY -- COVERAGE TESTING
+#
+# Gareth Rees, Ravenbrook Limited, 2001-12-04
+# Ned Batchelder, 2004-12-12
+# http://nedbatchelder.com/code/modules/coverage.html
+#
+#
+# 1. INTRODUCTION
+#
+# This module provides coverage testing for Python code.
+#
+# The intended readership is all Python developers.
+#
+# This document is not confidential.
+#
+# See [GDR 2001-12-04a] for the command-line interface, programmatic
+# interface and limitations.  See [GDR 2001-12-04b] for requirements and
+# design.
+
+rUsage:
+
+coverage.py -x [-p] MODULE.py [ARG1 ARG2 ...]
+Execute module, passing the given command-line arguments, collecting
+coverage data. With the -p option, write to a temporary file containing
+the machine name and process ID.
+
+coverage.py -e
+Erase collected coverage data.
+
+coverage.py -c
+Collect data from multiple coverage files (as created by -p option above)
+and store it into a single file representing the union of the coverage.
+
+coverage.py -r [-m] [-o dir1,dir2,...] FILE1 FILE2 ...
+Report on the statement coverage for the given files.  With the -m
+option, show line numbers of the statements that weren't executed.
+
+coverage.py -a [-d dir] [-o dir1,dir2,...] FILE1 FILE2 ...
+Make annotated copies of the given files, marking statements that
+are executed with  and statements that are missed with !.  With
+the -d option, make the copies in that directory.  Without the -d
+option, make each copy in the same directory as the original.
+
+-o dir,dir2,...
+  Omit reporting or annotating files when their filename path starts with
+  a directory listed in the omit list.
+  e.g. python coverage.py -i -r -o c:\python23,lib\enthought\traits
+
+Coverage data is saved in the file .coverage by default.  Set the
+COVERAGE_FILE environment variable to save it somewhere else.
+
+__version__ = 2.6.20060823# see detailed history at the end of this file.
+
+import compiler
+import compiler.visitor
+import os
+import re
+import string
+import sys
+import threading
+import types
+from socket import gethostname
+
+# 2. IMPLEMENTATION
+#
+# This uses the singleton pattern.
+#
+# The word morf means a module object (from which the source file can
+# be deduced by suitable manipulation of the __file__ attribute) or a
+# filename.
+#
+# When we generate a coverage report we have to canonicalize every
+# filename in the coverage dictionary just in case it refers to the
+# module we are reporting on.  It seems a shame to throw away this
+# information so the data in the coverage dictionary is transferred to
+# the 'cexecuted' dictionary under the canonical filenames.
+#
+# The coverage dictionary is called c and the trace function t.  The
+# reason for these short names is that Python looks up variables by name
+# at runtime and so execution time depends on the length of variables!
+# In the bottleneck of this application it's appropriate to abbreviate
+# names to increase speed.
+
+class StatementFindingAstVisitor(compiler.visitor.ASTVisitor):
+def __init__(self, statements, excluded, suite_spots):
+compiler.visitor.ASTVisitor.__init__(self)
+self.statements = statements
+self.excluded = excluded
+self.suite_spots = suite_spots
+self.excluding_suite = 0
+
+def doRecursive(self, node):
+self.recordNodeLine(node)
+for n in node.getChildNodes():
+self.dispatch(n)
+
+visitStmt = visitModule = doRecursive
+
+def doCode(self, node):
+if hasattr(node, 'decorators') and node.decorators:
+self.dispatch(node.decorators)
+self.recordAndDispatch(node.code)
+else:
+self.doSuite(node, node.code)
+
+visitFunction = visitClass = doCode
+
+def getFirstLine(self, node):
+# Find the first line in the tree node.
+lineno = node.lineno
+for n in node.getChildNodes():
+f = 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-01 Thread noreply

revno: 6519
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-07-01 23:31:21 -0400
message:
  Convert failing test_message.py to doctests bounces.txt and message.txt, which
  of course now succeed.
  
  Rename Bouncer.py's BounceMessage() method to bounce_message() and remove the
  'msgdata' parameter, which wasn't being used.  Change the RejectNotice
  exception class to expose .notice directly, as there's no reason for this to
  be an accessor or property.
  
  Move the coverage.py installation to the install-packages target instead of
  the install-other target, so that it only gets installed once the pythonlib
  directory is created.
removed:
  Mailman/testing/test_message.py
added:
  Mailman/docs/bounces.txt
  Mailman/docs/message.txt
modified:
  Mailman/Bouncer.py
  Mailman/Errors.py
  Mailman/Queue/IncomingRunner.py
  misc/Makefile.in

=== removed file 'Mailman/testing/test_message.py'
--- a/Mailman/testing/test_message.py   2007-01-19 04:38:06 +
+++ b/Mailman/testing/test_message.py   1970-01-01 00:00:00 +
@@ -1,98 +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.
-
-Unit tests for the various Message class methods.
-
-import email
-import unittest
-
-from Mailman import Errors
-from Mailman import Message
-from Mailman import Version
-from Mailman.testing.emailbase import EmailBase
-
-
-
-class TestSentMessage(EmailBase):
-def test_user_notification(self):
-eq = self.assertEqual
-unless = self.failUnless
-msg = Message.UserNotification(
-'[EMAIL PROTECTED]',
-'[EMAIL PROTECTED]',
-'Your Test List',
-'About your test list')
-msg.send(self._mlist)
-qmsg = email.message_from_string(self._readmsg())
-eq(qmsg['subject'], 'Your Test List')
-eq(qmsg['from'], '[EMAIL PROTECTED]')
-eq(qmsg['to'], '[EMAIL PROTECTED]')
-# The Message-ID: header has some time-variant information
-msgid = qmsg['message-id']
-unless(msgid.startswith('mailman.'))
-unless(msgid.endswith('[EMAIL PROTECTED]'))
-eq(qmsg['sender'], '[EMAIL PROTECTED]')
-eq(qmsg['errors-to'], '[EMAIL PROTECTED]')
-eq(qmsg['x-beenthere'], '[EMAIL PROTECTED]')
-eq(qmsg['x-mailman-version'], Version.VERSION)
-eq(qmsg['precedence'], 'bulk')
-# UserNotifications have reduced_list_headers so it won't have
-# List-Help, List-Subscribe, or List-Unsubscribe.  XXX Why would that
-# possibly be?
-eq(qmsg['list-help'],
-   'mailto:[EMAIL PROTECTED]')
-eq(qmsg['list-subscribe'], \
-http://www.example.com/mailman/listinfo/[EMAIL PROTECTED], 
-\tmailto:[EMAIL PROTECTED])
-eq(qmsg['list-id'], '_xtest.example.com')
-eq(qmsg['list-unsubscribe'], \
-http://www.example.com/mailman/listinfo/[EMAIL PROTECTED], 
-\tmailto:[EMAIL PROTECTED])
-eq(qmsg.get_payload(), 'About your test list')
-
-def test_bounce_message(self):
-eq = self.assertEqual
-unless = self.failUnless
-msg = email.message_from_string(\
-To: [EMAIL PROTECTED]
-From: [EMAIL PROTECTED]
-Subject: and another thing
-
-yadda yadda yadda
-, Message.Message)
-self._mlist.BounceMessage(msg, {})
-qmsg = email.message_from_string(self._readmsg())
-unless(qmsg.is_multipart())
-eq(len(qmsg.get_payload()), 2)
-# The first payload is the details of the bounce action, and the
-# second message is the message/rfc822 attachment of the original
-# message.
-msg1 = qmsg.get_payload(0)
-eq(msg1.get_content_type(), 'text/plain')
-eq(msg1.get_payload(), '[No bounce details are available]')
-msg2 = qmsg.get_payload(1)
-eq(msg2.get_content_type(), 'message/rfc822')
-unless(msg2.is_multipart())
-msg3 = msg2.get_payload(0)
-eq(msg3.get_payload(), 'yadda yadda yadda\n')
-
-
-
-def test_suite():
-suite = unittest.TestSuite()
-suite.addTest(unittest.makeSuite(TestSentMessage))
-return suite

=== added file 'Mailman/docs/bounces.txt'
--- a/Mailman/docs/bounces.txt  1970-01-01 00:00:00 +

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-02 Thread noreply

revno: 6521
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Tue 2007-07-03 01:09:53 -0400
message:
  Convert TestHold to a doctest and update code as necessary.  No general
  modernization of Hold.py was performed.
added:
  Mailman/docs/hold.txt
modified:
  Mailman/Handlers/Hold.py
  Mailman/ListAdmin.py
  Mailman/MailList.py
  Mailman/database/model/mailinglist.py
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/hold.txt'
--- a/Mailman/docs/hold.txt 1970-01-01 00:00:00 +
+++ b/Mailman/docs/hold.txt 2007-07-03 05:09:53 +
@@ -0,0 +1,373 @@
+Holding messages
+
+
+One of the most important functions of Mailman is to moderate messages by
+holding some for approval before they will post to the mailing list.  Messages
+are held when they meet any of a number of criteria.
+
+ import os
+ import errno
+ from Mailman.Handlers.Hold import process
+ from Mailman.Queue.Switchboard import Switchboard
+ from Mailman.configuration import config
+ from Mailman.database import flush
+ mlist = config.list_manager.create('[EMAIL PROTECTED]')
+ mlist.preferred_language = 'en'
+ mlist.real_name = '_XTest'
+ # XXX This will almost certainly change once we've worked out the web
+ # space layout for mailing lists now.
+ mlist._data.web_page_url = 'http://lists.example.com/'
+ flush()
+
+XXX The Hold handler requires that the mailing list be locked because it
+touches the pending database.  Eventually the pending database should be moved
+into the real database so that the lock is no longer necessary.
+
+ mlist.Lock()
+
+Here's a helper function used when we don't care about what's in the virgin
+queue or in the pending database.
+
+ switchboard = Switchboard(config.VIRGINQUEUE_DIR)
+ def clear():
+... for filebase in switchboard.files:
+... msg, msgdata = switchboard.dequeue(filebase)
+... switchboard.finish(filebase)
+... for holdfile in os.listdir(config.DATA_DIR):
+... if holdfile.startswith('heldmsg-'):
+... os.unlink(os.path.join(config.DATA_DIR, holdfile))
+... try:
+... os.unlink(os.path.join(config.DATA_DIR, 'pending.db'))
+... except OSError, e:
+... if e.errno  errno.ENOENT:
+... raise
+
+
+Short circuiting
+
+
+If the message metadata indicates that the message is pre-approved, then the
+handler returns immediately.
+
+ from email import message_from_string
+ from Mailman.Message import Message
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+...
+... An important message.
+... , Message)
+ msgdata = {'approved': True}
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+From: [EMAIL PROTECTED]
+BLANKLINE
+An important message.
+BLANKLINE
+ msgdata
+{'approved': True}
+
+
+Administrivia
+-
+
+Mailman scans parts of the message for administrivia, meaning text that looks
+like an email command.  This is to prevent people sending 'help' or
+'subscribe' message, etc. to the list members.  First, we enable the scanning
+of administrivia for the list.
+
+ mlist.administrivia = True
+ flush()
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... Subject: unsubscribe
+...
+... , Message)
+ process(mlist, msg, {})
+Traceback (most recent call last):
+...
+Administrivia
+ clear()
+
+
+Maximum number of recipients
+
+
+Mailman will hold messages that have more than a specified number of explicit
+recipients.
+
+ mlist.max_num_recipients = 5
+ flush()
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... To: [EMAIL PROTECTED], [EMAIL PROTECTED]
+... Cc: [EMAIL PROTECTED]
+... Cc: [EMAIL PROTECTED] (Dan Person)
+... To: Elly Q. Person [EMAIL PROTECTED]
+...
+... Hey folks!
+... , Message)
+ process(mlist, msg, {})
+Traceback (most recent call last):
+...
+TooManyRecipients
+ clear()
+
+
+Implicit destination
+
+
+Mailman will hold messages that have implicit destination, meaning that the
+mailing list's posting address isn't included in the explicit recipients.
+
+ mlist.require_explicit_destination = True
+ mlist.acceptable_aliases = ''
+ flush()
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... Subject: An implicit message
+...
+... , Message)
+ process(mlist, msg, {})
+Traceback (most recent call last):
+...
+ImplicitDestination
+ clear()
+
+A message gated from NNTP will obviously have an implicit destination.  Such
+gated messages will not be held for implicit destination because it's assumed
+that Mailman pulled it from the appropriate news group.
+
+ msgdata = 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-03 Thread noreply

revno: 6522
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-07-04 00:16:48 -0400
message:
  Convert the TestTagger to a doctest.  No other cleaning up of the handler
  module is done.
added:
  Mailman/docs/tagger.txt
modified:
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/tagger.txt'
--- a/Mailman/docs/tagger.txt   1970-01-01 00:00:00 +
+++ b/Mailman/docs/tagger.txt   2007-07-04 04:16:48 +
@@ -0,0 +1,244 @@
+Message tagger
+==
+
+Mailman has a topics system which works like this: a mailing list
+administrator sets up one or more topics, which is essentially a named regular
+expression.  The topic name can be any arbitrary string, and the name serves
+double duty as the 'topic tag'.  Each message that flows the mailing list has
+its Subject: and Keywords: headers compared against these regular
+expressions.  The message then gets tagged with the topic names of each hit.
+
+ from Mailman.Handlers.Tagger import process
+ from Mailman.Message import Message
+ from Mailman.Queue.Switchboard import Switchboard
+ from Mailman.configuration import config
+ from Mailman.database import flush
+ from email import message_from_string
+ mlist = config.list_manager.create('[EMAIL PROTECTED]')
+
+Topics must be enabled for Mailman to do any topic matching, even if topics
+are defined.
+
+ mlist.topics = [('bar fight', '.*bar.*', 'catch any bars', False)]
+ mlist.topics_enabled = False
+ mlist.topics_bodylines_limit = 0
+ flush()
+
+ msg = message_from_string(\
+... Subject: foobar
+... Keywords: barbaz
+...
+... , Message)
+ msgdata = {}
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+Subject: foobar
+Keywords: barbaz
+BLANKLINE
+BLANKLINE
+ msgdata
+{}
+
+However, once topics are enabled, message will be tagged.  There are two
+artifacts of tagging; an X-Topics: header is added with the topic name, and
+the message metadata gets a key with a list of matching topic names.
+
+ mlist.topics_enabled = True
+ flush()
+ msg = message_from_string(\
+... Subject: foobar
+... Keywords: barbaz
+...
+... , Message)
+ msgdata = {}
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+Subject: foobar
+Keywords: barbaz
+X-Topics: bar fight
+BLANKLINE
+BLANKLINE
+ msgdata['topichits']
+['bar fight']
+
+
+Scanning body lines
+---
+
+The tagger can also look at a certain number of body lines, but only for
+Subject: and Keyword: header-like lines.  When set to zero, no body lines are
+scanned.
+
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... Subject: nothing
+... Keywords: at all
+...
+... X-Ignore: something else
+... Subject: foobar
+... Keywords: barbaz
+... , Message)
+ msgdata = {}
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+From: [EMAIL PROTECTED]
+Subject: nothing
+Keywords: at all
+BLANKLINE
+X-Ignore: something else
+Subject: foobar
+Keywords: barbaz
+BLANKLINE
+ msgdata
+{}
+
+But let the tagger scan a few body lines and the matching headers will be
+found.
+
+ mlist.topics_bodylines_limit = 5
+ flush()
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... Subject: nothing
+... Keywords: at all
+...
+... X-Ignore: something else
+... Subject: foobar
+... Keywords: barbaz
+... , Message)
+ msgdata = {}
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+From: [EMAIL PROTECTED]
+Subject: nothing
+Keywords: at all
+X-Topics: bar fight
+BLANKLINE
+X-Ignore: something else
+Subject: foobar
+Keywords: barbaz
+BLANKLINE
+ msgdata['topichits']
+['bar fight']
+
+However, scanning stops at the first body line that doesn't look like a
+header.
+
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... Subject: nothing
+... Keywords: at all
+...
+... This is not a header
+... Subject: foobar
+... Keywords: barbaz
+... , Message)
+ msgdata = {}
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+From: [EMAIL PROTECTED]
+Subject: nothing
+Keywords: at all
+BLANKLINE
+This is not a header
+Subject: foobar
+Keywords: barbaz
+ msgdata
+{}
+
+When set to a negative number, all body lines will be scanned.
+
+ mlist.topics_bodylines_limit = -1
+ flush()
+ lots_of_headers = '\n'.join(['X-Ignore: zip'] * 100)
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+... Subject: nothing
+... Keywords: at all
+...
+... %s
+... Subject: foobar
+... Keywords: barbaz
+...  % lots_of_headers, Message)
+ msgdata = {}
+ process(mlist, msg, msgdata)
+ # 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-05 Thread noreply

revno: 6523
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Thu 2007-07-05 10:29:40 -0400
message:
  Convert the SpamDetect handler tests (what there was of them anyway) to a
  doctest, but don't otherwise clean up the handler module.
added:
  Mailman/docs/antispam.txt
modified:
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/antispam.txt'
--- a/Mailman/docs/antispam.txt 1970-01-01 00:00:00 +
+++ b/Mailman/docs/antispam.txt 2007-07-05 14:29:40 +
@@ -0,0 +1,75 @@
+Anti-spam defences
+==
+
+By design, Mailman does not have very sophisticated anti-spam measures because
+this type of filtering is done much more efficiently at the MTA level.  For
+example, if Mailman were to do spam detection, it could not reject the message
+at SMTP time.
+
+Still, Mailman does employ a small number of rather ham-handed anti-spam
+measures.
+
+ from Mailman.Handlers.SpamDetect import process
+ from Mailman.Message import Message
+ from Mailman.Queue.Switchboard import Switchboard
+ from Mailman.configuration import config
+ from Mailman.database import flush
+ from email import message_from_string
+ mlist = config.list_manager.create('[EMAIL PROTECTED]')
+ flush()
+
+
+Short circuiting
+
+
+If a message is pre-approved, this handler does nothing.
+
+ msg = message_from_string(\
+... From: [EMAIL PROTECTED]
+...
+... An important message.
+... , Message)
+ msgdata = {'approved': True}
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+From: [EMAIL PROTECTED]
+BLANKLINE
+An important message.
+BLANKLINE
+ msgdata
+{'approved': True}
+
+
+Header matching
+---
+
+There is a global configuration variable that can be set to a list of header
+matches.  Each item in that list is a 2-tuple of the header to match and a
+regular expression.  For example, if we wanted to block all message that come
+from 'aperson' regardless of the domain, we'd do something like the following
+in our mailman.cfg file:
+
+ config.KNOWN_SPAMMERS.append(('from', 'aperson'))
+
+Now if the same message is posted to the mailing list, and that message is not
+pre-approved.  The handler will throw an exception that signals the message is
+spam.
+
+ msgdata = {}
+ process(mlist, msg, msgdata)
+Traceback (most recent call last):
+...
+SpamDetected
+ print msg.as_string()
+From: [EMAIL PROTECTED]
+BLANKLINE
+An important message.
+BLANKLINE
+ msgdata
+{}
+
+
+Header filter rules
+---
+
+XXX Need tests.

=== modified file 'Mailman/testing/test_handlers.py'
--- a/Mailman/testing/test_handlers.py  2007-07-04 04:16:48 +
+++ b/Mailman/testing/test_handlers.py  2007-07-05 14:29:40 +
@@ -43,7 +43,6 @@
 from Mailman.Handlers import Moderate
 from Mailman.Handlers import Scrubber
 # Don't test handlers such as SMTPDirect and Sendmail here
-from Mailman.Handlers import SpamDetect
 from Mailman.Handlers import ToArchive
 from Mailman.Handlers import ToDigest
 from Mailman.Handlers import ToOutgoing
@@ -306,11 +305,6 @@
 
 
 
-class TestModerate(TestBase):
-pass
-
-
-
 class TestScrubber(TestBase):
 def test_save_attachment(self):
 mlist = self._mlist
@@ -403,36 +397,6 @@
 
 
 
-class TestSpamDetect(TestBase):
-def test_short_circuit(self):
-msgdata = {'approved': 1}
-rtn = SpamDetect.process(self._mlist, None, msgdata)
-# Not really a great test, but there's little else to assert
-self.assertEqual(rtn, None)
-
-def test_spam_detect(self):
-msg1 = email.message_from_string(\
-From: [EMAIL PROTECTED]
-
-A message.
-)
-msg2 = email.message_from_string(\
-To: [EMAIL PROTECTED]
-
-A message.
-)
-spammers = config.KNOWN_SPAMMERS[:]
-try:
-config.KNOWN_SPAMMERS.append(('from', '.?person'))
-self.assertRaises(SpamDetect.SpamDetected,
-  SpamDetect.process, self._mlist, msg1, {})
-rtn = SpamDetect.process(self._mlist, msg2, {})
-self.assertEqual(rtn, None)
-finally:
-config.KNOWN_SPAMMERS = spammers
-
-
-
 class TestToArchive(TestBase):
 def setUp(self):
 TestBase.setUp(self)
@@ -694,9 +658,7 @@
 suite = unittest.TestSuite()
 suite.addTest(unittest.makeSuite(TestApprove))
 suite.addTest(unittest.makeSuite(TestMimeDel))
-suite.addTest(unittest.makeSuite(TestModerate))
 suite.addTest(unittest.makeSuite(TestScrubber))
-suite.addTest(unittest.makeSuite(TestSpamDetect))
 suite.addTest(unittest.makeSuite(TestToArchive))
 suite.addTest(unittest.makeSuite(TestToDigest))
 suite.addTest(unittest.makeSuite(TestToOutgoing))



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-08 Thread noreply

revno: 6526
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-07-08 07:47:03 -0400
message:
  Convert ToOutgoing handler to a doctest.  Minor cleanup of the handler code to
  a more modern Python style.
added:
  Mailman/docs/outgoing.txt
modified:
  Mailman/Handlers/ToOutgoing.py
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/outgoing.txt'
--- a/Mailman/docs/outgoing.txt 1970-01-01 00:00:00 +
+++ b/Mailman/docs/outgoing.txt 2007-07-08 11:47:03 +
@@ -0,0 +1,150 @@
+The outgoing handler
+
+
+Mailman's outgoing queue is used as the wrapper around SMTP delivery to the
+upstream mail server.  The ToOutgoing handler does little more than drop the
+message into the outgoing queue, after calculating whether the message should
+be VERP'd or not.  VERP means Variable Envelope Return Path; we're using that
+term somewhat incorrectly, but within the spirit of the standard, which
+basically describes how to encode the recipient's address in the originator
+headers for unambigous bounce processing.
+
+ from Mailman.Handlers.ToOutgoing import process
+ from Mailman.Message import Message
+ from Mailman.Queue.Switchboard import Switchboard
+ from Mailman.configuration import config
+ from Mailman.database import flush
+ from email import message_from_string
+ mlist = config.list_manager.create('[EMAIL PROTECTED]')
+ flush()
+ switchboard = Switchboard(config.OUTQUEUE_DIR)
+
+ def queue_size():
+... size = len(switchboard.files)
+... for filebase in switchboard.files:
+... msg, msgdata = switchboard.dequeue(filebase)
+... switchboard.finish(filebase)
+... return size
+
+Craft a message destined for the outgoing queue.  Include some random metadata
+as if this message had passed through some other handlers.
+
+ msg = message_from_string(\
+... Subject: Here is a message
+...
+... Something of great import.
+... , Message)
+
+When certain conditions are met, the message will be VERP'd.  For example, if
+the message metadata already has a VERP key, this message will be VERP'd.
+
+ msgdata = dict(foo=1, bar=2, verp=True)
+ process(mlist, msg, msgdata)
+ print msg.as_string()
+Subject: Here is a message
+BLANKLINE
+Something of great import.
+ msgdata['verp']
+True
+
+While the queued message will not be changed, the queued metadata will have an
+additional key set: the mailing list name.
+
+ filebase = switchboard.files[0]
+ qmsg, qmsgdata = switchboard.dequeue(filebase)
+ switchboard.finish(filebase)
+ print qmsg.as_string()
+Subject: Here is a message
+BLANKLINE
+Something of great import.
+ sorted(qmsgdata.items())
+[('_parsemsg', False),
+ ('bar', 2), ('foo', 1),
+ ('listname', '[EMAIL PROTECTED]'),
+ ('received_time', ...),
+ ('verp', True), ('version', 3)]
+ queue_size()
+0
+
+If the list is set to personalize deliveries, and the global configuration
+option to VERP personalized deliveries is set, then the message will be
+VERP'd.
+
+ mlist.personalize = True
+ flush()
+ config.VERP_PERSONALIZED_DELIVERIES = True
+ msgdata = dict(foo=1, bar=2)
+ process(mlist, msg, msgdata)
+ msgdata['verp']
+True
+ queue_size()
+1
+
+However, if the global configuration variable prohibits VERP'ing, even
+personalized lists will not VERP.
+
+ config.VERP_PERSONALIZED_DELIVERIES = False
+ msgdata = dict(foo=1, bar=2)
+ process(mlist, msg, msgdata)
+ print msgdata.get('verp')
+None
+ queue_size()
+1
+
+If the list is not personalized, then the message may still be VERP'd based on
+the global configuration variable VERP_DELIVERY_INTERVAL.  This variable tells
+Mailman how often to VERP even non-personalized mailing lists.  It can be set
+to zero, which means non-personalized messages will never be VERP'd.
+
+ mlist.personalize = False
+ flush()
+ config.VERP_DELIVERY_INTERVAL = 0
+ msgdata = dict(foo=1, bar=2)
+ process(mlist, msg, msgdata)
+ print msgdata.get('verp')
+None
+ queue_size()
+1
+
+If the interval is set to 1, then every message will be VERP'd.
+
+ config.VERP_DELIVERY_INTERVAL = 1
+ for i in range(10):
+... msgdata = dict(foo=1, bar=2)
+... process(mlist, msg, msgdata)
+... print i, msgdata['verp']
+0 True
+1 True
+2 True
+3 True
+4 True
+5 True
+6 True
+7 True
+8 True
+9 True
+ queue_size()
+10
+
+If the interval is set to some other number, then one out of that many posts
+will be VERP'd.
+
+ config.VERP_DELIVERY_INTERVAL = 3
+ for i in range(10):
+... mlist.post_id = i
+... flush()
+... msgdata = dict(foo=1, bar=2)
+... process(mlist, msg, msgdata)
+... print i, 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-11 Thread noreply

revno: 6528
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-07-11 07:06:34 -0400
message:
  Convert ToArchive tests to doctests and do a minimal amount of handler module
  cleanup (really, not much was necessary).
added:
  Mailman/docs/archives.txt
modified:
  Mailman/Handlers/ToArchive.py
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/archives.txt'
--- a/Mailman/docs/archives.txt 1970-01-01 00:00:00 +
+++ b/Mailman/docs/archives.txt 2007-07-11 11:06:34 +
@@ -0,0 +1,141 @@
+Archives
+
+
+Updating the archives with posted messages is handled by a separate queue,
+which allows for better memory management and prevents blocking the main
+delivery processes while messages are archived.  This also allows external
+archivers to work in a separate process from the main Mailman delivery
+processes.
+
+ from Mailman.Handlers.ToArchive import process
+ from Mailman.Message import Message
+ from Mailman.Queue.Switchboard import Switchboard
+ from Mailman.configuration import config
+ from Mailman.database import flush
+ from email import message_from_string
+ mlist = config.list_manager.create('[EMAIL PROTECTED]')
+ mlist.preferred_language = 'en'
+ flush()
+ switchboard = Switchboard(config.ARCHQUEUE_DIR)
+
+A helper function.
+
+ def clear():
+... for filebase in switchboard.files:
+... msg, msgdata = switchboard.dequeue(filebase)
+... switchboard.finish(filebase)
+
+
+The purpose of the ToArchive handler is to make a simple decision as to
+whether the message should get archived and if so, to drop the message in the
+archiving queue.  Really the most important things are to determine when a
+message should /not/ get archived.
+
+For example, no digests should ever get archived.
+
+ mlist.archive = True
+ flush()
+ msg = message_from_string(\
+... Subject: A sample message
+...
+... A message of great import.
+... , Message)
+ process(mlist, msg, dict(isdigest=True))
+ switchboard.files
+[]
+
+If the mailing list is not configured to archive, then even regular deliveries
+won't be archived.
+
+ mlist.archive = False
+ flush()
+ process(mlist, msg, {})
+ switchboard.files
+[]
+
+There are two de-facto standards for a message to indicate that it does not
+want to be archived.  We've seen both in the wild so both are supported.  The
+X-No-Archive: header can be used to indicate that the message should not be
+archived.  Confusingly, this header's value is actually ignored.
+
+ mlist.archive = True
+ flush()
+ msg = message_from_string(\
+... Subject: A sample message
+... X-No-Archive: YES
+...
+... A message of great import.
+... , Message)
+ process(mlist, msg, dict(isdigest=True))
+ switchboard.files
+[]
+
+Even a 'no' value will stop the archiving of the message.
+
+ msg = message_from_string(\
+... Subject: A sample message
+... X-No-Archive: No
+...
+... A message of great import.
+... , Message)
+ process(mlist, msg, dict(isdigest=True))
+ switchboard.files
+[]
+
+Another header that's been observed is the X-Archive: header.  Here, the
+header's case folded value must be 'no' in order to prevent archiving.
+
+ msg = message_from_string(\
+... Subject: A sample message
+... X-Archive: No
+...
+... A message of great import.
+... , Message)
+ process(mlist, msg, dict(isdigest=True))
+ switchboard.files
+[]
+
+But if the value is 'yes', then the message will be archived.
+
+ msg = message_from_string(\
+... Subject: A sample message
+... X-Archive: Yes
+...
+... A message of great import.
+... , Message)
+ process(mlist, msg, {})
+ len(switchboard.files)
+1
+ filebase = switchboard.files[0]
+ qmsg, qdata = switchboard.dequeue(filebase)
+ switchboard.finish(filebase)
+ print qmsg.as_string()
+Subject: A sample message
+X-Archive: Yes
+BLANKLINE
+A message of great import.
+BLANKLINE
+ sorted(qdata.items())
+[('_parsemsg', False), ('received_time', ...), ('version', 3)]
+
+Without either archiving header, and all other things being the same, the
+message will get archived.
+
+ msg = message_from_string(\
+... Subject: A sample message
+...
+... A message of great import.
+... , Message)
+ process(mlist, msg, {})
+ len(switchboard.files)
+1
+ filebase = switchboard.files[0]
+ qmsg, qdata = switchboard.dequeue(filebase)
+ switchboard.finish(filebase)
+ print qmsg.as_string()
+Subject: A sample message
+BLANKLINE
+A message of great import.
+BLANKLINE
+ sorted(qdata.items())
+[('_parsemsg', False), ('received_time', ...), ('version', 3)]

=== modified file 'Mailman/Handlers/ToArchive.py'
--- 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-11 Thread noreply

revno: 6529
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Thu 2007-07-12 00:12:45 -0400
message:
  Convert the Scrubber test to a doctest, and fix Scrubber.py, but otherwise
  don't modernize the Scrubber handler.
  
  The is the last of the handler test conversions until we figure out what to do
  with the Approve handler.  In a unified user database the semantics of this
  are unclear.
added:
  Mailman/docs/scrubber.txt
modified:
  Mailman/Handlers/Scrubber.py
  Mailman/testing/test_handlers.py

=== added file 'Mailman/docs/scrubber.txt'
--- a/Mailman/docs/scrubber.txt 1970-01-01 00:00:00 +
+++ b/Mailman/docs/scrubber.txt 2007-07-12 04:12:45 +
@@ -0,0 +1,217 @@
+The scrubber
+
+
+The scrubber is an integral part of Mailman, both in the normal delivery of
+messages and in components such as the archiver.  Its primary purpose is to
+scrub attachments from messages so that binary goop doesn't end up in an
+archive message.
+
+ from Mailman.Handlers.Scrubber import process, save_attachment
+ from Mailman.Message import Message
+ from Mailman.configuration import config
+ from Mailman.database import flush
+ from email import message_from_string
+ mlist = config.list_manager.create('[EMAIL PROTECTED]')
+ mlist.preferred_language = 'en'
+ flush()
+
+Helper functions for getting the attachment data.
+
+ import os, re
+ def read_attachment(filename, remove=True):
+... path = os.path.join(mlist.archive_dir(), filename)
+... fp = open(path)
+... try:
+... data = fp.read()
+... finally:
+... fp.close()
+... if remove:
+... os.unlink(path)
+... return data
+
+ from urlparse import urlparse
+ def read_url_from_message(msg):
+... url = None
+... for line in msg.get_payload().splitlines():
+... mo = re.match('URL: (?Purl[^]+)', line)
+... if mo:
+... url = mo.group('url')
+... break
+... path = '/'.join(urlparse(url).path.split('/')[3:])
+... return read_attachment(path)
+
+
+Saving attachments
+--
+
+The Scrubber handler exposes a function called save_attachments() which can be
+used to strip various types of attachments and store them in the archive
+directory.  This is a public interface used by components outside the normal
+processing pipeline.
+
+Site administrators can decide whether the scrubber should use the attachment
+filename suggested in the message's Content-Disposition: header or not.  If
+enabled, the filename will be used when this header attribute is present (yes,
+this is an unfortunate double negative).
+
+ config.SCRUBBER_DONT_USE_ATTACHMENT_FILENAME = False
+ msg = message_from_string(\
+... Content-Type: image/gif; name=xtest.gif
+... Content-Transfer-Encoding: base64
+... Content-Disposition: attachment; filename=xtest.gif
+... 
+... R0lGODdhAQABAIAAACwAAQABAAACAQUAOw==
+... , Message)
+ save_attachment(mlist, msg, '')
+'http://www.example.com/pipermail/[EMAIL PROTECTED]//xtest.gif'
+ data = read_attachment('xtest.gif')
+ data[:6]
+'GIF87a'
+ len(data)
+34
+
+Saving the attachment does not alter the original message.
+
+ print msg.as_string()
+Content-Type: image/gif; name=xtest.gif
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename=xtest.gif
+BLANKLINE
+R0lGODdhAQABAIAAACwAAQABAAACAQUAOw==
+
+The site administrator can also configure Mailman to ignore the
+Content-Disposition: filename.  This is the default for reasons described in
+the Defaults.py.in file.
+
+ config.SCRUBBER_DONT_USE_ATTACHMENT_FILENAME = True
+ msg = message_from_string(\
+... Content-Type: image/gif; name=xtest.gif
+... Content-Transfer-Encoding: base64
+... Content-Disposition: attachment; filename=xtest.gif
+... 
+... R0lGODdhAQABAIAAACwAAQABAAACAQUAOw==
+... , Message)
+ save_attachment(mlist, msg, '')
+'http://www.example.com/pipermail/[EMAIL PROTECTED]/.../attachment.gif'
+ data = read_attachment('xtest.gif')
+Traceback (most recent call last):
+IOError: [Errno ...] No such file or directory:
+'.../archives/private/[EMAIL PROTECTED]/xtest.gif'
+ data = read_attachment('attachment.gif')
+ data[:6]
+'GIF87a'
+ len(data)
+34
+
+
+Scrubbing image attachments
+---
+
+When scrubbing image attachments, the original message is modified to include
+a reference to the attachment file as available through the on-line archive.
+
+ msg = message_from_string(\
+... MIME-Version: 1.0
+... Content-Type: multipart/mixed; boundary=BOUNDARY
+...
+... --BOUNDARY
+... Content-type: text/plain; charset=us-ascii
+... 
+... This 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-11 Thread noreply
 __ne__(self, other):
-return not self.__eq__(other)
-
-@property
-def name(self):
-return self._name
-
-def add(self, member):
-self._members.add(member)
-
-def remove(self, member):
-self._members.remove(member)
-
-@property
-def members(self):
-for member in self._members:
-yield member
-
-
-
-class ListManager(object):
-implements(IListManager)
-
-def __init__(self):
-self._mlists = {}
-
-def add(self, mlist):
-self._mlists[mlist.fqdn_listname] = mlist
-
-def remove(self, mlist):
-del self._mlists[mlist.fqdn_listname]
-
-@property
-def mailing_lists(self):
-return self._mlists.itervalues()
-
-@property
-def names(self):
-return self._mlists.iterkeys()
-
-def get(self, fqdn_listname):
-return self._mlists.get(fqdn_listname)
-
-
-
-class MailingList(object):
-implements(IMailingListIdentity,
-   IMailingListAddresses,
-   IMailingListURLs,
-   IMailingListRosters,
-   IMailingListStatistics,
-   )
-
-def __init__(self, list_name, host_name, web_host):
-self._listname  = list_name
-self._hostname  = hostname
-self._webhost   = web_host
-self._fqdn_listname = Utils.fqdn_listname(list_name, host_name)
-# Rosters
-self._owners= set(Roster(self.owner_address))
-self._moderators= set(Roster(self._listname + '-moderators@' +
- self._hostname))
-self._members   = set(Roster(self.posting_address))
-# Statistics
-self._created_on= datetime.datetime.now()
-self._last_posting  = None
-self._post_number   = 0
-self._last_digest   = None
-
-# IMailingListIdentity
-
-@property
-def list_name(self):
-return self._listname
-
-@property
-def host_name(self):
-return self._hostname
-
-@property
-def fqdn_listname(self):
-return self._fqdn_listname
-
-# IMailingListAddresses
-
-@property
-def posting_address(self):
-return self._fqdn_listname
-
-@property
-def noreply_address(self):
-return self._listname + '-noreply@' + self._hostname
-
-@property
-def owner_address(self):
-return self._listname + '-owner@' + self._hostname
-
-@property
-def request_address(self):
-return self._listname + '-request@' + self._hostname
-
-@property
-def bounces_address(self):
-return self._listname + '-bounces@' + self._hostname
-
-@property
-def confirm_address(self):
-return self._listname + '-confirm@' + self._hostname
-
-@property
-def join_address(self):
-return self._listname + '-join@' + self._hostname
-
-@property
-def leave_address(self):
-return self._listname + '-leave@' + self._hostname
-
-@property
-def subscribe_address(self):
-return self._listname + '-subscribe@' + self._hostname
-
-@property
-def unsubscribe_address(self):
-return self._listname + '-unsubscribe@' + self._hostname
-
-# IMailingListURLs
-
-protocol = 'http'
-
-@property
-def web_host(self):
-return self._webhost
-
-def script_url(self, target, context=None):
-if context is None:
-return urlparse.urlunsplit((self.protocol, self.web_host, target,
-# no extra query or fragment
-'', ''))
-return urlparse.urljoin(context.location, target)
-
-# IMailingListRosters
-
-@property
-def owner_rosters(self):
-return iter(self._owners)
-
-@property
-def moderator_rosters(self):
-return iter(self._moderators)
-
-@property
-def member_rosters(self):
-return iter(self._members)
-
-def add_owner_roster(self, roster):
-self._owners.add(roster)
-
-def add_moderator_roster(self, roster):
-self._moderators.add(roster)
-
-def add_member_roster(self, roster):
-self._members.add(roster)
-
-def remove_owner_roster(self, roster):
-self._owners.discard(roster)
-
-def remove_moderator_roster(self, roster):
-self._moderators.discard(roster)
-
-def remove_member_roster(self, roster):
-self._members.discard(roster)
-
-@property
-def owners(self):
-for roster in self._owners:
-for member in roster.members:
-yield member
-
-@property
-def moderators(self):
-for roster in self._moderators:
-for member in roster.members:
-yield member
-
-@property
-def administrators(self):
-for member in self.owners:
-yield member
-for member in self.moderators:
-yield member
-
-@property
-def members(self

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-07-17 Thread noreply

revno: 985
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Tue 2007-07-17 10:59:14 -0700
message:
  Detect 'who' with 1 or 2 arguments as administrivia.
modified:
  Mailman/Utils.py

=== modified file 'Mailman/Utils.py'
--- a/Mailman/Utils.py  2006-08-30 14:54:22 +
+++ b/Mailman/Utils.py  2007-07-17 17:59:14 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
+# 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
@@ -574,7 +574,7 @@
 'set': (3, 3),
 'subscribe':   (0, 3),
 'unsubscribe': (0, 1),
-'who': (0, 0),
+'who': (0, 2),
 }
 
 # Given a Message.Message object, test for administrivia (eg subscribe,



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-17 Thread noreply

revno: 6531
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Tue 2007-07-17 11:00:34 -0700
message:
  Detect 'who' with 1 or 2 arguments as administrivia.
modified:
  Mailman/Utils.py

=== modified file 'Mailman/Utils.py'
--- a/Mailman/Utils.py  2007-06-18 14:50:23 +
+++ b/Mailman/Utils.py  2007-07-17 18:00:34 +
@@ -538,7 +538,7 @@
 'set': (3, 3),
 'subscribe':   (0, 3),
 'unsubscribe': (0, 1),
-'who': (0, 0),
+'who': (0, 2),
 }
 
 # Given a Message.Message object, test for administrivia (eg subscribe,



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-21 Thread noreply

revno: 6532
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sat 2007-07-21 16:19:54 -0400
message:
  Merge the setuptools branch.  Fix a couple of test modules that are
  disabled anyway.
removed:
  Mailman/Archiver/Makefile.in
  Mailman/Bouncers/Makefile.in
  Mailman/Cgi/Makefile.in
  Mailman/Commands/Makefile.in
  Mailman/Gui/Makefile.in
  Mailman/Handlers/Makefile.in
  Mailman/MTA/Makefile.in
  Mailman/Makefile.in
  Mailman/Queue/Makefile.in
  Mailman/Queue/tests/Makefile.in
  Mailman/bin/Makefile.in
  Mailman/database/Makefile.in
  Mailman/database/model/Makefile.in
  Mailman/docs/Makefile.in
  Mailman/ext/Makefile.in
  Mailman/interfaces/Makefile.in
  Mailman/interfaces/manager.py
  Mailman/testing/Makefile.in
  Mailman/testing/base.py
  Mailman/testing/bounces/Makefile.in
  Makefile.in
  bin/Makefile.in
  bin/check_db
  bin/convert.py
  bin/mailmanctl
  bin/mmshell
  bin/qrunner
  configure
  configure.in
  cron/Makefile.in
  install-sh
  messages/Makefile.in
  misc/Elixir-0.3.0.tar.gz
  misc/Makefile.in
  misc/SQLAlchemy-0.3.3.tar.gz
  misc/munepy-1.1-py2.5.egg
  misc/pysqlite-2.3.2.tar.gz
  misc/setuptools-0.6c3.tar.gz
  misc/wsgiref-0.1.2-py2.4.egg
  misc/zope.interface-3.3.0.1.tar.gz
  mkinstalldirs
  scripts/Makefile.in
  src/
  src/Makefile.in
  src/cgi-wrapper.c
  src/common.c
  src/common.h
  src/mail-wrapper.c
  src/vsnprintf.c
  templates/Makefile.in
  tests/Makefile.in
  tests/msgs/Makefile.in
added:
  MANIFEST.in
  Mailman/bin/make_instance.py
  Mailman/data/__init__.py
  Mailman/docs/languages.txt
  Mailman/interfaces/languages.py
  Mailman/languages.py
  Mailman/messages/__init__.py
  Mailman/templates/__init__.py
  Mailman/tests/bounces/__init__.py
  ez_setup.py
  setup.py
renamed:
  Mailman/Defaults.py.in = Mailman/Defaults.py
  Mailman/testing = Mailman/tests
  bin/cleanarch = Mailman/bin/cleanarch.py
  messages = Mailman/messages
  misc = Mailman/data
  misc/mailman.cfg.sample = Mailman/data/mailman.cfg.in
  templates = Mailman/templates
modified:
  .bzrignore
  Mailman/Archiver/Archiver.py
  Mailman/Archiver/HyperArch.py
  Mailman/Cgi/admin.py
  Mailman/Cgi/confirm.py
  Mailman/Cgi/create.py
  Mailman/Cgi/listinfo.py
  Mailman/Cgi/options.py
  Mailman/Cgi/rmlist.py
  Mailman/Cgi/roster.py
  Mailman/Cgi/subscribe.py
  Mailman/Commands/cmd_confirm.py
  Mailman/Commands/cmd_help.py
  Mailman/Commands/cmd_lists.py
  Mailman/Commands/cmd_password.py
  Mailman/Commands/cmd_set.py
  Mailman/Commands/cmd_who.py
  Mailman/Deliverer.py
  Mailman/Gui/Archive.py
  Mailman/Gui/Autoresponse.py
  Mailman/Gui/Bounce.py
  Mailman/Gui/ContentFilter.py
  Mailman/Gui/Digest.py
  Mailman/Gui/General.py
  Mailman/Gui/Language.py
  Mailman/Gui/Privacy.py
  Mailman/Gui/Topics.py
  Mailman/Gui/Usenet.py
  Mailman/HTMLFormatter.py
  Mailman/MailList.py
  Mailman/Mailbox.py
  Mailman/OldStyleMemberships.py
  Mailman/Post.py
  Mailman/SafeDict.py
  Mailman/Utils.py
  Mailman/Version.py
  Mailman/bin/__init__.py
  Mailman/bin/genaliases.py
  Mailman/bin/mailmanctl.py
  Mailman/bin/newlist.py
  Mailman/bin/rmlist.py
  Mailman/bin/testall.py
  Mailman/bin/withlist.py
  Mailman/configuration.py
  Mailman/docs/acknowledge.txt
  Mailman/docs/digests.txt
  Mailman/i18n.py
  Mailman/messages/fr/LC_MESSAGES/mailman.po
  Mailman/tests/emailbase.py
  Mailman/tests/test_bounces.py
  Mailman/tests/test_handlers.py
  Mailman/tests/test_membership.py
  Mailman/tests/test_security_mgr.py
  Mailman/tests/testing.cfg.in
  Mailman/versions.py
  Mailman/Defaults.py
  Mailman/bin/cleanarch.py
  Mailman/data/mailman.cfg.in

revno: 6530.1.10
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: setup
timestamp: Sat 2007-07-21 14:52:50 -0400
message:
  Remove some obsolete command line scripts:
  
  - bin/check_dbs because there are no more pickles
  - bin/convert because in MM3 everything will use $-strings and we'll do 
the
conversion on import of the old list data
  - bin/mmshell because setuptools provides its own equivalent
  - bin/qrunner and bin/mailmanctl because the files were empty
  
  There are a bunch of scripts still left in bin/ which will eventually get
  removed.  I'm leaving them for now because they're either helpers 
generally
  tangential to Mailman (msgfmt, po2template, pygettext, templ2pot, 
transcheck),
  or are using old interfaces that will go away soon (clone_member, convert,
  discard, fix_url, list_admins, remove_members, reset_pw, sync_members).
  
  Also moved bin/cleanarch into Mailman/bin/cleanarch.py and updated it to 
use
  optparse.
  
  Also added a small patch to genalias to standardize its help printing.

revno: 6530.1.9
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-21 Thread noreply

revno: 6533
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sat 2007-07-21 16:34:44 -0400
message:
  Some updates
modified:
  README.txt

=== modified file 'README.txt'
--- a/README.txt2007-05-08 14:46:15 +
+++ b/README.txt2007-07-21 20:34:44 +
@@ -10,7 +10,11 @@
 case second `m'.  Any other spelling is incorrect.
 
 Mailman is written primarily in Python, a free object-oriented scripting
-language.  There is some ANSI C code for security purposes.
+language.  Python is available for all platforms that Mailman is supported
+on, which includes GNU/Linux and most other Unix-like operating systems
+(e.g. Solaris, *BSD, MacOSX, etc.).  It does not run on Windows, although
+web and mail clients on any platform should be able to interact with
+Mailman just fine.
 
 Mailman was originally developed by John Viega.  Subsequent development
 (through version 1.0b3) was by Ken Manheimer.  Further work towards the
@@ -19,6 +23,8 @@
 Version 1.0 and beyond have been primarily maintained by Barry Warsaw with
 contributions from many; see the ACKNOWLEDGMENTS file for details.  Jeremy
 Hylton helped considerably with the Pipermail code in Mailman 2.0.
+Mailman 2.1 is now being primarily maintained by Mark Sapiro and Tokio
+Kikuchi.  Barry Warsaw is the lead developer on Mailman 3.
 
 The Mailman home page is:
 
@@ -29,6 +35,10 @@
 http://www.gnu.org/software/mailman
 http://mailman.sf.net
 
+You might also be interested in the Mailman wiki at:
+
+http://wiki.list.org
+
 Mailman 3.0 requires Python 2.5 or greater, which can be downloaded from:
 
 http://www.python.org
@@ -36,12 +46,6 @@
 It is recommended that you use at least Python 2.5.1, the latest release
 as of this writing (08-May-2007).
 
-You will need an ANSI C compiler to build both Python and Mailman; gcc
-(the GNU C compiler) works just fine.  Mailman currently works only on
-GNU/Linux and other Unix-like operating systems (e.g. Solaris, *BSD,
-MacOSX, etc.).  It does not run on Windows, although web and mail clients
-on any platform should be able to interact with Mailman just fine.
-
 
 FEATURES
 
@@ -65,7 +69,7 @@
 
 - Integrated auto-replies.
 
-- Majordomo-style email based commands.
+- Email commands.
 
 - Integrated bounce detection within an extensible framework.
 
@@ -85,8 +89,7 @@
 mailing lists.
 
 Mailman works with any web server that supports CGI/1.1.  The HTML it
-generates is quite pedestrian and stingy on the graphics so it should be
-friendly to most web browsers and network connections.
+generates should be friendly to most web browsers and network connections.
 
 You will need root access on the machine hosting your Mailman installation
 in order to complete some of the configuration steps.  See the INSTALL.txt



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-07-24 Thread noreply

revno: 6534
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: entrypoints
timestamp: Tue 2007-07-24 18:45:25 -0400
message:
  Add setuptools plug-in entry point for defining different database backends.
  Now someone could distribute a setuptools package that provided say, a MySQL
  database implementation and very easily override the stock database.  How
  awesome is setuptools?
  
  Removed MANAGERS_INIT_FUNCTION since setuptools gives us a much more standard
  way of defining this plug-in entry point.  Remove other old crud from
  Defaults.py.
  
  Restructure our own 'stock' database backend to be a plugin so it's totally on
  par with any other package.  The only special case is that if more than one
  such entry point is defined, we filter out the 'stock' one (i.e. ours) under
  the assumption that the user is overriding it.  If we still have more than one
  plug-in, it's an error.
  
  Restructure the initialization subsystem to use the plug-in, doing all the
  proper assertions and what not.  The IDatabase interface defines what the
  database back-end plugin must provide.  I've no doubt this will eventually
  need a bit more fleshing out, but it gives all this stuff a principled hook
  point instead of something ad-hoc.
added:
  Mailman/interfaces/database.py
modified:
  Mailman/Defaults.py
  Mailman/database/__init__.py
  Mailman/initialize.py
  setup.py

=== added file 'Mailman/interfaces/database.py'
--- a/Mailman/interfaces/database.py1970-01-01 00:00:00 +
+++ b/Mailman/interfaces/database.py2007-07-24 22:45:25 +
@@ -0,0 +1,48 @@
+# Copyright (C) 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.
+
+Interfaces for database interaction.
+
+By providing an object with this interface and declaring it in a package
+setup.py file as an entry point in the 'mailman.database' group with the name
+'initializer', you can distribute entirely different database layers for
+Mailman's back end.
+
+
+from zope.interface import Interface, Attribute
+
+
+
+class IDatabase(Interface):
+Database layer interface.
+
+def initialize():
+Initialize the database layer, using whatever means necessary.
+
+def flush():
+Flush current database changes.
+
+# XXX Eventually we probably need to support a transaction manager
+# interface, e.g. begin(), commit(), abort().  We will probably also need
+# to support a shutdown() method for cleanly disconnecting from the
+# database.sy
+
+list_manager = Attribute(
+The IListManager instance provided by the database layer.)
+
+user_manager = Attribute(
+The IUserManager instance provided by the database layer.)

=== modified file 'Mailman/Defaults.py'
--- a/Mailman/Defaults.py   2007-07-17 03:55:49 +
+++ b/Mailman/Defaults.py   2007-07-24 22:45:25 +
@@ -1,5 +1,3 @@
-# -*- python -*-
-
 # Copyright (C) 1998-2007 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
@@ -19,11 +17,6 @@
 
 Distributed default settings for significant Mailman config variables.
 
-# NEVER make site configuration changes to this file.  ALWAYS make them in
-# mm_cfg.py instead, in the designated area.  See the comments in that file
-# for details.
-
-
 import os
 
 from munepy import Enum
@@ -110,11 +103,6 @@
 # Database options
 #
 
-# Initialization function for creating the IListManager, IUserManager, and
-# IMessageManager objects, as a Python dotted name.  This function must take
-# zero arguments.
-MANAGERS_INIT_FUNCTION = 'Mailman.database.initialize'
-
 # Use this to set the SQLAlchemy database engine URL.  You generally have one
 # primary database connection for all of Mailman.  List data and most rosters
 # will store their data in this database, although external rosters may access

=== modified file 'Mailman/database/__init__.py'
--- a/Mailman/database/__init__.py  2007-05-28 20:21:41 +
+++ b/Mailman/database/__init__.py  2007-07-24 22:45:25 +
@@ -20,30 +20,45 @@
 import os
 
 from elixir import objectstore
+from zope.interface import implements
 
+from Mailman.interfaces import IDatabase
 from Mailman.database.listmanager import ListManager
 from 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-01 Thread noreply

revno: 6536
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Mon 2007-07-23 17:52:39 -0400
message:
  Remove an empty file
removed:
  Mailman/Site.py

=== removed file 'Mailman/Site.py'


--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-01 Thread noreply
1 revision was removed from the branch.


--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-01 Thread noreply

revno: 6538
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-08-01 17:05:06 -0400
message:
  Repair some test suite regressions.
modified:
  Mailman/Handlers/Hold.py
  Mailman/LockFile.py
  Mailman/Message.py
  Mailman/Queue/NewsRunner.py
  Mailman/docs/addresses.txt
  Mailman/docs/hold.txt
  Mailman/docs/news-runner.txt
  Mailman/docs/pending.txt

=== modified file 'Mailman/Handlers/Hold.py'
--- a/Mailman/Handlers/Hold.py  2007-08-01 20:11:08 +
+++ b/Mailman/Handlers/Hold.py  2007-08-01 21:05:06 +
@@ -35,12 +35,14 @@
 from email.mime.message import MIMEMessage
 from email.mime.text import MIMEText
 from types import ClassType
+from zope.interface import implements
 
 from Mailman import Errors
 from Mailman import Message
-from Mailman import Pending
 from Mailman import Utils
 from Mailman import i18n
+from Mailman.configuration import config
+from Mailman.interfaces import IPendable, IPending
 
 log = logging.getLogger('mailman.vette')
 
@@ -129,6 +131,12 @@
 
 
 
+class HeldMessagePendable(dict):
+implements(IPendable)
+PEND_KEY = 'held message'
+
+
+
 def process(mlist, msg, msgdata):
 if msgdata.get('approved'):
 return
@@ -239,7 +247,9 @@
 #
 # This message should appear to come from list-admin so as to handle any
 # bounce processing that might be needed.
-cookie = mlist.pend_new(Pending.HELD_MESSAGE, id)
+pendable = HeldMessagePendable(type=HeldMessagePendable.PEND_KEY,
+   id=str(id))
+token = IPending(config.db).add(pendable)
 # Get the language to send the response in.  If the sender is a member,
 # then send it in the member's language, otherwise send it in the mailing
 # list's preferred language.
@@ -247,9 +257,9 @@
 lang = (member.preferred_language if member else mlist.preferred_language)
 if not fromusenet and ackp(msg) and mlist.respond_to_post_requests and \
mlist.autorespondToSender(sender, lang):
-# Get a confirmation cookie
+# Get a confirmation token
 d['confirmurl'] = '%s/%s' % (mlist.GetScriptURL('confirm', absolute=1),
- cookie)
+ token)
 lang = msgdata.get('lang', lang)
 subject = _('Your message to $listname awaits moderator approval')
 text = Utils.maketext('postheld.txt', d, lang=lang, mlist=mlist)
@@ -284,7 +294,7 @@
 message will be approved for posting to the list.  The Approved: header can
 also appear in the first line of the body of the reply.)),
 _charset=Utils.GetCharSet(lang))
-dmsg['Subject'] = 'confirm ' + cookie
+dmsg['Subject'] = 'confirm ' + token
 dmsg['Sender'] = requestaddr
 dmsg['From'] = requestaddr
 dmsg['Date'] = email.utils.formatdate(localtime=True)

=== modified file 'Mailman/LockFile.py'
--- a/Mailman/LockFile.py   2007-05-28 20:21:41 +
+++ b/Mailman/LockFile.py   2007-08-01 21:05:06 +
@@ -59,12 +59,13 @@
 import random
 import socket
 import logging
+import datetime
 import traceback
 
 # Units are floating-point seconds.
-DEFAULT_LOCK_LIFETIME  = 15
+DEFAULT_LOCK_LIFETIME  = datetime.timedelta(seconds=15)
 # Allowable a bit of clock skew
-CLOCK_SLOP = 10
+CLOCK_SLOP = datetime.timedelta(seconds=10)
 # This is appropriate for Mailman, but you may want to change this if you're
 # using this code outside Mailman.
 log = logging.getLogger('mailman.locks')
@@ -95,8 +96,8 @@
 Create the resource lock using lockfile as the global lock file.  Each
 process laying claim to this resource lock will create their own
 temporary lock files based on the path specified by lockfile.
-Optional lifetime is the number of seconds the process expects to hold
-the lock.
+Optional lifetime is a timedelta specifying the number of seconds the
+process expects to hold the lock.
 
 set_lifetime(lifetime):
 Set a new lock lifetime.  This takes affect the next time the file is
@@ -155,7 +156,7 @@
 self._owned = True
 
 def __repr__(self):
-return 'LockFile %s: %s [%s: %ssec] pid=%s' % (
+return 'LockFile %s: %s [%s: %s] pid=%s' % (
 id(self), self._lockfile,
 self.locked() and 'locked' or 'unlocked',
 self._lifetime, os.getpid())
@@ -400,7 +401,8 @@
 return None
 
 def _touch(self, filename=None):
-t = time.time() + self._lifetime
+expiration_date = datetime.datetime.now() + self._lifetime
+t = time.mktime(expiration_date.timetuple())
 try:
 # XXX We probably don't need to modify atime, but this is easier.
 os.utime(filename or self._tmpfname, (t, t))

=== modified file 'Mailman/Message.py'
--- a/Mailman/Message.py2007-08-01 20:11:08 +
+++ 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-01 Thread noreply

revno: 6534
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-07-22 19:52:34 -0400
message:
  The start of a message store definition.  Whether this will end up being used
  for the archive or not is left to be seen.
  
  Define an interface, test, and implementation of a basic message store using
  globally unique identifiers of the form: archive/hash/seqno
  
  - archive is the base url of the archive, e.g. http://archives.example.com.
This is available in the List-Archive header.
  - hash is the base32 encoded sha1 hash of the message's Message-ID and Date
headers, which it must have.  This is available in the X-List-ID-Hash
header.
  - seqno is a sequence number specific to the archive which will uniquely
identify the message should there be a Message-ID/Date collision.  this is
available in the X-List-Sequence-Number header.
  
  Added a MESSAGES_DIR variable to the config.
  
  Added a .message_store attribute to the config.
added:
  Mailman/database/messagestore.py
  Mailman/database/model/message.py
  Mailman/docs/messagestore.txt
  Mailman/interfaces/messagestore.py
modified:
  Mailman/configuration.py
  Mailman/database/__init__.py
  Mailman/database/model/__init__.py
  Mailman/docs/archives.txt

=== added file 'Mailman/database/messagestore.py'
--- a/Mailman/database/messagestore.py  1970-01-01 00:00:00 +
+++ b/Mailman/database/messagestore.py  2007-07-22 23:52:34 +
@@ -0,0 +1,140 @@
+# Copyright (C) 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.
+
+from __future__ import with_statement
+
+__metaclass__ = type
+__all__ = [
+'MessageStore',
+]
+
+import os
+import errno
+import base64
+import hashlib
+import cPickle as pickle
+
+from zope.interface import implements
+
+from Mailman import Utils
+from Mailman.configuration import config
+from Mailman.database.model import Message
+from Mailman.interfaces import IMessageStore
+
+# It could be very bad if you have already stored files and you change this
+# value.  We'd need a script to reshuffle and resplit.
+MAX_SPLITS = 2
+EMPTYSTRING = ''
+
+
+
+class MessageStore:
+implements(IMessageStore)
+
+def add(self, message):
+# Ensure that the message has the requisite headers.
+message_ids = message.get_all('message-id', [])
+dates = message.get_all('date', [])
+if not (len(message_ids) == 1 and len(dates) == 1):
+raise ValueError(
+'Exactly one Message-ID and one Date header required')
+# Calculate and insert the X-List-ID-Hash.
+message_id = message_ids[0]
+date = dates[0]
+shaobj = hashlib.sha1(message_id)
+shaobj.update(date)
+hash32 = base64.b32encode(shaobj.digest())
+del message['X-List-ID-Hash']
+message['X-List-ID-Hash'] = hash32
+# Calculate the path on disk where we're going to store this message
+# object, in pickled format.
+parts = []
+split = list(hash32)
+while split and len(parts)  MAX_SPLITS:
+parts.append(split.pop(0) + split.pop(0))
+parts.append(EMPTYSTRING.join(split))
+relpath = os.path.join(*parts)
+# Store the message in the database.  This relies on the database
+# providing a unique serial number, but to get this information, we
+# have to use a straight insert instead of relying on Elixir to create
+# the object.
+result = Message.table.insert().execute(
+hash=hash32, path=relpath, message_id=message_id)
+# Add the additional header.
+seqno = result.last_inserted_ids()[0]
+del message['X-List-Sequence-Number']
+message['X-List-Sequence-Number'] = str(seqno)
+# Now calculate the full file system path.
+path = os.path.join(config.MESSAGES_DIR, relpath, str(seqno))
+# Write the file to the path, but catch the appropriate exception in
+# case the parent directories don't yet exist.  In that case, create
+# them and try again.
+while True:
+try:
+with open(path, 'w') as fp:
+# -1 says to use the highest protocol available.
+ 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-01 Thread noreply

revno: 6535
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Mon 2007-07-23 01:57:48 -0400
message:
  Remove last vestiges of dbcontext
removed:
  Mailman/database/dbcontext.py
modified:
  Mailman/bin/testall.py

=== removed file 'Mailman/database/dbcontext.py'
--- a/Mailman/database/dbcontext.py 2007-05-28 20:21:41 +
+++ b/Mailman/database/dbcontext.py 1970-01-01 00:00:00 +
@@ -1,174 +0,0 @@
-# Copyright (C) 2006-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.
-
-import os
-import sys
-import logging
-import weakref
-
-from elixir import create_all, metadata, objectstore
-from sqlalchemy import create_engine
-from string import Template
-from urlparse import urlparse
-
-from Mailman import Version
-from Mailman.configuration import config
-from Mailman.database.txnsupport import txn
-
-
-
-class MlistRef(weakref.ref):
-def __init__(self, mlist, callback):
-super(MlistRef, self).__init__(mlist, callback)
-self.fqdn_listname = mlist.fqdn_listname
-
-
-
-class DBContext(object):
-def __init__(self):
-# Special transaction used only for MailList.Lock() .Save() and
-# .Unlock() interface.
-self._mlist_txns = {}
-
-def connect(self):
-# Calculate the engine url
-url = Template(config.SQLALCHEMY_ENGINE_URL).safe_substitute(
-config.paths)
-# XXX By design of SQLite, database file creation does not honor
-# umask.  See their ticket #1193:
-# http://www.sqlite.org/cvstrac/tktview?tn=1193,31
-#
-# This sucks for us because the mailman.db file /must/ be group
-# writable, however even though we guarantee our umask is 002 here, it
-# still gets created without the necessary g+w permission, due to
-# SQLite's policy.  This should only affect SQLite engines because its
-# the only one that creates a little file on the local file system.
-# This kludges around their bug by touching the database file before
-# SQLite has any chance to create it, thus honoring the umask and
-# ensuring the right permissions.  We only try to do this for SQLite
-# engines, and yes, we could have chmod'd the file after the fact, but
-# half dozen and all...
-self._touch(url)
-engine = create_engine(url)
-engine.echo = config.SQLALCHEMY_ECHO
-metadata.connect(engine)
-# Load and create the Elixir active records.  This works by
-# side-effect.
-import Mailman.database.model
-create_all()
-# Validate schema version.
-v = Mailman.database.model.Version.get_by(component='schema')
-if not v:
-# Database has not yet been initialized
-v = Mailman.database.model.Version(
-component='schema',
-version=Version.DATABASE_SCHEMA_VERSION)
-objectstore.flush()
-elif v.version  Version.DATABASE_SCHEMA_VERSION:
-# XXX Update schema
-raise SchemaVersionMismatchError(v.version)
-
-def _touch(self, url):
-parts = urlparse(url)
-if parts.scheme  'sqlite':
-return
-path = os.path.normpath(parts.path)
-fd = os.open(path, os.O_WRONLY |  os.O_NONBLOCK | os.O_CREAT, 0666)
-# Ignore errors
-if fd  0:
-os.close(fd)
-
-# Cooperative method for use with @txn decorator
-def _withtxn(self, meth, *args, **kws):
-try:
-txn = objectstore.session.current.create_transaction()
-rtn = meth(*args, **kws)
-except:
-txn.rollback()
-raise
-else:
-txn.commit()
-return rtn
-
-def _unlock_mref(self, mref):
-txn = self._mlist_txns.pop(mref.fqdn_listname, None)
-if txn is not None:
-txn.rollback()
-
-# Higher level interface
-def api_lock(self, mlist):
-# Don't try to re-lock a list
-if mlist.fqdn_listname in self._mlist_txns:
-return
-txn = objectstore.session.current.create_transaction()
-mref = MlistRef(mlist, self._unlock_mref)
-# If 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-02 Thread noreply

revno: 6539
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Thu 2007-08-02 10:47:56 -0400
message:
  Refactor IDatabase interface so that the user_manager, list_manager,
  message_store, and pendings 'databases' hang off the IDatabase object attached
  to the config object.  For IPending, no adaptation is necessary.
modified:
  Mailman/Handlers/Hold.py
  Mailman/Queue/Runner.py
  Mailman/app/registrar.py
  Mailman/database/__init__.py
  Mailman/docs/ack-headers.txt
  Mailman/docs/acknowledge.txt
  Mailman/docs/addresses.txt
  Mailman/docs/after-delivery.txt
  Mailman/docs/antispam.txt
  Mailman/docs/archives.txt
  Mailman/docs/avoid-duplicates.txt
  Mailman/docs/bounces.txt
  Mailman/docs/calc-recips.txt
  Mailman/docs/cleanse.txt
  Mailman/docs/cook-headers.txt
  Mailman/docs/decorate.txt
  Mailman/docs/digests.txt
  Mailman/docs/file-recips.txt
  Mailman/docs/filtering.txt
  Mailman/docs/hold.txt
  Mailman/docs/listmanager.txt
  Mailman/docs/membership.txt
  Mailman/docs/message.txt
  Mailman/docs/messagestore.txt
  Mailman/docs/mlist-addresses.txt
  Mailman/docs/news-runner.txt
  Mailman/docs/nntp.txt
  Mailman/docs/outgoing.txt
  Mailman/docs/pending.txt
  Mailman/docs/registration.txt
  Mailman/docs/reply-to.txt
  Mailman/docs/replybot.txt
  Mailman/docs/runner.txt
  Mailman/docs/scrubber.txt
  Mailman/docs/subject-munging.txt
  Mailman/docs/tagger.txt
  Mailman/docs/usermanager.txt
  Mailman/docs/users.txt
  Mailman/initialize.py
  Mailman/interfaces/database.py
  Mailman/tests/test_documentation.py

=== modified file 'Mailman/Handlers/Hold.py'
--- a/Mailman/Handlers/Hold.py  2007-08-01 21:05:06 +
+++ b/Mailman/Handlers/Hold.py  2007-08-02 14:47:56 +
@@ -42,7 +42,7 @@
 from Mailman import Utils
 from Mailman import i18n
 from Mailman.configuration import config
-from Mailman.interfaces import IPendable, IPending
+from Mailman.interfaces import IPendable
 
 log = logging.getLogger('mailman.vette')
 
@@ -249,7 +249,7 @@
 # bounce processing that might be needed.
 pendable = HeldMessagePendable(type=HeldMessagePendable.PEND_KEY,
id=str(id))
-token = IPending(config.db).add(pendable)
+token = config.db.pendings.add(pendable)
 # Get the language to send the response in.  If the sender is a member,
 # then send it in the member's language, otherwise send it in the mailing
 # list's preferred language.

=== modified file 'Mailman/Queue/Runner.py'
--- a/Mailman/Queue/Runner.py   2007-06-28 05:11:50 +
+++ b/Mailman/Queue/Runner.py   2007-08-02 14:47:56 +
@@ -147,7 +147,7 @@
 #
 # Find out which mailing list this message is destined for.
 listname = msgdata.get('listname')
-mlist = config.list_manager.get(listname)
+mlist = config.db.list_manager.get(listname)
 if not mlist:
 log.error('Dequeuing message destined for missing list: %s',
   listname)

=== modified file 'Mailman/app/registrar.py'
--- a/Mailman/app/registrar.py  2007-08-01 20:11:08 +
+++ b/Mailman/app/registrar.py  2007-08-02 14:47:56 +
@@ -32,7 +32,7 @@
 from Mailman.Utils import ValidateEmail
 from Mailman.configuration import config
 from Mailman.i18n import _
-from Mailman.interfaces import IDomain, IPendable, IPending, IRegistrar
+from Mailman.interfaces import IDomain, IPendable, IRegistrar
 
 __i18n_templates__ = True
 
@@ -57,7 +57,7 @@
 ValidateEmail(address)
 # Check to see if there is already a verified IAddress in the database
 # matching this address.  If so, there's nothing to do.
-usermgr = config.user_manager
+usermgr = config.db.user_manager
 addr = usermgr.get_address(address)
 if addr and addr.verified_on:
 # Before returning, see if this address is linked to a user.  If
@@ -73,8 +73,7 @@
 pendable = PendableRegistration(type=PendableRegistration.PEND_KEY,
 address=address,
 real_name=real_name)
-pendingdb = IPending(config.db)
-token = pendingdb.add(pendable)
+token = config.db.pendings.add(pendable)
 # Set up some local variables for translation interpolation.
 domain = IDomain(self._context)
 domain_name = _(domain.domain_name)
@@ -96,8 +95,7 @@
 def confirm(self, token):
 See `IUserRegistrar`.
 # For convenience
-pendingdb = IPending(config.db)
-pendable = pendingdb.confirm(token)
+pendable = config.db.pendings.confirm(token)
 if pendable is None:
 return False
 missing = object()
@@ -114,7 +112,7 @@
 # We are going to end up with an IAddress for the verified address
 # and an IUser linked to this IAddress.  See if any of these objects
 # currently exist in our database.
-

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-08-03 Thread noreply

revno: 986
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-08-03 17:46:05 -0700
message:
  Backported dumpdb changes from the 3.0 branch to allow dumping of marshals.
  This has been broken since 2.1.5!
modified:
  bin/dumpdb

=== modified file 'bin/dumpdb'
--- a/bin/dumpdb2005-08-27 01:40:17 +
+++ b/bin/dumpdb2007-08-04 00:46:05 +
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! /usr/bin/python
 #
 # Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
 #
@@ -45,16 +45,15 @@
 -- or if the file ends in neither suffix -- use the -p or -m flags.
 
 
-import os
 import sys
 import getopt
 import pprint
-from cPickle import load
+import cPickle
+import marshal
 from types import StringType
 
 import paths
 # Import this /after/ paths so that the sys.path is properly hacked
-from email.Generator import Generator
 from Mailman.i18n import _
 
 PROGRAM = sys.argv[0]
@@ -121,37 +120,35 @@
 # Handle dbs
 pp = pprint.PrettyPrinter(indent=4)
 if filetype == 1:
-# BAW: this probably doesn't work if there are mixed types of .db
-# files (i.e. some marshals, some bdbs).
-d = DumperSwitchboard().read(filename)
+load = marshal.load
+typename = 'marshal'
+else:
+load = cPickle.load
+typename = 'pickle'
+fp = open(filename)
+m = []
+try:
+cnt = 1
 if doprint:
-pp.pprint(d)
-return d
-else:
-fp = open(filename)
-m = []
-try:
-cnt = 1
+print _('[- start %(typename)s file -]')
+while True:
+try:
+obj = load(fp)
+except EOFError:
+if doprint:
+print _('[- end %(typename)s file -]')
+break
 if doprint:
-print _('[- start pickle file -]')
-while True:
-try:
-obj = load(fp)
-except EOFError:
-if doprint:
-print _('[- end pickle file -]')
-break
-if doprint:
-print _('- start object %(cnt)s -')
-if isinstance(obj, StringType):
-print obj
-else:
-pp.pprint(obj)
-cnt += 1
-m.append(obj)
-finally:
-fp.close()
-return m
+print _('- start object %(cnt)s -')
+if isinstance(obj, StringType):
+print obj
+else:
+pp.pprint(obj)
+cnt += 1
+m.append(obj)
+finally:
+fp.close()
+return m
 
 
 



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.2] (no title)

2007-08-03 Thread noreply

revno: 986
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.2
timestamp: Fri 2007-08-03 17:44:44 -0700
message:
  Backported dumpdb changes from the 3.0 branch to allow dumping of marshals.
  This has been broken since 2.1.5!
modified:
  bin/dumpdb

=== modified file 'bin/dumpdb'
--- a/bin/dumpdb2005-08-27 01:40:17 +
+++ b/bin/dumpdb2007-08-04 00:44:44 +
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! /usr/bin/python
 #
 # Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
 #
@@ -45,16 +45,15 @@
 -- or if the file ends in neither suffix -- use the -p or -m flags.
 
 
-import os
 import sys
 import getopt
 import pprint
-from cPickle import load
+import cPickle
+import marshal
 from types import StringType
 
 import paths
 # Import this /after/ paths so that the sys.path is properly hacked
-from email.Generator import Generator
 from Mailman.i18n import _
 
 PROGRAM = sys.argv[0]
@@ -121,37 +120,35 @@
 # Handle dbs
 pp = pprint.PrettyPrinter(indent=4)
 if filetype == 1:
-# BAW: this probably doesn't work if there are mixed types of .db
-# files (i.e. some marshals, some bdbs).
-d = DumperSwitchboard().read(filename)
+load = marshal.load
+typename = 'marshal'
+else:
+load = cPickle.load
+typename = 'pickle'
+fp = open(filename)
+m = []
+try:
+cnt = 1
 if doprint:
-pp.pprint(d)
-return d
-else:
-fp = open(filename)
-m = []
-try:
-cnt = 1
+print _('[- start %(typename)s file -]')
+while True:
+try:
+obj = load(fp)
+except EOFError:
+if doprint:
+print _('[- end %(typename)s file -]')
+break
 if doprint:
-print _('[- start pickle file -]')
-while True:
-try:
-obj = load(fp)
-except EOFError:
-if doprint:
-print _('[- end pickle file -]')
-break
-if doprint:
-print _('- start object %(cnt)s -')
-if isinstance(obj, StringType):
-print obj
-else:
-pp.pprint(obj)
-cnt += 1
-m.append(obj)
-finally:
-fp.close()
-return m
+print _('- start object %(cnt)s -')
+if isinstance(obj, StringType):
+print obj
+else:
+pp.pprint(obj)
+cnt += 1
+m.append(obj)
+finally:
+fp.close()
+return m
 
 
 



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.2

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.2/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-08-03 Thread noreply

revno: 987
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-08-03 18:09:33 -0700
message:
  Ooops! The previous rev copied a configured file by mistake. Fixed.
modified:
  bin/dumpdb

=== modified file 'bin/dumpdb'
--- a/bin/dumpdb2007-08-04 00:46:05 +
+++ b/bin/dumpdb2007-08-04 01:09:33 +
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#! @PYTHON@
 #
 # Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
 #



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.2] (no title)

2007-08-03 Thread noreply

revno: 987
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.2
timestamp: Fri 2007-08-03 18:10:34 -0700
message:
  Ooops! The previous rev copied a configured file by mistake. Fixed.
modified:
  bin/dumpdb

=== modified file 'bin/dumpdb'
--- a/bin/dumpdb2007-08-04 00:44:44 +
+++ b/bin/dumpdb2007-08-04 01:10:34 +
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#! @PYTHON@
 #
 # Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
 #



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.2

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.2/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1] (no title)

2007-08-03 Thread noreply

revno: 988
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-08-03 18:16:56 -0700
message:
  Updated copyright year.
modified:
  bin/dumpdb

=== modified file 'bin/dumpdb'
--- a/bin/dumpdb2007-08-04 01:09:33 +
+++ b/bin/dumpdb2007-08-04 01:16:56 +
@@ -1,6 +1,6 @@
 #! @PYTHON@
 #
-# Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
+# 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



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.2] (no title)

2007-08-03 Thread noreply

revno: 988
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.2
timestamp: Fri 2007-08-03 18:16:07 -0700
message:
  Updated copyright year.
modified:
  bin/dumpdb

=== modified file 'bin/dumpdb'
--- a/bin/dumpdb2007-08-04 01:10:34 +
+++ b/bin/dumpdb2007-08-04 01:16:07 +
@@ -1,6 +1,6 @@
 #! @PYTHON@
 #
-# Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
+# 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



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/2.2

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.2/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-06 Thread noreply

revno: 6545
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Mon 2007-08-06 10:53:01 -0500
message:
  Simple update.
modified:
  Mailman/bin/version.py

=== modified file 'Mailman/bin/version.py'
--- a/Mailman/bin/version.py2007-01-19 04:38:06 +
+++ b/Mailman/bin/version.py2007-08-06 15:53:01 +
@@ -32,9 +32,7 @@
 Print the Mailman version and exit.))
 opts, args = parser.parse_args()
 if args:
-parser.print_help()
-print  sys.stderr, _('Unexpected arguments')
-sys.exit(1)
+parser.error(_('Unexpected arguments'))
 return parser, opts, args
 
 
@@ -42,7 +40,7 @@
 def main():
 parser, opts, args = parseargs()
 # Yes, this is kind of silly
-print _('Using Mailman version: $Version.MAILMAN_VERSION')
+print _('Using $Version.MAILMAN_VERSION')
 
 
 



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-06 Thread noreply

revno: 6544
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Mon 2007-08-06 10:50:27 -0500
message:
  Make bin/list_owners work again.
modified:
  Mailman/bin/list_owners.py

=== modified file 'Mailman/bin/list_owners.py'
--- a/Mailman/bin/list_owners.py2007-05-28 20:21:41 +
+++ b/Mailman/bin/list_owners.py2007-08-06 15:50:27 +
@@ -22,6 +22,8 @@
 from Mailman.MailList import MailList
 from Mailman.configuration import config
 from Mailman.i18n import _
+from Mailman.initialize import initialize
+
 
 __i18n_templates__ = True
 
@@ -52,16 +54,17 @@
 
 def main():
 parser, opts, args = parseargs()
-config.load(opts.config)
+initialize(opts.config)
 
-listnames = set(args or config.list_manager.names)
+listmgr = config.db.list_manager
+listnames = set(args or listmgr.names)
 bylist = {}
 
 for listname in listnames:
-mlist = MailList(listname, lock=False)
-addrs = mlist.owner[:]
+mlist = listmgr.get(listname)
+addrs = [addr.address for addr in mlist.owners.addresses]
 if opts.moderators:
-addrs.extend(mlist.moderator)
+addrs.extend([addr.address for addr in mlist.moderators.addresses])
 bylist[listname] = addrs
 
 if opts.with_listnames:
@@ -79,9 +82,7 @@
 for listname in listnames:
 for addr in bylist[listname]:
 unique.add(addr)
-keys = list(unique)
-keys.sort()
-for k in keys:
+for k in sorted(unique):
 print k
 
 



--
(no title)
https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-06 Thread noreply

revno: 6541
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-08-05 07:30:30 -0400
message:
  Added a doctest for styles.
added:
  Mailman/docs/styles.txt
modified:
  Mailman/app/styles.py

=== added file 'Mailman/docs/styles.txt'
--- a/Mailman/docs/styles.txt   1970-01-01 00:00:00 +
+++ b/Mailman/docs/styles.txt   2007-08-05 11:30:30 +
@@ -0,0 +1,142 @@
+List styles
+===
+
+List styles are a way to name and apply a canned collection of attribute
+settings.  Every style has a name, which must be unique within the context of
+a specific style manager.  There is usually only one global style manager.
+
+Styles also have a priority, which allows you to specify the order in which
+multiple styles will be applied.  A style has a `match` function which is used
+to determine whether the style should be applied to a particular mailing list
+or not.  And finally, application of a style to a mailing list can really
+modify the mailing list any way it wants.
+
+Let's start with a vanilla mailing list and a default style manager.
+
+ from Mailman.configuration import config
+ from Mailman.database import flush
+ mlist = config.db.list_manager.create('[EMAIL PROTECTED]')
+ from Mailman.app.styles import style_manager
+
+
+The default style
+-
+
+There is a default style which implements the legacy application of list
+defaults from Defaults.py.  This style only matching a mailing list when no
+other styles match, and it has the lowest priority.  The low priority means
+that it is matched last and if it matches, it is applied last.
+
+ default_style = style_manager.get('default')
+ default_style.name
+'default'
+ default_style.priority
+0
+ sorted(style.name for style in style_manager.styles)
+['default']
+
+Given a mailing list, you can ask the style manager to find all the styles
+that match the list.  The registered styles will be sorted by decreasing
+priority and each style's `match()` method will be called in turn.  The sorted
+list of matching styles will be returned -- but not applied -- by the style
+manager's `lookup()` method.
+
+ [style.name for style in style_manager.lookup(mlist)]
+['default']
+
+If the site administrator modified their mailman.cfg file, the default style
+would pick this up and apply it to the mailing list.
+
+ print mlist.msg_footer
+None
+ config.DEFAULT_MSG_FOOTER = u'default footer'
+ default_style.apply(mlist)
+ flush()
+ mlist.msg_footer
+u'default footer'
+
+
+Registering styles
+--
+
+New styles must implement the IStyle interface.
+
+ from zope.interface import implements
+ from Mailman.interfaces import IStyle
+ class TestStyle(object):
+... name = 'test'
+... priority = 10
+... def apply(self, mailing_list):
+... # Just does something very simple.
+... mailing_list.msg_footer = u'test footer'
+... def match(self, mailing_list, styles):
+... # Applies to any test list
+... if 'test' in mailing_list.fqdn_listname:
+... styles.append(self)
+
+You can register a new style with the style manager.
+
+ style_manager.register(TestStyle())
+
+And now if you lookup matching styles, you should find only the new test
+style.  This is because the default style only gets applied when no other
+styles match the mailing list.
+
+ sorted(style.name for style in style_manager.lookup(mlist))
+['test']
+ for style in style_manager.lookup(mlist):
+... style.apply(mlist)
+ flush()
+ mlist.msg_footer
+u'test footer'
+
+
+Style priority
+--
+
+When multiple styles match a particular mailing list, they are applied in
+descending order of priority.  In other words, a priority zero style would be
+applied last.
+
+ class AnotherTestStyle(TestStyle):
+... name = 'another'
+... priority = 5
+... # Use the base class's match() method.
+... def apply(self, mailing_list):
+... mailing_list.msg_footer = u'another footer'
+
+ mlist.msg_footer = u''
+ flush()
+ mlist.msg_footer
+u''
+ style_manager.register(AnotherTestStyle())
+ for style in style_manager.lookup(mlist):
+... style.apply(mlist)
+ flush()
+ mlist.msg_footer
+u'another footer'
+
+You can change the priority of a style, and if you reapply the styles, they
+will take effect in the new priority order.
+
+ style_1 = style_manager.get('test')
+ style_1.priority = 5
+ style_2 = style_manager.get('another')
+ style_2.priority = 10
+ for style in style_manager.lookup(mlist):
+... style.apply(mlist)
+ flush()
+ mlist.msg_footer
+u'test footer'
+
+
+Corner cases
+
+
+If you register a style with the same name as an already registered style, you
+get 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-06 Thread noreply

revno: 6543
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-08-05 22:49:04 -0500
message:
  Fixed a problem where members of a deleted mailing list were hanging around.
  This would cause duplicate members (e.g. owners) if you created, deleted and
  then recreated the mailing list.
  
  Mailman.app.create - Mailman.app.lifecycle; Mailman/doc/create.txt -
  Mailman/doc/lifecycle.txt; also added a remove_list() function.
  
  Added SubscriptionError base class, made HostileSubscriptionError inherit from
  that, and added a new AlreadySubscribedError.
  
  Rewrote bin/rmlist to use the new lifecycle.remove_list() function.
  
  IAddress.subscribe() must now throw an AlreadySubscribedError if the address
  is already subscribed to the mailing list with the given role.
  
  Added a Subscribers roster, attached to the IMailingList which gives access to
  all subscribers of a mailing list, regardless of their role.  Added a new test
  for this roster.
renamed:
  Mailman/app/create.py = Mailman/app/lifecycle.py
  Mailman/docs/create.txt = Mailman/docs/lifecycle.txt
modified:
  Mailman/Errors.py
  Mailman/app/__init__.py*
  Mailman/bin/newlist.py
  Mailman/bin/rmlist.py
  Mailman/database/model/address.py
  Mailman/database/model/mailinglist.py
  Mailman/database/model/roster.py
  Mailman/docs/membership.txt
  Mailman/interfaces/address.py
  Mailman/interfaces/mlistrosters.py
  Mailman/app/lifecycle.py
  Mailman/docs/lifecycle.txt

=== renamed file 'Mailman/app/create.py' = 'Mailman/app/lifecycle.py'
--- a/Mailman/app/create.py 2007-08-05 12:42:16 +
+++ b/Mailman/app/lifecycle.py  2007-08-06 03:49:04 +
@@ -17,6 +17,10 @@
 
 Application level list creation.
 
+import os
+import shutil
+import logging
+
 from Mailman import Errors
 from Mailman import Utils
 from Mailman.Utils import ValidateEmail
@@ -25,6 +29,14 @@
 from Mailman.configuration import config
 from Mailman.constants import MemberRole
 
+__all__ = [
+'create_list',
+'remove_list',
+]
+
+
+log = logging.getLogger('mailman.error')
+
 
 
 def create_list(fqdn_listname, owners=None):
@@ -58,3 +70,47 @@
 addr = list(user.addresses)[0]
 addr.subscribe(mlist, MemberRole.owner)
 return mlist
+
+
+
+def remove_list(fqdn_listname, mailing_list=None, archives=True):
+Remove the list and all associated artifacts and subscriptions.
+removeables = []
+# mailing_list will be None when only residual archives are being removed.
+if mailing_list:
+# Remove all subscriptions, regardless of role.
+for member in mailing_list.subscribers.members:
+member.unsubscribe()
+# Delete the mailing list from the database.
+config.db.list_manager.delete(mailing_list)
+# Do the MTA-specific list deletion tasks
+if config.MTA:
+modname = 'Mailman.MTA.' + config.MTA
+__import__(modname)
+sys.modules[modname].remove(mailing_list)
+# Remove the list directory.
+removeables.append(os.path.join(config.LIST_DATA_DIR, fqdn_listname))
+# Remove any stale locks associated with the list.
+for filename in os.listdir(config.LOCK_DIR):
+fn_listname = filename.split('.')[0]
+if fn_listname == fqdn_listname:
+removeables.append(os.path.join(config.LOCK_DIR, filename))
+if archives:
+private_dir = config.PRIVATE_ARCHIVE_FILE_DIR
+public_dir  = config.PUBLIC_ARCHIVE_FILE_DIR
+removeables.extend([
+os.path.join(private_dir, fqdn_listname),
+os.path.join(private_dir, fqdn_listname + '.mbox'),
+os.path.join(public_dir, fqdn_listname),
+os.path.join(public_dir, fqdn_listname + '.mbox'),
+])
+# Now that we know what files and directories to delete, delete them.
+for target in removeables:
+if os.path.islink(target):
+os.unlink(target)
+elif os.path.isdir(target):
+shutil.rmtree(target)
+elif os.path.isfile(target):
+os.unlink(target)
+else:
+log.error('Could not delete list artifact: $target')

=== renamed file 'Mailman/docs/create.txt' = 'Mailman/docs/lifecycle.txt'
--- a/Mailman/docs/create.txt   2007-08-05 12:42:16 +
+++ b/Mailman/docs/lifecycle.txt2007-08-06 03:49:04 +
@@ -1,12 +1,12 @@
-Application level list creation

-
-The low-level way to create a new mailing list is to use the IListManager
-interface.  This interface simply adds the appropriate database entries to
-record the list's creation.
-
-There is a higher level interface for creating mailing lists which performs a
-few additional tasks such as:
+Application level list lifecycle
+
+
+The low-level way to create and delete a mailing list is to use the
+IListManager interface.  This 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0] (no title)

2007-08-06 Thread noreply

revno: 6542
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-08-05 08:42:16 -0400
message:
  Added a doctest for the Mailman.app.create module.
  
  BadListNameError is gone.  Use InvalidEmailAddress instead.
  
  Move owner registration from bin/newlist to Mailman/app/create.py, but do not
  verified owner email addresses here.  Eventually we'll hook in the IRegistrar
  stuff for unverified owner addresses.
  
  IStyleManager.register() verifies that its registering an IStyle.
  
  Added IStyleManager.unregister(), along with updated interfaces and doctests.
  
  Clean up all styles except the default one in the system documentation test
  harness.
added:
  Mailman/docs/create.txt
modified:
  Mailman/Cgi/create.py
  Mailman/Errors.py
  Mailman/app/create.py
  Mailman/app/styles.py
  Mailman/bin/newlist.py
  Mailman/docs/styles.txt
  Mailman/interfaces/styles.py
  Mailman/tests/test_documentation.py

=== added file 'Mailman/docs/create.txt'
--- a/Mailman/docs/create.txt   1970-01-01 00:00:00 +
+++ b/Mailman/docs/create.txt   2007-08-05 12:42:16 +
@@ -0,0 +1,123 @@
+Application level list creation
+---
+
+The low-level way to create a new mailing list is to use the IListManager
+interface.  This interface simply adds the appropriate database entries to
+record the list's creation.
+
+There is a higher level interface for creating mailing lists which performs a
+few additional tasks such as:
+
+ * validating the list's posting address (which also serves as the list's
+   fully qualified name);
+ * ensuring that the list's domain is registered;
+ * applying all matching styles to the new list;
+ * creating and assigning list owners;
+ * notifying watchers of list creation;
+ * creating ancillary artifacts (such as the list's on-disk directory)
+
+ from Mailman.app.create import create_list
+
+
+Posting address validation
+--
+
+If you try to use the higher-level interface to create a mailing list with a
+bogus posting address, you get an exception.
+
+ create_list('not a valid address')
+Traceback (most recent call last):
+...
+InvalidEmailAddress: 'not a valid address'
+
+If the posting address is valid, but the domain has not been registered with
+Mailman yet, you get an exception.
+
+ create_list('[EMAIL PROTECTED]')
+Traceback (most recent call last):
+...
+BadDomainSpecificationError: example.org
+
+
+Creating a list applies its styles
+--
+
+Start by registering a test style.
+
+ from zope.interface import implements
+ from Mailman.interfaces import IStyle
+ class TestStyle(object):
+... implements(IStyle)
+... name = 'test'
+... priority = 10
+... def apply(self, mailing_list):
+... # Just does something very simple.
+... mailing_list.msg_footer = u'test footer'
+... def match(self, mailing_list, styles):
+... # Applies to any test list
+... if 'test' in mailing_list.fqdn_listname:
+... styles.append(self)
+ from Mailman.app.styles import style_manager
+ style_manager.register(TestStyle())
+
+Using the higher level interface for creating a list, applies all matching
+list styles.
+
+ mlist_1 = create_list('[EMAIL PROTECTED]')
+ from Mailman.database import flush
+ flush()
+ mlist_1.fqdn_listname
+'[EMAIL PROTECTED]'
+ mlist_1.msg_footer
+u'test footer'
+
+
+Creating a list with owners
+---
+
+You can also specify a list of owner email addresses.  If these addresses are
+not yet known, they will be registered, and new users will be linked to them.
+However the addresses are not verified.
+
+ owners = ['[EMAIL PROTECTED]', '[EMAIL PROTECTED]',
+...   '[EMAIL PROTECTED]', '[EMAIL PROTECTED]']
+ mlist_2 = create_list('[EMAIL PROTECTED]', owners)
+ flush()
+ mlist_2.fqdn_listname
+'[EMAIL PROTECTED]'
+ mlist_2.msg_footer
+u'test footer'
+ sorted(addr.address for addr in mlist_2.owners.addresses)
+['[EMAIL PROTECTED]', '[EMAIL PROTECTED]',
+ '[EMAIL PROTECTED]', '[EMAIL PROTECTED]']
+
+None of the owner addresses are verified.
+
+ any(addr.verified_on is not None for addr in mlist_2.owners.addresses)
+False
+
+However, all addresses are linked to users.
+
+ # The owners have no names yet
+ len(list(mlist_2.owners.users))
+4
+
+If you create a mailing list with owner addresses that are already known to
+the system, they won't be created again.
+
+ from Mailman.configuration import config
+ usermgr = config.db.user_manager
+ user_a = usermgr.get_user('[EMAIL PROTECTED]')
+ user_b = usermgr.get_user('[EMAIL PROTECTED]')
+ user_c = usermgr.get_user('[EMAIL PROTECTED]')
+ user_d = usermgr.get_user('[EMAIL PROTECTED]')
+ 

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-09-12 Thread noreply

revno: 989
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Wed 2007-09-12 14:36:43 -0400
message:
  Start using barry at list dot org for all Mailman correspondances.
modified:
  doc/mailman-admin.tex
  doc/mailman-install.tex

=== modified file 'doc/mailman-admin.tex'
--- a/doc/mailman-admin.tex 2003-02-08 07:14:13 +
+++ b/doc/mailman-admin.tex 2007-09-12 18:36:43 +
@@ -9,7 +9,7 @@
 % At minimum, give your name and an email address.  You can include a
 % snail-mail address if you like.
 \author{Barry A. Warsaw}
[EMAIL PROTECTED]
+%\authoraddress{barry (at) list dot org}
 
 \date{\today}  % XXX update before tagging release!
 \release{2.1}  % software release, not documentation

=== modified file 'doc/mailman-install.tex'
--- a/doc/mailman-install.tex   2007-02-15 01:59:46 +
+++ b/doc/mailman-install.tex   2007-09-12 18:36:43 +
@@ -2,7 +2,7 @@
 
 \title{GNU Mailman - Installation Manual}
 \author{Barry Warsaw}
-\authoraddress{\email{barry(at)python.org}}
+\authoraddress{\email{barry (at) list dot org}}
 
 \date{\today}
 \release{2.1}   % software release, not documentation



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-12 Thread noreply

revno: 6549
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: listadmin-bye
timestamp: Wed 2007-09-12 22:44:07 -0400
message:
  SQLAlchemy = 0.3.10 is required.
modified:
  Mailman/database/model/pending.py
  setup.py

=== modified file 'Mailman/database/model/pending.py'
--- a/Mailman/database/model/pending.py 2007-08-08 04:24:13 +
+++ b/Mailman/database/model/pending.py 2007-09-13 02:44:07 +
@@ -99,8 +99,8 @@
 return None
 pending = pendings[0]
 pendable = UnpendedPendable()
-# Find all PendingKeyValue entries that are associated with the
-# pending object's ID.
+# Find all PendedKeyValue entries that are associated with the pending
+# object's ID.
 q = PendedKeyValue.filter(
 PendedKeyValue.c.pended_id == Pending.c.id).filter(
 Pending.c.id == pending.id)
@@ -116,8 +116,8 @@
 now = datetime.datetime.now()
 for pending in Pending.select():
 if pending.expiration_date  now:
-# Find all PendingKeyValue entries that are associated with
-# the pending object's ID.
+# Find all PendedKeyValue entries that are associated with the
+# pending object's ID.
 q = PendedKeyValue.filter(
 PendedKeyValue.c.pended_id == Pending.c.id).filter(
 Pending.c.id == pending.id)

=== modified file 'setup.py'
--- a/setup.py  2007-08-05 04:32:09 +
+++ b/setup.py  2007-09-13 02:44:07 +
@@ -91,7 +91,7 @@
 # Third-party requirements.
 install_requires = [
 'Elixir',
-'SQLAlchemy',
+'SQLAlchemy=0.3.10',
 'munepy',
 'wsgiref',
 'zope.interface',



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-12 Thread noreply

revno: 6548
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-09-09 19:13:36 -0400
message:
  Support forwarding of held posts.
modified:
  Mailman/app/moderator.py
  Mailman/docs/requests.txt

=== modified file 'Mailman/app/moderator.py'
--- a/Mailman/app/moderator.py  2007-09-09 17:22:27 +
+++ b/Mailman/app/moderator.py  2007-09-09 23:13:36 +
@@ -147,7 +147,7 @@
 i18n.set_language(language)
 try:
 fmsg = Message.UserNotification(
-addr, mlist.bounces_address,
+addresses, mlist.bounces_address,
 _('Forward of moderated message'),
 lang=language)
 finally:

=== modified file 'Mailman/docs/requests.txt'
--- a/Mailman/docs/requests.txt 2007-09-09 17:22:27 +
+++ b/Mailman/docs/requests.txt 2007-09-09 23:13:36 +
@@ -393,9 +393,29 @@
  flush()
  qmsg, qdata = dequeue()
  print qmsg.as_string()
-XXX
+Subject: Forward of moderated message
+From: [EMAIL PROTECTED]
+To: [EMAIL PROTECTED]
+MIME-Version: 1.0
+Content-Type: message/rfc822
+Message-ID: ...
+Date: ...
+Precedence: bulk
+BLANKLINE
+From: [EMAIL PROTECTED]
+To: [EMAIL PROTECTED]
+Subject: Something important
+Message-ID: 12345
+X-List-ID-Hash: 4CF7EAU3SIXBPXBB5S6PEUMO62MWGQN6
+X-List-Sequence-Number: ...
+BLANKLINE
+Here's something important about our mailing list.
+BLANKLINE
  sorted(qdata.items())
-XXX
+[('_parsemsg', False), ('listname', '[EMAIL PROTECTED]'),
+('nodecorate', True), ('received_time', ...),
+('recips', ['[EMAIL PROTECTED]']),
+('reduced_list_headers', True), ('version', 3)]
 
 
 Holding subscription requests



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-12 Thread noreply

revno: 6546
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Tue 2007-08-07 23:24:13 -0500
message:
  Interfaces IRequests and IListRequests which are substitutes for the ListAdmin
  mixin.  This latter will go away soon.  Added implementation and tests.  The
  implementation has some cruft though -- it forces us to use a flush() in the
  code because I don't yet know how to get to SA's last_inserted_ids().
  
  Note that this implementation abuses the IPendings interface in order to store
  arbitrary string key/value pairs.
  
  Fix the auto-discovery of interfaces by allowing Enums in interface files as
  well.  Long term, this is how it should work anyway.
added:
  Mailman/database/model/requests.py
  Mailman/docs/requests.txt
  Mailman/interfaces/requests.py
modified:
  Mailman/database/__init__.py
  Mailman/database/model/__init__.py
  Mailman/database/model/pending.py
  Mailman/interfaces/__init__.py
  Mailman/interfaces/pending.py

=== added file 'Mailman/database/model/requests.py'
--- a/Mailman/database/model/requests.py1970-01-01 00:00:00 +
+++ b/Mailman/database/model/requests.py2007-08-08 04:24:13 +
@@ -0,0 +1,121 @@
+# Copyright (C) 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.
+
+Implementations of the IRequests and IListRequests interfaces.
+
+from datetime import timedelta
+from elixir import *
+from zope.interface import implements
+
+from Mailman.configuration import config
+from Mailman.database.types import EnumType
+from Mailman.interfaces import IListRequests, IPendable, IRequests, RequestType
+
+
+MAILINGLIST_KIND = 'Mailman.database.model.mailinglist.MailingList'
+
+
+__metaclass__ = type
+__all__ = [
+'Requests',
+]
+
+
+
+class DataPendable(dict):
+implements(IPendable)
+
+
+
+class ListRequests:
+implements(IListRequests)
+
+def __init__(self, mailing_list):
+self.mailing_list = mailing_list
+
+@property
+def count(self):
+results = _Request.select_by(mailing_list=self.mailing_list._data)
+return len(results)
+
+@property
+def held_requests(self):
+results = _Request.select_by(mailing_list=self.mailing_list._data)
+for request in results:
+yield request.id, request.type
+
+def hold_request(self, request_type, key, data=None):
+if request_type not in RequestType:
+raise TypeError(request_type)
+if data is None:
+data_hash = None
+else:
+# We're abusing the pending database as a way of storing arbitrary
+# key/value pairs, where both are strings.  This isn't ideal but
+# it lets us get auxiliary data almost for free.  We may need to
+# lock this down more later.
+pendable = DataPendable()
+pendable.update(data)
+token = config.db.pendings.add(pendable, timedelta(days=5000))
+data_hash = token
+result = _Request(key=key, type=request_type,
+  mailing_list=self.mailing_list._data,
+  data_hash=data_hash)
+# XXX We need a handle on last_inserted_ids() instead of requiring a
+# flush of the database to get a valid id.
+config.db.flush()
+return result.id
+
+def get_request(self, request_id):
+result = _Request.get(request_id)
+if result is None:
+return None
+if result.data_hash is None:
+return result.key, result.data_hash
+pendable = config.db.pendings.confirm(result.data_hash, expunge=False)
+data = dict()
+data.update(pendable)
+return result.key, data
+
+def delete_request(self, request_id):
+result = _Request.get(request_id)
+if result is None:
+raise KeyError(request_id)
+# Throw away the pended data.
+config.db.pendings.confirm(result.data_hash)
+result.delete()
+
+
+
+class Requests:
+implements(IRequests)
+
+def get_list_requests(self, mailing_list):
+return ListRequests(mailing_list)
+
+
+
+class _Request(Entity):
+Table for mailing list hold requests.
+
+has_field('key',  

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-12 Thread noreply

revno: 6547
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-09-09 13:22:27 -0400
message:
  ListAdmin mostly gone, but not quite.
  
  Mailman/app/moderator.py: Most of the application level interface
  provided by ListAdmin is moved here now, including the ability to hold
  messages, subscriptions, and unsubscriptions, and to handle message
  (defer, discard, reject, accept).  More work needed.
  
  Some untested conversion of API in Mailman/Cgi/admindb.py, confirm.py,
  bin/checkdbs.py.
  
  messagestore.py: Don't use or require the Date: header in the global
  message ID calculation.  As described on the mailing list, we're only
  going to use the Message-ID header.
  
  IListRequests: added count_of() and of_type() methods.
added:
  Mailman/app/moderator.py
modified:
  Mailman/Cgi/admindb.py
  Mailman/Cgi/confirm.py
  Mailman/MailList.py
  Mailman/Utils.py
  Mailman/bin/checkdbs.py
  Mailman/database/messagestore.py
  Mailman/database/model/requests.py
  Mailman/docs/requests.txt
  Mailman/interfaces/requests.py

=== added file 'Mailman/app/moderator.py'
--- a/Mailman/app/moderator.py  1970-01-01 00:00:00 +
+++ b/Mailman/app/moderator.py  2007-09-09 17:22:27 +
@@ -0,0 +1,352 @@
+# Copyright (C) 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.
+
+Application support for moderators.
+
+from __future__ import with_statement
+
+__all__ = [
+'hold_message',
+]
+
+import logging
+
+from datetime import datetime
+from email.utils import formatdate, getaddresses, make_msgid
+
+from Mailman import Message
+from Mailman import Utils
+from Mailman import i18n
+from Mailman.Queue.sbcache import get_switchboard
+from Mailman.configuration import config
+from Mailman.constants import Action
+from Mailman.interfaces import RequestType
+
+_ = i18n._
+__i18n_templates__ = True
+
+log = logging.getLogger('mailman.vette')
+
+
+
+def hold_message(mlist, msg, msgdata=None, reason=None):
+if msgdata is None:
+msgdata = {}
+else:
+# Make a copy of msgdata so that subsequent changes won't corrupt the
+# request database.  TBD: remove the `filebase' key since this will
+# not be relevant when the message is resurrected.
+msgdata = msgdata.copy()
+if reason is None:
+reason = ''
+# Add the message to the message store.  It is required to have a
+# Message-ID header.
+if 'message-id' not in msg:
+msg['Message-ID'] = make_msgid()
+seqno = config.db.message_store.add(msg)
+global_id = '%s/%s' % (msg['X-List-ID-Hash'], seqno)
+# Prepare the message metadata with some extra information needed only by
+# the moderation interface.
+msgdata['_mod_global_id'] = global_id
+msgdata['_mod_fqdn_listname'] = mlist.fqdn_listname
+msgdata['_mod_sender'] = msg.get_sender()
+msgdata['_mod_subject'] = msg.get('subject', _('(no subject)'))
+msgdata['_mod_reason'] = reason
+msgdata['_mod_hold_date'] = datetime.now().isoformat()
+# Now hold this request.  We'll use the message's global ID as the key.
+requestsdb = config.db.requests.get_list_requests(mlist)
+request_id = requestsdb.hold_request(
+RequestType.held_message, global_id, msgdata)
+return request_id
+
+
+
+def handle_message(mlist, id, action,
+   comment=None, preserve=False, forward=None):
+requestdb = config.db.requests.get_list_requests(mlist)
+key, msgdata = requestdb.get_request(id)
+# Handle the action.
+rejection = None
+global_id = msgdata['_mod_global_id']
+if action is Action.defer:
+# Nothing to do, but preserve the message for later.
+preserve = True
+elif action is Action.discard:
+rejection = 'Discarded'
+elif action is Action.reject:
+rejection = 'Refused'
+sender = msgdata['_mod_sender']
+subject = msgdata['_mod_subject']
+member = mlist.members.get_member(sender)
+if member:
+language = member.preferred_language
+else:
+language = None
+_refuse(mlist, _('Posting of your message titled $subject'),
+sender, comment or _('[No reason given]'), language)
+  

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-16 Thread noreply

revno: 6552
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-09-16 22:10:05 -0400
message:
  Finish clean up of ListAdmin class removal.  Start by actually
  removing the module.  Then, fix a few tests that failed as a result of
  this work.
  
  Mailman/Handlers/Hold.py: Call hold_message() instead of
  mlist.HoldMessage().
  
  The message store also no longer requires a Date: header, so clean up
  a few tests that were still expecting that.
  
  Extend cleaning_teardown() in test_documentation.py so that both the
  message store and any list-centric requests are cleaned up after each
  test.
removed:
  Mailman/ListAdmin.py
modified:
  Mailman/Handlers/Hold.py
  Mailman/docs/hold.txt
  Mailman/docs/messagestore.txt
  Mailman/tests/test_documentation.py

=== removed file 'Mailman/ListAdmin.py'
--- a/Mailman/ListAdmin.py  2007-07-03 05:09:53 +
+++ b/Mailman/ListAdmin.py  1970-01-01 00:00:00 +
@@ -1,494 +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.
-
-Mixin class for MailList which handles administrative requests.
-
-Two types of admin requests are currently supported: adding members to a
-closed or semi-closed list, and moderated posts.
-
-Pending subscriptions which are requiring a user's confirmation are handled
-elsewhere.
-
-
-from __future__ import with_statement
-
-import os
-import time
-import email
-import errno
-import cPickle
-import logging
-import marshal
-
-from cStringIO import StringIO
-from email.Generator import Generator
-from email.MIMEMessage import MIMEMessage
-from email.Utils import getaddresses
-
-from Mailman import Errors
-from Mailman import Message
-from Mailman import Utils
-from Mailman import i18n
-from Mailman.Queue.sbcache import get_switchboard
-from Mailman.UserDesc import UserDesc
-from Mailman.configuration import config
-
-_ = i18n._
-
-# Request types requiring admin approval
-IGN = 0
-HELDMSG = 1
-SUBSCRIPTION = 2
-UNSUBSCRIPTION = 3
-
-# Return status from __handlepost()
-DEFER = 0
-REMOVE = 1
-LOST = 2
-
-DASH = '-'
-NL = '\n'
-
-log = logging.getLogger('mailman.vette')
-
-
-
-class ListAdmin:
-def InitTempVars(self):
-self._db = None
-self._filename = os.path.join(self.full_path, 'request.pck')
-
-def _opendb(self):
-if self._db is None:
-assert self.Locked()
-try:
-with open(self._filename) as fp:
-self._db = cPickle.load(fp)
-except IOError, e:
-if e.errno  errno.ENOENT:
-raise
-self._db = {}
-# put version number in new database
-self._db['version'] = IGN, config.REQUESTS_FILE_SCHEMA_VERSION
-
-def _closedb(self):
-if self._db is not None:
-assert self.Locked()
-# Save the version number
-self._db['version'] = IGN, config.REQUESTS_FILE_SCHEMA_VERSION
-# Now save a temp file and do the tmpfile-real file dance.  BAW:
-# should we be as paranoid as for the config.pck file?  Should we
-# use pickle?
-tmpfile = self._filename + '.tmp'
-with open(tmpfile, 'w') as fp:
-cPickle.dump(self._db, fp, 1)
-fp.flush()
-os.fsync(fp.fileno())
-self._db = None
-# Do the dance
-os.rename(tmpfile, self._filename)
-
-@property
-def _next_id(self):
-assert self.Locked()
-while True:
-missing = object()
-next = self.next_request_id
-self.next_request_id += 1
-if self._db.setdefault(next, missing) is missing:
-return next
-
-def SaveRequestsDb(self):
-self._closedb()
-
-def NumRequestsPending(self):
-self._opendb()
-# Subtract one for the version pseudo-entry
-return len(self._db) - 1
-
-def _getmsgids(self, rtype):
-self._opendb()
-ids = sorted([k for k, (op, data) in self._db.items() if op == rtype])
-return ids
-
-def GetHeldMessageIds(self):
-return self._getmsgids(HELDMSG)
-
-def 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-19 Thread noreply

revno: 6554
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-09-19 07:28:58 -0400
message:
  Implement a context manager for Python 2.5's with statement, which is
  used where we used to do a try/except to temporarily change the global
  translation language.  This makes the code shorter and cleaner.  E.g.
  
  with i18n.using_language(another_language):
  # do something
modified:
  Mailman/Archiver/HyperArch.py
  Mailman/Cgi/subscribe.py
  Mailman/Deliverer.py
  Mailman/Handlers/Hold.py
  Mailman/Handlers/ToDigest.py
  Mailman/MailList.py
  Mailman/Queue/Runner.py
  Mailman/app/membership.py
  Mailman/app/moderator.py
  Mailman/bin/add_members.py
  Mailman/bin/change_pw.py
  Mailman/bin/newlist.py
  Mailman/i18n.py
  TODO.txt

=== modified file 'Mailman/Archiver/HyperArch.py'
--- a/Mailman/Archiver/HyperArch.py 2007-07-15 01:23:28 +
+++ b/Mailman/Archiver/HyperArch.py 2007-09-19 11:28:58 +
@@ -26,6 +26,8 @@
(probably in the 'update_dirty_archives' method).
 
 
+from __future__ import with_statement
+
 import os
 import re
 import sys
@@ -114,13 +116,8 @@
 if e.errno  errno.ENOENT: raise
 return _('size not available')
 if size  1000:
-# Avoid i18n side-effects
-otrans = i18n.get_translation()
-try:
-i18n.set_language(lang)
+with i18n.using_language(lang):
 out = _(' %(size)i bytes ')
-finally:
-i18n.set_translation(otrans)
 return out
 elif size  100:
 return ' %d KB ' % (size / 1000)
@@ -269,17 +266,12 @@
 # article (for this list) could be different from the site-wide
 # preferred language, so we need to ensure no side-effects will
 # occur.  Think what happens when executing bin/arch.
-otrans = i18n.get_translation()
-try:
-i18n.set_language(lang)
+with i18n.using_language(lang):
 if self.author == self.email:
 self.author = self.email = re.sub('@', _(' at '),
   self.email)
 else:
 self.email = re.sub('@', _(' at '), self.email)
-finally:
-i18n.set_translation(otrans)
-
 # Snag the content-* headers.  RFC 1521 states that their values are
 # case insensitive.
 ctype = message.get('Content-Type', 'text/plain')
@@ -401,14 +393,10 @@
 self.decoded['email'] = email
 if subject:
 if config.ARCHIVER_OBSCURES_EMAILADDRS:
-otrans = i18n.get_translation()
-try:
-i18n.set_language(self._lang)
+with i18n.using_language(self._lang):
 atmark = unicode(_(' at '), Utils.GetCharSet(self._lang))
 subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
   '\g1' + atmark + '\g2', subject)
-finally:
-i18n.set_translation(otrans)
 self.decoded['subject'] = subject
 self.decoded['stripped'] = self.strip_subject(subject or self.subject)
 
@@ -443,9 +431,7 @@
 def as_html(self):
 d = self.__dict__.copy()
 # avoid i18n side-effects
-otrans = i18n.get_translation()
-i18n.set_language(self._lang)
-try:
+with i18n.using_language(self._lang):
 d[prev], d[prev_wsubj] = self._get_prev()
 d[next], d[next_wsubj] = self._get_next()
 
@@ -468,9 +454,6 @@
 d['listurl'] = self._mlist.GetScriptURL('listinfo', absolute=1)
 d['listname'] = self._mlist.real_name
 d['encoding'] = ''
-finally:
-i18n.set_translation(otrans)
-
 charset = Utils.GetCharSet(self._lang)
 d[encoding] = html_charset % charset
 
@@ -562,14 +545,10 @@
 if not isinstance(body, unicode):
 body = unicode(body, cset, 'replace')
 if config.ARCHIVER_OBSCURES_EMAILADDRS:
-otrans = i18n.get_translation()
-try:
+with i18n.using_language(self._lang):
 atmark = unicode(_(' at '), cset)
-i18n.set_language(self._lang)
 body = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
   '\g1' + atmark + '\g2', body)
-finally:
-i18n.set_translation(otrans)
 # Return body to character set of article.
 body = body.encode(cset, 'replace')
 return NL.join(headers) % d + '\n\n' + body + '\n'
@@ -668,12 +647,10 @@
 def html_foot(self):
 # avoid i18n side-effects
 mlist = self.maillist
-otrans = i18n.get_translation()
-i18n.set_language(mlist.preferred_language)
 # Convenience
 def quotetime(s):
 return 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-19 Thread noreply

revno: 6555
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-09-19 22:35:37 -0400
message:
  InitTempVars() is completely eradicated.  The only bit I think we
  still need temporarily is the _gui component initialization, so this
  has been moved into MailList.__init__().
  
  Fixed the __getattr__() super call to properly dispatch up.
  
  Removed the _memberadaptor instance variable initialization.  The
  whole MemberAdaptor stuff is next on the chopping block.
  
  Essentially MailList locking is gone too now, although it's not  yet
  completely eradicated.  However, the __repr__() no longer states the
  lock status.
  
  The full_path property is now just an attribute on the underlying
  MailingList database object.
modified:
  Mailman/MailList.py
  Mailman/database/model/mailinglist.py
  Mailman/docs/hold.txt
  Mailman/docs/membership.txt
  Mailman/docs/requests.txt
  TODO.txt

=== modified file 'Mailman/MailList.py'
--- a/Mailman/MailList.py   2007-09-19 11:28:58 +
+++ b/Mailman/MailList.py   2007-09-20 02:35:37 +
@@ -97,12 +97,16 @@
 
 def __init__(self, data):
 self._data = data
-# Only one level of mixin inheritance allowed
+# Only one level of mixin inheritance allowed.
 for baseclass in self.__class__.__bases__:
 if hasattr(baseclass, '__init__'):
 baseclass.__init__(self)
-# Initialize volatile attributes
-self.InitTempVars()
+# Initialize the web u/i components.
+self._gui = []
+for component in dir(Gui):
+if component.startswith('_'):
+continue
+self._gui.append(getattr(Gui, component)())
 # Give the extension mechanism a chance to process this list.
 try:
 from Mailman.ext import init_mlist
@@ -114,15 +118,11 @@
 def __getattr__(self, name):
 missing = object()
 if name.startswith('_'):
-return super(MailList, self).__getattr__(name)
+return getattr(super(MailList, self), name)
 # Delegate to the database model object if it has the attribute.
 obj = getattr(self._data, name, missing)
 if obj is not missing:
 return obj
-# Delegate to the member adapter next.
-obj = getattr(self._memberadaptor, name, missing)
-if obj is not missing:
-return obj
 # Finally, delegate to one of the gui components.
 for guicomponent in self._gui:
 obj = getattr(guicomponent, name, missing)
@@ -132,12 +132,7 @@
 raise AttributeError(name)
 
 def __repr__(self):
-if self.Locked():
-status = '(locked)'
-else:
-status = '(unlocked)'
-return 'mailing list %s %s at %x' % (
-self.fqdn_listname, status, id(self))
+return 'mailing list %s at %x' % (self.fqdn_listname, id(self))
 
 
 #
@@ -170,15 +165,6 @@
 
 
 
-#
-# Useful accessors
-#
-@property
-def full_path(self):
-return self._full_path
-
-
-
 # IMailingListAddresses
 
 @property
@@ -278,42 +264,6 @@
 
 
 #
-# Instance and subcomponent initialization
-#
-def InitTempVars(self):
-Set transient variables of this and inherited classes.
-# Because of the semantics of the database layer, it's possible that
-# this method gets called more than once on an existing object.  For
-# example, if the MailList object is expunged from the current db
-# session, then this may get called again when the object's persistent
-# attributes are re-read from the database.  This can have nasty
-# consequences, so ensure that we're only called once.
-if hasattr(self, '_lock'):
-return
-# Attach a membership adaptor instance.
-parts = config.MEMBER_ADAPTOR_CLASS.split(DOT)
-adaptor_class = parts.pop()
-adaptor_module = DOT.join(parts)
-__import__(adaptor_module)
-mod = sys.modules[adaptor_module]
-self._memberadaptor = getattr(mod, adaptor_class)(self)
-self._make_lock(self.fqdn_listname)
-# Create the list's data directory.
-self._full_path = os.path.join(config.LIST_DATA_DIR, 
self.fqdn_listname)
-Utils.makedirs(self._full_path)
-# Only one level of mixin inheritance allowed
-for baseclass in self.__class__.__bases__:
-if hasattr(baseclass, 'InitTempVars'):
-baseclass.InitTempVars(self)
-# Now, initialize our gui components
-self._gui = []
-for component in dir(Gui):
-if component.startswith('_'):
-continue
-self._gui.append(getattr(Gui, component)())
-
-
-#
 # Web API support via administrative categories
 #
 def GetConfigCategories(self):

=== 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-20 Thread noreply

revno: 6556
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Thu 2007-09-20 22:39:20 -0400
message:
  Get bin/add_members and bin/list_members to work again (for the most
  part).  Mostly this is just updating the code to use the new APIs, but
  there's also some other code clean up involved.  There's still more to
  do for sure, but this is a start.
modified:
  Mailman/bin/add_members.py
  Mailman/bin/list_lists.py
  Mailman/bin/list_members.py
  Mailman/bin/newlist.py
  Mailman/database/model/mailinglist.py
  TODO.txt

=== modified file 'Mailman/bin/add_members.py'
--- a/Mailman/bin/add_members.py2007-09-19 11:28:58 +
+++ b/Mailman/bin/add_members.py2007-09-21 02:39:20 +
@@ -22,7 +22,7 @@
 import optparse
 
 from cStringIO import StringIO
-from email.Utils import parseaddr
+from email.utils import parseaddr
 
 from Mailman import Errors
 from Mailman import MailList
@@ -30,7 +30,10 @@
 from Mailman import Utils
 from Mailman import Version
 from Mailman import i18n
+from Mailman.app.membership import add_member
 from Mailman.configuration import config
+from Mailman.constants import DeliveryMode
+from Mailman.initialize import initialize
 
 _ = i18n._
 __i18n_templates__ = True
@@ -69,13 +72,9 @@
   help=_('Alternative configuration file to use'))
 opts, args = parser.parse_args()
 if not args:
-parser.print_help()
-print  sys.stderr, _('Missing listname')
-sys.exit(1)
+parser.error(_('Missing listname'))
 if len(args)  1:
-parser.print_help()
-print  sys.stderr, _('Unexpected arguments')
-sys.exit(1)
+parser.error(_('Unexpected arguments'))
 if opts.welcome_msg is not None:
 ch = opts.welcome_msg[0].lower()
 if ch == 'y':
@@ -83,9 +82,7 @@
 elif ch == 'n':
 opts.welcome_msg = False
 else:
-parser.print_help()
-print  sys.stderr, _('Illegal value for -w: $opts.welcome_msg')
-sys.exit(1)
+parser.error(_('Illegal value for -w: $opts.welcome_msg'))
 if opts.admin_notify is not None:
 ch = opts.admin_notify[0].lower()
 if ch == 'y':
@@ -93,17 +90,11 @@
 elif ch == 'n':
 opts.admin_notify = False
 else:
-parser.print_help()
-print  sys.stderr, _('Illegal value for -a: $opts.admin_notify')
-sys.exit(1)
+parser.error(_('Illegal value for -a: $opts.admin_notify'))
 if opts.regular is None and opts.digest is None:
-parser.print_help()
-print  sys.stderr, _('At least one of -r or -d is required')
-sys.exit(1)
+parser.error(_('At least one of -r or -d is required'))
 if opts.regular == '-' and opts.digest == '-':
-parser.print_help()
-print  sys.stderr, _(-r and -d cannot both be '-')
-sys.exit(1)
+parser.error(_(-r and -d cannot both be '-'))
 return parser, opts, args
 
 
@@ -131,45 +122,37 @@
 self._outfp.write(msg)
 
 
-class UserDesc:
-pass
-
-
 
-def addall(mlist, members, digest, ack, outfp):
+def addall(mlist, subscribers, delivery_mode, ack, admin_notify, outfp):
 tee = Tee(outfp)
-for member in members:
-userdesc = UserDesc()
-userdesc.fullname, userdesc.address = parseaddr(member)
-userdesc.digest = digest
-
+for subscriber in subscribers:
 try:
-mlist.ApprovedAddMember(userdesc, ack, 0)
-except Errors.MMAlreadyAMember:
-print  tee, _('Already a member: $member')
+fullname, address = parseaddr(subscriber)
+password = Utils.MakeRandomPassword()
+add_member(mlist, address, fullname, password, delivery_mode,
+   config.DEFAULT_SERVER_LANGUAGE, ack, admin_notify)
+except AlreadySubscribedError:
+print  tee, _('Already a member: $subscriber')
 except Errors.InvalidEmailAddress:
 if userdesc.address == '':
 print  tee, _('Bad/Invalid email address: blank line')
 else:
 print  tee, _('Bad/Invalid email address: $member')
 else:
-print  tee, _('Subscribed: $member')
+print  tee, _('Subscribing: $subscriber')
 
 
 
 def main():
 parser, opts, args = parseargs()
-config.load(opts.config)
+initialize(opts.config)
 
 listname = args[0].lower().strip()
-try:
-mlist = MailList.MailList(listname)
-except Errors.MMUnknownListError:
-parser.print_help()
-print  sys.stderr, _('No such list: $listname')
-sys.exit(1)
+mlist = config.db.list_manager.get(listname)
+if mlist is None:
+parser.error(_('No such list: $listname'))
 
-# Set up defaults
+# Set up defaults.
 if opts.welcome_msg is None:
 send_welcome_msg = 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-21 Thread noreply

revno: 6557
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Fri 2007-09-21 08:51:38 -0400
message:
  OMGW00T: After over a decade, the MailList mixin class is gone!  Well,
  mostly.  It's no longer needed by anything in the test suite, and
  therefore the list manager returns database MailingList objects
  directly.  The wrapper cruft has been removed.
  
  To accomplish this, a couple of hacks were added to the Mailman.app
  package, which will get cleaned up over time.  The MailList module
  itself (and its few remaining mixins) aren't yet removed from the tree
  because some of the code is still not tested, and I want to leave this
  code around until I've finished converting it.
added:
  Mailman/app/archiving.py
  Mailman/app/bounces.py
  Mailman/app/replybot.py
modified:
  Mailman/Bouncer.py
  Mailman/Handlers/CookHeaders.py
  Mailman/Handlers/Hold.py
  Mailman/Handlers/Replybot.py
  Mailman/Handlers/Scrubber.py
  Mailman/Handlers/ToDigest.py
  Mailman/MailList.py
  Mailman/Queue/CommandRunner.py
  Mailman/Utils.py
  Mailman/app/lifecycle.py
  Mailman/app/membership.py
  Mailman/database/listmanager.py
  Mailman/database/model/mailinglist.py
  Mailman/database/model/requests.py
  Mailman/docs/acknowledge.txt
  Mailman/docs/bounces.txt
  Mailman/docs/cook-headers.txt
  Mailman/docs/hold.txt
  Mailman/docs/listmanager.txt
  Mailman/docs/replybot.txt
  Mailman/docs/requests.txt
  Mailman/docs/scrubber.txt
  TODO.txt

=== added file 'Mailman/app/archiving.py'
--- a/Mailman/app/archiving.py  1970-01-01 00:00:00 +
+++ b/Mailman/app/archiving.py  2007-09-21 12:51:38 +
@@ -0,0 +1,36 @@
+# Copyright (C) 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.
+
+Application level archiving support.
+
+from string import Template
+
+from Mailman.configuration import config
+
+
+
+def get_base_archive_url(mlist):
+if mlist.archive_private:
+url = mlist.script_url('private') + '/index.html'
+else:
+web_host = config.domains.get(mlist.host_name, mlist.host_name)
+url = Template(config.PUBLIC_ARCHIVE_URL).safe_substitute(
+listname=mlist.fqdn_listname,
+hostname=web_host,
+fqdn_listname=mlist.fqdn_listname,
+)
+return url

=== added file 'Mailman/app/bounces.py'
--- a/Mailman/app/bounces.py1970-01-01 00:00:00 +
+++ b/Mailman/app/bounces.py2007-09-21 12:51:38 +
@@ -0,0 +1,163 @@
+# Copyright (C) 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.
+
+Application level bounce handling.
+
+__all__ = [
+'bounce_message',
+'has_explicit_destination',
+'has_matching_bounce_header',
+]
+
+import re
+import logging
+
+from email.mime.message import MIMEMessage
+from email.mime.text import MIMEText
+from email.utils import getaddresses
+
+from Mailman import Message
+from Mailman import Utils
+from Mailman.i18n import _
+
+log = logging.getLogger('mailman.config')
+
+
+
+def bounce_message(mlist, msg, e=None):
+# Bounce a message back to the sender, with an error message if provided
+# in the exception argument.
+sender = msg.get_sender()
+subject = msg.get('subject', _('(no subject)'))
+subject = Utils.oneline(subject,
+Utils.GetCharSet(mlist.preferred_language))
+if e is None:
+notice = _('[No bounce details are available]')
+else:
+notice = _(e.notice)
+# Currently we always craft bounces as MIME messages.
+bmsg = 

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-09-21 Thread noreply

revno: 991
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-09-21 15:41:19 -0700
message:
  It is reported that some RedHat packages (for at least FC5 and FC6, but not
  FC7) contain a full working distutils in the 'python' package, but only
  contain the Python header files in the 'python-devel' package.  This allows
  configure to succeed, but make install fails to setup the japanese and
  korean codecs.  This change adds a specific test for Python.h to the
  distutils test.
modified:
  configure

=== modified file 'configure'
--- a/configure 2006-12-29 21:56:04 +
+++ b/configure 2007-09-21 22:41:19 +
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 7462 .
+# From configure.in Revision: 8122 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59.
 #
@@ -1446,7 +1446,14 @@
 except distutils.errors.DistutilsPlatformError:
 res = no
 else:
-res = yes
+# some RedHat packages put distutils in python, but the C headers
+# are in python-devel so check for headers too.
+import os.path
+pdothpath = distutils.sysconfig.get_config_var('CONFINCLUDEPY')
+if os.path.isfile(os.path.join(pdothpath, Python.h)):
+res = yes
+else:
+res = no
 fp = open(conftest.out, w)
 fp.write(%s\n % res)
 fp.close()
@@ -1462,13 +1469,15 @@
 * Distutils is not available or is incomplete for $PYTHON
 * If you installed Python from RPM (or other package manager)
 * be sure to install the -devel package, or install Python
-* from source.  See README.LINUX for details 5
+* from source.  See sec. 15.1 of the Installation Manual for
+* details 5
 echo $as_me: error:
 
 * Distutils is not available or is incomplete for $PYTHON
 * If you installed Python from RPM (or other package manager)
 * be sure to install the -devel package, or install Python
-* from source.  See README.LINUX for details 2;}
+* from source.  See sec. 15.1 of the Installation Manual for
+* details 2;}
{ (exit 1); exit 1; }; }
 fi
 echo $as_me:$LINENO: result: $havedistutils 5
@@ -4369,9 +4378,10 @@
   # 1. Remove the extension, and $U if already installed.
   ac_i=`echo $ac_i |
 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
-  # 2. Add them.
-  ac_libobjs=$ac_libobjs $ac_i\$U.$ac_objext
-  ac_ltlibobjs=$ac_ltlibobjs $ac_i'$U.lo'
+  # 2. Prepend LIBOBJDIR.  When used with automake=1.10 LIBOBJDIR
+  #will be set to the directory where LIBOBJS objects are built.
+  ac_libobjs=$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext
+  ac_ltlibobjs=$ac_ltlibobjs \${LIBOBJDIR}$ac_i'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-09-21 Thread noreply

revno: 990
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-09-21 15:22:15 -0700
message:
  It is reported that some RedHat packages (for at least FC5 and FC6, but not
  FC7) contain a full working distutils in the 'python' package, but only
  contain the Python header files in the 'python-devel' package.  This allows
  configure to succeed, but make install fails to setup the japanese and
  korean codecs.  This change adds a specific test for Python.h to the
  distutils test.
modified:
  configure.in

=== modified file 'configure.in'
--- a/configure.in  2006-12-29 21:56:04 +
+++ b/configure.in  2007-09-21 22:22:15 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
+# 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
@@ -101,7 +101,14 @@
 except distutils.errors.DistutilsPlatformError:
 res = no
 else:
-res = yes
+# some RedHat packages put distutils in python, but the C headers
+# are in python-devel so check for headers too.
+import os.path
+pdothpath = distutils.sysconfig.get_config_var('CONFINCLUDEPY')
+if os.path.isfile(os.path.join(pdothpath, Python.h)):
+res = yes
+else:
+res = no
 fp = open(conftest.out, w)
 fp.write(%s\n % res)
 fp.close()
@@ -117,7 +124,8 @@
 * Distutils is not available or is incomplete for $PYTHON
 * If you installed Python from RPM (or other package manager)
 * be sure to install the -devel package, or install Python
-* from source.  See README.LINUX for details])
+* from source.  See sec. 15.1 of the Installation Manual for
+* details])
 fi
 AC_MSG_RESULT($havedistutils)
 



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-29 Thread noreply

revno: 6559
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Thu 2007-09-27 22:33:04 -0400
message:
  Repair the test suite.
modified:
  Mailman/Queue/Runner.py
  Mailman/docs/listmanager.txt
  Mailman/docs/mlist-addresses.txt
  Mailman/tests/test_handlers.py
  Mailman/tests/test_membership.py

=== modified file 'Mailman/Queue/Runner.py'
--- a/Mailman/Queue/Runner.py   2007-09-19 11:28:58 +
+++ b/Mailman/Queue/Runner.py   2007-09-28 02:33:04 +
@@ -28,7 +28,6 @@
 from cStringIO import StringIO
 
 from Mailman import Errors
-from Mailman import MailList
 from Mailman import Utils
 from Mailman import i18n
 from Mailman.Queue.Switchboard import Switchboard
@@ -204,7 +203,7 @@
 the primary overridable method for processing each message.
 Subclasses, must provide implementation for this method.
 
-mlist is the MailList instance this message is destined for.
+mlist is the IMailingList instance this message is destined for.
 
 msg is the Message object representing the message.
 

=== modified file 'Mailman/docs/listmanager.txt'
--- a/Mailman/docs/listmanager.txt  2007-09-21 12:51:38 +
+++ b/Mailman/docs/listmanager.txt  2007-09-28 02:33:04 +
@@ -25,12 +25,6 @@
  IMailingList.providedBy(mlist)
 True
 
-This object has an identity.
-
- from Mailman.interfaces import IMailingListIdentity
- IMailingListIdentity.providedBy(mlist)
-True
-
 All lists with identities have a short name, a host name, and a fully
 qualified listname.  This latter is what uniquely distinguishes the mailing
 list to the system.

=== modified file 'Mailman/docs/mlist-addresses.txt'
--- a/Mailman/docs/mlist-addresses.txt  2007-08-02 14:47:56 +
+++ b/Mailman/docs/mlist-addresses.txt  2007-09-28 02:33:04 +
@@ -5,12 +5,9 @@
 These are defined in the IMailingListAddresses interface.
 
  from Mailman.configuration import config
- from Mailman.interfaces import IMailingListAddresses
  from Mailman.database import flush
  mlist = config.db.list_manager.create('[EMAIL PROTECTED]')
  flush()
- IMailingListAddresses.providedBy(mlist)
-True
 
 The posting address is where people send messages to be posted to the mailing
 list.  This is exactly the same as the fully qualified list name.

=== modified file 'Mailman/tests/test_handlers.py'
--- a/Mailman/tests/test_handlers.py2007-07-21 20:19:54 +
+++ b/Mailman/tests/test_handlers.py2007-09-28 02:33:04 +
@@ -23,7 +23,6 @@
 from Mailman import Errors
 from Mailman import Message
 from Mailman import passwords
-from Mailman.MailList import MailList
 from Mailman.configuration import config
 
 from Mailman.Handlers import Approve
@@ -114,5 +113,4 @@
 
 def test_suite():
 suite = unittest.TestSuite()
-## suite.addTest(unittest.makeSuite(TestApprove))
 return suite

=== modified file 'Mailman/tests/test_membership.py'
--- a/Mailman/tests/test_membership.py  2007-07-21 20:19:54 +
+++ b/Mailman/tests/test_membership.py  2007-09-28 02:33:04 +
@@ -21,8 +21,6 @@
 import time
 import unittest
 
-from Mailman import MailList
-from Mailman import MemberAdaptor
 from Mailman import Utils
 from Mailman import passwords
 from Mailman.Errors import NotAMemberError



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-29 Thread noreply

revno: 6560
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sat 2007-09-29 11:09:14 -0400
message:
  qrunner, mailmanctl and various other repairs.
  
  The convenience methods in Defaults for getting seconds, minutes, hours, and
  days now returns a subtype of timedelta, which provides conversion to float
  and int for compatibility with interfaces that require those values
  (e.g. signal.alarm() and time.sleep().
  
  In bin/make_instance, the var_dir really needs to be an absolute path,
  otherwise it's possible to get a var dir nested inside the var dir.
  
  More MailList object eradication.
modified:
  Mailman/Defaults.py
  Mailman/LockFile.py
  Mailman/Queue/BounceRunner.py
  Mailman/Queue/RetryRunner.py
  Mailman/Queue/Runner.py
  Mailman/bin/mailmanctl.py
  Mailman/bin/make_instance.py
  Mailman/bin/withlist.py

=== modified file 'Mailman/Defaults.py'
--- a/Mailman/Defaults.py   2007-09-28 02:15:00 +
+++ b/Mailman/Defaults.py   2007-09-29 15:09:14 +
@@ -24,17 +24,27 @@
 
 
 
+class CompatibleTimeDelta(timedelta):
+def __float__(self):
+# Convert to float seconds.
+return (self.days * 24 * 60 * 60 +
+self.seconds + self.microseconds / 1.0e6)
+
+def __int__(self):
+return int(float(self))
+
+
 def seconds(s):
-return timedelta(seconds=s)
+return CompatibleTimeDelta(seconds=s)
 
 def minutes(m):
-return timedelta(minutes=m)
+return CompatibleTimeDelta(minutes=m)
 
 def hours(h):
-return timedelta(hours=h)
+return CompatibleTimeDelta(hours=h)
 
 def days(d):
-return timedelta(days=d)
+return CompatibleTimeDelta(days=d)
 
 
 # Some convenient constants
@@ -714,7 +724,7 @@
 # Qrunner defaults
 #
 
-# Which queues should the qrunner master watchdog spawn?  add_qrunners() takes
+# Which queues should the qrunner master watchdog spawn?  add_qrunner() takes
 # one required argument, which is the name of the qrunner to start
 # (capitalized and without the 'Runner' suffix).  Optional second argument
 # specifies the number of parallel processes to fork for each qrunner.  If

=== modified file 'Mailman/LockFile.py'
--- a/Mailman/LockFile.py   2007-08-01 21:05:06 +
+++ b/Mailman/LockFile.py   2007-09-29 15:09:14 +
@@ -64,8 +64,8 @@
 
 # Units are floating-point seconds.
 DEFAULT_LOCK_LIFETIME  = datetime.timedelta(seconds=15)
-# Allowable a bit of clock skew
-CLOCK_SLOP = datetime.timedelta(seconds=10)
+# Allowable a bit of clock skew, in seconds.
+CLOCK_SLOP = 10
 # This is appropriate for Mailman, but you may want to change this if you're
 # using this code outside Mailman.
 log = logging.getLogger('mailman.locks')

=== modified file 'Mailman/Queue/BounceRunner.py'
--- a/Mailman/Queue/BounceRunner.py 2007-01-05 06:47:39 +
+++ b/Mailman/Queue/BounceRunner.py 2007-09-29 15:09:14 +
@@ -19,9 +19,9 @@
 
 import os
 import re
-import time
 import cPickle
 import logging
+import datetime
 
 from email.MIMEMessage import MIMEMessage
 from email.MIMEText import MIMEText
@@ -81,10 +81,11 @@
 config.DATA_DIR, 'bounce-events-%05d.pck' % os.getpid())
 self._bounce_events_fp = None
 self._bouncecnt = 0
-self._nextaction = time.time() + config.REGISTER_BOUNCES_EVERY
+self._nextaction = (datetime.datetime.now() +
+config.REGISTER_BOUNCES_EVERY)
 
 def _queue_bounces(self, listname, addrs, msg):
-today = time.localtime()[:3]
+today = datetime.date.today()
 if self._bounce_events_fp is None:
 self._bounce_events_fp = open(self._bounce_events_file, 'a+b')
 for addr in addrs:
@@ -129,7 +130,7 @@
 self._register_bounces()
 
 def _doperiodic(self):
-now = time.time()
+now = datetime.datetime.now()
 if self._nextaction  now or self._bouncecnt == 0:
 return
 # Let's go ahead and register the bounces we've got stored up

=== modified file 'Mailman/Queue/RetryRunner.py'
--- a/Mailman/Queue/RetryRunner.py  2007-01-19 04:38:06 +
+++ b/Mailman/Queue/RetryRunner.py  2007-09-29 15:09:14 +
@@ -38,4 +38,4 @@
 
 def _snooze(self, filecnt):
 # We always want to snooze
-time.sleep(self.SLEEPTIME)
+time.sleep(float(self.SLEEPTIME))

=== modified file 'Mailman/Queue/Runner.py'
--- a/Mailman/Queue/Runner.py   2007-09-28 02:33:04 +
+++ b/Mailman/Queue/Runner.py   2007-09-29 15:09:14 +
@@ -229,9 +229,9 @@
 based on this value.  By default, we only snooze if there was nothing
 to do last time around.
 
-if filecnt or self.SLEEPTIME = 0:
+if filecnt or float(self.SLEEPTIME) = 0:
 return
-time.sleep(self.SLEEPTIME)
+time.sleep(float(self.SLEEPTIME))
 
 def _shortcircuit(self):
 Return a true value if the individual file processing 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-09-29 Thread noreply

revno: 6562
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sat 2007-09-29 15:10:52 -0400
message:
  Eradicate mm_cfg.py
removed:
  Mailman/mm_cfg.py.dist.in
modified:
  Mailman/Defaults.py
  Mailman/Message.py
  Mailman/configuration.py

=== removed file 'Mailman/mm_cfg.py.dist.in'
--- a/Mailman/mm_cfg.py.dist.in 2007-01-19 04:38:06 +
+++ b/Mailman/mm_cfg.py.dist.in 1970-01-01 00:00:00 +
@@ -1,44 +0,0 @@
-# -*- python -*-
-
-# Copyright (C) 1998-2007,1999,2000,2001,2002 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.
-
-This module contains your site-specific settings.
-
-From a brand new distribution it should be copied to mm_cfg.py.  If you
-already have an mm_cfg.py, be careful to add in only the new settings you
-want.  Mailman's installation procedure will never overwrite your mm_cfg.py
-file.
-
-The complete set of distributed defaults, with documentation, are in the file
-Defaults.py.  In mm_cfg.py, override only those you want to change, after the
-
-  from Defaults import *
-
-line (see below).
-
-Note that these are just default settings; many can be overridden via the
-administrator and user interfaces on a per-list or per-user basis.
-
-
-
-###
-# Here's where we get the distributed defaults.
-
-from Defaults import *
-
-##
-# Put YOUR site-specific settings below this line.

=== modified file 'Mailman/Defaults.py'
--- a/Mailman/Defaults.py   2007-09-29 15:09:14 +
+++ b/Mailman/Defaults.py   2007-09-29 19:10:52 +
@@ -89,14 +89,6 @@
 # a human.
 SITE_OWNER_ADDRESS = '[EMAIL PROTECTED]'
 
-# DEFAULT_HOST_NAME has been replaced with DEFAULT_EMAIL_HOST, however some
-# sites may have the former in their mm_cfg.py files.  If so, we'll believe
-# that, otherwise we'll believe DEFAULT_EMAIL_HOST.  Same for DEFAULT_URL.
-DEFAULT_HOST_NAME = None
-DEFAULT_URL = None
-
-HOME_PAGE = 'index.html'
-
 # Normally when a site administrator authenticates to a web page with the site
 # password, they get a cookie which authorizes them as the list admin.  It
 # makes me nervous to hand out site auth cookies because if this cookie is
@@ -1342,12 +1334,13 @@
 # element being the description, as described in the catalogs, and second
 # element is the language charset.  I have chosen code from /usr/share/locale
 # in my GNU/Linux. :-)
-# TK: Now the site admin can select languages for the installation from
-# those in the distribution tarball.  We don't touch add_language() function
-# for backward compatibility in mm_cfg.py syntax.  You may have to add your
-# own language in mm_cfg.py if it is not included in the distribution even
-# if you had put language files in source directory and configured by
-# `--with-languages' option.
+#
+# TK: Now the site admin can select languages for the installation from those
+# in the distribution tarball.  We don't touch add_language() function for
+# backward compatibility.  You may have to add your own language in your
+# mailman.cfg file, if it is not included in the distribution even if you had
+# put language files in source directory and configured by `--with-languages'
+# option.
 def _(s):
 return s
 

=== modified file 'Mailman/Message.py'
--- a/Mailman/Message.py2007-09-29 18:55:25 +
+++ b/Mailman/Message.py2007-09-29 19:10:52 +
@@ -98,13 +98,13 @@
 header value found is returned.  However the search order is
 determined by the following:
 
-- If mm_cfg.USE_ENVELOPE_SENDER is true, then the search order is
+- If config.USE_ENVELOPE_SENDER is true, then the search order is
   Sender:, From:, unixfrom
 
 - Otherwise, the search order is From:, Sender:, unixfrom
 
 The optional argument use_envelope, if given overrides the
-mm_cfg.USE_ENVELOPE_SENDER setting.  It should be set to either 0 or 1
+config.USE_ENVELOPE_SENDER setting.  It should be set to either 0 or 1
 (don't use None since that indicates no-override).
 
 unixfrom should never be empty.  The return address is always

=== modified file 'Mailman/configuration.py'
--- a/Mailman/configuration.py  

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-04 Thread noreply

revno: 993
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 18:40:13 -0700
message:
  /cygdrive/c/MM_bzr/log.txt
modified:
  Mailman/Queue/MaildirRunner.py*

=== modified file 'Mailman/Queue/MaildirRunner.py' (properties changed)
--- a/Mailman/Queue/MaildirRunner.py2005-08-27 01:40:17 +
+++ b/Mailman/Queue/MaildirRunner.py2007-10-05 01:40:13 +
@@ -1,4 +1,4 @@
-# Copyright (C) 2002 by the Free Software Foundation, Inc.
+# Copyright (C) 2002-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
@@ -12,7 +12,8 @@
 #
 # 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.
 
 Maildir pre-queue runner.
 
@@ -66,11 +67,22 @@
 # listname-request@
 lre = re.compile(r
  ^# start of string
- (?Plistname[EMAIL PROTECTED]) # listname@ or listname-subq@
+ (?Plistname[EMAIL PROTECTED])# listname@ or listname-subq@ (non-greedy)
  (?:  # non-grouping
-  # dash separator
-   (?Psubq[EMAIL PROTECTED])  # everything up to + or - or @
+   (?Psubq  # any known suffix
+ admin|
+ bounces|
+ confirm|
+ join|
+ leave|
+ owner|
+ request|
+ subscribe|
+ unsubscribe
+   )
  )?   # if it exists
+ [EMAIL PROTECTED] # followed by + or @
  , re.VERBOSE | re.IGNORECASE)
 
 



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-04 Thread noreply

revno: 992
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 18:35:10 -0700
message:
  /cygdrive/c/MM_bzr/log.txt
modified:
  Mailman/versions.py

=== modified file 'Mailman/versions.py'
--- a/Mailman/versions.py   2005-12-30 18:50:08 +
+++ b/Mailman/versions.py   2007-10-05 01:35:10 +
@@ -483,10 +483,11 @@
 # blow away the original timestamp and request id.  This means the
 # request will live a little longer than it possibly should have,
 # but that's no big deal.
+import email
 for p in v:
 author, text = p[2]
 reason = p[3]
-msg = Message.OutgoingMessage(text)
+msg = email.message_from_string(text, Message.Message)
 l.HoldMessage(msg, reason)
 del r[k]
 elif k == 'add_member':



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-04 Thread noreply

revno: 994
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 18:43:42 -0700
message:
  /cygdrive/c/MM_bzr/log.txt
modified:
  Mailman/Handlers/MimeDel.py

=== modified file 'Mailman/Handlers/MimeDel.py'
--- a/Mailman/Handlers/MimeDel.py   2005-12-30 18:50:08 +
+++ b/Mailman/Handlers/MimeDel.py   2007-10-05 01:43:42 +
@@ -256,4 +256,4 @@
 fext = fext[1:]
 else:
 fext = ''
-return fext
+return fext.lower()



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-04 Thread noreply

revno: 997
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 19:53:13 -0700
message:
  Fixed MaildirRunner.py to handle hyphenated list names.



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-04 Thread noreply

revno: 995
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 19:50:56 -0700
message:
  In rare cases, versions.py can encounter a very old list with held posts in
  its requests dictionary.  It then tries to create a Message.OutgoingMessage
  object from the message text, but that class no longer exists.  Fixed by
  using email.message_from_string() instead.
modified:
  Mailman/versions.py

=== modified file 'Mailman/versions.py'
--- a/Mailman/versions.py   2007-10-05 01:35:10 +
+++ b/Mailman/versions.py   2007-10-05 02:50:56 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
+# 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



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-04 Thread noreply

revno: 996
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 19:52:04 -0700
message:
  MimeDel.py neglected to lower case file extensions for comparison with
  lower cased *_filename_extensions.  Fixed.
modified:
  Mailman/Handlers/MimeDel.py

=== modified file 'Mailman/Handlers/MimeDel.py'
--- a/Mailman/Handlers/MimeDel.py   2007-10-05 01:43:42 +
+++ b/Mailman/Handlers/MimeDel.py   2007-10-05 02:52:04 +
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2005 by the Free Software Foundation, Inc.
+# Copyright (C) 2002-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



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-05 Thread noreply

revno: 6563
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Fri 2007-10-05 17:17:58 -0400
message:
  Remove an unnecessary (and now broken) import.
  
  Lower case the list name before calling remove_list().
modified:
  Mailman/bin/rmlist.py

=== modified file 'Mailman/bin/rmlist.py'
--- a/Mailman/bin/rmlist.py 2007-08-06 03:49:04 +
+++ b/Mailman/bin/rmlist.py 2007-10-05 21:17:58 +
@@ -23,7 +23,6 @@
 from Mailman import Errors
 from Mailman import Utils
 from Mailman import Version
-from Mailman.MailList import MailList
 from Mailman.app.lifecycle import remove_list
 from Mailman.configuration import config
 from Mailman.i18n import _
@@ -63,7 +62,7 @@
 parser, opts, args = parseargs()
 initialize(opts.config)
 
-fqdn_listname = args[0]
+fqdn_listname = args[0].lower()
 mlist = config.db.list_manager.get(fqdn_listname)
 if mlist is None:
 if not opts.archives:



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-06 Thread noreply

revno: 6565
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sat 2007-10-06 15:15:24 -0400
message:
  merge upstream
modified:
  Mailman/bin/rmlist.py

revno: 6562.1.1
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Fri 2007-10-05 17:17:58 -0400
message:
  Remove an unnecessary (and now broken) import.
  
  Lower case the list name before calling remove_list().
modified:
  Mailman/bin/rmlist.py

=== modified file 'Mailman/bin/rmlist.py'
--- a/Mailman/bin/rmlist.py 2007-08-06 03:49:04 +
+++ b/Mailman/bin/rmlist.py 2007-10-05 21:17:58 +
@@ -23,7 +23,6 @@
 from Mailman import Errors
 from Mailman import Utils
 from Mailman import Version
-from Mailman.MailList import MailList
 from Mailman.app.lifecycle import remove_list
 from Mailman.configuration import config
 from Mailman.i18n import _
@@ -63,7 +62,7 @@
 parser, opts, args = parseargs()
 initialize(opts.config)
 
-fqdn_listname = args[0]
+fqdn_listname = args[0].lower()
 mlist = config.db.list_manager.get(fqdn_listname)
 if mlist is None:
 if not opts.archives:



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-06 Thread noreply

revno: 6564
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sat 2007-10-06 15:09:34 -0400
message:
  Changes to support the Approved/Approve header with the new user
  model.  Specifically, where a mailing list used to have both a
  password and a moderator password, both of which could be used in the
  Approved header, now a mailing list has only a shared moderator
  password.  This moderator password's only purpose in life is to allow
  for Approved header posting.
  
  test_handlers.py is now completely ported to doctests, so it's removed.
removed:
  Mailman/tests/test_handlers.py
added:
  Mailman/docs/approve.txt
modified:
  Mailman/Handlers/Approve.py
  Mailman/database/model/mailinglist.py

=== removed file 'Mailman/tests/test_handlers.py'
--- a/Mailman/tests/test_handlers.py2007-09-28 02:33:04 +
+++ b/Mailman/tests/test_handlers.py1970-01-01 00:00:00 +
@@ -1,116 +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.
-
-Unit tests for the various Mailman/Handlers/*.py modules.
-
-import email
-import unittest
-
-from Mailman import Errors
-from Mailman import Message
-from Mailman import passwords
-from Mailman.configuration import config
-
-from Mailman.Handlers import Approve
-# Don't test handlers such as SMTPDirect and Sendmail here
-
-
-
-def password(cleartext):
-return passwords.make_secret(cleartext, passwords.Schemes.ssha)
-
-
-
-class TestApprove(unittest.TestCase):
-def test_short_circuit(self):
-msgdata = {'approved': 1}
-rtn = Approve.process(self._mlist, None, msgdata)
-# Not really a great test, but there's little else to assert
-self.assertEqual(rtn, None)
-
-def test_approved_moderator(self):
-mlist = self._mlist
-mlist.mod_password = password('wazoo')
-msg = email.message_from_string(\
-Approved: wazoo
-
-)
-msgdata = {}
-Approve.process(mlist, msg, msgdata)
-self.failUnless(msgdata.has_key('approved'))
-self.assertEqual(msgdata['approved'], 1)
-
-def test_approve_moderator(self):
-mlist = self._mlist
-mlist.mod_password = password('wazoo')
-msg = email.message_from_string(\
-Approve: wazoo
-
-)
-msgdata = {}
-Approve.process(mlist, msg, msgdata)
-self.failUnless(msgdata.has_key('approved'))
-self.assertEqual(msgdata['approved'], 1)
-
-def test_approved_admin(self):
-mlist = self._mlist
-mlist.password = password('wazoo')
-msg = email.message_from_string(\
-Approved: wazoo
-
-)
-msgdata = {}
-Approve.process(mlist, msg, msgdata)
-self.failUnless(msgdata.has_key('approved'))
-self.assertEqual(msgdata['approved'], 1)
-
-def test_approve_admin(self):
-mlist = self._mlist
-mlist.password = password('wazoo')
-msg = email.message_from_string(\
-Approve: wazoo
-
-)
-msgdata = {}
-Approve.process(mlist, msg, msgdata)
-self.failUnless(msgdata.has_key('approved'))
-self.assertEqual(msgdata['approved'], 1)
-
-def test_unapproved(self):
-mlist = self._mlist
-mlist.password = password('zoowa')
-msg = email.message_from_string(\
-Approve: wazoo
-
-)
-msgdata = {}
-Approve.process(mlist, msg, msgdata)
-self.assertEqual(msgdata.get('approved'), None)
-
-def test_trip_beentheres(self):
-mlist = self._mlist
-msg = email.message_from_string(\
-X-BeenThere: %s
-
- % mlist.GetListEmail())
-self.assertRaises(Errors.LoopError, Approve.process, mlist, msg, {})
-
-
-
-def test_suite():
-suite = unittest.TestSuite()
-return suite

=== added file 'Mailman/docs/approve.txt'
--- a/Mailman/docs/approve.txt  1970-01-01 00:00:00 +
+++ b/Mailman/docs/approve.txt  2007-10-06 19:09:34 +
@@ -0,0 +1,418 @@
+Pre-approved postings
+=
+
+Messages can contain a pre-approval, which is used to bypass the message
+approval queue.  This has several use cases:
+
+- A list administrator can send an emergency message to the mailing list from
+  an unregistered address, say if they are away from their normal 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-06 Thread noreply

revno: 6563
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-10-03 19:54:26 -0400
message:
  Remove unused test base class and add a standalone SMTP proxy script.
removed:
  Mailman/tests/emailbase.py
added:
  Mailman/tests/smtplistener.py

=== removed file 'Mailman/tests/emailbase.py'
--- a/Mailman/tests/emailbase.py2007-07-18 15:46:44 +
+++ b/Mailman/tests/emailbase.py1970-01-01 00:00:00 +
@@ -1,106 +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.
-
-Base class for tests that email things.
-
-import os
-import time
-import errno
-import smtpd
-import socket
-import asyncore
-import subprocess
-
-from Mailman.configuration import config
-from Mailman.tests.base import TestBase
-
-TESTPORT = 10825
-
-
-
-MSGTEXT = None
-
-class OneShotChannel(smtpd.SMTPChannel):
-def smtp_QUIT(self, arg):
-smtpd.SMTPChannel.smtp_QUIT(self, arg)
-raise asyncore.ExitNow
-
-
-class SinkServer(smtpd.SMTPServer):
-def handle_accept(self):
-conn, addr = self.accept()
-channel = OneShotChannel(self, conn, addr)
-
-def process_message(self, peer, mailfrom, rcpttos, data):
-global MSGTEXT
-MSGTEXT = data
-
-
-
-class EmailBase(TestBase):
-def setUp(self):
-TestBase.setUp(self)
-try:
-# Second argument is ignored.
-self._server = SinkServer(('localhost', TESTPORT), None)
-except:
-TestBase.tearDown(self)
-raise
-try:
-os.system('bin/mailmanctl -C %s -q start' % config.filename)
-# If any errors occur in the above, be sure to manually call
-# tearDown().  unittest doesn't call tearDown() for errors in
-# setUp().
-except:
-self.tearDown()
-raise
-
-def tearDown(self):
-os.system('bin/mailmanctl -C %s -q stop' % config.filename)
-self._server.close()
-# Wait a while until the server actually goes away
-while True:
-try:
-s = socket.socket()
-s.connect(('localhost', TESTPORT))
-s.close()
-time.sleep(3)
-except socket.error, e:
-# IWBNI e had an errno attribute
-if e[0] in (errno.ECONNREFUSED, errno.ETIMEDOUT):
-break
-else:
-raise
-TestBase.tearDown(self)
-
-def _readmsg(self):
-global MSGTEXT
-# Save and unlock the list so that the qrunner process can open it and
-# lock it if necessary.  We'll re-lock the list in our finally clause
-# since that if an invariant of the test harness.
-self._mlist.Unlock()
-try:
-try:
-# timeout is in milliseconds, see asyncore.py poll3()
-asyncore.loop()
-MSGTEXT = None
-except asyncore.ExitNow:
-pass
-asyncore.close_all()
-return MSGTEXT
-finally:
-self._mlist.Lock()

=== added file 'Mailman/tests/smtplistener.py'
--- a/Mailman/tests/smtplistener.py 1970-01-01 00:00:00 +
+++ b/Mailman/tests/smtplistener.py 2007-10-03 23:54:26 +
@@ -0,0 +1,91 @@
+# Copyright (C) 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.
+
+import sys
+import smtpd
+import mailbox
+import asyncore
+import optparse
+
+from email import 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-06 Thread noreply
1 revision was removed from the branch.


--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-09 Thread noreply

revno: 6567
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-10-10 00:16:12 -0400
message:
  Remove the action.py module, move this to Mailman/interfaces/__init__.py.
  
  Convert IMailingList.personalize to a enum.
  
  Change all non-obsolete occurances of GetListEmail() to posting_address.
removed:
  Mailman/interfaces/action.py
modified:
  Mailman/Commands/cmd_info.py
  Mailman/Handlers/CookHeaders.py
  Mailman/Handlers/SMTPDirect.py
  Mailman/Handlers/ToOutgoing.py
  Mailman/MailList.py
  Mailman/app/styles.py
  Mailman/bin/gate_news.py
  Mailman/bin/withlist.py
  Mailman/database/model/mailinglist.py
  Mailman/docs/cook-headers.txt
  Mailman/docs/news-runner.txt
  Mailman/docs/outgoing.txt
  Mailman/interfaces/__init__.py
  Mailman/interfaces/mailinglist.py
  Mailman/queue/news.py

=== removed file 'Mailman/interfaces/action.py'
--- a/Mailman/interfaces/action.py  2007-10-10 02:18:14 +
+++ b/Mailman/interfaces/action.py  1970-01-01 00:00:00 +
@@ -1,31 +0,0 @@
-# Copyright (C) 2006-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.
-
-__all__ = [
-'Action',
-]
-
-from munepy import Enum
-
-
-
-class Action(Enum):
-hold= 0
-reject  = 1
-discard = 2
-accept  = 3
-defer   = 4

=== modified file 'Mailman/Commands/cmd_info.py'
--- a/Mailman/Commands/cmd_info.py  2007-01-19 04:38:06 +
+++ b/Mailman/Commands/cmd_info.py  2007-10-10 04:16:12 +
@@ -37,10 +37,10 @@
 return STOP
 listname = mlist.real_name
 description = mlist.description or _('n/a')
-postaddr = mlist.GetListEmail()
-requestaddr = mlist.GetRequestEmail()
-owneraddr = mlist.GetOwnerEmail()
-listurl = mlist.GetScriptURL('listinfo', absolute=1)
+postaddr = mlist.posting_address
+requestaddr = mlist.request_address
+owneraddr = mlist.owner_address
+listurl = mlist.script_url('listinfo')
 res.results.append(_('List name:%(listname)s'))
 res.results.append(_('Description:  %(description)s'))
 res.results.append(_('Postings to:  %(postaddr)s'))

=== modified file 'Mailman/Handlers/CookHeaders.py'
--- a/Mailman/Handlers/CookHeaders.py   2007-10-10 02:18:14 +
+++ b/Mailman/Handlers/CookHeaders.py   2007-10-10 04:16:12 +
@@ -29,7 +29,7 @@
 from Mailman.app.archiving import get_base_archive_url
 from Mailman.configuration import config
 from Mailman.i18n import _
-from Mailman.interfaces import ReplyToMunging
+from Mailman.interfaces import Personalization, ReplyToMunging
 
 CONTINUATION = ',\n\t'
 COMMASPACE = ', '
@@ -148,7 +148,7 @@
 # above code?
 # Also skip Cc if this is an anonymous list as list posting address
 # is already in From and Reply-To in this case.
-if (mlist.personalize == 2 and
+if (mlist.personalize == Personalization.full and
 mlist.reply_goes_to_list  ReplyToMunging.point_to_list and
 not mlist.anonymous_list):
 # Watch out for existing Cc headers, merge, and remove dups.  Note
@@ -158,7 +158,7 @@
 for pair in getaddresses(msg.get_all('cc', [])):
 add(pair)
 i18ndesc = uheader(mlist, mlist.description, 'Cc')
-add((str(i18ndesc), mlist.GetListEmail()))
+add((str(i18ndesc), mlist.posting_address))
 del msg['Cc']
 msg['Cc'] = COMMASPACE.join([formataddr(pair) for pair in new])
 # Add list-specific headers as defined in RFC 2369 and RFC 2919, but only

=== modified file 'Mailman/Handlers/SMTPDirect.py'
--- a/Mailman/Handlers/SMTPDirect.py2007-01-19 04:38:06 +
+++ b/Mailman/Handlers/SMTPDirect.py2007-10-10 04:16:12 +
@@ -42,6 +42,7 @@
 from Mailman.Handlers import Decorate
 from Mailman.SafeDict import MsgSafeDict
 from Mailman.configuration import config
+from Mailman.interfaces import Personalization
 
 DOT = '.'
 
@@ -114,7 +115,7 @@
 # recipients they'll swallow in a single transaction.
 deliveryfunc = None
 if (not msgdata.has_key('personalize') or msgdata['personalize']) and (
-   msgdata.get('verp') or mlist.personalize):
+   msgdata.get('verp') or mlist.personalize  Personalization.none):

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-09 Thread noreply

revno: 6566
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Tue 2007-10-09 22:18:14 -0400
message:
  Reorganize the enums so that they live in the most appropriate interface.  The
  only constant left in Mailman.constants is now actually a constant.
added:
  Mailman/interfaces/action.py
modified:
  Mailman/Bouncer.py
  Mailman/Defaults.py
  Mailman/Handlers/CalcRecips.py
  Mailman/Handlers/CookHeaders.py
  Mailman/Handlers/ToDigest.py
  Mailman/app/lifecycle.py
  Mailman/app/membership.py
  Mailman/app/moderator.py
  Mailman/app/styles.py
  Mailman/bin/add_members.py
  Mailman/bin/list_members.py
  Mailman/bin/set_members.py
  Mailman/constants.py
  Mailman/database/model/roster.py
  Mailman/docs/acknowledge.txt
  Mailman/docs/addresses.txt
  Mailman/docs/avoid-duplicates.txt
  Mailman/docs/calc-recips.txt
  Mailman/docs/file-recips.txt
  Mailman/docs/membership.txt
  Mailman/docs/reply-to.txt
  Mailman/docs/requests.txt
  Mailman/interfaces/mailinglist.py
  Mailman/interfaces/member.py

=== added file 'Mailman/interfaces/action.py'
--- a/Mailman/interfaces/action.py  1970-01-01 00:00:00 +
+++ b/Mailman/interfaces/action.py  2007-10-10 02:18:14 +
@@ -0,0 +1,31 @@
+# Copyright (C) 2006-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.
+
+__all__ = [
+'Action',
+]
+
+from munepy import Enum
+
+
+
+class Action(Enum):
+hold= 0
+reject  = 1
+discard = 2
+accept  = 3
+defer   = 4

=== modified file 'Mailman/Bouncer.py'
--- a/Mailman/Bouncer.py2007-09-28 02:15:00 +
+++ b/Mailman/Bouncer.py2007-10-10 02:18:14 +
@@ -29,7 +29,7 @@
 from Mailman import Utils
 from Mailman import i18n
 from Mailman.configuration import config
-from Mailman.constants import DeliveryStatus
+from Mailman.interfaces import DeliveryStatus
 
 EMPTYSTRING = ''
 

=== modified file 'Mailman/Defaults.py'
--- a/Mailman/Defaults.py   2007-09-29 19:10:52 +
+++ b/Mailman/Defaults.py   2007-10-10 02:18:14 +
@@ -20,7 +20,7 @@
 import os
 from datetime import timedelta
 
-from Mailman.constants import *
+from Mailman.interfaces import ReplyToMunging
 
 
 

=== modified file 'Mailman/Handlers/CalcRecips.py'
--- a/Mailman/Handlers/CalcRecips.py2007-06-19 15:13:09 +
+++ b/Mailman/Handlers/CalcRecips.py2007-10-10 02:18:14 +
@@ -27,8 +27,8 @@
 from Mailman import Message
 from Mailman import Utils
 from Mailman.configuration import config
-from Mailman.constants import DeliveryStatus
 from Mailman.i18n import _
+from Mailman.interfaces import DeliveryStatus
 
 
 

=== modified file 'Mailman/Handlers/CookHeaders.py'
--- a/Mailman/Handlers/CookHeaders.py   2007-09-21 12:51:38 +
+++ b/Mailman/Handlers/CookHeaders.py   2007-10-10 02:18:14 +
@@ -28,8 +28,8 @@
 from Mailman import Version
 from Mailman.app.archiving import get_base_archive_url
 from Mailman.configuration import config
-from Mailman.constants import ReplyToMunging
 from Mailman.i18n import _
+from Mailman.interfaces import ReplyToMunging
 
 CONTINUATION = ',\n\t'
 COMMASPACE = ', '

=== modified file 'Mailman/Handlers/ToDigest.py'
--- a/Mailman/Handlers/ToDigest.py  2007-09-29 18:55:25 +
+++ b/Mailman/Handlers/ToDigest.py  2007-10-10 02:18:14 +
@@ -52,7 +52,7 @@
 from Mailman.Mailbox import Mailbox
 from Mailman.Mailbox import Mailbox
 from Mailman.configuration import config
-from Mailman.constants import DeliveryMode, DeliveryStatus
+from Mailman.interfaces import DeliveryMode, DeliveryStatus
 from Mailman.queue import Switchboard
 
 _ = i18n._

=== modified file 'Mailman/app/lifecycle.py'
--- a/Mailman/app/lifecycle.py  2007-09-21 12:51:38 +
+++ b/Mailman/app/lifecycle.py  2007-10-10 02:18:14 +
@@ -27,7 +27,7 @@
 from Mailman.app.plugins import get_plugin
 from Mailman.app.styles import style_manager
 from Mailman.configuration import config
-from Mailman.constants import MemberRole
+from Mailman.interfaces import MemberRole
 
 __all__ = [
 'create_list',

=== modified file 'Mailman/app/membership.py'
--- a/Mailman/app/membership.py 2007-09-21 12:51:38 +
+++ b/Mailman/app/membership.py 2007-10-10 02:18:14 +
@@ -25,7 +25,7 @@
 from Mailman import Utils
 from 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-10 Thread noreply

revno: 6568
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-10-10 23:22:03 -0400
message:
  General cleanups some of which is even tested wink.  Mailman.LockFile module
  is moved to Mailman.lockfile.
  
  Remove a few more MailList methods that aren't used any more, e.g. the lock
  related stuff, the Save() and CheckValues() methods, as well as
  ChangeMemberName().
  
  Add a missing import to lifecycle.py.
  
  We no longer need withlist to unlock the mailing list.  Also, expose
  config.db.flush() in the namespace of withlist directly, under 'flush'.
renamed:
  Mailman/LockFile.py = Mailman/lockfile.py
modified:
  Mailman/Archiver/HyperArch.py
  Mailman/Archiver/HyperDatabase.py
  Mailman/Handlers/Scrubber.py
  Mailman/MTA/Manual.py
  Mailman/MTA/Postfix.py
  Mailman/MailList.py
  Mailman/app/lifecycle.py
  Mailman/bin/arch.py
  Mailman/bin/gate_news.py
  Mailman/bin/mailmanctl.py
  Mailman/bin/withlist.py
  Mailman/database/__init__.py
  Mailman/database/usermanager.py
  Mailman/queue/archive.py
  Mailman/queue/bounce.py
  Mailman/queue/command.py
  Mailman/queue/incoming.py
  Mailman/queue/outgoing.py
  Mailman/tests/test_lockfile.py
  Mailman/lockfile.py

=== renamed file 'Mailman/LockFile.py' = 'Mailman/lockfile.py'
--- a/Mailman/LockFile.py   2007-09-29 15:09:14 +
+++ b/Mailman/lockfile.py   2007-10-11 03:22:03 +
@@ -47,6 +47,14 @@
 your clocks are properly synchronized.
 
 
+__metaclass__ = type
+__all__ = [
+'LockError',
+'AlreadyLockedError',
+'NotLockedError',
+'LockFile',
+]
+
 # This code has undergone several revisions, with contributions from Barry
 # Warsaw, Thomas Wouters, Harald Meland, and John Viega.  It should also work
 # well outside of Mailman so it could be used for other Python projects

=== modified file 'Mailman/Archiver/HyperArch.py'
--- a/Mailman/Archiver/HyperArch.py 2007-09-19 11:28:58 +
+++ b/Mailman/Archiver/HyperArch.py 2007-10-11 03:22:03 +
@@ -43,10 +43,10 @@
 from email.Header import decode_header, make_header
 
 from Mailman import Errors
-from Mailman import LockFile
 from Mailman import MailList
 from Mailman import Utils
 from Mailman import i18n
+from Mailman import lockfile
 from Mailman.Archiver import HyperDatabase
 from Mailman.Archiver import pipermail
 from Mailman.Mailbox import ArchiverMailbox
@@ -786,12 +786,12 @@
 def GetArchLock(self):
 if self._lock_file:
 return 1
-self._lock_file = LockFile.LockFile(
+self._lock_file = lockfile.LockFile(
 os.path.join(config.LOCK_DIR,
  self.maillist.fqdn_listname + '-arch.lock'))
 try:
 self._lock_file.lock(timeout=0.5)
-except LockFile.TimeOutError:
+except lockfile.TimeOutError:
 return 0
 return 1
 

=== modified file 'Mailman/Archiver/HyperDatabase.py'
--- a/Mailman/Archiver/HyperDatabase.py 2007-01-19 04:38:06 +
+++ b/Mailman/Archiver/HyperDatabase.py 2007-10-11 03:22:03 +
@@ -27,7 +27,7 @@
 # package/project modules
 #
 import pipermail
-from Mailman import LockFile
+from Mailman.lockfile import LockFile
 
 CACHESIZE = pipermail.CACHESIZE
 
@@ -58,7 +58,7 @@
 def __init__(self, path):
 self.current_index = 0
 self.path = path
-self.lockfile = LockFile.LockFile(self.path + .lock)
+self.lockfile = LockFile(self.path + .lock)
 self.lock()
 self.__dirty = 0
 self.dict = {}

=== modified file 'Mailman/Handlers/Scrubber.py'
--- a/Mailman/Handlers/Scrubber.py  2007-09-21 12:51:38 +
+++ b/Mailman/Handlers/Scrubber.py  2007-10-11 03:22:03 +
@@ -17,6 +17,8 @@
 
 Cleanse a message for archiving.
 
+from __future__ import with_statement
+
 import os
 import re
 import sha
@@ -34,13 +36,13 @@
 from email.parser import HeaderParser
 from email.utils import make_msgid, parsedate
 
-from Mailman import LockFile
 from Mailman import Message
 from Mailman import Utils
 from Mailman.Errors import DiscardMessage
 from Mailman.app.archiving import get_base_archive_url
 from Mailman.configuration import config
 from Mailman.i18n import _
+from Mailman.lockfile import LockFile
 
 # Path characters for common platforms
 pre = re.compile(r'[/\\:]')
@@ -422,10 +424,7 @@
 ext = '.bin'
 path = None
 # We need a lock to calculate the next attachment number
-lockfile = os.path.join(fsdir, 'attachments.lock')
-lock = LockFile.LockFile(lockfile)
-lock.lock()
-try:
+with LockFile(os.path.join(fsdir, 'attachments.lock')):
 # Now base the filename on what's in the attachment, uniquifying it if
 # necessary.
 if not filename or config.SCRUBBER_DONT_USE_ATTACHMENT_FILENAME:
@@ -461,8 +460,6 @@
 extra = '-%04d' % counter
 else:
 break
-finally:
-lock.unlock()
 # `path' 

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-18 Thread noreply

revno: 1000
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-18 13:34:36 -0700
message:
  MailList.Create() - added an assertion that the listname is lower case.
modified:
  Mailman/MailList.py

=== modified file 'Mailman/MailList.py'
--- a/Mailman/MailList.py   2006-03-12 02:24:53 +
+++ b/Mailman/MailList.py   2007-10-18 20:34:36 +
@@ -470,6 +470,7 @@
 #
 def Create(self, name, admin, crypted_password,
langs=None, emailhost=None):
+assert name == name.lower(), 'List name must be all lower case.'
 if Utils.list_exists(name):
 raise Errors.MMListAlreadyExistsError, name
 # Validate what will be the list's posting address.  If that's



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-10-18 Thread noreply

revno: 999
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-18 13:29:49 -0700
message:
  Added a call to warnings.filterwarnings() to misc/paths.py.in to supress the
  Python 2.5 DeprecationWarning on string exceptions.
modified:
  misc/paths.py.in

=== modified file 'misc/paths.py.in'
--- a/misc/paths.py.in  2006-10-12 00:48:48 +
+++ b/misc/paths.py.in  2007-10-18 20:29:49 +
@@ -1,6 +1,6 @@
 # -*- python -*-
 
-# Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
+# 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
@@ -24,8 +24,9 @@
 # attributes that other modules may use to get the absolute path to the
 # installed Mailman distribution.
 
+import os
 import sys
-import os
+from warnings import filterwarnings
 
 # some scripts expect this attribute to be in this module
 prefix = '@prefix@'
@@ -35,6 +36,9 @@
 if exec_prefix == '${prefix}':
 exec_prefix = prefix
 
+# Supress Python 2.5 warning about string exceptions.
+filterwarnings('ignore', '.* string exception', DeprecationWarning)
+
 # Check if ja/ko codecs are available before changing path.
 try:
 s = unicode('OK', 'iso-2022-jp')



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-31 Thread noreply

revno: 6571
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-10-31 17:43:04 -0400
message:
  Elixir 0.4.0 has a bug that bites us.
modified:
  setup.py

=== modified file 'setup.py'
--- a/setup.py  2007-10-31 21:38:51 +
+++ b/setup.py  2007-10-31 21:43:04 +
@@ -90,7 +90,7 @@
 },
 # Third-party requirements.
 install_requires = [
-'Elixir',
+'Elixir0.4.0',
 'SQLAlchemy',
 'locknix',
 'munepy',



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-10-31 Thread noreply

revno: 6570
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Wed 2007-10-31 17:39:41 -0400
message:
  more ignores
modified:
  .bzrignore

=== modified file '.bzrignore'
--- a/.bzrignore2007-07-21 14:04:17 +
+++ b/.bzrignore2007-10-31 21:39:41 +
@@ -7,3 +7,5 @@
 misc/mailman
 setuptoolsbzr-*.egg
 staging
+TAGS
+var/



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-11-06 Thread noreply

revno: 6573
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Tue 2007-11-06 18:03:28 -0800
message:
  - Scrubber.py
Fixed an issue where an implicit text/plain part without any headers gets
lost.
  
Moved the cleansing of the filename extension to a place where it is
guaranteed to be a string as opposed to an empty list.
modified:
  Mailman/Handlers/Scrubber.py

=== modified file 'Mailman/Handlers/Scrubber.py'
--- a/Mailman/Handlers/Scrubber.py  2007-10-31 21:38:51 +
+++ b/Mailman/Handlers/Scrubber.py  2007-11-07 02:03:28 +
@@ -46,7 +46,7 @@
 # Path characters for common platforms
 pre = re.compile(r'[/\\:]')
 # All other characters to strip out of Content-Disposition: filenames
-# (essentially anything that isn't an alphanum, dot, slash, or underscore.
+# (essentially anything that isn't an alphanum, dot, dash, or underscore).
 sre = re.compile(r'[^-\w.]')
 # Regexp to strip out leading dots
 dre = re.compile(r'^\.*')
@@ -265,7 +265,7 @@
 # If the message isn't a multipart, then we'll strip it out as an
 # attachment that would have to be separately downloaded.  Pipermail
 # will transform the url into a hyperlink.
-elif part and not part.is_multipart():
+elif part._payload and not part.is_multipart():
 payload = part.get_payload(decode=True)
 ctype = part.get_content_type()
 # XXX Under email 2.5, it is possible that payload will be None.
@@ -313,7 +313,8 @@
 charsets = []
 for part in msg.walk():
 # TK: bug-id 1099138 and multipart
-if not part or part.is_multipart():
+# MAS test payload - if part may fail if there are no headers.
+if not part._payload or part.is_multipart():
 continue
 # All parts should be scrubbed to text/plain by now.
 partctype = part.get_content_type()
@@ -410,8 +411,6 @@
 ext = fnext or guess_extension(ctype, fnext)
 else:
 ext = guess_extension(ctype, fnext)
-# Allow only alphanumerics, dash, underscore, and dot
-ext = sre.sub('', ext)
 if not ext:
 # We don't know what it is, so assume it's just a shapeless
 # application/octet-stream, unless the Content-Type: is
@@ -421,6 +420,8 @@
 ext = '.txt'
 else:
 ext = '.bin'
+# Allow only alphanumerics, dash, underscore, and dot
+ext = sre.sub('', ext)
 path = None
 # We need a lock to calculate the next attachment number
 with Lock(os.path.join(fsdir, 'attachments.lock')):



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-06 Thread noreply

revno: 1001
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 14:07:28 -0800
message:
  Changed the descriptions of the ARCHIVE_TO_MBOX settings to more
  accurately represent their current meaning.
modified:
  Mailman/Defaults.py.in

=== modified file 'Mailman/Defaults.py.in'
--- a/Mailman/Defaults.py.in2007-05-08 03:16:04 +
+++ b/Mailman/Defaults.py.in2007-11-04 22:07:28 +
@@ -217,11 +217,13 @@
 # ARCHIVE_TO_MBOX
 #-1 - do not do any archiving
 # 0 - do not archive to mbox, use builtin mailman html archiving only
-# 1 - archive to mbox to use an external archiving mechanism only
-# 2 - archive to both mbox and builtin mailman html archiving -
-# use this to make both external archiving mechanism work and
-# mailman's builtin html archiving.  the flat mail file can be
-# useful for searching, external archivers, etc.
+# 1 - do not use builtin mailman html archiving, archive to mbox only
+# 2 - archive to both mbox and builtin mailman html archiving.
+# See the settings below for PUBLIC_EXTERNAL_ARCHIVER and
+# PRIVATE_EXTERNAL_ARCHIVER which can be used to replace mailman's
+# builtin html archiving with an external archiver.  The flat mail
+# mbox file can be useful for searching, and is another way to
+# interface external archivers, etc.
 ARCHIVE_TO_MBOX = 2
 
 # 0 - yearly



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-06 Thread noreply

revno: 1003
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 15:03:38 -0800
message:
  - Cgi/options.py - fixed to not present the empty topic to user.
  - Handlers/CalcRecips.py - Changed to not process topics if topics
are disabled for the list.
modified:
  Mailman/Cgi/options.py
  Mailman/Handlers/CalcRecips.py

=== modified file 'Mailman/Cgi/options.py'
--- a/Mailman/Cgi/options.py2006-08-30 14:54:22 +
+++ b/Mailman/Cgi/options.py2007-11-04 23:03:38 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
+# 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
@@ -797,6 +797,8 @@
 if mlist.topics:
 table = Table(border=0)
 for name, pattern, description, emptyflag in mlist.topics:
+if emptyflag:
+continue
 quotedname = urllib.quote_plus(name)
 details = Link(mlist.GetScriptURL('options') +
'/%s/?VARHELP=%s' % (user, quotedname),

=== modified file 'Mailman/Handlers/CalcRecips.py'
--- a/Mailman/Handlers/CalcRecips.py2005-08-27 01:40:17 +
+++ b/Mailman/Handlers/CalcRecips.py2007-11-04 23:03:38 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
+# 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
@@ -12,7 +12,8 @@
 # 
 # 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.
 
 Calculate the regular (i.e. non-digest) recipients of the message.
 
@@ -91,6 +92,10 @@
 
 
 def do_topic_filters(mlist, msg, msgdata, recips):
+if not mlist.topics_enabled:
+# MAS: if topics are currently disabled for the list, send to all
+# regardless of ReceiveNonmatchingTopics
+return
 hits = msgdata.get('topichits')
 zaprecips = []
 if hits:



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-06 Thread noreply

revno: 1005
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Tue 2007-11-06 17:41:17 -0800
message:
  - Scrubber.py
Fixed an issue where an implicit text/plain part without any headers gets
lost.
  
Moved the cleansing of the filename extension to a place where it is
guaranteed to be a string as opposed to an empty list.
modified:
  Mailman/Handlers/Scrubber.py

=== modified file 'Mailman/Handlers/Scrubber.py'
--- a/Mailman/Handlers/Scrubber.py  2007-06-22 17:49:27 +
+++ b/Mailman/Handlers/Scrubber.py  2007-11-07 01:41:17 +
@@ -45,7 +45,7 @@
 # Path characters for common platforms
 pre = re.compile(r'[/\\:]')
 # All other characters to strip out of Content-Disposition: filenames
-# (essentially anything that isn't an alphanum, dot, slash, or underscore.
+# (essentially anything that isn't an alphanum, dot, dash, or underscore).
 sre = re.compile(r'[^-\w.]')
 # Regexp to strip out leading dots
 dre = re.compile(r'^\.*')
@@ -298,7 +298,7 @@
 # If the message isn't a multipart, then we'll strip it out as an
 # attachment that would have to be separately downloaded.  Pipermail
 # will transform the url into a hyperlink.
-elif part and not part.is_multipart():
+elif part._payload and not part.is_multipart():
 payload = part.get_payload(decode=True)
 ctype = part.get_type()
 # XXX Under email 2.5, it is possible that payload will be None.
@@ -349,7 +349,8 @@
 text = []
 for part in msg.walk():
 # TK: bug-id 1099138 and multipart
-if not part or part.is_multipart():
+# MAS test payload - if part may fail if there are no headers.
+if not part._payload or part.is_multipart():
 continue
 # All parts should be scrubbed to text/plain by now.
 partctype = part.get_content_type()
@@ -447,8 +448,6 @@
 ext = fnext or guess_extension(ctype, fnext)
 else:
 ext = guess_extension(ctype, fnext)
-# Allow only alphanumerics, dash, underscore, and dot
-ext = sre.sub('', ext)
 if not ext:
 # We don't know what it is, so assume it's just a shapeless
 # application/octet-stream, unless the Content-Type: is
@@ -458,6 +457,8 @@
 ext = '.txt'
 else:
 ext = '.bin'
+# Allow only alphanumerics, dash, underscore, and dot
+ext = sre.sub('', ext)
 path = None
 # We need a lock to calculate the next attachment number
 lockfile = os.path.join(fsdir, 'attachments.lock')



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-06 Thread noreply

revno: 1002
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 14:41:26 -0800
message:
  Added removal of Authentication-Results: header.
modified:
  Mailman/Handlers/CleanseDKIM.py

=== modified file 'Mailman/Handlers/CleanseDKIM.py'
--- a/Mailman/Handlers/CleanseDKIM.py   2007-05-08 03:16:04 +
+++ b/Mailman/Handlers/CleanseDKIM.py   2007-11-04 22:41:26 +
@@ -29,8 +29,8 @@
 
 
 def process(mlist, msg, msgdata):
-if not mm_cfg.REMOVE_DKIM_HEADERS:
-return
-del msg['domainkey-signature']
-del msg['dkim-signature']
+if mm_cfg.REMOVE_DKIM_HEADERS:
+del msg['domainkey-signature']
+del msg['dkim-signature']
+del msg['authentication-results']
 



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-06 Thread noreply

revno: 1004
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 15:19:31 -0800
message:
  Added Date and Message-ID headers to the confirm reply
  message that Mailman adds to the admin notification.
modified:
  Mailman/Handlers/Hold.py

=== modified file 'Mailman/Handlers/Hold.py'
--- a/Mailman/Handlers/Hold.py  2006-07-30 19:35:36 +
+++ b/Mailman/Handlers/Hold.py  2007-11-04 23:19:31 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
+# 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
@@ -283,6 +283,8 @@
 dmsg['Subject'] = 'confirm ' + cookie
 dmsg['Sender'] = requestaddr
 dmsg['From'] = requestaddr
+dmsg['Date'] = email.Utils.formatdate(localtime=True)
+dmsg['Message-ID'] = Utils.unique_message_id(mlist)
 nmsg.attach(text)
 nmsg.attach(MIMEMessage(msg))
 nmsg.attach(MIMEMessage(dmsg))



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-11-09 Thread noreply

revno: 6574
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Fri 2007-11-09 12:29:46 -0800
message:
  Fixed Mailman/queue/command.py to decode a quoted-printable or base64
  encoded message part.
modified:
  Mailman/queue/command.py

=== modified file 'Mailman/queue/command.py'
--- a/Mailman/queue/command.py  2007-10-11 03:22:03 +
+++ b/Mailman/queue/command.py  2007-11-09 20:29:46 +
@@ -83,7 +83,7 @@
 if part is None:
 # E.g the outer Content-Type: was text/html
 return
-body = part.get_payload()
+body = part.get_payload(decode=True)
 # text/plain parts better have string payloads
 assert isinstance(body, basestring)
 lines = body.splitlines()



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-09 Thread noreply

revno: 1006
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-11-09 12:25:33 -0800
message:
  Fixed Mailman/Queue/CommandRunner.py to decode a quoted-printable or base64
  encoded message part.
modified:
  Mailman/Queue/CommandRunner.py

=== modified file 'Mailman/Queue/CommandRunner.py'
--- a/Mailman/Queue/CommandRunner.py2005-08-27 01:40:17 +
+++ b/Mailman/Queue/CommandRunner.py2007-11-09 20:25:33 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2004 by the Free Software Foundation, Inc.
+# 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
@@ -93,7 +93,7 @@
 if part is None:
 # E.g the outer Content-Type: was text/html
 return
-body = part.get_payload()
+body = part.get_payload(decode=True)
 # text/plain parts better have string payloads
 assert isinstance(body, StringType) or isinstance(body, UnicodeType)
 lines = body.splitlines()



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-11-11 Thread noreply

revno: 6577
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-11-11 21:31:22 -0800
message:
  Mailman/Bouncers/SMTP32.py - Added a recognition. Improved address pattern.
  
  Mailman/Bouncers/SimpleMatch.py - Improved two regexps.
  
  Mailman/tests/test_bounces.py - Added a test.
modified:
  Mailman/Bouncers/SMTP32.py
  Mailman/Bouncers/SimpleMatch.py
  Mailman/tests/test_bounces.py

=== modified file 'Mailman/Bouncers/SMTP32.py'
--- a/Mailman/Bouncers/SMTP32.py2007-01-19 04:38:06 +
+++ b/Mailman/Bouncers/SMTP32.py2007-11-12 05:31:22 +
@@ -4,14 +4,14 @@
 # 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 
+# along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 # USA.
 
@@ -38,9 +38,10 @@
 |delivery\ failed[^:]*:   # wild...
 |unknown\ user[^:]*:
 |undeliverable\ +to
+|delivery\ userid[^:]*:
 )
 \s*   # space separator
-(?Paddr.*)  # and finally, the address
+(?Paddr[^\s]*)  # and finally, the address
 ''', re.IGNORECASE | re.VERBOSE)
 
 

=== modified file 'Mailman/Bouncers/SimpleMatch.py'
--- a/Mailman/Bouncers/SimpleMatch.py   2007-01-19 04:38:06 +
+++ b/Mailman/Bouncers/SimpleMatch.py   2007-11-12 05:31:22 +
@@ -101,7 +101,10 @@
  _c('^(?Paddr[EMAIL PROTECTED]@[^\s@:]+):')),
 # thehartford.com
 (_c('Delivery to the following recipients failed'),
- _c(Bogus - there actually isn't anything),
+ # this one may or may not have the original message, but there's nothing
+ # unique to stop on, so stop on the first line of at least 3 characters
+ # that doesn't start with 'D' (to not stop immediately) and has no '@'.
+ _c('[EMAIL PROTECTED],}$'),
  _c('^\s*(?Paddr[EMAIL PROTECTED]@[EMAIL PROTECTED])\s*$')),
 # and another thehartfod.com/hartfordlife.com
 (_c('^Your message\s*$'),
@@ -160,7 +163,7 @@
  _c('^-'),
  _c('\s(?Paddr[EMAIL PROTECTED]@[EMAIL PROTECTED])[\s,]')),
 # pla.net.py (MDaemon.PRO ?)
-(_c('no such user here'),
+(_c('- no such user here'),
  _c('There is no user'),
  _c('^(?Paddr[EMAIL PROTECTED]@[EMAIL PROTECTED])\s')),
 # Next one goes here...

=== modified file 'Mailman/tests/test_bounces.py'
--- a/Mailman/tests/test_bounces.py 2007-07-18 15:46:44 +
+++ b/Mailman/tests/test_bounces.py 2007-11-12 05:31:22 +
@@ -115,6 +115,7 @@
  '[EMAIL PROTECTED]']),
 ('SMTP32', 'smtp32_05.txt', ['[EMAIL PROTECTED]']),
 ('SMTP32', 'smtp32_06.txt', ['[EMAIL PROTECTED]']),
+('SMTP32', 'smtp32_07.txt', ['[EMAIL PROTECTED]']),
 # Qmail
 ('Qmail', 'qmail_01.txt', ['[EMAIL PROTECTED]']),
 ('Qmail', 'qmail_02.txt', ['[EMAIL PROTECTED]']),



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-11-11 Thread noreply

revno: 6576
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-11-11 18:50:47 -0800
message:
  Added a test message.
added:
  Mailman/tests/bounces/smtp32_07.txt

=== added file 'Mailman/tests/bounces/smtp32_07.txt'
--- a/Mailman/tests/bounces/smtp32_07.txt   1970-01-01 00:00:00 +
+++ b/Mailman/tests/bounces/smtp32_07.txt   2007-11-12 02:50:47 +
@@ -0,0 +1,81 @@
+Received: from smtp.digikom.net (smtp.digikom.net [195.43.38.47])
+   by sb7.songbird.com (8.12.11.20060308/8.12.11) with ESMTP id
+   kBP0vmk8004590
+   for [EMAIL PROTECTED]; Sun, 24 Dec 2006 16:57:49 -0800
+Received: from s05.dknet.se ([195.43.38.5]) by smtp.digikom.net with Microsoft
+   SMTPSVC(5.0.2195.6713); Mon, 25 Dec 2006 01:57:36 +0100
+Date: Mon, 25 Dec 2006 01:57:35 +0100
+Message-Id: [EMAIL PROTECTED]
+Mime-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+From: Postmaster [EMAIL PROTECTED]
+Sender: [EMAIL PROTECTED]
+To: [EMAIL PROTECTED]
+Subject: Undeliverable Mail
+X-Mailer: SMTP32 v8.15
+X-Declude-Sender:  [208.184.79.137]
+X-OriginalArrivalTime: 25 Dec 2006 00:57:36.0535 (UTC)
+   FILETIME=[AB0D2270:01C727BF]
+X-SongbirdInformation: [EMAIL PROTECTED] for more information
+X-Songbird: Clean
+X-Songbird-From: 
+
+Invalid final delivery userid: [EMAIL PROTECTED]
+
+
+Original message follows.
+
+Received: from sb7.songbird.com [208.184.79.137] by s05.dknet.se with ESMTP
+  (SMTPD32-8.15) id A1F789D00148; Mon, 25 Dec 2006 01:57:27 +0100
+Received: from sb7.songbird.com (sb7.songbird.com [127.0.0.1])
+   by sb7.songbird.com (8.12.11.20060308/8.12.11) with ESMTP id 
kBP0vFHx004449
+   for [EMAIL PROTECTED]; Sun, 24 Dec 2006 16:57:15 -0800
+Subject: The results of your email commands
+From: [EMAIL PROTECTED]
+To: [EMAIL PROTECTED]
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary1423078280==
+Message-ID: [EMAIL PROTECTED]
+Date: Sun, 24 Dec 2006 16:57:14 -0800
+Precedence: bulk
+X-BeenThere: [EMAIL PROTECTED]
+X-Mailman-Version: 2.1.5
+List-Id: Grizzly Peak Cyclists general discussion list gpc-talk.grizz.org
+X-List-Administrivia: yes
+Sender: [EMAIL PROTECTED]
+Errors-To: [EMAIL PROTECTED]
+X-SongbirdInformation: [EMAIL PROTECTED] for more information
+X-Songbird: Clean
+X-Songbird-From: [EMAIL PROTECTED]
+X-Declude-Sender: [EMAIL PROTECTED] [208.184.79.137]
+
+--===1423078280==
+Content-Type: text/plain; charset=us-ascii
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+
+The results of your email command are provided below. Attached is your
+original message.
+
+- Results:
+[EMAIL PROTECTED] is not a member of the GPC-talk mailing list
+
+- Unprocessed:
++ 5 inches or money back
+YO Chap
+I don't care why your member is so small, but 82% of women do.
+They are pretty sure that bigger Johnson will make their desire
+stronger. You have the chance to change your life.
+Here http://www.baleful.us you can get the thing.
+It will help you for sure.
+The remedy can be sent worldwide.
+If you wont be satisfied - we will return all you money.
+No bullshit.
+-- 
+sknkoinmrnohnlnjnhrmotnhotoqnsniohnfopolofqlofnpofnfngshohnron
+dfkjghwenflgkdwdfwkjgghs
+was whirling round inside his head. Among  them were the villa in Nice,  
the
+
+[message truncated]
+
+



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-18 Thread noreply

revno: 1011
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-18 13:25:16 -0800
message:
  Added Hebrew translation from Dov Zamir minus the apparently unused
  'direction' addition to the LC_DESCRIPTIONS dictionary.
added:
  messages/he/
  messages/he/LC_MESSAGES/
  messages/he/LC_MESSAGES/mailman.po
  templates/he/
  templates/he/admindbdetails.html
  templates/he/admindbpreamble.html
  templates/he/admindbsummary.html
  templates/he/adminsubscribeack.txt
  templates/he/adminunsubscribeack.txt
  templates/he/admlogin.html
  templates/he/approve.txt
  templates/he/archidxentry.html
  templates/he/archidxfoot.html
  templates/he/archidxhead.html
  templates/he/archlistend.html
  templates/he/archliststart.html
  templates/he/archtoc.html
  templates/he/archtocentry.html
  templates/he/archtocnombox.html
  templates/he/article.html
  templates/he/bounce.txt
  templates/he/checkdbs.txt
  templates/he/convert.txt
  templates/he/cronpass.txt
  templates/he/disabled.txt
  templates/he/emptyarchive.html
  templates/he/headfoot.html
  templates/he/help.txt
  templates/he/invite.txt
  templates/he/listinfo.html
  templates/he/masthead.txt
  templates/he/newlist.txt
  templates/he/nomoretoday.txt
  templates/he/options.html
  templates/he/postack.txt
  templates/he/postauth.txt
  templates/he/postheld.txt
  templates/he/private.html
  templates/he/probe.txt
  templates/he/refuse.txt
  templates/he/roster.html
  templates/he/subauth.txt
  templates/he/subscribe.html
  templates/he/subscribeack.txt
  templates/he/unsub.txt
  templates/he/unsubauth.txt
  templates/he/userpass.txt
  templates/he/verify.txt
modified:
  Mailman/Defaults.py.in

The size of the diff (12545 lines) is larger than your specified limit of 5000 
lines

--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-18 Thread noreply

revno: 1008
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-18 12:01:26 -0800
message:
  Gui/GuiBase.py - Deleted the _escape() method - not needed since 2.1.9
  
  Gui/GuiBase.py
  Gui/Privacy.py
  Handlers/Moderate.py - Patched with a slightly modified version of sf patch
 1220144 - allow specifying another list in
 accept_these_nonmembers.
modified:
  Mailman/Gui/GUIBase.py
  Mailman/Gui/Privacy.py
  Mailman/Handlers/Moderate.py

=== modified file 'Mailman/Gui/GUIBase.py'
--- a/Mailman/Gui/GUIBase.py2005-08-27 01:40:17 +
+++ b/Mailman/Gui/GUIBase.py2007-11-18 20:01:26 +
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2004 by the Free Software Foundation, Inc.
+# Copyright (C) 2002-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
@@ -12,7 +12,8 @@
 #
 # 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.
 
 Base class for all web GUI components.
 
@@ -77,6 +78,10 @@
 re.compile(addr)
 except re.error:
 raise ValueError
+elif wtype == mm_cfg.EmailListEx and addr.startswith('@'):
+# XXX Needs to be reviewed for [EMAIL PROTECTED] names.
+# check for existence of list?
+pass
 else:
 raise
 addrs.append(addr)
@@ -122,10 +127,6 @@
 # Validate all the attributes for this category
 pass
 
-def _escape(self, property, value):
-value = value.replace('', 'lt;')
-return value
-
 def handleForm(self, mlist, category, subcat, cgidata, doc):
 for item in self.GetConfigInfo(mlist, category, subcat):
 # Skip descriptions and legacy non-attributes
@@ -144,10 +145,9 @@
 elif not cgidata.has_key(property):
 continue
 elif isinstance(cgidata[property], ListType):
-val = [self._escape(property, x.value)
-   for x in cgidata[property]]
+val = [x.value for x in cgidata[property]]
 else:
-val = self._escape(property, cgidata[property].value)
+val = cgidata[property].value
 # Coerce the value to the expected type, raising exceptions if the
 # value is invalid.
 try:

=== modified file 'Mailman/Gui/Privacy.py'
--- a/Mailman/Gui/Privacy.py2005-12-30 18:50:08 +
+++ b/Mailman/Gui/Privacy.py2007-11-18 20:01:26 +
@@ -1,17 +1,17 @@
-# Copyright (C) 2001-2005 by the Free Software Foundation, Inc.
+# 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 
+# along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 # USA.
 
@@ -59,7 +59,7 @@
 _('Confirm'),
 _('Require approval'),
 _('Confirm and approve')),
-   0, 
+   0,
_('What steps are required for subscription?br'),
_('''None - no verification steps (emNot
Recommended /em)br
@@ -67,7 +67,7 @@
Require approval - require list administrator
Approval for subscriptions br
Confirm and approve - both confirm and approve
-   
+
p(*) when someone requests a subscription,
Mailman sends them a notice with a unique
subscription request number that they must reply to
@@ -88,7 +88,7 @@
Require approval - require list administrator
approval for 

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-11-18 Thread noreply

revno: 6578
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-11-18 16:38:59 -0500
message:
  Convert to the Storm Python ORM storm.canonical.com.  There were several
  reasons for this, but most importantly, the changes from SQLAlchemy/Elixir 0.3
  to 0.4 were substantial and caused a lot of work.  This work unfortunately did
  not result in a working branch due to very strange and inconsistent behavior
  with Unicode columns.  Sometimes such columns would return Unicode, sometimes
  8-bit strings, with no rhyme or reason.  I gave up debugging this after many
  hours of head scratching.
  
  Oh yeah, no more flush!
  
  Storm enforces Unicode columns, which is very nice, though requires us to add
  lots of 'u's in places we didn't have them before.  Ultimately, this is a good
  thing so that the core of Mailman will be Unicode consistent.
  
  One thing I still want to clean up after this, is the function-scoped imports
  in the model code.  Part of the reason for the separate model classes was to
  avoid this, but for now, we'll live with it.  Storm's architecture requires us
  to maintain a database-table-class registry for simple clearing after tests
  in Database._reset().  This is made fairly simple by Storm allowing us to use
  our own metaclass for model classes.
  
  Storm does require that we write our own SQL files, which is a downside, but I
  think our schema will be easy enough that this won't be a huge burden.  Plus
  we have a head-start wink.
  
  Another cool thing about Storm is the explicit use of stores for objects.
  This should eventually allow me to flesh out my idea of storage pillars for 1)
  lists, 2) users, 3) messages.
  
  Some other changes:
  
  - pylint and pyflakes cleanups
  - SQLALCHEMY_ENGINE_URL - DEFAULT_DATABASE_URL
  - Don't import-* from Version in Defaults.py
  - Add interface method to Mailman.Message.Message so that __getitem__() and
get_all() always return Unicode headers, even when the underlying objects
are strings.  This should generally be safe as headers are required by RFC
to be within the ASCII range.
  - Fix bin/arch.py to use proper initialization.
added:
  Mailman/database/model/mailman.sql
modified:
  Mailman/Defaults.py
  Mailman/Handlers/Hold.py
  Mailman/Handlers/Scrubber.py
  Mailman/MTA/Postfix.py
  Mailman/Message.py
  Mailman/app/membership.py
  Mailman/app/styles.py
  Mailman/bin/arch.py
  Mailman/bin/gate_news.py
  Mailman/bin/mailmanctl.py
  Mailman/bin/testall.py
  Mailman/configuration.py
  Mailman/database/__init__.py
  Mailman/database/listmanager.py
  Mailman/database/messagestore.py
  Mailman/database/model/__init__.py
  Mailman/database/model/address.py
  Mailman/database/model/language.py
  Mailman/database/model/mailinglist.py
  Mailman/database/model/member.py
  Mailman/database/model/message.py
  Mailman/database/model/pending.py
  Mailman/database/model/preferences.py
  Mailman/database/model/requests.py
  Mailman/database/model/roster.py
  Mailman/database/model/user.py
  Mailman/database/model/version.py
  Mailman/database/types.py
  Mailman/database/usermanager.py
  Mailman/docs/ack-headers.txt
  Mailman/docs/acknowledge.txt
  Mailman/docs/addresses.txt
  Mailman/docs/after-delivery.txt
  Mailman/docs/antispam.txt
  Mailman/docs/approve.txt
  Mailman/docs/archives.txt
  Mailman/docs/avoid-duplicates.txt
  Mailman/docs/bounces.txt
  Mailman/docs/calc-recips.txt
  Mailman/docs/cleanse.txt
  Mailman/docs/cook-headers.txt
  Mailman/docs/decorate.txt
  Mailman/docs/digests.txt
  Mailman/docs/file-recips.txt
  Mailman/docs/filtering.txt
  Mailman/docs/hold.txt
  Mailman/docs/lifecycle.txt
  Mailman/docs/listmanager.txt
  Mailman/docs/membership.txt
  Mailman/docs/message.txt
  Mailman/docs/messagestore.txt
  Mailman/docs/mlist-addresses.txt
  Mailman/docs/news-runner.txt
  Mailman/docs/nntp.txt
  Mailman/docs/outgoing.txt
  Mailman/docs/pending.txt
  Mailman/docs/registration.txt
  Mailman/docs/reply-to.txt
  Mailman/docs/replybot.txt
  Mailman/docs/requests.txt
  Mailman/docs/runner.txt
  Mailman/docs/scrubber.txt
  Mailman/docs/styles.txt
  Mailman/docs/subject-munging.txt
  Mailman/docs/switchboard.txt
  Mailman/docs/tagger.txt
  Mailman/docs/usermanager.txt
  Mailman/docs/users.txt
  Mailman/initialize.py
  Mailman/interfaces/database.py
  Mailman/queue/__init__.py
  Mailman/tests/test_documentation.py
  setup.py

revno: 6572.1.12
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 30storm
timestamp: Sat 2007-11-17 17:38:50 -0500
message:
  Merge cleanup branch
modified:
  Mailman/Defaults.py
  Mailman/Handlers/Hold.py
  Mailman/Handlers/Scrubber.py
  Mailman/MTA/Postfix.py
  Mailman/app/membership.py
  Mailman/bin/arch.py
  Mailman/bin/gate_news.py
  Mailman/bin/mailmanctl.py
  

[Mailman-checkins] [Branch ~mailman-coders/mailman/3.0]

2007-11-18 Thread noreply

revno: 6579
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 3.0
timestamp: Sun 2007-11-18 16:57:20 -0500
message:
  This one took care of itself. :)
modified:
  TODO.txt

=== modified file 'TODO.txt'
--- a/TODO.txt  2007-09-21 12:51:38 +
+++ b/TODO.txt  2007-11-18 21:57:20 +
@@ -1,8 +1,6 @@
 This list is by no means complete.  I'm just using it to track short term
 things that I need to do.
 
-Fix the XXX in model/requests.py where we need a flush because we can't get to
-last_inserted_id()
 Get rid of PickleTypes
 Get rid of MailList class! (done for test suite!)
 Add tests for bin/newlist and bin/rmlist



--

https://code.launchpad.net/~mailman-coders/mailman/3.0

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/3.0/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-18 Thread noreply

revno: 1009
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-18 12:12:22 -0800
message:
  Scrubber.py - changed to use part.get_payload(), not part._payload.
modified:
  Mailman/Handlers/Scrubber.py

=== modified file 'Mailman/Handlers/Scrubber.py'
--- a/Mailman/Handlers/Scrubber.py  2007-11-07 01:41:17 +
+++ b/Mailman/Handlers/Scrubber.py  2007-11-18 20:12:22 +
@@ -298,7 +298,7 @@
 # If the message isn't a multipart, then we'll strip it out as an
 # attachment that would have to be separately downloaded.  Pipermail
 # will transform the url into a hyperlink.
-elif part._payload and not part.is_multipart():
+elif part.get_payload() and not part.is_multipart():
 payload = part.get_payload(decode=True)
 ctype = part.get_type()
 # XXX Under email 2.5, it is possible that payload will be None.
@@ -350,7 +350,7 @@
 for part in msg.walk():
 # TK: bug-id 1099138 and multipart
 # MAS test payload - if part may fail if there are no headers.
-if not part._payload or part.is_multipart():
+if not part.get_payload() or part.is_multipart():
 continue
 # All parts should be scrubbed to text/plain by now.
 partctype = part.get_content_type()



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-18 Thread noreply

revno: 1013
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-18 14:26:26 -0800
message:
  Added 'he' to the messages/ and templates/ Makefile.in
modified:
  messages/Makefile.in
  templates/Makefile.in

=== modified file 'messages/Makefile.in'
--- a/messages/Makefile.in  2006-08-04 12:20:33 +
+++ b/messages/Makefile.in  2007-11-18 22:26:26 +
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2005 by the Free Software Foundation, Inc.
+# 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
@@ -48,8 +48,8 @@
 MSGMERGE=  msgmerge
 
 # CVS available languages
-LANGUAGES= ar ca cs da de es et eu fi fr hr hu ia it ja ko lt nl no pl \
-   pt pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
+LANGUAGES= ar ca cs da de es et eu fi fr he hr hu ia it ja ko lt nl no \
+   pl pt pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
 LANGDIRS=  $(LANGUAGES:%=messages/%/LC_MESSAGES)
 # Human readable po file
 POFILES=   $(LANGUAGES:%=%/LC_MESSAGES/mailman.po)

=== modified file 'templates/Makefile.in'
--- a/templates/Makefile.in 2006-08-04 12:20:33 +
+++ b/templates/Makefile.in 2007-11-18 22:26:26 +
@@ -42,8 +42,8 @@
 
 SHELL= /bin/sh
 
-LANGUAGES= ar ca cs da de en es et eu fi fr hr hu ia it ja ko lt nl \
-   no pl pt pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
+LANGUAGES= ar ca cs da de en es et eu fi fr he hr hu ia it ja ko lt \
+   nl no pl pt pt_BR ro ru sl sr sv tr uk vi zh_CN zh_TW
 
 # Modes for directories and executables created by the install
 # process.  Default to group-writable directories but



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-18 Thread noreply

revno: 1014
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-18 17:59:38 -0800
message:
  Privacy.py - Last check-in was too agressive at removing trailing blanks.
modified:
  Mailman/Gui/Privacy.py

=== modified file 'Mailman/Gui/Privacy.py'
--- a/Mailman/Gui/Privacy.py2007-11-18 20:01:26 +
+++ b/Mailman/Gui/Privacy.py2007-11-19 01:59:38 +
@@ -67,7 +67,7 @@
Require approval - require list administrator
Approval for subscriptions br
Confirm and approve - both confirm and approve
-
+   
p(*) when someone requests a subscription,
Mailman sends them a notice with a unique
subscription request number that they must reply to
@@ -88,7 +88,7 @@
Require approval - require list administrator
approval for subscriptions br
Confirm and approve - both confirm and approve
-
+   
p(*) when someone requests a subscription,
Mailman sends them a notice with a unique
subscription request number that they must reply to
@@ -359,13 +359,13 @@
  against every recipient address in the message.  The matching is
  performed with Python's re.match() function, meaning they are
  anchored to the start of the string.
-
+ 
  pFor backwards compatibility with Mailman 1.1, if the regexp
  does not contain an `@', then the pattern is matched against just
  the local part of the recipient address.  If that match fails, or
  if the pattern does contain an `@', then the pattern is matched
  against the entire recipient address.
-
+ 
  pMatching against the local part is deprecated; in a future
  release, the pattern will always be matched against the entire
  recipient address.)),
@@ -399,7 +399,7 @@
  case, each rule is matched in turn, with processing stopped after
  the first match.
 
- Note that headers are collected from all the attachments
+ Note that headers are collected from all the attachments 
  (except for the mailman administrivia message) and
  matched against the regular expressions. With this feature,
  you can effectively sort out messages with dangerous file



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-18 Thread noreply

revno: 1015
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-18 18:16:20 -0800
message:
  Updated mailman.pot again to undo unnecessary Privacy.py changes.
modified:
  messages/mailman.pot

=== modified file 'messages/mailman.pot'
--- a/messages/mailman.pot  2007-11-18 21:27:53 +
+++ b/messages/mailman.pot  2007-11-19 02:16:20 +
@@ -5,7 +5,7 @@
 msgid 
 msgstr 
 Project-Id-Version: PACKAGE VERSION\n
-POT-Creation-Date: Sun Nov 18 12:59:04 2007\n
+POT-Creation-Date: Sun Nov 18 18:03:33 2007\n
 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n
 Last-Translator: FULL NAME [EMAIL PROTECTED]\n
 Language-Team: LANGUAGE [EMAIL PROTECTED]\n
@@ -3049,90 +3049,94 @@
 msgstr 
 
 #: Mailman/Defaults.py:1347
+msgid Hebrew
+msgstr 
+
+#: Mailman/Defaults.py:1348
 msgid Croatian
 msgstr 
 
-#: Mailman/Defaults.py:1348
+#: Mailman/Defaults.py:1349
 msgid Hungarian
 msgstr 
 
-#: Mailman/Defaults.py:1349
+#: Mailman/Defaults.py:1350
 msgid Interlingua
 msgstr 
 
-#: Mailman/Defaults.py:1350
+#: Mailman/Defaults.py:1351
 msgid Italian
 msgstr 
 
-#: Mailman/Defaults.py:1351
+#: Mailman/Defaults.py:1352
 msgid Japanese
 msgstr 
 
-#: Mailman/Defaults.py:1352
+#: Mailman/Defaults.py:1353
 msgid Korean
 msgstr 
 
-#: Mailman/Defaults.py:1353
+#: Mailman/Defaults.py:1354
 msgid Lithuanian
 msgstr 
 
-#: Mailman/Defaults.py:1354
+#: Mailman/Defaults.py:1355
 msgid Dutch
 msgstr 
 
-#: Mailman/Defaults.py:1355
+#: Mailman/Defaults.py:1356
 msgid Norwegian
 msgstr 
 
-#: Mailman/Defaults.py:1356
+#: Mailman/Defaults.py:1357
 msgid Polish
 msgstr 
 
-#: Mailman/Defaults.py:1357
+#: Mailman/Defaults.py:1358
 msgid Portuguese
 msgstr 
 
-#: Mailman/Defaults.py:1358
+#: Mailman/Defaults.py:1359
 msgid Portuguese (Brazil)
 msgstr 
 
-#: Mailman/Defaults.py:1359
+#: Mailman/Defaults.py:1360
 msgid Romanian
 msgstr 
 
-#: Mailman/Defaults.py:1360
+#: Mailman/Defaults.py:1361
 msgid Russian
 msgstr 
 
-#: Mailman/Defaults.py:1361
+#: Mailman/Defaults.py:1362
 msgid Serbian
 msgstr 
 
-#: Mailman/Defaults.py:1362
+#: Mailman/Defaults.py:1363
 msgid Slovenian
 msgstr 
 
-#: Mailman/Defaults.py:1363
+#: Mailman/Defaults.py:1364
 msgid Swedish
 msgstr 
 
-#: Mailman/Defaults.py:1364
+#: Mailman/Defaults.py:1365
 msgid Turkish
 msgstr 
 
-#: Mailman/Defaults.py:1365
+#: Mailman/Defaults.py:1366
 msgid Ukrainian
 msgstr 
 
-#: Mailman/Defaults.py:1366
+#: Mailman/Defaults.py:1367
 msgid Vietnamese
 msgstr 
 
-#: Mailman/Defaults.py:1367
+#: Mailman/Defaults.py:1368
 msgid Chinese (China)
 msgstr 
 
-#: Mailman/Defaults.py:1368
+#: Mailman/Defaults.py:1369
 msgid Chinese (Taiwan)
 msgstr 
 
@@ -4548,7 +4552,7 @@
Require approval - require list administrator\n
Approval for subscriptions br\n
Confirm and approve - both confirm and approve\n
-\n
+   \n
p(*) when someone requests a subscription,\n
Mailman sends them a notice with a unique\n
subscription request number that they must reply 
to\n
@@ -4565,7 +4569,7 @@
Require approval - require list administrator\n
approval for subscriptions br\n
Confirm and approve - both confirm and approve\n
-\n
+   \n
p(*) when someone requests a subscription,\n
Mailman sends them a notice with a unique\n
subscription request number that they must reply 
to\n
@@ -4925,13 +4929,13 @@
  against every recipient address in the message.  The matching 
is\n
  performed with Python's re.match() function, meaning they are\n
  anchored to the start of the string.\n
-\n
+ \n
  pFor backwards compatibility with Mailman 1.1, if the regexp\n
  does not contain an `@', then the pattern is matched against 
just\n
  the local part of the recipient address.  If that match fails, 
or\n
  if the pattern does contain an `@', then the pattern is 
matched\n
  against the entire recipient address.\n
-\n
+ \n
  pMatching against the local part is deprecated; in a future\n
  release, the pattern will always be matched against the entire\n
  recipient address.
@@ -4976,7 +4980,7 @@
  case, each rule is matched in turn, with processing stopped 
after\n
  the first match.\n
 \n
- Note that headers are collected from all the attachments\n
+ Note that headers are collected from all the attachments \n
  (except for the mailman administrivia message) and\n
  matched against the regular expressions. With this feature,\n
  you can 

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-19 Thread noreply

revno: 1016
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Mon 2007-11-19 12:30:51 -0800
message:
  BounceRunner.py - Fixed a mail loop if a list owner puts the list's -bounces
or -admin address in the list's owner attribute (1834569).
modified:
  Mailman/Queue/BounceRunner.py

=== modified file 'Mailman/Queue/BounceRunner.py'
--- a/Mailman/Queue/BounceRunner.py 2006-03-09 22:09:34 +
+++ b/Mailman/Queue/BounceRunner.py 2007-11-19 20:30:51 +
@@ -180,11 +180,21 @@
 #   but a list owner address itself bounced.  That's bad, and for now
 #   we'll simply log the problem and attempt to deliver the message to
 #   the site owner.
-#
+# - the list owner could have set listname-bounces as the owner
+#   address.  That's really bad as it results in a loop of ever
+#   growing unrecognized bounce messages.  We detect this based on the
+#   X-BeenThere header and handle it like a list owner bounce.  No
+#   real bounce will have an X-BeenThere header for the list.
+bts = [s.strip().lower() for s in msg.get_all('x-beenthere', [])]
+if mlist.GetListEmail().lower() in bts:
+bt = True
+else:
+bt = False
 # All messages to [EMAIL PROTECTED] have their envelope sender set
 # to [EMAIL PROTECTED] (no virtual domain).  Is this a bounce for a
-# message to a list owner, coming to the site owner?
-if msg.get('to', '') == Utils.get_site_email(extra='owner'):
+# message to a list owner, coming to the site owner, or an owner
+# notice sent directly to the -bounces address?
+if msg.get('to', '') == Utils.get_site_email(extra='owner') or bt:
 # Send it on to the site owners, but craft the envelope sender to
 # be the -loop detection address, so if /they/ bounce, we won't
 # get stuck in a bounce loop.
@@ -192,6 +202,7 @@
  recips=[Utils.get_site_email()],
  envsender=Utils.get_site_email(extra='loop'),
  )
+return
 # List isn't doing bounce processing?
 if not mlist.bounce_processing:
 return



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-20 Thread noreply

revno: 986
committer: Tokio Kikuchi [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Mon 2007-09-17 14:51:10 +0900
message:
  merge from launchpad
modified:
  bin/dumpdb
  doc/mailman-admin.tex
  doc/mailman-install.tex

revno: 984.1.5
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Wed 2007-09-12 14:36:43 -0400
message:
  Start using barry at list dot org for all Mailman correspondances.
modified:
  doc/mailman-admin.tex
  doc/mailman-install.tex

revno: 984.1.4
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-08-03 18:16:56 -0700
message:
  Updated copyright year.
modified:
  bin/dumpdb

revno: 984.1.3
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-08-03 18:09:33 -0700
message:
  Ooops! The previous rev copied a configured file by mistake. Fixed.
modified:
  bin/dumpdb

revno: 984.1.2
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-08-03 17:46:05 -0700
message:
  Backported dumpdb changes from the 3.0 branch to allow dumping of 
marshals.
  This has been broken since 2.1.5!
modified:
  bin/dumpdb

=== modified file 'bin/dumpdb'
--- a/bin/dumpdb2005-08-27 01:40:17 +
+++ b/bin/dumpdb2007-08-04 01:16:56 +
@@ -1,6 +1,6 @@
 #! @PYTHON@
 #
-# Copyright (C) 1998-2005 by the Free Software Foundation, Inc.
+# 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
@@ -45,16 +45,15 @@
 -- or if the file ends in neither suffix -- use the -p or -m flags.
 
 
-import os
 import sys
 import getopt
 import pprint
-from cPickle import load
+import cPickle
+import marshal
 from types import StringType
 
 import paths
 # Import this /after/ paths so that the sys.path is properly hacked
-from email.Generator import Generator
 from Mailman.i18n import _
 
 PROGRAM = sys.argv[0]
@@ -121,37 +120,35 @@
 # Handle dbs
 pp = pprint.PrettyPrinter(indent=4)
 if filetype == 1:
-# BAW: this probably doesn't work if there are mixed types of .db
-# files (i.e. some marshals, some bdbs).
-d = DumperSwitchboard().read(filename)
+load = marshal.load
+typename = 'marshal'
+else:
+load = cPickle.load
+typename = 'pickle'
+fp = open(filename)
+m = []
+try:
+cnt = 1
 if doprint:
-pp.pprint(d)
-return d
-else:
-fp = open(filename)
-m = []
-try:
-cnt = 1
+print _('[- start %(typename)s file -]')
+while True:
+try:
+obj = load(fp)
+except EOFError:
+if doprint:
+print _('[- end %(typename)s file -]')
+break
 if doprint:
-print _('[- start pickle file -]')
-while True:
-try:
-obj = load(fp)
-except EOFError:
-if doprint:
-print _('[- end pickle file -]')
-break
-if doprint:
-print _('- start object %(cnt)s -')
-if isinstance(obj, StringType):
-print obj
-else:
-pp.pprint(obj)
-cnt += 1
-m.append(obj)
-finally:
-fp.close()
-return m
+print _('- start object %(cnt)s -')
+if isinstance(obj, StringType):
+print obj
+else:
+pp.pprint(obj)
+cnt += 1
+m.append(obj)
+finally:
+fp.close()
+return m
 
 
 

=== modified file 'doc/mailman-admin.tex'
--- a/doc/mailman-admin.tex 2003-02-08 07:14:13 +
+++ b/doc/mailman-admin.tex 2007-09-12 18:36:43 +
@@ -9,7 +9,7 @@
 % At minimum, give your name and an email address.  You can include a
 % snail-mail address if you like.
 \author{Barry A. Warsaw}
[EMAIL PROTECTED]
+%\authoraddress{barry (at) list dot org}
 
 \date{\today}  % XXX update before tagging release!
 \release{2.1}  % software release, not documentation

=== modified file 'doc/mailman-install.tex'
--- a/doc/mailman-install.tex   2007-02-15 01:59:46 +
+++ b/doc/mailman-install.tex   2007-09-12 18:36:43 +
@@ -2,7 

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-20 Thread noreply

revno: 987
committer: Tokio Kikuchi [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-11-16 11:48:35 +0900
message:
  merge and commit
added:
  .bzrignore
modified:
  Mailman/Archiver/HyperArch.py
  Mailman/Cgi/options.py
  Mailman/Defaults.py.in
  Mailman/Handlers/CalcRecips.py
  Mailman/Handlers/CleanseDKIM.py
  Mailman/Handlers/Hold.py
  Mailman/Handlers/MimeDel.py
  Mailman/Handlers/Scrubber.py
  Mailman/MailList.py
  Mailman/Queue/CommandRunner.py
  Mailman/Queue/MaildirRunner.py*
  Mailman/versions.py
  configure
  configure.in
  misc/paths.py.in

revno: 984.1.22
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Fri 2007-11-09 12:25:33 -0800
message:
  Fixed Mailman/Queue/CommandRunner.py to decode a quoted-printable or 
base64
  encoded message part.
modified:
  Mailman/Queue/CommandRunner.py

revno: 984.1.21
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Tue 2007-11-06 17:41:17 -0800
message:
  - Scrubber.py
Fixed an issue where an implicit text/plain part without any headers 
gets
lost.
  
Moved the cleansing of the filename extension to a place where it is
guaranteed to be a string as opposed to an empty list.
modified:
  Mailman/Handlers/Scrubber.py

revno: 984.1.20
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 15:19:31 -0800
message:
  Added Date and Message-ID headers to the confirm reply
  message that Mailman adds to the admin notification.
modified:
  Mailman/Handlers/Hold.py

revno: 984.1.19
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 15:03:38 -0800
message:
  - Cgi/options.py - fixed to not present the empty topic to user.
  - Handlers/CalcRecips.py - Changed to not process topics if topics
are disabled for the list.
modified:
  Mailman/Cgi/options.py
  Mailman/Handlers/CalcRecips.py

revno: 984.1.18
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 14:41:26 -0800
message:
  Added removal of Authentication-Results: header.
modified:
  Mailman/Handlers/CleanseDKIM.py

revno: 984.1.17
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Sun 2007-11-04 14:07:28 -0800
message:
  Changed the descriptions of the ARCHIVE_TO_MBOX settings to more
  accurately represent their current meaning.
modified:
  Mailman/Defaults.py.in

revno: 984.1.16
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-18 13:34:36 -0700
message:
  MailList.Create() - added an assertion that the listname is lower case.
modified:
  Mailman/MailList.py

revno: 984.1.15
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-18 13:29:49 -0700
message:
  Added a call to warnings.filterwarnings() to misc/paths.py.in to supress 
the
  Python 2.5 DeprecationWarning on string exceptions.
modified:
  misc/paths.py.in

revno: 984.1.14
committer: Barry Warsaw [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Mon 2007-10-08 22:06:49 -0400
message:
  Added a .bzrignore to ignore generated files.
added:
  .bzrignore

revno: 984.1.13
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 19:53:13 -0700
message:
  Fixed MaildirRunner.py to handle hyphenated list names.

revno: 984.1.12
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 19:52:04 -0700
message:
  MimeDel.py neglected to lower case file extensions for comparison with
  lower cased *_filename_extensions.  Fixed.
modified:
  Mailman/Handlers/MimeDel.py

revno: 984.1.11
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Thu 2007-10-04 19:50:56 -0700
message:
  In rare cases, versions.py can encounter a very old list with held posts 

[Mailman-checkins] [Branch ~mailman-coders/mailman/2.1]

2007-11-20 Thread noreply

revno: 985
committer: Tokio Kikuchi [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Wed 2007-07-25 10:18:15 +0900
message:
  merge from mailman-coders
modified:
  Mailman/Utils.py

revno: 984.1.1
committer: Mark Sapiro [EMAIL PROTECTED]
branch nick: 2.1
timestamp: Tue 2007-07-17 10:59:14 -0700
message:
  Detect 'who' with 1 or 2 arguments as administrivia.
modified:
  Mailman/Utils.py

=== modified file 'Mailman/Utils.py'
--- a/Mailman/Utils.py  2006-08-30 14:54:22 +
+++ b/Mailman/Utils.py  2007-07-17 17:59:14 +
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc.
+# 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
@@ -574,7 +574,7 @@
 'set': (3, 3),
 'subscribe':   (0, 3),
 'unsubscribe': (0, 1),
-'who': (0, 0),
+'who': (0, 2),
 }
 
 # Given a Message.Message object, test for administrivia (eg subscribe,



--

https://code.launchpad.net/~mailman-coders/mailman/2.1

You are receiving this branch notification because you are subscribed to it.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+subscription/mailman-checkins.
___
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org



  1   2   3   4   5   6   7   8   9   10   >