summaryrefslogtreecommitdiff
path: root/Mailman/MailList.py (follow)
Commit message (Collapse)AuthorAgeFilesLines
...
* New feature (hopefully, the last one before feature freeze for 1.2 :)bwarsaw2000-03-031-30/+63
| | | | | | | | | | | | | | | | | | | | | | | Elaborate the Reply-To munging to handle parallel lists, e.g. a checkins list where discussions about changes should be conducted on a parallel development list. Specifically, There's a new configuration attribute called `reply_to_address' which contains the string address to stuff in the Reply-To: header. The config attr reply_goes_to_list now takes three values 0 (no change) means no reply-to munging occurs 1 (no change) reply-to is munged to the list address 2 (new value) reply-to is munged to reply_to_address In both cases, if the original message contains a Reply-To: header, it is discarded. This could be controversial; it might be better to honor an existing Reply-To: header in case #2, but that seems like it would be less useful. GetConfigInfo(): Add the necessary machinery to effect the above change. Also, use TEXTFIELDWIDTH as the standard width for all string entry fields.
* Mixin the Autoresponder class.bwarsaw2000-02-191-1/+5
| | | | | | | | MailList.__init__(): Call Autoresponder.InitVars(). This only works for new mailing lists. MailList.GetConfigInfo(): Get the `autoreply' configuration info from the Autoresponder class.
* CloseLogs(): new method, useful to avoid `Too many open files' errorshmeland2000-02-131-2/+10
| | | | | | when iterating over lots of lists. __del__(): Call CloseLogs() instead of accessing self._log_files directly.
* GetScriptURL(): Use ./ if a relative script URL prefix is the emptybwarsaw1999-12-271-0/+2
| | | | string.
* GetOptionsURL(): typobwarsaw1999-12-261-1/+1
|
* GetRelativeScriptURL(): transcription errorbwarsaw1999-12-261-1/+1
|
* GetOptionsURL(): transcription errorbwarsaw1999-12-261-1/+1
|
* GetScriptURL(), GetOptionsURL(): generalized method to get a script'sbwarsaw1999-12-251-18/+21
| | | | | | | | | | | url, both absolute and relative. Now takes an optional argument `relative' to switch on the base part. GetAbsoluteOptionsURL(), GetAbsoluteScriptURL(), GetRelativeScriptURL(): use method above. TBD: We should probably track down and rewrite any instances of the old methods in the code.
* HasExplicitDest(): The argument order of the re.match()s is backwards;bwarsaw1999-12-161-4/+4
| | | | | it should match the found recipient against the acceptable alternative.
* __init__(): Turn on logging of a MailList object's lock. Primarilybwarsaw1999-12-091-1/+2
| | | | for debugging purposes.
* AddMember(), ApprovedAddMembers(), DeleteMember(): Convert messagebwarsaw1999-11-241-29/+40
| | | | | | | | | delivery to pipeline architecture by using HandlerAPI.DeliverToUser() for fast track delivery of the notification messages. ApprovedAddMembers(): Don't need to call Reap anymore (it's gone). Post(): ...process() => ...DeliverToList()
* __init__(): Removed redundant setting of self._full_path. This isbwarsaw1999-11-121-1/+2
| | | | | | | also done in InitTempVars() which is called just before the conditional. InitTempVars(): If name is false, then set self._full_path to None.
* __del__(): wrap Unlock in it's separate try/exceptbwarsaw1999-11-121-2/+5
|
* Move Unlock() call into try clause in case the list hasn't even gottenbwarsaw1999-11-121-2/+3
| | | | far enough to have a lock object
* ApprovedAddMember(): When raising an Errors.MMAlreadyAMemberbwarsaw1999-11-111-1/+1
| | | | exception, make the value the address that was being added.
* ProcessConfirmation(): Ensure that the mailing list is Save()'d evenbwarsaw1999-11-101-7/+9
| | | | if an MMNeedApproval exception is raised.
* Don't need to import pathsbwarsaw1999-11-101-1/+0
|
* reworked importsbwarsaw1999-11-101-197/+62
| | | | | | | | | | | | | | | | | | | InitTempVars(): no longer need to call Digest.InitTempVars(), but we /do/ need to call ListAdmin.InitTempVars(). Save(): must call SaveRequestDb() to flush out any unsaved changes to the request database. AddMember(): New call for entering the subscription request requiring approval to the requests database. ApprovedAddMembers(), DeleteMember(): Use new Message object interface. Post(): Massively re-vamped. Now uses the message pipeline found in Mailman.Handlers.HandlerAPI.process(). internal_name(), fullpath(): New functional interface to this data.
* ApprovedAddMembers(): each time through the loop, do a reap ofbwarsaw1999-10-301-0/+1
| | | | subchildren
* InitTempVars(): Use <site> for lock file name when no list name isbwarsaw1999-09-021-1/+1
| | | | given (as is the case with calling bin/mmsitepass)
* Load(): Ignore AlreadyLockedErrors.bwarsaw1999-08-231-1/+4
|
* Ditch the posix lockfile stuff in favor of the now "standard" LockFilebwarsaw1999-08-211-29/+21
| | | | | | | | | | | | | | | | | | module. Specifically: __del__(): Be sure to unlock the list when it gets GC'd InitTempVars(): _tmp_lock => __createlock_p _lock_file => __lock __lock is now a LockFile object and all locking goes through this object. Load(): _tmp_lock => __createlock_p Locked(), Lock(), Unlock(): Use the new LockFile object as the basis for locking. Also, Unlock() should catch AlreadyLockedError for backwards compatable semantics.
* Save(): When the list is created for the first time :) config.db maybwarsaw1999-07-211-1/+6
| | | | not exist.
* Save(): Harald's fix (slightly rewritten by Barry) for window ofbwarsaw1999-07-211-23/+13
| | | | | opportunity where config.db could be missing, causing bogus "list not found" errors.
* Post(): Add `cgiext' key with value taken from mm_cfg.CGIEXT. Thisbwarsaw1999-07-181-2/+4
| | | | gets the proper URL into regular footers.
* .Post(): Try working around the "owner-alias" sendmail feature byhmeland1999-07-051-1/+7
| | | | | | using GetSender iff use of GetEnvelopeSender was attempted but returned an address beginning with '%s-admin' % self._internal_name
* GetUserOption(), SetUserOption(): The invariant is that the keys forbwarsaw1999-07-031-0/+2
| | | | | | | | list.user_option must be lowercase addresses (i.e. canonicalized addrs). The DATA_FILE_VERSION bump will fix existing lists and these two functions always lowercase the user address before checking it. Fixes PR#74
* MailList.Save(): Rewrite to be more robust in maintaining a validbwarsaw1999-07-011-13/+28
| | | | | | | | config.db file in the face of IOErrors during the marshal write. This is critical code so we have to make sure we get it right, but I've been running it on python.org for about a day and have seen no problems under normal conditions. I've tested under failure mode too, but not under real world conditions.
* re.match() was being used when we wanted re.search() for findinghmeland1999-06-151-2/+2
| | | | already inserted subject prefixes :(
* Create(): Do ValidateEmail(admin) before trying to actually createhmeland1999-06-131-2/+2
| | | | | anything, to disallow bin/newlist creating lists with bogus admin addresses.
* Changes to speed up mass subscription via the web:hmeland1999-06-041-39/+106
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | MailList.py: Changed MailList.SetUserOption() to take a `save_list' keyword argument (defaulting to true). When false, SetUserOption won't do self.Save() after changing the option. New function MailList.ApprovedAddMembers() (note plural) that takes a list of prospective new list members (and possibly a list of corresponding passwords), and does _all_ the necessary list changes before saving the list configuration. Empty passwords are substituted with randomly generated ones. Returns a dict with {address: exception_tuple} entries -- exception_tuple is either None or a two-element tuple containing the first exception type and value raised when trying to add address. The exception traceback object isn't included in the returned dict, because a) I don't think it is very useful for the relevant exceptions, and b) using it wrongly could cause some fuzz with Python's garbage collector -- i.e. we would leak memory. Changed MailList.ApprovedAddMember() to be a mere wrapper, calling the new ApprovedAddMembers() function and reraising any exception in the returned dict. Also made the logic of the code doing subject prefixing a bit clearer, and changed MailList.aside_new() so that list's config.db files are saved with umask 007 (as they contain all list members' passwords in clear text). Utils.py: New function MakeRandomPassword(length=4), used by MailList.ApprovedAddMembers() whenever empty passwords are found. The default random password length should possibly be made site configurable. Also, fixed an error in the _badchars regular expression -- the final "," was probably meant to be inside the character set. Cgi/admin.py: Changed ChangeOptions() to use the new MailList.ApprovedAddMembers() function.
* eradicate "maillist" as a nounbwarsaw1999-05-051-14/+15
|
* GetConfigInfo(): increase max_message_size field to 5 charactersbwarsaw1999-05-031-1/+2
|
* Post(): For anonymous lists, set Reply-to: header to the list emailbwarsaw1999-05-011-0/+1
| | | | address.
* Post(): When the sender does not want copies of their messages, andbwarsaw1999-04-161-1/+7
| | | | | has delivery disabled, they won't be on the recipients list. Catch and ignore the failure in .remove().
* Post(): New policy for message loops (e.g. messages that show up atbwarsaw1999-04-161-3/+2
| | | | | | | | | | the mailing list that have a matching X-BeenThere header). Instead of holding such messages for approval, an MMLoopingPost error is raised. This is caught by the post CGI script, which logs this occurance and sends a notice (containing the original message) to the list admin. This way, the admin knows there's a problem and can track the loop down, but isn't so inconvenienced to go the the Web page just to discard the message (the usual disposition).
* LogMsg(): small efficiency hackbwarsaw1999-04-021-1/+1
|
* Load(): Include the exception details when marshal.load() failsbwarsaw1999-03-311-2/+3
|
* Post(): when not including sender in recipients, remove address in abwarsaw1999-03-301-12/+2
| | | | case-preserving way.
* Load(): Verify that the unmarshaled config information is of typebwarsaw1999-03-291-3/+6
| | | | DictType.
* Sweeping changes to hopefully and finally (for 1.0 at least) make sanebwarsaw1999-03-291-9/+69
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | address case matching. These changes require the DATA_FILE_VERSION to be bumped, which should auto-update your config.db files. I sure hope this works correctly! Details of changes: MailList.GetUserSubscribedAddress(): New method. If the address is a member, this returns the case-preserved address the user is subscribed with. If not a member, None is returned. MailList.GetUserCanonicalAddress(): New method. If the address is a member, this returns the lowercased address the user is subscribed with. If not a member, None is returned. MailList.FindUser(): Wrote down, in a big comment, the constraints for the dictionaries self.members, self.digest_members, self.passwords. This wasn't always followed, but now it should be. FindUser() is now also guaranteed to return the lowercased version of the subscribed email address. This wasn't always the case. FindUser() also provides a shortcut for the common case. ApprovedAddMember(): Guarantee that passwords stored in self.passwords are keyed off the lowercased address. Deliverer.MailUserPassword(): Find the user's password using the lowercased version of their address. However, be sure to use their case-preserved address for the recipient of the password email. Digester.SetUserDigest(): Fixed a fairly old bug where a user switching from regular to digest membership (or vice versa) would get their case-preserved address blown away. I don't think there's any way to recover this information, but at least now we properly save it. SecurityManager.ConfirmUserPassword(): Simplified address matching stuff, since we now guarantee that FindUser() will return a lowercased address, and that the passwords dictionary has lowercased keys. FindUser() will return None if the address isn't found, and it also has a built-in shortcut so that the more expensive FindMatchingAddresses() isn't called in the common case. I eliminated the case-insensitive password comparision that Ken rightly questioned in his comment. admin.py: In the list of members, display a member's case-preserved address instead of their lowercased address. Also, obscure the URL in the hyperlink (probably not terribly necessary). handle_opts.py: When the password can't be found (when emailing it), put the address we tried to find in the result message. Makes for better debugging. options.py: Use a better mechanism for finding if the member has a case-preserved address different from their lowercased address.
* (Defaults.py.in): Added USE_ENVELOPE_SENDER variable, which is set tobwarsaw1999-03-091-4/+8
| | | | | | | | | | | | | 1 by default. This instructs the MailList.Post() method to use first the envelope sender (i.e. Unix "From " line) and then the From: header. However, this breaks member_only_posting on some systems (for reasons unknown). Set this variable to 0 in mm_cfg.py to use only the From: header, although this can open the list up to spam. (MailList.py): in Post(), check USE_ENVELOPE_SENDER to see if GetEnvelopeSender() should be called. (FAQ): Add a question refering to USE_ENVELOPE_SENDER.
* MailList.HasExplicitDest(): Protect use of user-supplied regexp. Ifhmeland1999-03-021-4/+24
| | | | | | | | | | | | | | | the regexp specifying a list alias doesn't compile, match against the re.escape(invalid_regexp) instead. MailList.parse_matching_header_opt(): Only return triples having compileable regexps. If some line in `bounce_matching_headers' results in an invalid regexp, this is logged and ignored (possibly a lot of times, until the misconfiguration is fixed). Also, the re.split() on the lines in `bounce_matching_headers' is now called with third arg `maxsplit' set to 1 to avoid splitting the header lines more than once. I don't have any Python prior to 1.5.1 handy, but my copy of the Library Reference states that this argument was ignored in the original 1.5 release -- implying that it existed.
* GetRelativeScriptURL(), GetAbsoluteScriptURL(): tack the new CGIbwarsaw1999-02-281-3/+5
| | | | | extension onto all script paths generated by these functions. This takes care of about 90% of the support for CGI extensions.
* Post(): Fixed some bogosities in removing sender from recipients whenbwarsaw1999-01-241-5/+5
| | | | | dont_send_to_sender is true. Code ordering problem, and argument to recipients.remove() was wrong.
* HasExplicitDest(): Essentially undo previous change, sincebwarsaw1999-01-131-1/+1
| | | | rfc822.Message.getaddrlist() now does the right thing.
* HasExplicitDest(): Use new getallrecipients() so that we really do getbwarsaw1999-01-121-1/+1
| | | | | | | all the To: and Cc: line recipients. Previously, we'd only get the first of any existing headers, and this meant that even if the list appeared on a later Cc: header, the message would get incorrectly flagged as an implicit destination.
* GetAbsoluteOptionsURL(): Downcase the address, since it could come inbwarsaw1999-01-091-1/+2
| | | | here in its case-preserved form.
* ApprovedAddMember(): Use the new ValidateEmail() interfacebwarsaw1999-01-091-2/+2
|
* Save(): Can't use a bare `raise' here, since Python 1.5 doesn't havebwarsaw1999-01-051-1/+1
| | | | | it and there are still some 1.5 users out there (thanks Brad Crittenden for finding this).