summaryrefslogtreecommitdiff
path: root/Mailman
Commit message (Collapse)AuthorAgeFilesLines
...
* Post.py contains the virtual mailing list support (i.e. the ability tobwarsaw2001-07-192-0/+119
| | | | | | | | | send a message from a list, but with an explicit list of recipients). There is both an importable API and a command line API when called as a script. TopicMgr.py contains the mixin class for initializing MailList attributes related to the topic filter feature.
* The usual.bwarsaw2001-07-191-0/+1
|
* There are the admin gui component modules, which now contain all thebwarsaw2001-07-1912-0/+1184
| | | | | GetConfigInfo() structures that used to be in the modules one directory up.
* 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.
* MMMemberError, MMBadUserError, MMNotAMemberError, MMNoSuchUserError,bwarsaw2001-07-191-6/+14
| | | | | | | | | | | MMAlreadyAMember: Make these class based exceptions. MemberError, NotAMemberError, AlreadyReceivingDigests, AlreadyReceivingRegularDeliveries, CantDigestError, MustDigestError: Add these "new wave" exceptions, which are raised by the MemberAdaptors. NB: I really need to go through and make all the exceptions sane!
* All membership related attribute access should use the MemberAdaptorbwarsaw2001-07-191-109/+94
| | | | | | | | | | | | | | | | | | | | | | | | | | | API instead, e.g. IsMember() -> isMember() self.passwords.* -> getMemberPassword() ConfirmUserPassword() -> [do the comparison ourselves] ChangeUserPassword() -> setMemberPassword() GetUserOption() -> getMemberOption() GetDigestMembers() -> getDigestMemberKeys() GetMembers() -> getRegularMemberKeys() DeleteMember() -> ApprovedDeleteMember() option_info: Make order agree w/ option_desc. ProcessPasswordCmd(): Fix the response string so that it isn't broken on two lines. Remove unnecessary exception handlers. be raised. ProcessOptionsCmd(), ProcessSetCmd(), ProcessUnsubscribeCmd(): Rewrite and simply to use the new membership API. Remove unnecessary exception handlers. ProcessSetCommand(): Split usage printing into __setcmd_usage() method.
* All membership related attribute access should use the MemberAdaptorbwarsaw2001-07-191-11/+13
| | | | | | | | | | | | | API instead, e.g. GetDigestMembers() -> getDigestMemberKeys() GetUserOption() -> getMemberOption() GetMembers() -> getRegularMemberKeys() FormatOptionButton(): Add ReceiveNonmatchingTopics flag. FormatBox(): Add optional `value' parameter, which if supplied is the default value for teh input box (default is the empty string).
* GLOBAL_PIPELINE: Add the new Tagger handler before CalcRecips (whichbwarsaw2001-07-191-4/+13
| | | | | | | | | | | | depends on it). ADMIN_CATEGORIES: Here's where we define the category names for the admin ui. Topics: A new widget type. ReceiveNonmatchingTopics: New member option flag controlling whether a user receives or ignores a message that does not matching any topics.
* All membership related attribute access should use the MemberAdaptorbwarsaw2001-07-193-31/+44
| | | | | | | | | | | | API instead, e.g. GetUserOption() -> getMemberOption() GetPreferredLanguage() -> getMemberLanguage() IsMember() -> isMember() GetDigestDeliveryMembers() -> getDigestMemberKeys() ToDigest.py: clear the one_last_digest() dictionary after sending the digest.
* Now, try to remove it!bwarsaw2001-07-191-555/+0
|
* Committing to see if I can finally get rid of this file. :(bwarsaw2001-07-191-0/+555
|
* dequeue(): Be a bit more robust about possible exceptions, ensuringbwarsaw2001-07-191-12/+14
| | | | that the msgfp file is definitely closed.
* GetConfigInfo(): Removed.bwarsaw2001-07-191-17/+0
|
* A revamp to use the new membership API. Specifically,bwarsaw2001-07-191-3/+3
| | | | process_form(): IsMember()/FindUser() -> isMember();
* A revamp to use the new membership API, and to be able to set/getbwarsaw2001-07-191-49/+187
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | member's real names. Specifically, main(): IsMember() -> isMember(); FindUser()/GetUserSubscribedAddress() -> getMemberCPAddress() GetPreferredLanguage() -> getMemberLanguage() Support the printing of topic details when they click on the "Details" link after the topic name (works like admin interface's VARHELP). In the change-of-address stanza, add a check for the fullname field, which contains the member's real name. After extracting the fullname, new-address, and confirm-address fields, be more careful about including error messages, so that if the real name field is set or cleared, we ignore the address fields if they are both blank. Handle setting the member's name globally, just like a global change of address. DeleteMember() -> ApprovedDeleteMember() Add recognition of the ReceiveNonmatchingTopics flag to determine what the user wants for messages that match no topics (they can either receive them or ignore them). GetUserOption() -> getMemberOption() Add processing of user topic selections. SetUserOption() -> setMemberOption() and don't special case when setting digest deliver; setMemberOption() handles that properly. options_page(): Include the user's full name in presentable_user, as in "john.doe@dom.ain, John Doe". If there's no user name then just print the email address as before. "Change My Address" button -> "Change My Address and Name" Add replacements for the fullname box, and the topics option. IsMember() -> isMember() ChangeUserPassword() -> setMemberPassword() SetUserOption() -> setMemberOption() topic_details(): New method to include the topic details in the top information area.
* main(): Extract the cgi data using keep_blank_values=1 so we'll knowbwarsaw2001-07-191-4/+4
| | | | | | | | | | | when the admin is trying to login with an empty password field. When WebAuthenticate() fails, check the `adminpw' cgi key to determine whether this was a login attempt, or the first visit of this link. show_requests(): SUBSCRIPTION pending records now include the supplied user real name (i.e. fullname), so use this when unpacking the tuple.
* A revamp to use the new category components, the new membership API,bwarsaw2001-07-191-113/+164
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | and to be able to set/get member's real names. Specifically, CATEGORIES: Don't hardwire these here. Instead they are extracted via mlist.GetConfigCategories(). main(): GetMembers() -> getRegularMemberKeys() get_config_options(): Removed. Use mlist.GetConfigInfo() instead. show_results(): Don't hardwire sub-categories. Instead get them from mlist.GetConfigSubCategories(). get_item_gui_value(): Added a new kind of gui widget, the `Topics' widget which includes at least three boxes (for topic name, regexp, and description), along with possibly a Delete button, an Add button, and an "add where" pull down menu. membership_options(): Instead of using GetMembers() and GetDigestMembers(), use the new membership API methods getMembers(), getMemberName(). Also use getMemberOption() instead of GetUserOption(). In the membership list, add a text box for the member's real name. change_option(): We now allow gui components to optionally handle the form data themselves. If the component has a HandleForm() method, it is called, passing the MailList object, the cgi form data structure, and the Document object. DeleteMember() -> ApprovedDeleteMember() SetUserDigest() -> setMemberOption(... mm_cfg.Digests, ...) SetPreferredLanguage() -> setMemberLanguage() SetUserOption() -> setMemberOption() Added setMemberName() to set the member's full name. get_config_options(): Removed.
* Descend into the Gui subdirectory.bwarsaw2001-07-191-1/+1
|
* confirm(): Add optional argument `expunge' defaulting to true. Thisbwarsaw2001-07-191-4/+10
| | | | | | is a flag specifying whether pending entries should be removed from the database or not, and will be used with the revamped confirmation web ui.
* InitVars(): With the new mixin architecture, InitVars() needs to takebwarsaw2001-07-191-19/+7
| | | | | | | | | | | | | zero arguments, so we remove the crypted_password parameter. This means that self.password will be set in MailList instead. AuthContextInfo(): Instead of getting the user password directly out of self.passwords, use the API method getMemberPassword() -- which itself raises MMNotAMemberError if the user isn't a member of the list. ChangeUserPassword(): Removed. Use the new setMemberPassword() API method.
* Some code re-organization.bwarsaw2001-07-191-76/+29
| | | | | | | | | | ValidateEmail(): Add `/' to the list of _badchars in email addresses instead of making it bad only if it points to an existing directory (!). ParseAddrs(): Removed since rfc822.parseaddr() now works for all cases, according to RFC 2822 (but we'll need to supply the rfc822.py from Python 2.2 now).
* All:bwarsaw2001-07-185-212/+8
| | | | | | | | | | | | | | | | | | | | | | | | GetConfigInfo(): Removed. All admin ui gui elements are moved into components in the Mailman/Gui subdirectory. All membership related attribute access should use the MemberAdaptor API instead, e.g. IsMember() -> isMember() GetUserOption() -> getMemberOption() SetUserOption() -> setMemberOption() Also use ApprovedDeleteMember() instead of DeleteMember(). Deliverer.py: Remove last vestiges of os.environ['LANG'] Digester.py: SetUserDigest(): Removed. This is replaced by OldStyleMemberships's setMemberOption() method when flag == mm_cfg.Digests
* Bump the version number to 2.1a3 and kick the DATA_FILE_VERSION to 30bwarsaw2001-07-181-3/+3
| | | | so the new variables from versions.py will get installed.
* NewVars(): Add the following attributes to MailList instances, if theybwarsaw2001-07-181-0/+5
| | | | | | | | | | | | | | | don't already have them: - topics: a list of all admin specified topics - topics_enabled: a flag specifying whether topics are enabled - topics_bodylines_limit: the number of lines of the body that the topic tagger should look for Subject: and Keywords: lines - one_last_digest: A hold over from an earlier time, this holds addresses of folks who switched from digest to regular delivery - usernames: holds the dictionary of email addresses to Real Names but if a user has no assigned Real Name, they have no entry in this dictionary.
* intermediatebwarsaw2001-07-181-0/+262
|
* intermediatebwarsaw2001-07-181-0/+228
|
* _dopipeline(): We don't need to save the return value of __import__().bwarsaw2001-07-131-1/+1
|
* _dopipeline(): Do not include the blank Exception catch-all here, butbwarsaw2001-07-131-9/+0
| | | | | | | | | | instead let them percolate up to Runner.__oneloop(). Now, the proper action when an uncaught exception occurs is to shunt the message instead of trying forever to re-deliver it (possibly causing logs/error to fill up /very/ quickly). Shunted messages can always be resent by moving them back to qfiles/in.
* process(): Be much more careful about bogus source strings for thebwarsaw2001-07-131-13/+14
| | | | | | | | | | | | | | dictionary interpolation. Since they're coming from the great unwashed masses, the autoresponse texts could have bogus %()s bits in them, and using a SafeDict doesn't guard against all kinds of exceptions. So, if any exception is caught during interpolation, log it, and use the raw autoresponse text in the email. Also, because we're not using the buggy rfc822.py module anymore, we don't need to special case the situation when the first line of the autoresponse text has a colon in it.
* hold_for_approval(): Inside admin_immed_notify (i.e. when we'rebwarsaw2001-07-131-1/+1
| | | | | | | | | | | notifying the administrator of the held message), use the list's preferred_language to get the charset. This fixes the UnboundLocalError that occurs if dont_respond_to_post_requests and admin_immed_notify are both true (it shouldn't have been using `lang' in the first place, since that's the /user's/ preferred language, not the admin's). Bug found by Mentor Cana.
* add_error_message(): Don't translate tag if it is the empty string.bwarsaw2001-07-121-1/+4
| | | | Found by Juan Carlos Rey Anaya.
* show_post_requests(): If the heldmsg is lost, the IOError will havebwarsaw2001-07-121-1/+1
| | | | the error code on e.errno, not e.code. Found by Mentor Cana.
* start_runner(): Changed indentation, since the parent always returns.bwarsaw2001-07-111-14/+20
| | | | | Also added a note why "mailmanctl restart" doesn't Do The Right Thing w.r.t. allowing the subrunners to re-import various Mailman modules.
* main(): Catch MMNoSuchUserError which can happen if two unsub requestsbwarsaw2001-07-111-0/+4
| | | | | | were sent and the user confirmed (by web click) them both. The first will delete the member but the second will raise this exception, so do something more sensible than letting it trickle to the top.
* 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.
* __NoMailCmdResponse => __noresponsebwarsaw2001-07-111-20/+29
| | | | | | | | | | | | | | | | | | AddToResponse(): Use augmented assignment where appropriate. ParseMailCommands(): Set the __noresponse flag to 0 at the top of this method, so there's no chance that a previously handled command will mess up sending a response to this command. ProcessConfirmCmd(): Save the results from ProcessConfirmation() and check the operation in the first element. If it's a Pending.SUBSCRIPTION and the mailing list already sends out welcome messages, then don't send a "succeed" confirmation ourselves. Also, in the big except clause, catch MMNoSuchUserError which can happen if the user has made two unsub requests and confirmed them both (the second will trigger the exception). Do something more sensible than letting the exception trickle all the way back up. ;)
* main(): Forgot to re-install the real translation context after thebwarsaw2001-07-111-0/+1
| | | | | trick-out of template_data. Add back the definition of _ (provided by Juan Carlos Rey Anaya).
* _dopipeline(): Use a better mechanism for digging out the process()bwarsaw2001-07-101-4/+5
| | | | | | | | | function from the dynamically imported module. Also, MessageHeld -> HoldMessage Also, catch RejectMessage exceptions, bouncing the rejected message via mlist.BounceMessage().
* InitVars(): Fix the out-of-date comment.bwarsaw2001-07-101-1/+1
|
* GetConfigInfo(): Add some text to the welcome_msg details whichbwarsaw2001-07-101-1/+9
| | | | explains the wrapping rules for the value.
* Added support for an Urgent: header, which should contain a passwordbwarsaw2001-07-101-0/+47
| | | | | | | | | | | | | | | | | | (either the list administrator's, or the list moderator's). If the message contains this header with a matching password, the message is sent to the entire list membership immediately, even to those members who receive the message via digests. Note that the message /is/ still digested too. Specifically, RejectUrgentMessage: New class, derived from RejectMessage, which is raised if the password in the Urgent: header does not match. Thus, the original message is returned to the sender immediately, and is not held or posted. process(): Check Urgent: for a matching list moderator's or list administrator's header. If found, set the recipients list to both the regular and digest delivery members. If Urgent: is found, but the password doesn't match, bounce the message back to the sender.
* BSDDBdatabase.__openIndices(): 'pas' -> 'pass'twouters2001-07-101-1/+1
|
* Add missing import of 'syslog'.twouters2001-07-101-0/+1
|
* MailCommandHandler.ProcessOptionCmd() and MailCommandHandler.ProcessSetCmd():twouters2001-07-101-2/+2
| | | | 'option_descs' -> 'option_desc', as that is what the global is named.
* UpdateOldVars(): 'setatrr' -> 'setattr'twouters2001-07-101-1/+1
|
* SecurityManager.MakeCookie(): 'MMBadUserError' -> 'Errors.MMBadUserError'twouters2001-07-101-1/+1
|
* 'UnimplementedError' -> 'NotImplementedError'twouters2001-07-102-3/+3
|
* import time so it can be used.twouters2001-07-101-0/+1
|
* Add back COMMASPACE to globals, as it apparently *is* used, just nottwouters2001-07-101-1/+3
| | | | | | correctly. prepare_message(): 'COMMA' -> 'COMMASPACE'
* Don't forget to import LockFile for its exception.twouters2001-07-101-0/+1
|