| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
| |
list traffic.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
| |
- use fullpath() instead of _full_path directly
- Don't os.path.join() up the list path, instead use
Site.get_listpath()
|
| |
|
|
|
|
|
|
|
|
| |
written by Ben Gertzfield, ported to MM2.1 by Marc MERLIN.
Specifically,
InitVars(): Add the new_member_options attribute.
(Also, untabbification)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
| |
member_moderation_notice.
|
| |
|
|
| |
confirmation message we're sending to the requester.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
|
| |
host_name should preceed web_page_url, and the latter should be
composed of DEFAULT_URL_PATTERN and DEFAULT_URL_HOST.
|
| | |
|
| |
|
|
|
| |
confirmation processing switch. This sure does call out for an
object-oriented approach. ;)
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
| |
permanently records the Unix time the list was created.
|
| | |
|
| |
|
|
| |
schemas.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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. ;/
|
| |
|
|
| |
as the exception value.
|
| |
|
|
|
| |
get_all() call so that even if the field is missing, we get a
valid list object.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
| |
Also, use cStringIO directly instead of our own hack-around StringIO
module.
|
| |
|
|
|
| |
confirm string construction to not use %(cookie)s -- unnecessary
since de-i18n-ifying these strings. Found by Mikhail Sobolev.
|
| |
|
|
|
|
| |
subject text, which contains the robot command "confirm" should
not be translated, otherwise MailCommandHandler will break.
Reported by Daniel Buchmann.
|
| |
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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".
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
| |
MAILMAN_OWNER, use Utils.get_site_email(). The former config
variable is going away.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
| |
during the Load(), unlock the list and re-raise the exception.
|
| |
|
|
| |
ProcessConfirmation(): Use the new ApprovedAddMember() interface.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
| |
AttributeErrors, which can mask real bugs.
|
| |
|
|
|
|
|
|
|
|
|
| |
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.)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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.
|
| |
|
|
|
|
|
| |
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.
|
| |
|
|
| |
explains the wrapping rules for the value.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
| |
list of available languages.
|
| |
|
|
|
|
| |
removed.
Create(): Don't call InitTemplates() as this has been removed.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|