summaryrefslogtreecommitdiff
path: root/Mailman/MailList.py
Commit message (Collapse)AuthorAgeFilesLines
...
* InitVars(): Add the `emergency' attribute for putting the brakes onbwarsaw2002-03-151-0/+2
| | | | list traffic.
* ApprovedAddMember(), ApprovedDeleteMember(): The admin notificationbwarsaw2002-03-141-2/+4
| | | | | | messages should be sent to the -owner address rather than the self.owner[s] directly. Also, the messages should look like they're coming from the site list's -owner.
* GetConfirmEmail(): Returns a VERP-ish reply address for VERPdbwarsaw2002-03-141-4/+49
| | | | | | | | | | | confirmation messages. Requires the confirmation cookie. InviteNewMember(): Perform the actions to invite a person to the mailing list. This involves sending the person an invitation confirmation message and sticking them in the pending database. AddMember(), ProcessConfirmation(): Pending.SUBSCRIPTION now takes a single object, a UserDesc, instead of a tuple of components.
* Patches to help localize where file system layout decisions are made.bwarsaw2002-03-051-9/+5
| | | | | | | - use fullpath() instead of _full_path directly - Don't os.path.join() up the list path, instead use Site.get_listpath()
* Patches to support duplicate suppression for explicit recipients,bwarsaw2002-03-051-2/+3
| | | | | | | | | | written by Ben Gertzfield, ported to MM2.1 by Marc MERLIN. Specifically, InitVars(): Add the new_member_options attribute. (Also, untabbification)
* __del__(): Remove this because it prevents the garbage collector frombwarsaw2002-03-011-7/+0
| | | | | | | | | | | | | | | | | | | | | being able to free cycles containing MailList objects (see the gc module's documentation under the gc.garbage attribute for details). AFAICT, this has no effect on operations currently, because I believe we are pretty rigorous about unlocking MailList objects explicitly. This has a dramatic effect on memory leakage too, since there were/are cycles containing these fairly heavyweight objects that previously, the garbage collector couldn't free. We'll need to watch carefully for stale locks being left around, because I believe the MailList objects were at least being finalized during process shutdown, but maybe not, and it's a very dubious practice to be depending on anyway. Note: this doesn't completely eliminate the unbounded memory growth, although this in conjunction with shutting off the archiver appears to improve the steady state of memory usage (and perhaps not coincidentally greatly improves performance).
* AddMember(), ConfirmUnsubscription(): We have to handle the confirmbwarsaw2002-03-011-4/+8
| | | | | | | | cookie Subject: header the same way we do for ChangeMemberAddress(). That is, we can't set this header in the UserNotification constructor, but have to add it in afterwards, so the header doesn't get encoded (a reply to the encoded confirm header will bollux up MailCommandHandler).
* ChangeMemberAddress(): Pass the member's language into thebwarsaw2002-02-281-4/+14
| | | | | | | | | | | | | | | | | UserNotification constructor so that the verification message gets encoded correctly. There's one gotcha that affects all confirmation messages (and I will audit this next). From the comment: # BAW: We don't pass the Subject: into the UserNotification # constructor because it will encode it in the charset of the language # being used. For non-us-ascii charsets, this means it will probably # quopri quote it, and thus replies will also be quopri encoded. But # MailCommandHandler doesn't yet grok such headers, and I'm avoiding # fixing that until a future version which will completely rewrite the # mail command handling. So, just set the Subject: in a separate # step, although we have to delete the one UserNotification adds. Sigh.
* AddMember(), ApprovedAddMember(), ApprovedDeleteMember(): Whenbwarsaw2002-02-111-6/+3
| | | | | | | | creating the UserNotification message object, pass in the language that the message should be in. This allows us to get the character set and header encodings right. Patch by Ben Gertzfield.
* InitVars(): Add new list attributes: member_moderation_action andbwarsaw2002-01-211-0/+5
| | | | member_moderation_notice.
* AddMember(): Add MIME-Version: and Content-Type: headers to thebwarsaw2002-01-061-0/+3
| | | | confirmation message we're sending to the requester.
* InitVars(): Add new attribute ban_list which contains a list of emailbwarsaw2002-01-061-0/+24
| | | | | | | | | | addresses or regular expressions that are matched against the subscribing address to see if it is banned from this list. AddMember(): Implement the banned subscription logic. For each item in ban_list match it against the subscribing address, case insensitively. If there is a match, raise MembershipIsBanned exception. If the pattern starts with a ^ it is a regular expression.
* ChangeMemberName(): Fix typo found by Dan Mick.bwarsaw2002-01-041-1/+1
|
* InitVars(): Change the order of some of the attribute assignments;bwarsaw2002-01-021-3/+4
| | | | | host_name should preceed web_page_url, and the latter should be composed of DEFAULT_URL_PATTERN and DEFAULT_URL_HOST.
* CheckVersion(): Slight simplification.bwarsaw2001-12-311-16/+15
|
* ProcessConfirmation(): Add handling of Pending.RE_ENABLE to the bigbwarsaw2001-12-271-0/+5
| | | | | confirmation processing switch. This sure does call out for an object-oriented approach. ;)
* getListAddress(): Basic method for calculating a sub-address of thebwarsaw2001-11-201-10/+16
| | | | | | | | | | list given the extension. GetAdminEmail(), GetOwnerEmail(), GetRequestEmail(), GetListEmail(): Define in terms of getListAddress(). ApprovedAddMember(), ApprovedDeleteMember(): Utils.get_site_email()'s second argument should not include the leading dash.
* InitVars(): Add a hidden config variable `created_at' whichbwarsaw2001-10-271-0/+5
| | | | permanently records the Unix time the list was created.
* CheckVersion(): Can't lock an already locked list!bwarsaw2001-10-221-1/+2
|
* CheckVersion(): The list must be locked in order to auto-update thebwarsaw2001-10-221-10/+17
| | | | schemas.
* InitVars(): New MailList attributes:bwarsaw2001-10-211-8/+17
| | | | | | | | | | | | | | | | | | | | send_goodbye_msg: Says whether to send the goodbye_msg to members when they get unsubscribed. unsubscribe_policy: What is this list's policy on unsubscribes? (0 == unrestricted, 1 == admin approval) include_rfc2369_headers: Should the RFC 2369 headers be included in the messages? Defaults to yes (and requires site admin complicity to disable). DeleteMember(): New method which first checks unsubscribe_policy before deleting the member address. ApprovedDeleteMember(): Change userack default argument value to None. Also, when userack is None, default it to the value of self.send_goodbye_msg. Then of course, only send the unsubscribe ack if userack is true.
* InitVars(): New list attribute first_strip_reply_to.bwarsaw2001-10-201-0/+1
|
* InitVars(): Remove the initializations for the obsolete listbwarsaw2001-10-151-17/+71
| | | | | | | | | | | | | | | | | | | | | | | | | | | | attributes posters, forbidden_posters, moderated, and member_posting_only. Add initializations for the new sender-centric moderation attributes default_member_moderation, accept_these_nonmembers, hold_these_nonmembers, reject_these_nonmembers, discard_these_nonmembers, forward_auto_discards, generic_nonmember_action. GetConfigInfo(): Rework this framework so that it doesn't return a dictionary with keys being the category. Instead, pass the category and subcategory in as arguments and let the dispatched-to gui methods decide whether and what to return in response to these arguments. This allows the framework to be more robust, and to easily handle extensions via subcategories (as was done to the Privacy category). ApprovedAddMember(): Set the newly subscribed member's Moderate flag to self.default_member_moderation. ProcessConfirmation(): Argument userdesc_overrides -> context. In the SUBSCRIPTION clause, only add context to userdesc if context is an instance of UserDesc. Also, add a HELD_MESSAGE clause which handles admin approval/discard of held messages via email response. This code is a bit more elaborate than I'd like it to be, so perhaps it should be factored out. ;/
* AddMember(): When raising MMAlreadyAMember, include the email addressbwarsaw2001-10-121-1/+1
| | | | as the exception value.
* HasExplicitDest(), hasMatchingHeader(): Pass a failobj of [] to thebwarsaw2001-10-091-2/+2
| | | | | get_all() call so that even if the field is missing, we get a valid list object.
* Switch to using binary cpickles as the config file data format.bwarsaw2001-10-041-47/+70
| | | | | | | | | | | | | | | | | | | | | | | | Marshal is not guaranteed to be compatible across Python versions, and while I'm not aware of any breakage since Py1.5.2, better to be defensive here. Specific changes include: __save(): Dump the dict to the file as a binary cPickle. Do the dump directly instead of dumping a string to fp.write() since -- I hope -- cPickle doesn't suffer from the same problem as the comment describes marshal as suffering from (I don't actually remember the details of that). __load(): Teach this method how to load .pck (i.e. config.pck) pickle files, but retain the ability to load .db marshal files for automatic upgrade. Also, add a catch of cPickle.PicklingError to the big except clause. Load(): Teach this how to load .pck and .db files, always defaulting to .pck first. If the primary file was ever corrupt and we had to load from the .last file, we'll make a copy of .last to a .safety file just in case.
* Convert from mimelib to email.bwarsaw2001-10-011-8/+4
| | | | | Also, use cStringIO directly instead of our own hack-around StringIO module.
* AddMember(), ChangeMemberAddress(), ConfirmUnsubscription(): Fixedbwarsaw2001-09-051-3/+3
| | | | | confirm string construction to not use %(cookie)s -- unnecessary since de-i18n-ifying these strings. Found by Mikhail Sobolev.
* AddMember(), ChangeMemberAddress(), ConfirmUnsubscription(): Thebwarsaw2001-08-301-3/+3
| | | | | | subject text, which contains the robot command "confirm" should not be translated, otherwise MailCommandHandler will break. Reported by Daniel Buchmann.
* Create(): Let any exceptions in the os.makedirs() call percolate up.bwarsaw2001-08-201-5/+2
| | | | | | | I.e. don't catch and transform OSErrors to MMUnknownListErrors. Also, don't do a Save() here. The caller is now responsible for saving the list.
* InitVars(): In order to make the General options consistently displaybwarsaw2001-08-171-3/+3
| | | | | | | | | | | binary radio options as "No" then "Yes", we had to change the polarity of dont_respond_to_post_requests. Rename the option respond_to_post_requests and use versions to update the attribute and value. AddMember(): In HoldSubscription() call, the local variable `name' holds the user's full name, not `fullname'. Also say "moderator" instead of "administrator".
* InitTempVars(): Removed the _ready attribute, as it really isn'tbwarsaw2001-08-141-16/+10
| | | | | | | | | | | | | | | | | | | | | | | | | used anywhere anymore. InitVars(): Added the available_languages attribute which will hold the list of language codes supported by this mailing list. Create(): Take an extra optional argument `langs' which holds a list of language codes that the mailing list should initially support. Default this to the list's preferred language (which in turn defaults to DEFAULT_SERVER_LANGUAGE). Save(): I don't think we need IsListInitialized() any more. Load(): Removed the _ready attribute. IsListInitialized(): Removed. GetAvailableLanguages(): Don't key the list of available languages off the subdirectories in lists/<mylist>. The tiered-template lookup only requires those directories to exist if there are site customizations of the templates. Instead, return the value of self.available_languages, but with DEFAULT_SERVER_LANGUAGE forced as a member.
* ApprovedAddMember(), ApprovedDeleteMember(): Instead of usingbwarsaw2001-08-041-4/+5
| | | | | MAILMAN_OWNER, use Utils.get_site_email(). The former config variable is going away.
* InitVars(): Initialize the `personalize' list attribute. Defaults to 0.bwarsaw2001-08-031-0/+1
|
* Another step towards conversion to MemberAdaptor API.bwarsaw2001-07-291-27/+9
| | | | | | | | | | | | | | | | | | | | | | | GetPreferredLanguage() -> getMemberLanguage() ApprovedChangeMemberAddress(): When changing the addresses globally, watch out for a list that has the newaddress already subscribed. Skip it in that case (but there probably should be some way of reporting this situation back to the caller). ProcessConfirmation(): Optional argument userdesc_overrides, defaulting to None, which allows the caller to override parts of the subscription record. This is used in the confirm screen to, e.g. override the real name supplied in the original listinfo subscription request. Also, use the UserDesc helper class. When processing a CHANGE_OF_ADDRESS, return both the oldaddr and the new addr. SetPreferredLanguage(), GetPreferredLanguage(): Removed. Use the MemberAdaptor API methods instead.
* Lock(): If /any/ exception (not just MMUnknownListError) is raisedbwarsaw2001-07-261-1/+1
| | | | during the Load(), unlock the list and re-raise the exception.
* AddMember(): Cut-and-paste typo; mlist -> self; fullname -> namebwarsaw2001-07-201-3/+10
| | | | ProcessConfirmation(): Use the new ApprovedAddMember() interface.
* ApprovedAddMembers(): Rid ourselves of this horror. The right way tobwarsaw2001-07-191-113/+115
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | do it now is to loop over ApprovedAddMember() -- which no longer Save()'s after each addition! -- catching any exceptions that it might raise. The whole API for ApprovedAddMembers() was gross. AddMember(): Change the signature so that it takes only two arguments (the cancerous growth of the parameters was becoming a nightmare). The first argument is a "userdesc", essentially an instance with some well defined public attributes, and the old "remote" parameter. Any parsing of strings into fullname, emailname should be done before AddMember() is called. userdesc holds everything relevant about this subscription request: the language, password, digest flag, etc. AddMember() still validates the email address, checks to see if its already a member, and applies the list's subscription policy. ApprovedAddMember(): This now does all the work of adding a new member, and setting their digest flag. It also sends the subscriber an acknowledgement, and the admin the subscribeack. It assumes that the subscription request has passed list policy. ProcessConfirmation(): Remove the backwards compatibility hack for pre-2.1a3 entries in the requests.db. That database automatically updates its schema now.
* GetConfigInfo(): Do specific hasattr() tests instead of catchingbwarsaw2001-07-191-4/+2
| | | | AttributeErrors, which can mask real bugs.
* AddMember(): ApprovedAddMember doesn't take a fullname argument, don't trytwouters2001-07-191-5/+5
| | | | | | | | | | | to send it. Thanks to the beauty of optional arguments, this changed the fullname into the password, and used the password as the 'digest' flag, causing all new members to be considered digest members ;P ProcessConfirmation(): Adjust to the fact that the subscription info now carries the fullname too. Also change the error message so the printf operator doesn't complain about 'not all arguments converted' when 'data' is a sequence (which it is guaranteed to be.)
* Major overhaul. Summary:bwarsaw2001-07-191-958/+404
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - There's no more GetConfigInfo() in the mixin classes. All admin ui categories and content comes from components in the new Mailman.Gui package. - All MailList attribute access for user-centric information is moved out of here into the OldStyleMemberships (a subclass, aka implementation of the MemberAdaptor interface). - An extension mechanism to MailList objects has been added. Drop a file called extend.py in the lists/<yourlist> directory; this gets execfile'd, and the function extend() is called after the instance is initialized. Use this to override anything (e.g. the _memberadaptor attribute). - Lots of code reorganization. Specific changes: MailList subclasses: Added TopicMgr __init__(): Don't call MailCommandHandler.__init__() explicitly. Instead, loop through base classes calling their __init__()'s if they have them. Initialize _memberadaptor to be an OldStyleMemberships instance. After the instance has been locked and loaded <snort!> execfile extend.py and run its extend() function, if it has one. InitTempVars(): Like __init__(), cycle through all base classes, calling each's InitTempVars() if they have one. Also, instantiate the gui components by dir'ing the Gui package and instantiating each callable not prefixed by _ (they will be the individual classes). GetMembers(), GetDigestMembers(), GetDeliveryMembers(), GetDigestDeliveryMembers(), __AddMember(), GetUserSubscribedAddress(), GetUserCanonicalAddress(), GetUserOption(), SetUserOption(), FindUser(): Removed. __getattr__(): Added for auto-delegation first to the _memberadaptor, and then to the gui components. __repr__(): Change the printable representation slightly so that "(unlocked)" is printed if the list is unlocked, and also to not include the class/module name. Also use %x format instead of coercing the id to hex(). InitVars(): Add usernames and passwords dicts for traditional membership management. Like __init__(), cycle through all base classes, calling each's InitVars() if they have one. Set self.password here instead of in SecurityManager's InitVar(). GetConfigCategories(): New method which returns a CategoryDict instance (subclass of UserDict), containing the order ADMIN_CATEGORIES as extracted from the gui components GetConfigCategory() methods. GetConfigSubCategories(): For a particular category, get the list of subcategories by calling a gui component's GetConfigSubCategories() method if it has one. GetConfigInfo(): Delegate to gui components. Save(): Ignore attributes if their name starts with _ (like before) or if their value type is MethodType. AddMember(): Rewrite to use (Python 2.2's) rfc822.parseaddr() which supplants Utils.ParseAddrs(). We also don't remove spaces from the name any more, but we do still lowercase the domain. Also, IsMember() -> isMember(). Call ApprovedAddMember() passing in the fullname. Same with HoldSubscription(). ApprovedAddMembers(): Use MemberAdaptor API, and rfc822.parseaddr(). DeleteMember() -> ApprovedDeleteMember(). Also rewrite to use MemberAdaptor API. ChangeMemberName(): New method which changes a member's real name, both for this list, and globally. ChangeMemberAddress(), ApprovedChangeMemberAddress(): Use MemberAdaptor API. ProcessConfirmation(): DeleteMember() -> ApprovedDeleteMember(). GetPreferredLanguage(): Allow name to default to None, meaning return the list's preferred_language.
* AddMember(), ChangeMemberAddress(), ConfirmUnsubscription(): Shortenbwarsaw2001-07-111-3/+3
| | | | | | | the Subject: header so that it contains just the word "confirm" and the confirmation cookie. This doesn't lose any important information (which is still contained in the body of the message), and it helps for MUAs that like to wrap long Subject: lines.
* GetConfigInfo(): Add some text to the welcome_msg details whichbwarsaw2001-07-101-1/+9
| | | | explains the wrapping rules for the value.
* Use better syslog() calling convention.bwarsaw2001-06-271-19/+18
|
* Add support for the list moderator role, and change of addressbwarsaw2001-05-311-5/+134
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | requests. Specifically, InitVars(): Add the moderator attribute, which is a list of email addresses a la the owner attribute. GetConfigInfo(): Added some details to the `owner' attribute describing the different list-related roles. Also added the `moderator' attribute and copied the description of roles to its details too. ChangeMemberAddress(): Added support for change-of-address. This method simply pends the request and sends the confirmation email to the new address (the old one is already verified by way of the web authentication). ApprovedChangeMemberAddress(): Effects the actual change-of-address by adding the member, copying over the user options and the language settings, and then removing the old address. Acknowledgements are always sent. Handle the global change-of-address by searching for all the matching lists (must match both host_name and have the old address of the user as a member), and recursively calling ApprovedChangeMemberAddress() on those lists -- with the global flag turned off of course! ProcessConfirmation(): Add support for CHANGE_OF_ADDRESS, which simply unpacks the data and calls ApprovedChangeMemberAddress(). ApprovedAddMember(): Fixed a bug in the order of arguments in the call to ApprovedAddMembers() - plural. DeleteMember(): Fixed a bug in the i18n-marked subject text, related to auto-interpolation. SetPreferredLanguage(): Assert that the language we're setting to is in the list of available languages (helped catch the ApprovedAddMember() bug above). Also, only add DEFAULT_SERVER_LANGUAGE if it isn't already an item in the list.
* GetAvailableLanguages(): Add a comment.bwarsaw2001-05-251-0/+4
|
* GetAvailableLanguages(): Always add the server default language to thebwarsaw2001-05-251-0/+1
| | | | list of available languages.
* InitVars(): Don't call HTMLFormatter.InitVars() as this has beenbwarsaw2001-05-221-2/+0
| | | | | | removed. Create(): Don't call InitTemplates() as this has been removed.
* A few language related safety issues:bwarsaw2001-05-201-2/+8
| | | | | | | | | | GetConfigInfo(): If list support for a language was removed, but the list's preferred_language wasn't updated, you could get a ValueError when setting up the selection widget. Just use the first entry in the list. GetAvailableLanguages(): Ignore the language directory if LC_DESCRIPTIONS hasn't been updated to include the language.
* GetConfigInfo(), AddMember(), ConfirmUnsubscription(),bwarsaw2001-05-181-8/+6
| | | | | | | | | | ApprovedAddMember(), DeleteMember(): Instead of passing in the list's preferred language, simple pass in self; maketext() digs the preferred language out of the list object. In AddMember(), ConfirmUnsubscription(), and ApprovedAddMember(), the argument `lang' is also passed in case the user chose a language other than the list's default.