changeset 43:196db636a8fd

fixed sorting of project lists.
author casties
date Sun, 28 Apr 2013 14:17:32 +0200
parents c00410ae0444
children 05754bca0114
files HashTree.py MPIWGProjects.py zpt/project/project_template.zpt
diffstat 3 files changed, 33 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/HashTree.py	Fri Apr 26 21:44:21 2013 +0200
+++ b/HashTree.py	Sun Apr 28 14:17:32 2013 +0200
@@ -44,10 +44,7 @@
             else:
                 sub = [self.value]
                 
-            keys = self.children.keys()
-            keys.sort()
-            for k in keys:
-                #logging.debug("getSubtreeList: k=%s sub=%s"%(k,sub))
+            for k in sorted(self.children.keys()):
                 sub.extend(self.children.get(k).getSubtreeAsList())
                 
             return sub
@@ -59,9 +56,7 @@
             return "(%s:%s)"%(self.key, self.value)
         else:
             sub = "(%s:%s):["%(self.key, self.value)
-            keys = self.children.keys()
-            keys.sort()
-            for k in keys:
+            for k in sorted(self.children.keys()):
                 sub += self.children.get(k).getSubtreeAsText()
                 sub += ", "
                 
@@ -73,12 +68,19 @@
 class HashTree:
     """Tree using dictionaries"""
     
+    # root HashTreeNode
     root = None
+    # separator by which key strings are split into parts
     keySeparator = '.'
+    # function applied to key parts
     keyFn = None
     
     def __init__(self, keySeparator='.', keyFn=None):
-        """creates a HashTree"""
+        """creates a HashTree.
+        
+        @param keySeparator string by which key strings are split into parts
+        @param keyFn function applied to key parts (e.g. int if key parts are numbers)
+        """
         self.root = HashTreeNode()
         self.keySeparator = keySeparator
         self.keyFn = keyFn
@@ -91,9 +93,11 @@
             keys = key.split(self.keySeparator)
             if self.keyFn is not None:
                 keys = [self.keyFn(k) for k in keys]
+                
         elif isinstance(key, list):
             # its a list - keep
             keys = key
+            
         else:
             # not a list - wrap in list
             keys = [key]
@@ -154,7 +158,10 @@
         if node.children is None:
             return []
         else:
-            return [n.value for (k, n) in node.children.items() if n.value is not None]
+            # sort children by key
+            childlist = sorted(node.children.items(), key=lambda x:x[0])
+            # and return the values
+            return [n.value for (k, n) in childlist if n.value is not None]
 
 
     def getAncestorsOf(self, key):
--- a/MPIWGProjects.py	Fri Apr 26 21:44:21 2013 +0200
+++ b/MPIWGProjects.py	Sun Apr 28 14:17:32 2013 +0200
@@ -816,10 +816,9 @@
               
     def getImageList(self):
         """returns the sorted list of images for this project"""
-        items = self.objectValues(spec='MPIWGProject_image')[:]
+        items = self.objectValues(spec='MPIWGProject_image')
         # sort by place
-        items.sort(key=lambda x:int(getattr(x, 'place', 0)))
-        return items          
+        return sorted(items, key=lambda x:int(getattr(x, 'place', 0)))
 
 
     def getDepartment(self):
@@ -887,6 +886,7 @@
             return t[0]
         else:
             return t
+
         
     def getFundingInstitutions(self):
         """returns the funding institutions"""
@@ -1742,7 +1742,7 @@
         checkedScientists = {}
         names = {}
         keys = {}
-        for key in formdata.keys(): 
+        for key in formdata: 
             # gehe durch das Formular
             keyParts = key.split("_")
             if keyParts[0] == "responsibleScientist": 
@@ -1753,7 +1753,7 @@
                 elif keyParts[1] == "key":
                     keys[nr] = formdata[key]
          
-        for nr in names.keys():
+        for nr in names:
             name = names[nr]
             key = keys.get(nr, None)
             username = None
@@ -1861,7 +1861,7 @@
             # create responsibleScientistsList automatically
             newScientists = {}
             names = p.identifyNames(p.getResponsibleScientists())
-            for name in names.keys():
+            for name in names:
                 logging.debug("updateAllProjectMembers: name=%s" % repr(name))
                 members = names[name]
                 if len(members) > 0:
@@ -1931,12 +1931,12 @@
 
 
     def getProjectTree(self):
-        """returns the project hierarchy tree (and caches it).
+        """Return the project hierarchy tree (and cache it).
         
-        returns HashTree instance."""
+        Returns HashTree instance."""
         tree = self._v_projectTree 
         if tree is None:
-            tree = HashTree(keySeparator='.', keyFn=lambda x:getInt(x))
+            tree = HashTree(keySeparator='.', keyFn=getInt)
             for p in self.objectValues(spec='MPIWGProject'):
                 tree.add(p.getNumber(), p)
                 
@@ -1947,7 +1947,7 @@
     
     
     def getProjectsAsList(self, start, active=1, archived=1):
-        """returns flattened list of projects, starting from start.
+        """Return flattened list of projects, starting from start.
 
         active = 0 : all projects
         active = 1 : active projects
@@ -1969,7 +1969,7 @@
     
 
     def getProject(self, projectNumber=None):
-        """returns the matching project"""
+        """Return the matching project"""
         tree = self.getProjectTree()
         if projectNumber is not None:
             return tree.get(projectNumber)
@@ -1978,7 +1978,7 @@
 
     
     def getProjectsOfMember(self, key, active=1, archived=1):
-        """returns a list of all projects of a member.
+        """Return a list of all projects of a member.
     
         @param key: member's key
         active = 0 : all projects
@@ -1995,15 +1995,17 @@
         # find projects in tree
         for r in res:
             p = tree.get(r.project_number)
+            # check if active
             if p is not None and p.checkActive(active) and p.checkArchived(archived):
                 projects.append(p)
             
+        projects.sort(key=lambda p:[int(n) for n in p.getNumber().split('.')])
         return projects        
         
         
     security.declareProtected('View management screens', 'updateAllProjectMembers')
     def updateAllProjectMembers(self, updateResponsibleScientistsList=False):
-        """re-creates responsibleScientistsLists and projects_members table from all current projects"""
+        """Re-create responsibleScientistsLists and projects_members table from all current projects."""
         # empty table
         self.executeZSQL('truncate table projects_members')
         cnt = 0
@@ -2019,7 +2021,7 @@
 
     security.declareProtected('View management screens', 'updateAllProjects')
     def updateAllProjects(self, updateResponsibleScientistsList=False):
-        """patches all current projects for old problems"""
+        """Patch all current projects for legacy problems."""
         cnt = 0
         # go through all projects
         for project in self.objectValues(spec='MPIWGProject'):
--- a/zpt/project/project_template.zpt	Fri Apr 26 21:44:21 2013 +0200
+++ b/zpt/project/project_template.zpt	Sun Apr 28 14:17:32 2013 +0200
@@ -138,7 +138,7 @@
                      children here/getSubProjects;"
          tal:condition="children">
       <h2>
-        Projects 
+        Projects
         <span class="proj_state">
           <a href="?" tal:omit-tag="python:not (here.isArchivedProject() or showArchive)">current</a>
           &nbsp;