| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
| |
form, and defaulting to mlist.preferred_language.
process_form(): Suck the fullname value out of the form, defaulting to
the empty string. Call AddMember() with the new and improved
interface.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
-a/--admin-notify flag, which allows the user to inhibit sending the
administrator a notification of subscriptions.
class Tee: helper class so that output can be sent both to stdout, and
to a StringIO which might be sent to the list admin.
class UserDesc: for use with ApprovedAddMember().
addall(): New function which does the loop-over-ApprovedAddMember()
for a list of email addresses. Output is sent to the tee.
main(): Slightly better option handling (it secretly accepts y, Y,
yes, YES, YOWSA, n, N, NO, NINE for boolean options). Don't hide
IOErrors if the digestfile or regularfile can't be opened for some
reason. Be sure to Save() the list after all is said and done;
ApprovedAddMember() does not do this anymore!
|
| | |
|
| |
|
|
|
|
| |
form, and defaulting to mlist.preferred_language.
list_listinfo(): Add a replacement for the (new) fullname box.
|
| |
|
|
|
|
|
| |
called, be sure to catch MMNeedApproval, which can be raised if
subscriptions are confirm+approve.
(Yeah, I know this is eventually going to get rewritten...)
|
| |
|
|
| |
requests database automatically updates its schema now.
|
| |
|
|
|
|
|
| |
don't unquote the lines. Rewrite this function to not use
ApprovedAddMembers() -- which has been removed -- but instead to
loop over ApprovedAddMember(), keeping track of the results of
each individual addition.
|
| | |
|
| | |
|
| |
|
|
|
| |
changeMemberAddress(): If user_options doesn't have an entry for
memberkey, flags should default to 0, not None.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
__opendb(): Automatically update the schema based on the 'version'
entry (or lack thereof). Specifically, add a fullname field to
any held SUBSCRIPTION entries, and a msgdata dictionary to any
HELDMSG entries (but only if they don't have enough fields). This
update is currently keyed off the lack of 'version' entry; after
the update 'version' is set to REQUESTS_FILE_SCHEMA_VERSION.
__closedb(): Set the 'version' entry to REQUESTS_FILE_SCHEMA_VERSION
NumRequestsPending(): Subtract one from the length of the dictionary
to account for the internal bookkeeping 'version' entry.
__handlepost(): Remove the backwards compatibility hack for pre 2.0b3,
since __opendb() now does this.
HoldSubscription(): Accept a fullname field.
__handlesubscription(): Unpack the fullname field.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
full names are shown along with the email address (if it is
known). Also, backwards compatibility with pre-2.1a3 pending
database records (before a3 they didn't include the fullname).
|
| | |
|
| | |
|
| |
|
|
| |
AttributeErrors, which can mask real bugs.
|
| |
|
|
| |
"getUserOption"). Found by Mentor Cana.
|
| |
|
|
| |
`mysterious' eval() call.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
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.)
|
| |
|
|
| |
contained it.
|
| |
|
|
|
| |
cost me ten minutes to figure out I wasn't calling configure with the wrong
argument to change groupname :)
|
| | |
|
| |
|
|
| |
added.
|
| |
|
|
|
|
| |
list specialization (i.e. via extend.py) could substitute this module
for the traditional CalcRecips.py. This is mostly experimental and
exemplary.
|
| | |
|
| |
|
|
|
| |
completion. See the FIXME comment). Checking it in so I don't
have to keep rsync'ing to the office machine. ;/
|
| |
|
|
|
|
|
|
|
|
|
| |
to further cull the recipients.
do_topic_filters(): For each recipient of the regular delivery
message, if there are no topic hits, check the
ReceiveNonmatchingTopics option to see whether this recipient should
get the message. If there are topic hits, remove the recipient unless
they've indicated an interest in this topic (or they haven't specified
any interests).
|
| |
|
|
|
|
|
|
|
| |
optionally the same fields at the start of the body of a message),
looking for matches against topic regexps. For each one it finds, it
adds the matching topics to the message metadata, using the key
"topichits". It also adds an X-Topics: header.
CalcRecips will use this information to cull its recipient lists.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
|
| |
GetConfigInfo() structures that used to be in the modules one
directory up.
|
| |
|
|
| |
these out later.
|
| |
|
|
|
|
|
| |
recent checkins.
Also added Chris Ryan who inspired the componentization of the
MemberAdaptors.
|
| |
|
|
| |
recent checkins.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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!
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
API instead, e.g.
GetUserOption() -> getMemberOption()
GetPreferredLanguage() -> getMemberLanguage()
IsMember() -> isMember()
GetDigestDeliveryMembers() -> getDigestMemberKeys()
ToDigest.py: clear the one_last_digest() dictionary after sending the
digest.
|
| |
|
|
|
|
|
| |
API instead, e.g.
GetUserOption() -> getMemberOption()
GetUserSubscribedAddress() -> getMemberCPAddress()
|
| |
|
|
|
|
|
|
|
| |
API instead, e.g.
GetMembers()/GetDigestMembers() -> getMembers()
GetUserSubscribedAddress() -> getMemberCPAddress()
GetDeliveryMembers() -> getRegularMemberKeys()
GetDigestDeliveryMembers() -> getDigestMemberKeys()
|
| | |
|
| | |
|
| |
|
|
| |
that the msgfp file is definitely closed.
|
| | |
|
| |
|
|
| |
process_form(): IsMember()/FindUser() -> isMember();
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|