Code

Ran it through pychecker, made fixes
[roundup.git] / roundup / roundupdb.py
index c2aeafef6fec1129d52186001cbc43c88f815b3a..0ff49ece6d884dfb6154ea360dc2ebb102075b98 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: roundupdb.py,v 1.41 2002-01-15 00:12:40 richard Exp $
+# $Id: roundupdb.py,v 1.47 2002-02-27 03:16:02 richard Exp $
 
 __doc__ = """
 Extending hyperdb with types specific to issue-tracking.
 """
 
 import re, os, smtplib, socket, copy, time, random
-import mimetools, MimeWriter, cStringIO
+import MimeWriter, cStringIO
 import base64, mimetypes
 
 import hyperdb, date
@@ -42,6 +42,23 @@ def splitDesignator(designator, dre=re.compile(r'([^\d]+)(\d+)')):
     return m.group(1), m.group(2)
 
 
+def extractUserFromList(userClass, users):
+    '''Given a list of users, try to extract the first non-anonymous user
+       and return that user, otherwise return None
+    '''
+    if len(users) > 1:
+        # make sure we don't match the anonymous or admin user
+        for user in users:
+            if user == '1': continue
+            if userClass.get(user, 'username') == 'anonymous': continue
+            # first valid match will do
+            return user
+        # well, I guess we have no choice
+        return user[0]
+    elif users:
+        return users[0]
+    return None
+
 class Database:
     def getuid(self):
         """Return the id of the "user" node associated with the user
@@ -54,26 +71,27 @@ class Database:
             user is created if they don't exist in the db already
         '''
         (realname, address) = address
-        users = self.user.stringFind(address=address)
-        for dummy in range(2):
-            if len(users) > 1:
-                # make sure we don't match the anonymous or admin user
-                for user in users:
-                    if user == '1': continue
-                    if self.user.get(user, 'username') == 'anonymous': continue
-                    # first valid match will do
-                    return user
-                # well, I guess we have no choice
-                return user[0]
-            elif users:
-                return users[0]
-            # try to match the username to the address (for local
-            # submissions where the address is empty)
-            users = self.user.stringFind(username=address)
+
+        # try a straight match of the address
+        user = extractUserFromList(self.user,
+            self.user.stringFind(address=address))
+        if user is not None: return user
+
+        # try the user alternate addresses if possible
+        props = self.user.getprops()
+        if props.has_key('alternate_addresses'):
+            users = self.user.filter({'alternate_addresses': address},
+                [], [])
+            user = extractUserFromList(self.user, users)
+            if user is not None: return user
+
+        # try to match the username to the address (for local
+        # submissions where the address is empty)
+        user = extractUserFromList(self.user,
+            self.user.stringFind(username=address))
 
         # couldn't match address or username, so create a new user
         if create:
-            print 'CREATING USER', address
             return self.user.create(username=address, address=address,
                 realname=realname)
         else:
@@ -211,8 +229,15 @@ class FileClass(Class):
     def get(self, nodeid, propname, default=_marker, cache=1):
         ''' trap the content propname and get it from the file
         '''
+
+        poss_msg = 'Possibly a access right configuration problem.'
         if propname == 'content':
-            return self.db.getfile(self.classname, nodeid, None)
+            try:
+                return self.db.getfile(self.classname, nodeid, None)
+            except IOError, (strerror):
+                # BUG: by catching this we donot see an error in the log.
+                return 'ERROR reading file: %s%s\n%s\n%s'%(
+                        self.classname, nodeid, poss_msg, strerror)
         if default is not _marker:
             return Class.get(self, nodeid, propname, default, cache=cache)
         else:
@@ -391,6 +416,9 @@ class IssueClass(Class):
         if inreplyto:
             writer.addheader('In-Reply-To', inreplyto)
 
+        # add a uniquely Roundup header to help filtering
+        writer.addheader('X-Roundup-Name', self.db.config.INSTANCE_NAME)
+
         # attach files
         if message_files:
             part = writer.startmultipartbody('mixed')
@@ -461,13 +489,13 @@ class IssueClass(Class):
 
         # list the values
         m = []
-       l = props.items()
-       l.sort()
+        l = props.items()
+        l.sort()
         for propname, prop in l:
             value = cl.get(nodeid, propname, None)
-           # skip boring entries
-           if not value:
-               continue
+            # skip boring entries
+            if not value:
+                continue
             if isinstance(prop, hyperdb.Link):
                 link = self.db.classes[prop.classname]
                 if value:
@@ -514,8 +542,10 @@ class IssueClass(Class):
 
         # list the changes
         m = []
-        for propname, oldvalue in changed.items():
-            prop = cl.properties[propname]
+        l = changed.items()
+        l.sort()
+        for propname, oldvalue in l:
+            prop = props[propname]
             value = cl.get(nodeid, propname, None)
             if isinstance(prop, hyperdb.Link):
                 link = self.db.classes[prop.classname]
@@ -566,6 +596,22 @@ class IssueClass(Class):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.46  2002/02/25 14:22:59  grubert
+#  . roundup db: catch only IOError in getfile.
+#
+# Revision 1.44  2002/02/15 07:08:44  richard
+#  . Alternate email addresses are now available for users. See the MIGRATION
+#    file for info on how to activate the feature.
+#
+# Revision 1.43  2002/02/14 22:33:15  richard
+#  . Added a uniquely Roundup header to email, "X-Roundup-Name"
+#
+# Revision 1.42  2002/01/21 09:55:14  rochecompaan
+# Properties in change note are now sorted
+#
+# Revision 1.41  2002/01/15 00:12:40  richard
+# #503340 ] creating issue with [asignedto=p.ohly]
+#
 # Revision 1.40  2002/01/14 22:21:38  richard
 # #503353 ] setting properties in initial email
 #