summaryrefslogtreecommitdiff
path: root/Mailman/Utils.py (follow)
Commit message (Collapse)AuthorAgeFilesLines
* DeliverToUser(): I believe the forking done in here is no longerhmeland1999-07-011-20/+34
| | | | | | needed. For now, however (trying to move towards 1.0), I've merely reduced the amount of work done in the child, and wrapped it in a try: clause for catching fork() failures.
* TrySMTPDelivery(): Be smarter about handling the various exceptionshmeland1999-06-131-3/+45
| | | | smtplib.sendmail() can raise.
* Changes to speed up mass subscription via the web:hmeland1999-06-041-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* TrySMTPDelivery(): Force importation of smtplib out ofbwarsaw1999-04-271-11/+8
| | | | | Mailman.pythonlib so we're sure we're getting the latest and greatest version of this module.
* _badchars(): Disallow addresses with commas in thembwarsaw1999-03-261-1/+1
|
* ParseAddrs(): string.strip() all returned addresses.bwarsaw1999-03-251-3/+3
|
* Add ^ to the list of _badchars in email addressesbwarsaw1999-03-231-1/+1
|
* GetRandomSeed(): Return only combinations of upper and lower casebwarsaw1999-03-201-3/+9
| | | | letters.
* Utils.GetRequestURI(): New function, returns the full virtual path thehmeland1999-03-021-0/+19
| | | | | | | | | | calling CGI script was invoked with. Uses (non-standard, but convenient) environment variable REQUEST_URI when available, otherwise SCRIPT_NAME and PATH_INFO (which are part of the CGI/1.1 spec) if available, or simply returns optional argument `fallback' (which defaults to None). Cgi/admin.py, Cgi/admindb.py: Use it when generating admin authentication page.
* TrySMTPDelivery(): Slightly different format to the log format onbwarsaw1999-01-141-1/+5
| | | | | failure: the value is only printed if it's not false (e.g. None), and the deferred status is printed as well.
* ValidateEmail(): Raise a MMBadEmailError on empty str.bwarsaw1999-01-091-0/+2
|
* ValidateEmail(): Renamed from ValidEmail().bwarsaw1999-01-091-13/+13
| | | | | | | | | | | | | | | | Cleaned up its interface so that it always raises an exception if an address problem is uncovered (it used to both raise exceptions and return 0 or 1). It now has no useful return value. Added a re to barf on other unacceptable characters in an email address, currently: [ ] ( ) < > | ; Should there be others? The test that were there are retained, but the domain_parts test was cleaned up (there was a redundant test in there). Note that now unqualified addresses (e.g. those that don't contain an `@' are now DISALLOWED). This goes partially toward Greg Stein's suggestion.
* chunkify(): Don't put mm_cfg.DEFAULT_ADMIN_MEMBER_CHUNKSIZE as abwarsaw1999-01-061-1/+3
| | | | | | default arg value because then this module can't be imported in older versions of Mailman. Use None in the arglist, and set to the proper value when None is detected.
* reraise(): can now take an optional val argument, which is only usedbwarsaw1999-01-051-3/+7
| | | | | | when exc is not None. open_ex(): Use reraise().
* IsAdministrivia(): Made more stringent about 'set' command, since weklm1999-01-051-2/+5
| | | | | | | | | | | | | | | | | | | got a false positive for a message that had the last line of a paragraph (hence, short enough to look like administrivia) begin with 'set'. - Require all 3 arguments (for some reason it was requiring 2 or 3, while MailCommandHandler seems to clearly require 3 - perhaps we want to catch malformed administrivia, i'm just assuming not) - Require second arg of set command matches to be 'on' or 'off'. I guess administrivia is a delicate balance between weeding out non-administrivia and catching mis-directed admin messages, even ones that were badly formed. I'm inclined to opt for greater stingency, at the risk of not catching malformed and misdirected admin messages. Tough luck, the misguided poster will have to change their password. (I bet i get stung by this one day, myself...)
* ParseAddrs(): New function which attempts to parse out the emailbwarsaw1998-12-301-0/+42
| | | | | | | | | | addresses from lines such as User J. Person <person@allusers.com> person@allusers.com (User J. Person) It also handles bare email addresses. While this is rather simplistic regexp matching, I think it will catch most situations.
* reraise(): exc argument is optional, to more closely resemble Pythonbwarsaw1998-12-291-2/+5
| | | | 1.5.1's bare raise statement
* DeliverToUser(): Small stylistic tweak to change the sense of the testbwarsaw1998-12-291-19/+19
| | | | and put the child code in the block of the `if'.
* Fixed two instances where the old module named mm_err was beingbwarsaw1998-12-291-3/+3
| | | | | | | | | | referenced; these should be Errors. This was in response to an attempt to subscribe a list to itself by sending an subscribe email command and faking the From: field. Now we don't get a crash, but I'm not sure the current behavior is correct. The address (properly) doesn't get subscribed, but a message stating this *is* sent to the list!
* TrySMTPDelivery(): On advice from Dragon, we do a manual ehlo/helo,bwarsaw1998-12-231-1/+9
| | | | | then check to see if the remote SMTP supports DSN. If so, we'll add the NOTIFY=failure to the receipt options.
* TrySMTPDelivery(): Added hacky stuff to ensure (as best we can) thatbwarsaw1998-12-221-13/+22
| | | | | | | we're getting a modern smtplib.py, either from Python, or from Mailman.pythonlib package. Also, use the current standard interface to smtplib.
* open_ex(): Cosmetic change - lined up docstring (not sure why it wasklm1998-12-081-3/+4
| | | | bizarrely raggedy).
* These changes represent the changes that make mailman's addressingcotton1998-11-211-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | work like unix mail: username portions of addresses are case-preserved for delivery only. All other address comparisons are lowercase. up'd data version in Defaults to 13 ** MailList.py: added an __AddMember method that takes an address and whether or not it is a digest address as args and populates the member dictionary like this: if string.lower(addr) == LCDomain(addr): member_dict[addr] = 0 else: member_dictp[string.lower(addr)] == LCDomain(addr) added .GetDeliveryMembers() and .GetDigestDeliveryMembers() methods for use by posting and digest delivery mechanisms. changed a nested def portion in Post to use an explicit loop. **Digester.py: uses .GetDigestDeliveryMembers instead of .GetDigestMembers(). **Utils.py: address comparisons are lc. **versions.py: populate the member dicts according to the above formula. **Cgi/admin.py: fixed a bug introduced from the first change to using member dictionaries: all members were showing up as digest members on the admin membership page. changed a dict.get to dict.has_key to fix this. NOTE: this code is tested only insofar as I posted and poked around on the cgi's a bit, and let lists do the versions code. These changes should be tested more, but I *have* to go now and wanted to check them in before someone made it difficult to do so by changing stuff tomarrow, cause i'm gone all day tomarrow. scott
* GetPossibleMatchingAddrs(): Don't bomb with an exception if theklm1998-11-211-3/+4
| | | | | | address lacks a domain. (I'm currently returning the list with just the bare account name, scott please consider whether or not this is sensible, i'm going on partial knowledge of your changes.)
* whoops, just realized that there were a couple of places where icotton1998-11-191-0/+8
| | | | | | | | | | | | | didn't translate Utils.FindMatchingAddresses properly! in MailList.Post(), FindMatchingAddresses was applied to list.posters and list.forbidden_posters which are lists and not dicts, so I added a function in Utils called List2Dict that takes a list and retuns a dict keyed by the items in the list (it doesn't check for whether the items are hashable). All values are 1. This function is now used in MailList.Post(): where the FindMatchingAddresses was applied to an address list, it is now applied to Utils.List2Dict(address list). scott
* made FinMatchingAddresses require atleast the first dictionary, socotton1998-11-191-2/+3
| | | | | that it's signature is now FindMatchingAddresses(name, dict, *dicts). scott
* This change implements storing list members and digest members ascotton1998-11-191-8/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | dicts instead of lists, which optimizes Utils.FindMatchingAddresses and general membership management, especially for large lists. MailList.py now supplies .GetMembers() and .GetDigestMembers() to supply the data in list form to anything that needs it that way. An new install showed this worked fine with some cursory testing of the cgi's and interactive poking around. A detailed listing of the changes follows: Mailman/Defaults.py.in: change data version to 11 Mailman/Digester.py: initvars now instantiates digest_members as {} instead of [] lines 113-114 and 121-122 now use del This change implements storing list members and digest members as dicts instead of lists, which optimizes Utils.FindMatchingAddresses and general membership management, especially for large lists. MailList.py now supplies .GetMembers() and .GetDigestMembers() to supply the data in list form to anything that needs it that way. Though INSTALL shows up on the changed files section, a diff a few seconds ago didn't show any differences in that file, so I hope nobody changed it in the interim. An new install showed this worked fine with some cursory testing of the cgi's and interactive poking around. A detailed listing of the changes follows: Mailman/Defaults.py.in: change data version to 11 Mailman/Digester.py: initvars now instantiates digest_members as {} instead of [] lines 113-114 and 121-122 now use del list.[digest_]member instead of list.[digest_]members.remove when figuring who to actually send digests to, use list.GetDigestMembers() instead of list.digest_members. Mailman/HTMLFormatter: now uses list.Get[Digest]Members to get subscribers, and length of digested subscribers and regular members MailCommandHandler, SecurityManager,Cgi/handle_opts, Cgi/options: all simple replacements of list.[digest_]members with list.Get[Digest]Members(). Mailman/Cgi/admin.py: mostly simple replacements of list.[digest_]members with the Get..() methods, however, the membership management section now works much quicker and changes digest->nodigest subscriptions via dictionary manipulations. Mailman/versions.py: updates lists to use dicts and changed list.[digest_]members to use the list.Get[Digest]Members() methods. Mailman/Utils.py: added a function "GetPossibleMatchingAddresses" which when fed an address, returns the list of addresses that "smart" address matching would match. changed FindMatchingAddresses(name, list) to use a new signature: FindMatchingAddresses(name, *dicts), where dicts is a list of dictionaries keyed by addresses. Just realized that this would better be FindMatchingAddresses(name, dict, *dicts) so that it enforces atleast 2 args... I'll make that change in a sec. All uses of FindMatchingAddresses have been changed to fit the new arguments. scott ----:**-F1 cvs30458aaa 1:12PM 0.98 Mail (Text Fill)--L59--32%------------------------------------------- ?
* fixed up IsAdminsitrivia a bit as per the problems reported bycotton1998-11-131-6/+9
| | | | | | | | Madarasz Gergely. IsAdministrivia now strips sigs and counts lines correctly from the body of the message instead of the whole message. In addition, I up'd the constant 10 for the maximum number of lines with text in them to 30. scott
* mkdir(): Default mode is 02775 which turns out to be more common inbwarsaw1998-11-041-2/+39
| | | | | | | | | the Archiving code -- the only place this function is used currently. open_ex(): Extended open. Like built-in open, but with an extra argument that includes the permissions the file should be created with. Avoids the need for chmod'ing the file. Also assures that umask(0).
* reraise(): Useful for re-raising an exception. This should makebwarsaw1998-11-031-8/+19
| | | | | | | | re-raising portable between Python 1.5.2 and earlier versions (which don't allow bare `raise'). mkdir(): Wrap os.mkdir() in a umask saving try/finally. See docstring for differences.
* changed the site site variable ADMIN_MEMBER_CHUNKSIZE to a per-listcotton1998-10-231-1/+1
| | | | | | | | | | | | | | | | | variable (admin_member_chunksize). this is not yet settable by means of cgi, but you can set it at an interactive python session. This is a start on making the membership management part of the admin cgi scalable for really big lists. details: * up'd DATA_FILE_VERSION in Mailman/Defaults.py.in * replaced ADMIN_MEMBER_CHUNKSIZE with DEFAULT_ADMIN_MEMBER_CHUNKSIZE in Mailman/Defaults.py.in. * added a list variable assignment in Mailman.MailList.InitVars * added code to add the admin_member_chunksize attribute to a list when versions change in Mailman/versions.py * made admin.py format members according to list.admin_member_chunksize instead of mm_cfg.ADMIN_MEMBER_CHUNKSIZE scott
* added adminitrivia filter and an "administrivia" list attribute thatcotton1998-10-121-3/+57
| | | | | | | | | | | | | | | | | is editable via the admin cgi to turn the filter on and off. I'm sure that the filter could catch more things, but it will have less false positives than majordomo anway :) a listing of the specific changes follows: Defaults.py.in changed data file version and added DEFAULT_ADMINISTRIVIA Utils.py added a function IsAdministrivia(msg) that does the filtering replaced re.sub with string.replace(much faster) in (Un)ObscureEmail. MailList.py: added the config info for the administrivia variable, and made the post method check it if the list has the variable set. versions.py: make new lists have an administrivia variable scott
* These changes allow case-preserved usernames in email addresses ofcotton1998-10-121-37/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | list members. I have yet to look at handling of -admin addresses. Also, there is a configurable variable in Defaults.py that allows the site admin to decide whether or not to do "smart address matching" - where scott@chronis.pobox.com matches scott@pobox.com as the same address (these addresses are in reality different addresses ;). A listing of the changes to the files follows: Defaults.py.in - added SMART_ADDRESS_MATCH variable and a short description, defaulting to 1. MailCommanHandler: removed string.lower(address) in processSubscribeCmd and replaced it with Utils.LCDomain(address) MailList.py: made AddMember and ApprovedAddMember use Utils.LCDomain(address) instead of string.lower(address) Utils.py: got rid of top level domain listing and commented out corresponding code in ValidEmail since it seems clear that we have no intention of using this anymore. added LCDomain(address) which lowercases only the domain part of an address if there is a domain part. made AddressesMatch use LCDomain instead of string.lower, made it check LCDomain(addr1) == LCDomain(addr2) if mm_cfg.SMART_ADDRESS_MATCH is set to 0, and do the match it used to do if that variable is set to 1. scott
* changed contact_transport so that it doesn't invoke a queue runcotton1998-10-051-11/+17
| | | | | | | | | | | | | ditto for Utils.SendTextToUser. rearranged OutgoingQueue so that 1) it sets a global lock to only allow on queue run at a time 2) enqueueMessage puts a queue entry in an active state 2) the queue run only processes messages in a deferred state or messages that are in an active state but stale 3) it has a deferMessage interface. which is now used by Utils.TrySMTPDelivery It now keeps track of the state of a q entry by means of file metadata - if the qfile is setuid, it's in active state, if it's not it's in deferred state. scott
* TrySMTPDelivery(): Regularize the ways that various exceptions areklm1998-08-031-14/+21
| | | | expressed, and log failures to smtp-failures.
* TrySMTPDelivery: The queueing activity had to be more discriminating,klm1998-08-011-5/+26
| | | | | | | | | | | | | | | | | or else failures, like bad local recipients, would remain on the queue forever, and cause repeat deliveries. (I believe this is part of the problem behind the repeats we're seeing - but i'm not convinced it's all of it.) To fix, i made it so only partcicular exceptions - currently socket.error, for absent SMTP listener - cause items to be left on queue. Otherwise it falls through to a blanket except which discards the item, leaving a note in the error log to that effect. *** I think where the info should go back to the maillist structure, to, e.g., disable the recipient, or whatever. However, this is happening in a forked process, so we cannot use an exception, and the routine itself doesn't, and shouldn't know which the list is.
* wrap(): Two small fixes: strip off the two extra newlines that get putbwarsaw1998-07-221-2/+9
| | | | | on the end of the last line of wrapped text; watch out for whitespace at the front of split lines.
* Whoops, there was another call to smtplib that needed the indirection.viega1998-07-201-1/+1
|
* Wrapped the call to smtplib with some queueing code.viega1998-07-201-3/+15
| | | | There's a new crontab entry that checks the queue once every 30 mins.
* Moved wrapping/filling to maketext() template generator.bwarsaw1998-07-061-7/+11
| | | | | | SendTextToUser() no longer has a raw argument and no longer calls wrap() in any way. maketext() has a raw argument, default to zero, which if true skips the call to wrap() on the interpolated text.
* Removed classes Logger and StampedLogger, into modules in thebwarsaw1998-07-021-119/+3
| | | | Mailman.Logging package
* Convert all module names to their new names.bwarsaw1998-06-191-6/+24
| | | | | | maketext(): New function which takes a template file name and a dictionary, reads the template from mm_cfg.TEMPLATE_DIR and interpolates the dictionary into the string.
* Fixed a bug where sometimes a leading / is missing from PATH_INFO.viega1998-06-051-1/+3
|
* Added a method: GetNestingLevel(), which returns how many ../'s areviega1998-06-031-0/+11
| | | | | needed to get back to http://xxxx/mailman/ based on the PATH_INFO environment variable.
* Fixed a bug in wrap where wrap would error if the length of the stringviega1998-06-031-1/+1
| | | | being wrapped was the same as the column parameter.
* Integrated Scott's cookie code into the distribution.viega1998-05-301-0/+14
| | | | | | Note that it does have one problem... If you have cookies off, you have to log in every time, plus your changes don't take effect! That definitely needs to be fixed.
* Modfied DeliverToUser to use smtplib instead of a call to sendmail.viega1998-05-281-10/+12
| | | | | Note that I'm using my smtplib right now, and not the one that comes w/ Python 1.5. That should probably be changed.
* Removed RCS crudbwarsaw1998-05-261-3/+73
| | | | | | | | | | | | | | | | | wrap(): New function which implements the wrapping and filling algorithm, as described in the function's docstring. After talking it over with Guido and Ken, this seemed like the best compromise for ensuring that emailed messages to users look okay, when their MUAs don't auto-wrap. SendTextToUser(): Added optional argument raw which defaults to zero (meaning by default, wrap and fill as per the rules in wrap()). When raw=1, no wrapping or filling of the text argument is performed. While Ken thinks that wrapping/filling should be turned off by default, I think there are many more cases where the text should be wrapped and filled than not, so this go'round tries to minimize code changes. If the consensus is to invert the default value, we can make that change after grep'ing the code.
* Fixed a typo in the zipcode.viega1998-05-261-2/+2
|
* Added copyright notices to all source files where I am legally entitled to ↵viega1998-05-251-1/+18
| | | | | | | do so. Added a copy of the GNU GPL. Added information about mailman-users in README, and reworded some text in there (made the credits less verbose... perhaps they should move to a credits file?)