diff --git a/roundup/mailgw.py b/roundup/mailgw.py
index 962d9b865e379772c49f1c53a9dc84d4512e8a0c..94594de1a938d88703409e2c841be2f9998ba8c5 100644 (file)
--- a/roundup/mailgw.py
+++ b/roundup/mailgw.py
an exception, the original message is bounced back to the sender with the
explanatory message given in the exception.
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 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
import hyperdb, date, password
import rfc2822
description="User may use the email interface")
security.addPermissionToRole('Admin', p)
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...
class Message(mimetools.Message):
''' subclass mimetools.Message so we can retrieve the parts of the
message...
def __init__(self, instance, db, arguments={}):
self.instance = instance
self.db = db
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)
# should we trap exceptions (normal usage) or pass them through
# (for testing)
fcntl.flock(f.fileno(), FCNTL.LOCK_UN)
return 0
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
'''Read a series of messages from the specified POP server.
'''
import getpass, poplib, socket
except socket.error, message:
print "POP server error:", message
return 1
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
numMessages = len(server.list()[1])
for i in range(1, numMessages+1):
# retr: returns
elif subtype == 'multipart/alternative':
# Search for text/plain in message with attachment and
# alternative text representation
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
part.getPart()
while 1:
# get the next part
if not name:
disp = part.getheader('content-disposition', None)
if disp:
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
if name:
name = name.strip()
# this is just an attachment
props[propname] = value.lower() in ('yes', 'true', 'on', '1')
elif isinstance(proptype, hyperdb.Number):
value = value.strip()
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
return errors, props
# try a straight match of the address
user = extractUserFromList(db.user, db.user.stringFind(address=address))
# 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)
# 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)
# try to match the username to the address (for local
# submissions where the address is empty)