Code

cgi fixes
[roundup.git] / roundup / mailgw.py
index 962d9b865e379772c49f1c53a9dc84d4512e8a0c..94594de1a938d88703409e2c841be2f9998ba8c5 100644 (file)
@@ -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. 
 
 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
@@ -113,6 +113,26 @@ def initialiseSecurity(security):
         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...
@@ -148,7 +168,7 @@ class MailGW:
     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)
@@ -196,7 +216,12 @@ class MailGW:
         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
@@ -216,8 +241,11 @@ class MailGW:
         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 
@@ -713,6 +741,7 @@ Subject was: "%s"
                 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
@@ -730,7 +759,7 @@ Subject was: "%s"
                     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
@@ -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] = 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
 
 
@@ -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))
 
     # 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)