X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fmailgw.py;h=94594de1a938d88703409e2c841be2f9998ba8c5;hb=3d6e89cfde3341b3bdb4a111f15b4ffae3000e27;hp=962d9b865e379772c49f1c53a9dc84d4512e8a0c;hpb=7b46399a02b16c931f4fe7c79ed45eeb774e1be8;p=roundup.git diff --git a/roundup/mailgw.py b/roundup/mailgw.py index 962d9b8..94594de 100644 --- a/roundup/mailgw.py +++ b/roundup/mailgw.py @@ -73,12 +73,12 @@ are calling the create() method to create a new node). If an auditor raises an exception, the original message is bounced back to the sender with the explanatory message given in the exception. -$Id: mailgw.py,v 1.108 2003-01-27 16:32:46 kedder Exp $ +$Id: mailgw.py,v 1.113 2003-03-24 02:54:35 richard Exp $ ''' import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri import time, random, sys -import traceback, MimeWriter +import traceback, MimeWriter, rfc822 import hyperdb, date, password import rfc2822 @@ -113,6 +113,26 @@ def initialiseSecurity(security): description="User may use the email interface") security.addPermissionToRole('Admin', p) +def getparam(str, param): + ''' From the rfc822 "header" string, extract "param" if it appears. + ''' + if ';' not in str: + return None + str = str[str.index(';'):] + while str[:1] == ';': + str = str[1:] + if ';' in str: + # XXX Should parse quotes! + end = str.index(';') + else: + end = len(str) + f = str[:end] + if '=' in f: + i = f.index('=') + if f[:i].strip().lower() == param: + return rfc822.unquote(f[i+1:].strip()) + return None + class Message(mimetools.Message): ''' subclass mimetools.Message so we can retrieve the parts of the message... @@ -148,7 +168,7 @@ class MailGW: def __init__(self, instance, db, arguments={}): self.instance = instance self.db = db - self.arguments = {} + self.arguments = arguments # should we trap exceptions (normal usage) or pass them through # (for testing) @@ -196,7 +216,12 @@ class MailGW: fcntl.flock(f.fileno(), FCNTL.LOCK_UN) return 0 - def do_pop(self, server, user='', password=''): + def do_apop(self, server, user='', password=''): + ''' Do authentication POP + ''' + self.do_pop(server, user, password, apop=1) + + def do_pop(self, server, user='', password='', apop=0): '''Read a series of messages from the specified POP server. ''' import getpass, poplib, socket @@ -216,8 +241,11 @@ class MailGW: except socket.error, message: print "POP server error:", message return 1 - server.user(user) - server.pass_(password) + if apop: + server.apop(user, password) + else: + server.user(user) + server.pass_(password) numMessages = len(server.list()[1]) for i in range(1, numMessages+1): # retr: returns @@ -713,6 +741,7 @@ Subject was: "%s" elif subtype == 'multipart/alternative': # Search for text/plain in message with attachment and # alternative text representation + # skip over intro to first boundary part.getPart() while 1: # get the next part @@ -730,7 +759,7 @@ Subject was: "%s" if not name: disp = part.getheader('content-disposition', None) if disp: - name = disp.getparam('filename') + name = getparam(disp, 'filename') if name: name = name.strip() # this is just an attachment @@ -946,7 +975,7 @@ def setPropArrayFromString(self, cl, propString, nodeid = None): props[propname] = value.lower() in ('yes', 'true', 'on', '1') elif isinstance(proptype, hyperdb.Number): value = value.strip() - props[propname] = int(value) + props[propname] = float(value) return errors, props @@ -978,14 +1007,16 @@ def uidFromAddress(db, address, create=1, **user_props): # try a straight match of the address user = extractUserFromList(db.user, db.user.stringFind(address=address)) - if user is not None: return user + if user is not None: + return user # try the user alternate addresses if possible props = db.user.getprops() if props.has_key('alternate_addresses'): users = db.user.filter(None, {'alternate_addresses': address}) user = extractUserFromList(db.user, users) - if user is not None: return user + if user is not None: + return user # try to match the username to the address (for local # submissions where the address is empty)