changeset 54:4600e31a0431

Merge with 1ed79b33200c4c4879e3dc314744451eef083902
author dwinter
date Tue, 30 Apr 2013 16:35:52 +0200
parents e718d9a72f19 (current diff) 1ed79b33200c (diff)
children 12cb73494367
files MPIWGProjects.py MPIWGRoot.py zpt/MPIWGProject_index.zpt zpt/MPIWGProject_newfile.zpt zpt/MPIWGProject_versionManageForm.zpt zpt/edit_MPIWGBasis.zpt
diffstat 17 files changed, 1429 insertions(+), 1400 deletions(-) [+]
line wrap: on
line diff
--- a/HashTree.py	Tue Apr 30 16:31:57 2013 +0200
+++ b/HashTree.py	Tue Apr 30 16:35:52 2013 +0200
@@ -76,7 +76,7 @@
     keyFn = None
     
     def __init__(self, keySeparator='.', keyFn=None):
-        """creates a HashTree.
+        """Create 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)
@@ -87,7 +87,7 @@
     
 
     def _splitkey(self, key):
-        """returns a list of key parts"""
+        """Return a list of key parts"""
         if isinstance(key, basestring):
             # its a string - split
             keys = key.split(self.keySeparator)
@@ -106,7 +106,8 @@
 
 
     def getNode(self, key):
-        """gets node under key from the tree.
+        """Return node under key from the tree.
+        
         key can be sequence of key string or a single string using keySeparator.
         If key is None, returns root node.
         """
@@ -125,7 +126,8 @@
 
 
     def get(self, key):
-        """gets value under key from the tree.
+        """Return value under key from the tree.
+        
         key can be sequence of key string or a single string using keySeparator.
         """
         node = self.getNode(key)
@@ -136,7 +138,8 @@
 
      
     def add(self, key, value):
-        """adds value under key to the tree.
+        """Add value under key to the tree.
+        
         key can be sequence of key string or a single string using keySeparator.
         """
         keys = self._splitkey(key)
@@ -153,7 +156,7 @@
 
         
     def getChildrenOf(self, key):
-        """returns the list of child (values) of the node under key."""
+        """Return the list of child (values) of the node under key."""
         node = self.getNode(key)
         if node.children is None:
             return []
@@ -165,8 +168,9 @@
 
 
     def getAncestorsOf(self, key):
-        """returns the list of ancestor (values) of the node under key.
-        ordered from root up."""
+        """Return the list of ancestor (values) of the node under key.
+        
+        Order: root element first."""
         keys = self._splitkey(key)
         node = self.root
         ancestors = []
--- a/MPIWGProjects.py	Tue Apr 30 16:31:57 2013 +0200
+++ b/MPIWGProjects.py	Tue Apr 30 16:35:52 2013 +0200
@@ -27,7 +27,9 @@
 import logging
 import time
 
-from SrvTxtUtils import getInt, unicodify, utf8ify, refreshingImageFileIndexHtml
+import xml.etree.ElementTree as ET
+
+from SrvTxtUtils import getInt, unicodify, utf8ify, serialize, refreshingImageFileIndexHtml
 from Products.MPIWGBibliography.BibliographyManager import BibliographyManager
 from bibliography import *
 from Products.ZDBInterface.ZDBInterfaceFolder import ZDBInterfaceFolder
@@ -72,8 +74,7 @@
 
 definedFields = fieldLabels.keys() # TODO: should this be sorted?
 
-checkFields = ['xdata_01']
-
+editableFields = ('xdata_01', 'xdata_05', 'xdata_07', 'xdata_08', 'xdata_11', 'xdata_12', 'xdata_13')
 
 # die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus Kompatibilitaetsgruenden, bleiben die Klassen hier noch drin.
 # Sonst funktionieren die alten Webseiten nicht mehr.
@@ -238,10 +239,9 @@
         self.orginallink = link[0:]
         self.objid = objid[0:]
     
-        self.projectWEB_title = object.getContent('WEB_title')[0:]
+        self.projectWEB_title = object.getProjectTitle()
        
         self.enabled = True;
-        self.ZCacheable_invalidate()
        
         if RESPONSE:
             self.redirect(RESPONSE, "../manageRelatedProjects")
@@ -299,16 +299,21 @@
     #
     # templates
     #
+    project_template = PageTemplateFile('zpt/project/project_template', globals())
+    # edit templates
     edit_css = ImageFile('css/edit.css', globals())
     # make css refreshable for development
     edit_css.index_html = refreshingImageFileIndexHtml
     edit_basic = PageTemplateFile('zpt/project/edit_basic', globals())
     editForm = PageTemplateFile('zpt/project/edit_description', globals())
     edit_template = PageTemplateFile('zpt/project/edit_template', globals())
-    project_template = PageTemplateFile('zpt/project/project_template', globals())
+    edit_related_projects = PageTemplateFile('zpt/project/edit_related_projects', globals())
+    # management templates
+    loadNewFileForm = PageTemplateFile('zpt/project/manage_newfile', globals())
+    description_only_html = PageTemplateFile('zpt/project/description_only_html', globals())
+
     # TODO: this should go away
     extendedBibliography = PageTemplateFile('zpt/project/extendedBibliography_template', globals())
-
     # TODO: compat
     edit_MPIWGProject_main = edit_template
 
@@ -354,348 +359,6 @@
         logging.debug(email.Utils.formatdate() + ' GMT')
         RESPONSE.redirect(url + addStr % timeStamp)
 
-    def decode(self, str):
-        """return unicode object"""
-        return unicodify(str)
-
-    def isCheckField(self, fieldname):
-        """return chechfield"""
-        return (fieldname in checkFields)
- 
-    def sortedByPlace(self, metatype):
-        """find metatype and sort by place"""
-        def sort(x, y):
-            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
-
-        logging.debug("MPIWGProjects begin: sorted by place: " + metatype)
-        founds = self.ZopeFind(self, obj_metatypes=[metatype]);
-        
-        founds.sort(sort)
-        logging.debug("MPIWGProjects end: sorted by place: " + metatype)
-        return founds
-    
-
-    def copyPublicationsToList(self, RESPONSE=None):
-        """copy publications in to list"""
-
-        publicationTxt = self.getContent('WEB_related_pub')
-
-        pubSplits = publicationTxt.split("<p>")
-
-        for pubSplit in pubSplits:
-            pubSplit = pubSplit.replace("</p>", "")
-            self.addPublication(pubSplit)
-
-        setattr(self, "WEB_related_pub_copied", True);
-        
-        if RESPONSE:
-                
-            self.redirect(RESPONSE, 'managePublications')
-        
-    def hasRelatedPublicationsOldVersion(self):
-        """teste ob es related publications gibt"""
-        
-        ret = True;
-        if (self.getContent('WEB_related_pub') == ''):
-            ret = False;  # nichts im alten feld
-        logging.debug("webrel:" + repr(ret))
-        if (getattr(self, 'WEB_related_pub_copied', False)):
-            ret = False;  # alte daten sind schon kopiert worden
-        
-        logging.debug("webrel_copied:" + repr(ret))
-        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_publication']);
-        
-        if(len(publications) > 0):
-            ret = False;  # es gibt publicationen in der neuen liste
-      
-        
-        logging.debug("len(publ)" + repr(ret))
-        
-        return ret;
-    
-    def copyImageToMargin(self, RESPONSE=None):  
-        """copy inline images to marginal images"""
-        # getImages from WEB_project_description
-        description = self.getContent('WEB_project_description')
-        
-        text2 = description
-        splitted = text2.split("""<p class="picture">""")
-        
-        imageURLs = []
-        imageCaptions = []
-        for split in  splitted[1:]:
-                tmp = split.split("</p>")
-                # return repr(splitted[1])
-                
-                try:
-                        imageURLs.append(tmp[0].split("\"")[1].encode('utf-8'))
-                except:
-                    
-                    try:
-                        imageURLs.append(tmp[0].split("src=")[1].split(" ")[0].encode('utf-8'))
-                    except:
-                        imageURLs.append("")
-                
-                split2 = "</p>".join(tmp[1:])
-
-
-                splitted = split2.split("""<p class="picturetitle">""")
-                if len(splitted) > 1:
-                    tmp = splitted[1].split("</p>")
-                    imageCaptions.append(tmp[0].encode('utf-8'))
-
-                else:
-                    # keine caption
-
-                    imageCaptions.append("")
-     
-        # eintragen:
-        for imageURL in imageURLs:
-            filename = imageURL.split("/")[-1]
-            # lege neues images object an, mit leerem bild
-
-            if self.ZopeFind(self, obj_ids=[filename]):
-                # existiert das bild schon, dann neuen filenamen
-                filename = "project_image_" + filename
-            
-            self.addImage(None, imageCaptions[imageURLs.index(imageURL)], filename=filename)
-            # hole die bilddaten aus der url
-            url = self.absolute_url() + "/" + imageURL
-            # url=self.absolute_url()+"/"+filename
-        
-            try:  # relative url
-                data = urllib.urlopen(url).read()
-            except:
-                try:  # absolute
-                    data = urllib.urlopen(self.imageURL).read()
-                except:
-                    logger("MPIWG Project", logging.ERROR, "can't open: %s" % url)
-            
-            obj = getattr(self, filename)
-            obj.update_data(data)
-        
-        if RESPONSE:
-            self.redirect(RESPONSE, 'manageImages')
-
-            
-    def manageImages(self, imageName=None, op=None):
-        """managage images"""
-        if imageName and op:
-            if op == 'up':
-                images = self.getImages()
-                for image in images:
-                    if image[0] == imageName:
-                        nr = images.index(image)
-                        if not nr == 0:
-                            images[nr - 1][1].place += 1
-                            images[nr][1].place -= 1
-                        pass
-            elif op == 'down':
-                images = self.getImages()
-                for image in images:
-                    if image[0] == imageName:
-                        nr = images.index(image)
-                        if not (nr == len(images) - 1):
-                            images[nr + 1][1].place -= 1
-                            images[nr][1].place += 1
-                        pass
-
-
-        pt = PageTemplateFile('zpt/project/edit_images', globals()).__of__(self)
-        return pt()
-
-    def managePublications(self, pubName=None, op=None):
-        """managage images"""
-        if pubName and op:
-            if op == 'up':
-                publications = self.getPublications()
-                for publication in publications:
-                    if publication[0] == pubName:
-                        nr = publications.index(publication)
-                        if not nr == 0:
-                            publications[nr - 1][1].place += 1
-                            publications[nr][1].place -= 1
-                        pass
-            elif op == 'down':
-                publications = self.getPublications()
-                for publication in publications:
-                    if publication[0] == pubName:
-                        nr = publications.index(publication)
-                        if not (nr == len(publications) - 1):
-                            publications[nr + 1][1].place -= 1
-                            publications[nr][1].place += 1
-                        pass
-
-
-        pt = PageTemplateFile('zpt/project/edit_publications', globals()).__of__(self)
-        return pt()
-    
-    def manageRelatedProjects(self, pubName=None, op=None):
-        """managage relatedProjectd"""
-        if pubName and op:
-            if op == 'up':
-                relatedProjects = self.getRelatedProjects()
-                for project in relatedProjects:
-                    if project[0] == pubName:
-                        nr = relatedProjects.index(project)
-                        if not nr == 0:
-                            relatedProjects[nr - 1][1].place += 1
-                            relatedProjects[nr][1].place -= 1
-                        pass
-            elif op == 'down':
-                relatedProjects = self.getRelatedProjects()
-                for project in relatedProjects:
-                    if project[0] == pubName:
-                        nr = relatedProjects.index(project)
-                        if not (nr == len(relatedProjects) - 1):
-                            relatedProjects[nr + 1][1].place -= 1
-                            relatedProjects[nr][1].place += 1
-                        pass
-
-
-        pt = PageTemplateFile('zpt/project/edit_related_projects', globals()).__of__(self)
-        return pt()
-    
-    
-    def hasExtendedPublicationList(self):
-        """test if extended publication list exists"""
-        if not hasattr(self, "publicationList"):
-            return False
-        else:
-            return True
-        
-    def createExtendedPublicationList(self, RESPONSE=None):
-        """erzeuge erweiterte publications liste"""
-        pl = BibliographyManager("publicationList", "", "institutsbiblio", self.connection_id)
-        self._setObject("publicationList", pl)
-    
-        zt = ZopePageTemplate('index.html')
-        pl._setObject('index.html', zt)
-        default_content_fn = os.path.join(package_home(globals()),
-                                              'zpt/showExtendedProjectBibliography.zpt')
-        text = open(default_content_fn).read()
-        zt.pt_edit(text, 'text/html')
-    
-        if RESPONSE:
-            self.redirect(RESPONSE, "managePublications")
-
-
-    def getPublications(self):
-        """get all Publications"""
-        def sort_images(x, y):
-            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
-
-        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_publication'])
-        
-        publications.sort(sort_images)
-        return publications
-
-    def getRelatedProjects(self):
-        """get all Publications"""
-        def sort_images(x, y):
-            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
-
-        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_relatedProject'])
-        
-        publications.sort(sort_images)
-        return publications
-
-    def addPublication(self, text, RESPONSE=None):
-        """add an MPIWG_Publication"""
-        number = self.getLastPublicationNumber() + 1
-        name = "publication_" + str(number)
-        while hasattr(self, name):
-            number += 1
-            name = "publication_" + str(number)
-        
-        newPublication = MPIWGProject_publication(name)
-
-        self._setObject(name, newPublication)
-        obj = getattr(self, name)
-        obj.text = text[0:]
-        obj.enabled = True;
-        obj.place = self.getLastPublicationNumber() + 1
-        obj.id = name
-        self.ZCacheable_invalidate()
-        if RESPONSE is not None:
-        
-            self.redirect(RESPONSE, 'managePublications')
-
-    def errorRelatedProjects(self, link):
-        """error creating a related project"""
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_project_error_relatedProject.zpt')).__of__(self)
-        return pt(link=link)
-
-    def addRelatedProject(self, link, RESPONSE=None):
-        """add an MPIWG_Publication"""
-        number = self.getLastPublicationNumber() + 1
-        name = "RelatedProject" + str(number)
-        while hasattr(self, name):
-            number += 1
-            name = "RelatedProject_" + str(number)
-        
-        # hole die id des projektes
-        splitted = link.split("/")
-        
-        # teste ob es das project gibt
-        if len(splitted) < 1:
-            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
-        
-        objid = splitted[-1]
-        object = getattr(self.projects, objid, None)
-        
-        if object == None:
-            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
-            return
-        
-        newPublication = MPIWGProject_relatedProject(name)
-
-        self._setObject(name, newPublication)
-        obj = getattr(self, name)
-        obj.orginallink = link[0:]
-        obj.objid = objid[0:]
-        logging.debug("add relobj:objid" + repr(obj.objid))
-        obj.projectWEB_title = object.getContent('WEB_title')[0:]
-        logging.debug("add relobj:webtitle" + repr(obj.projectWEB_title))
-        obj.enabled = True;
-        obj.place = self.getLastRelatedProjectNumber() + 1
-        obj.id = name
-        self.ZCacheable_invalidate()
-        if RESPONSE is not None:
-            self.redirect(RESPONSE, 'manageRelatedProjects')
-
- 
-    
-    def getLastPublicationNumber(self):
-        publications = self.getPublications()
-       
-        if not publications:
-            return 0
-        else:
-            return getattr(publications[-1][1], 'place', 0)
-        
-    def getLastRelatedProjectNumber(self):
-        publications = self.getRelatedProjects()
-        
-        if not publications:
-            return 0
-        else:
-            return getattr(publications[-1][1], 'place', 0)
-        
-    def deletePublication(self, id, RESPONSE=None):
-            """delete Publication id"""
-            self.manage_delObjects([id])
-            self.ZCacheable_invalidate()
-            if RESPONSE:
-                self.redirect(RESPONSE, 'managePublications')
-              
-    def deleteRelatedProject(self, id, RESPONSE=None):
-            """delete Publication id"""
-            self.manage_delObjects([id])
-            self.ZCacheable_invalidate()
-            if RESPONSE:
-                self.redirect(RESPONSE, 'manageRelatedProjects')
-
 
     def getNumber(self):
         """returns sorting number"""
@@ -801,15 +464,15 @@
         """returns the URL of the project thumbnail image"""
         thumb = self.projectThumb
         if thumb is None:
-            # get thumb from list
+            # get thumb from list (thumb is last image)
             imgs = self.getImageList()
             url = default
             if len(imgs) > 0:
-                thumb = imgs[0]
+                thumb = imgs[-1]
                 self.projectThumb = thumb
 
         if thumb is None:
-            return None
+            return default
         
         return thumb.absolute_url()
 
@@ -842,13 +505,13 @@
 
     def getDescription(self, filter=False):
         """returns the project description"""
-        t = getattr(self, 'WEB_project_description', None)
-        if isinstance(t, list):
+        text = getattr(self, 'WEB_project_description', None)
+        if isinstance(text, list):
             # compat with old lists
-            return t[0]
-        else:
-            return t
-        
+            text = text[0]
+
+        return text
+            
         
     def getSuperProjects(self):
         """returns a list of ancestor projects to the root"""
@@ -867,7 +530,7 @@
         items = self.objectValues(spec='MPIWGProject_relatedProject')
         # sort by place
         items.sort(key=lambda x:int(getattr(x, 'place', 0)))
-        return items          
+        return items
         
 
     def getRelatedPublications(self):
@@ -898,6 +561,215 @@
             return t
 
               
+    def manageImages(self, imageName=None, op=None):
+        """managage images"""
+        if imageName and op:
+            if op == 'up':
+                images = self.getImages()
+                for image in images:
+                    if image[0] == imageName:
+                        nr = images.index(image)
+                        if not nr == 0:
+                            images[nr - 1][1].place += 1
+                            images[nr][1].place -= 1
+                        pass
+            elif op == 'down':
+                images = self.getImages()
+                for image in images:
+                    if image[0] == imageName:
+                        nr = images.index(image)
+                        if not (nr == len(images) - 1):
+                            images[nr + 1][1].place -= 1
+                            images[nr][1].place += 1
+                        pass
+
+
+        # invalidate thumbnail
+        self.projectThumb = None
+        pt = PageTemplateFile('zpt/project/edit_images', globals()).__of__(self)
+        return pt()
+
+    def managePublications(self, pubName=None, op=None):
+        """managage images"""
+        if pubName and op:
+            if op == 'up':
+                publications = self.getPublications()
+                for publication in publications:
+                    if publication[0] == pubName:
+                        nr = publications.index(publication)
+                        if not nr == 0:
+                            publications[nr - 1][1].place += 1
+                            publications[nr][1].place -= 1
+                        pass
+            elif op == 'down':
+                publications = self.getPublications()
+                for publication in publications:
+                    if publication[0] == pubName:
+                        nr = publications.index(publication)
+                        if not (nr == len(publications) - 1):
+                            publications[nr + 1][1].place -= 1
+                            publications[nr][1].place += 1
+                        pass
+
+
+        pt = PageTemplateFile('zpt/project/edit_publications', globals()).__of__(self)
+        return pt()
+    
+    def manageRelatedProjects(self, pubName=None, op=None):
+        """manage related projects"""
+        if pubName and op:
+            if op == 'up':
+                relatedProjects = self.getRelatedProjects()
+                for project in relatedProjects:
+                    if project[0] == pubName:
+                        nr = relatedProjects.index(project)
+                        if not nr == 0:
+                            relatedProjects[nr - 1][1].place += 1
+                            relatedProjects[nr][1].place -= 1
+                        pass
+            elif op == 'down':
+                relatedProjects = self.getRelatedProjects()
+                for project in relatedProjects:
+                    if project[0] == pubName:
+                        nr = relatedProjects.index(project)
+                        if not (nr == len(relatedProjects) - 1):
+                            relatedProjects[nr + 1][1].place -= 1
+                            relatedProjects[nr][1].place += 1
+                        pass
+
+
+        pt = self.edit_related_projects
+        return pt()
+    
+    
+    def hasExtendedPublicationList(self):
+        """test if extended publication list exists"""
+        if not hasattr(self, "publicationList"):
+            return False
+        else:
+            return True
+        
+    def createExtendedPublicationList(self, RESPONSE=None):
+        """erzeuge erweiterte publications liste"""
+        pl = BibliographyManager("publicationList", "", "institutsbiblio", self.connection_id)
+        self._setObject("publicationList", pl)
+    
+        zt = ZopePageTemplate('index.html')
+        pl._setObject('index.html', zt)
+        default_content_fn = os.path.join(package_home(globals()),
+                                              'zpt/showExtendedProjectBibliography.zpt')
+        text = open(default_content_fn).read()
+        zt.pt_edit(text, 'text/html')
+    
+        if RESPONSE:
+            self.redirect(RESPONSE, "managePublications")
+
+
+    def getPublications(self):
+        """get all Publications"""
+        def sort_images(x, y):
+            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
+
+        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_publication'])
+        
+        publications.sort(sort_images)
+        return publications
+
+    def addPublication(self, text, RESPONSE=None):
+        """add an MPIWG_Publication"""
+        number = self.getLastPublicationNumber() + 1
+        name = "publication_" + str(number)
+        while hasattr(self, name):
+            number += 1
+            name = "publication_" + str(number)
+        
+        newPublication = MPIWGProject_publication(name)
+
+        self._setObject(name, newPublication)
+        obj = getattr(self, name)
+        obj.text = text[0:]
+        obj.enabled = True;
+        obj.place = self.getLastPublicationNumber() + 1
+        obj.id = name
+        self.ZCacheable_invalidate()
+        if RESPONSE is not None:
+        
+            self.redirect(RESPONSE, 'managePublications')
+
+    def errorRelatedProjects(self, link):
+        """error creating a related project"""
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_project_error_relatedProject.zpt')).__of__(self)
+        return pt(link=link)
+
+    def addRelatedProject(self, link, RESPONSE=None):
+        """add an MPIWG_Publication"""
+        number = self.getLastPublicationNumber() + 1
+        name = "RelatedProject" + str(number)
+        while hasattr(self, name):
+            number += 1
+            name = "RelatedProject_" + str(number)
+        
+        # hole die id des projektes
+        splitted = link.split("/")
+        
+        # teste ob es das project gibt
+        if len(splitted) < 1:
+            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
+        
+        objid = splitted[-1]
+        object = getattr(self.projects, objid, None)
+        
+        if object == None:
+            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
+            return
+        
+        newPublication = MPIWGProject_relatedProject(name)
+
+        self._setObject(name, newPublication)
+        obj = getattr(self, name)
+        obj.orginallink = link[0:]
+        obj.objid = objid[0:]
+        logging.debug("add relobj:objid" + repr(obj.objid))
+        obj.projectWEB_title = object.getContent('WEB_title')[0:]
+        logging.debug("add relobj:webtitle" + repr(obj.projectWEB_title))
+        obj.enabled = True;
+        obj.place = self.getLastRelatedProjectNumber() + 1
+        obj.id = name
+        self.ZCacheable_invalidate()
+        if RESPONSE is not None:
+            self.redirect(RESPONSE, 'manageRelatedProjects')
+
+     
+    def getLastPublicationNumber(self):
+        publications = self.getPublications()
+       
+        if not publications:
+            return 0
+        else:
+            return getattr(publications[-1][1], 'place', 0)
+        
+    def getLastRelatedProjectNumber(self):
+        publications = self.getRelatedProjects()
+        
+        if not publications:
+            return 0
+        else:
+            return getattr(publications[-1][1], 'place', 0)
+        
+    def deletePublication(self, id, RESPONSE=None):
+            """delete Publication id"""
+            self.manage_delObjects([id])
+            self.ZCacheable_invalidate()
+            if RESPONSE:
+                self.redirect(RESPONSE, 'managePublications')
+              
+    def deleteRelatedProject(self, id, RESPONSE=None):
+            """delete Publication id"""
+            self.manage_delObjects([id])
+            self.ZCacheable_invalidate()
+            if RESPONSE:
+                self.redirect(RESPONSE, 'manageRelatedProjects')
+
     def getImages(self):
         """get all Images"""
 
@@ -941,17 +813,6 @@
 
 
  
-    def hasChildren(self, date=None, onlyActive=1, onlyArchived=1):
-        """check if project has children"""
-        ct = self.getContexts(childs=self.getContent('xdata_05'),
-                                 depth=1, date=date, onlyActive=onlyActive)
-        
-        if ct and len(ct) > 0:
-             return True
-        else:
-             return False
-
-         
     def addImage(self, fileHd, caption, RESPONSE=None, filename=None):
         """add an MPIWG_Project_image"""
 
@@ -973,21 +834,14 @@
         # invalidate thumbnail
         self.projectThumb = None
         
-        if RESPONSE is not None:
-            
+        if RESPONSE is not None:            
             self.redirect(RESPONSE, 'manageImages')
 
-    def versionHeader(self):
-        """version Header, gibt header text entsprechend der aktuellen version aus"""
-        
-        actualTime = time.localtime()
-        retTXT = """<h2>This is an outdated version, for the actual version please refer to <a href="%s">%s</a></h2>"""
-        s = self.aq_parent.absolute_url()
-        # print getattr(self,'archiveTime',actualTime)
-        if getattr(self, 'archiveTime', actualTime) < actualTime:
-            return retTXT % (s, s)
-        else:
-            return ""
+
+    def getEditableFields(self):
+        """giveListofDatafields"""
+        return editableFields
+    
 
     def getActualVersion(self, date=None):
         """actuelle version"""
@@ -1061,19 +915,6 @@
     def delArchiveTime(self):
         """delete archive time"""
         del self.archiveTime
-
-    def versionManageForm(self):
-        """version Manage form:currently only set to invisible"""
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'MPIWGProject_versionManageForm.zpt')).__of__(self)
-        return pt()
-
-    def versionManage(self, invisible=None, RESPONSE=None):
-        """version Manage form:currently only set to invisible"""
-        self.invisible = invisible
-
-        if RESPONSE is not None:
-            self.redirect(RESPONSE, 'manage_main')
-
    
     def isActiveProject(self):
         """check if the project is still active, default is true."""
@@ -1241,125 +1082,6 @@
             return self.REQUEST['URL1'] + "/no_project"
         
             
-    def no_project(self):
-        """warnung: project noch nicht existent"""
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'no_project')).__of__(self)
-        return pt()
-    
-  
-    def harvest_page(self, context=None, mode="normal"):
-        """seite fuer harvesting fuer die Projektsuche"""
-       
-        if not context:
-            context = self
-            
-        if self.isActiveProject() and self.isCurrentVersion():
-             templates = self.en.getHarvestCache()
-            
-             ext = getattr(self, "harvest_main", None)
-             if ext:
-                 rendered = getattr(self, ext.getId())()
-                 templates[self.absolute_url()] = rendered
-                 transaction.commit()
-                 return rendered
-                 
-
-             pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'harvest_main')).__of__(context)    
-             
-             rendered = pt()
-             templates[self.absolute_url()] = rendered
-             transaction.commit()
-             return rendered
-                 
- 
-      
-    def index_html_old(self, request=True, context=None):
-        """show homepage"""
-    
-        bound_names = {}
-         
-        if not context:
-            context = self
-        if request:
-            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected', None) == None:
-                self.REQUEST.SESSION['MPI_redirected'] = 1
-                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date']) + "?date=" + self.REQUEST['date'])
-            else:
-                self.REQUEST.SESSION['MPI_redirected'] = None
-        
-        # ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
-      
-   
-        request2 = getattr(self, 'REQUEST', None)
-        
-        if request2 is not None:
-            response = request2.response
-            if not response.headers.has_key('content-type'):
-                response.setHeader('content-type', 'text/html')
-
-        security = getSecurityManager()
-        bound_names['user'] = security.getUser()
-      
-        # Retrieve the value from the cache.
-        keyset = None
-        if self.ZCacheable_isCachingEnabled():
-            
-            # Prepare a cache key.
-            keyset = {'here': self, 'params':request2['QUERY_STRING']}
-                      
-            result = self.ZCacheable_get(keywords=keyset)
-           
-            if result is not None:
-                # Got a cached value.
-                return result
-        
-        pt = getTemplate(self, "project_main")
-         # Execute the template in a new security context.
-        security.addContext(self)
-
-        try:
-            # logging.debug("index_html pt=%s"%repr(pt))
-            result = pt.pt_render(extra_context=bound_names)
-            # logging.debug("index_html result=%s"%repr(result))
-            if keyset is not None:
-                # Store the result in the cache.
-                self.ZCacheable_set(result, keywords=keyset)
-               
-            return result
-        finally:
-            security.removeContext(self)
-       
-
-      
-    def index_html_old2(self, request=True, context=None):
-        """show homepage"""
-        if not context:
-            context = self
-        if request:
-            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected', None) == None:
-                self.REQUEST.SESSION['MPI_redirected'] = 1
-                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date']) + "?date=" + self.REQUEST['date'])
-            else:
-                self.REQUEST.SESSION['MPI_redirected'] = None
-        
-        # ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
-      
-        ext = getattr(self, "project_main", None)
-        if ext:
-            return getattr(self, ext.getId())()
-        
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'project_main')).__of__(context)    
-
-        return pt()
-
-    
-    def getDataFields(self):
-        """giveListofDatafields"""
-        ret = []
-        for x in range(1, 14):
-            if not x in [6, 10, 9]:  # not used fields
-                ret.append('xdata_%02i' % x)
-        return ret
             
     def getDefinedFields(self):
         """show all defined fields"""
@@ -1462,18 +1184,6 @@
         # return utf8ify(text5) # return as utf-8 byte string
 
 
-    def showImagesOfPage(self, imageUrl=None):
-        """show Images of project"""
-        self.getContent('WEB_project_description', filter='yes')  # get the content and store image infos into session
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'projectImageView.zpt')).__of__(self)
-        return pt()
-        
-    
-    def show_html(self):
-        """simple index"""
-        # return "HI"
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'MPIWGProject_index.zpt')).__of__(self)
-        return pt()
 
     def saveFromPreview(self):
         """save content aus preview"""
@@ -1513,24 +1223,6 @@
         return pt()
     
 
-    def getPathStyle(self, path, selected, style=""):
-        """returns a string with the given style + 'sel' if path == selected."""
-
-        if path == selected:
-            return style + 'sel'
-        else:
-            return style    
-
-    def getLabel_old(self):
-        """returns label (or title) of this project"""
-        l = self.getContent('xdata_07')
-        if l:
-            return l
-        l = self.getContent('WEB_title')
-        if l:
-            return l
-        return self.title
-
     def getBreadcrumbs(self):
         """return list of breadcrumbs from here to the root"""
         crumbs = []
@@ -1547,28 +1239,19 @@
             baseUrl = "/en/research/projects/"
             
         # add in the internal project hierarchy
-        
-        ct = self.getContexts(parents=self.getContent('xdata_05'))
+        tree = self.getProjectTree()
+        ap = tree.getAncestorsOf(self.getNumber())
         # start with grandparents
-        ct.reverse()
-        for c in ct:
-            label = shortenString(c[0].getLabel(), 13)
-            crumbs.append((label, baseUrl + c[0].getId(), c[0]))            
+        for p in ap:
+            label = shortenString(p.getLabel(), 13)
+            crumbs.append((label, p.getUrl(baseUrl=baseUrl), p))            
 
         # add this project
-        crumbs.append((self.getLabel(), baseUrl + self.getId(), self))
+        crumbs.append((self.getLabel(), self.getUrl(baseUrl=baseUrl), self))
             
         return crumbs
 
-    def getRootProject(self):
-        """returns the root (=top level) project of the current project"""
-        ct = self.getContexts(parents=self.getContent('xdata_05'))
-        if len(ct) > 0:
-            return ct[-1][0]
-        else:
-            return self        
-
-
+    # TODO: is this used?
     def preview(self, description):
         """preview"""
         # logging.debug("preview description=%s"%description)
@@ -1586,82 +1269,20 @@
         # return self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+"/previewTemplate")
         
 
-    def getWebProject_description(self):
-        """get description"""
-        debug = self.REQUEST.cookies.get("MP_debug_code", None)
-        
-        if debug and debug == "western":
-            return """
-            <html>
-            <head>
-            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-            </head>
-            <body>%s</body>
-            </html>
-            """ % self.WEB_project_description[0]
-        
-        return """
-            <html>
-            <head>
-            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-            </head>
-            <body>%s</body>
-            </html>
-            """ % self.getContent('WEB_project_description')
-        
-        
-        
     def editMPIWGProjectForm(self):
         """editform"""
         pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_MPIWGProject.zpt')).__of__(self)
         return pt()
 
+
     def isResponsibleScientist(self, key):
         """teste ob eine Person in der Liste der respl. scientists auftaucht"""
         for resp in self.getResponsibleScientistsList():
-            if resp['key'] == key:
+            if resp.get('key', None) == utf8ify(key):
                 return True
         
         return False
         
-    def getPersonKeyList(self):
-        """gibt die key Liste der beteiligten Personen zurueck (utf8 codiert)"""
-        # logging.error("getPersonKeyList:%s"%getattr(self,'responsibleScientistsList',[]))
-        try:
-            return [utf8ify(x[1]) for x in getattr(self, 'responsibleScientistsList', [])]
-        except:
-            return[]
-        
-       
-    def myCapitalize(self, txt):
-        """kapitalisiere auch Namen mit -"""
-        splitted = [x.capitalize() for x in txt.split("-")]
-        return "-".join(splitted)
-    
-    def getNamesOrdered(self, list):
-        """Sortiert die Liste nach der Reihenfolge in xdata_01"""
-        
-        nameList = self.getContent('xdata_01')
-        if nameList.find(";") > -1:  # rate Trenner ist ;
-            names = nameList.split(";")  
-        else:
-            names = nameList.split(",")
-            
-        self._v_names = []
-        for name in names:
-            self._v_names.append(name.rstrip().lstrip())
-            
-            
-        def sort(x, y):
-            try:
-                return cmp(self._v_names.index(x[0]), self._v_names.index(y[0]))
-            except:
-                return 0
-            
-        list.sort(sort)
-        
-        return list
-        
         
     def identifyNames(self, nameList):
         """Bekommt eine Komma oder Semikolon getrennte Liste mit Name der Form Vorname MittelName(n) Nachname
@@ -1711,23 +1332,22 @@
             else:
                 returnNamesDict[name] = []
        
-        logging.debug("id: %s" % repr(returnNamesDict))
+        logging.debug("identified names: %s" % repr(returnNamesDict))
         return returnNamesDict
 
         
-    def editMPIWGProject(self, RESPONSE=None, fromEdit=None):
+    def editMPIWGProject(self, fromEdit=None, createNewVersion=True, RESPONSE=None):
         """edit the project and archive the old version"""
-        
-        self.copyObjectToArchive()  # archive the object
-        self.ZCacheable_invalidate()
+        logging.debug("editMPIWGProject(fromEdit=%s, createNewVersion=%s)"%(fromEdit,createNewVersion))
+        if createNewVersion:
+            self.copyObjectToArchive()  # archive the object
 
         formdata = self.REQUEST.form
-        logging.debug("REQUEST.form=%s" % repr(formdata))
         
         # set all definedFields
         for x in definedFields:
             if formdata.has_key(x):
-                setattr(self, x, formdata[x])
+                setattr(self, x, unicodify(formdata[x]))
 
         # TODO: What does this do?
         completedAt = formdata.get('completedAt')
@@ -1754,7 +1374,7 @@
                 # wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt
                 nr = keyParts[2]
                 if keyParts[1] == "name":
-                    names[nr] = formdata[key]
+                    names[nr] = unicodify(formdata[key])
                 elif keyParts[1] == "key":
                     keys[nr] = formdata[key]
          
@@ -1783,23 +1403,6 @@
                 RESPONSE.redirect('manage_main')
 
 
-    def isChecked(self, wert, list):
-        """check if wert is in ; seperated list"""
-
-        # felder sind manchmnal als liste mit einem element definiert
-        if type(list) is StringType or UnicodeType: 
-            splitted = list.split(";")
-        else:
-            splitted = list[0].split(";")
-
-        splitted = [y.rstrip().lstrip() for y in splitted]
-        
-        for x in splitted:
-            x = re.sub(r"[^A-z ]", "", x)
-            if (not x == u'') and x in wert:
-                return 1
-        return 0
-
     security.declareProtected('View management screens', 'editBasic')
     def editBasic(self, identifiedNames=None):
         """editform"""
@@ -1811,23 +1414,6 @@
         return pt(identifiedNames=identifiedNames)
 
 
-    security.declareProtected('View management screens', 'editMPIWGBasisForm')
-    def editMPIWGBasisForm(self):
-        """editform"""
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_MPIWGBasis.zpt')).__of__(self)
-        return pt()
-
-    security.declareProtected('View management screens', 'editMPIWGRelatedPublicationsForm')
-    def editMPIWGRelatedPublicationsForm(self):
-        """Edit related Publications"""
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_MPIWGRelatedPublications.zpt')).__of__(self)
-        return pt()
-        
-    
-    def loadNewFileForm(self):
-        """Neues XML-File einlesen"""
-        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'MPIWGProject_newfile.zpt')).__of__(self)
-        return pt()
 
     def loadNewFile(self, RESPONSE=None):
         """einlesen des neuen files"""
@@ -1861,6 +1447,143 @@
         return
     
     
+    def hasRelatedPublicationsOldVersion(self):
+        """teste ob es related publications gibt"""        
+        ret = True;
+        if (self.getRelatedPublications() == ''):
+            ret = False;  # nichts im alten feld
+        logging.debug("webrel:" + repr(ret))
+        if (getattr(self, 'WEB_related_pub_copied', False)):
+            ret = False;  # alte daten sind schon kopiert worden
+        
+        logging.debug("webrel_copied:" + repr(ret))
+        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_publication']);
+        
+        if(len(publications) > 0):
+            ret = False;  # es gibt publicationen in der neuen liste
+      
+        
+        logging.debug("len(publ)" + repr(ret))
+        
+        return ret;
+
+
+    def copyPublicationsToList(self, RESPONSE=None):
+        """copy publications in to list"""
+        publicationTxt = self.getRelatedPublications()
+
+        pubSplits = publicationTxt.split("<p>")
+
+        for pubSplit in pubSplits:
+            pubSplit = pubSplit.replace("</p>", "")
+            self.addPublication(pubSplit)
+
+        setattr(self, "WEB_related_pub_copied", True);
+        
+        if RESPONSE:
+                
+            self.redirect(RESPONSE, 'managePublications')
+        
+
+    def hasInlineImage(self):
+        """Return the number of inline images in the description."""
+        text = self.getDescription()
+        cnt = text.count('<p class="picture">')
+        return cnt
+    
+    
+    def copyImageToMargin(self, RESPONSE=None):  
+        """copy inline images to marginal images"""
+        # getImages from WEB_project_description
+        description = self.getDescription()
+        
+        text2 = description
+        splitted = text2.split("""<p class="picture">""")
+        
+        imageURLs = []
+        imageCaptions = []
+        for split in splitted[1:]:
+                tmp = split.split("</p>")
+                # return repr(splitted[1])
+                
+                try:
+                    imageURLs.append(tmp[0].split("\"")[1].encode('utf-8'))
+                except:
+                    
+                    try:
+                        imageURLs.append(tmp[0].split("src=")[1].split(" ")[0].encode('utf-8'))
+                    except:
+                        imageURLs.append("")
+                
+                split2 = "</p>".join(tmp[1:])
+                splitted = split2.split("""<p class="picturetitle">""")
+                if len(splitted) > 1:
+                    tmp = splitted[1].split("</p>")
+                    imageCaptions.append(tmp[0].encode('utf-8'))
+
+                else:
+                    # keine caption
+                    imageCaptions.append("")
+     
+        # eintragen:
+        for imageURL in imageURLs:
+            if not imageURL:
+                # no URL - no image
+                continue
+            
+            filename = imageURL.split("/")[-1]
+            # lege neues images object an, mit leerem bild
+
+            if filename in self:
+                # existiert das bild schon, dann neuen filenamen
+                filename = "project_image_" + filename
+                if filename in self:
+                    # exists too - assume its already converted
+                    logging.warn("copyImageToMargin: image %s exists - skipping!"%filename)
+                    continue
+            
+            self.addImage(None, imageCaptions[imageURLs.index(imageURL)], filename=filename)
+            # hole die bilddaten aus der url
+            url = self.absolute_url() + "/" + imageURL
+            # url=self.absolute_url()+"/"+filename
+        
+            try:  # relative url
+                data = urllib.urlopen(url).read()
+            except:
+                try:  # absolute
+                    data = urllib.urlopen(self.imageURL).read()
+                except:
+                    logging.error("copyImageToMargin: can't open: %s" % url)
+            
+            obj = getattr(self, filename)
+            obj.update_data(data)
+        
+        # clean description
+        logging.debug("copyImageToMargin: description:%s"%repr(description))
+        dom = ET.fromstring(utf8ify("<html>%s</html>"%description))
+        for e in dom.findall(".//p[@class='picture']"):
+            # remove contents
+            e.clear()
+            # remove tag
+            e.tag = None
+            
+        for e in dom.findall(".//p[@class='picturetitle']"):
+            # remove contents
+            e.clear()
+            # remove tag
+            e.tag = None
+            
+        # remove html tag
+        dom.tag = None
+        # set as new description
+        description = unicodify(serialize(dom))
+        logging.debug("copyImageToMargin: new description:%s"%repr(description))
+        setattr(self, 'WEB_project_description', description)
+        
+        if RESPONSE:
+            self.redirect(RESPONSE, 'manageImages')
+
+
     def updateProjectMembers(self, updateResponsibleScientistsList=False):
         """updates project-member table"""
         if updateResponsibleScientistsList:
@@ -1946,6 +1669,7 @@
         if tree is None:
             tree = HashTree(keySeparator='.', keyFn=getInt)
             for p in self.objectValues(spec='MPIWGProject'):
+                # add all projects
                 tree.add(p.getNumber(), p)
                 
             self._v_projectTree = tree
@@ -1954,7 +1678,7 @@
         return tree
     
     
-    def getProjectsAsList(self, start, active=1, archived=1):
+    def getProjectsAsList(self, start=None, active=1, archived=1):
         """Return flattened list of projects, starting from start.
 
         active = 0 : all projects
@@ -2011,6 +1735,118 @@
         return projects        
         
         
+    security.declareProtected('View management screens', 'changeProjectTree')
+    def changeProjectTree(self, RESPONSE=None):
+        """change the complete tree"""
+        form=self.REQUEST.form
+        hashList={}
+        onlyArchived=int(form.get("onlyArchived",0))
+        onlyActive=int(form.get("onlyActive",0))
+        dep=form.get("dep",None)
+        
+        fields = self.getProjectsAsList(start=dep, archived=onlyArchived, active=onlyActive)
+        
+        logging.info("GOT TREE!----------------------------------------------------")
+        for field in form.keys():
+            
+            splitted=field.split('_')
+            if (len(splitted)>1) and (splitted[1]=="runningNumber"): 
+                #feld hat die Form Nummer_name und runnignNumber
+                nr=int(splitted[0]) # nummer des Datensatzes
+                project = fields[nr]
+
+                #
+                # change active
+                #            
+                if form.has_key('%s_active'%nr): # active flag is set
+                    project.setActiveFlag(True)
+                else:
+                    project.setActiveFlag(False)
+                    
+                #    
+                # nummer hat sich geaendert
+                #
+                entryChanged = False;
+                pronum = project.getNumber()  
+                formnum = form['%s_number'%nr]
+                
+                if not (pronum == formnum):
+                    logging.debug("Changed!Number+++++++++++++++++++++++++++++++++")
+                    logging.debug(repr(fields[nr].xdata_05)+" ---> "+ repr(form[str(nr)+'_number']))
+                    entryChanged = True
+                    
+                #
+                # completed hat sich geaendert
+                #
+                td = project.transformDate # hole die funktion zum transformieren des datums
+                formstarted = form[str(nr)+'_started']                           
+                formcompleted = form[str(nr)+'_completed']  
+                                         
+                if not (td(project.getCompletedAt()) == td(formcompleted)):
+                    logging.info(repr(td(project.getCompletedAt()))+" ---> "+ repr(td(form[str(nr)+'_completed'])))
+                    logging.info("Changed!Completed+++++++++++++++++++++++++++++++++")
+                    entryChanged = True
+                
+                if not (td(project.getStartedAt()) == td(formstarted)):
+                    logging.info(repr(td(project.getStartedAt()))+" ---> "+ repr(td(form[str(nr)+'_started'])))
+                    logging.info("Changed!Started+++++++++++++++++++++++++++++++++")
+                    entryChanged = True
+                
+                if entryChanged:
+                    logging.info("Changed!+++++++++++++++++++++++++++++++++")
+                    project.copyObjectToArchive()
+                    project.xdata_05 = formnum
+                    project.setCompletedAt(formcompleted)
+                    project.setStartedAt(formstarted)
+                    # reset tree
+                    self._v_projectTree = None
+                
+        if RESPONSE is not None:
+            RESPONSE.redirect(self.en.MPIWGrootURL()+'/admin/showTree')
+
+
+    # TODO: it's broken. is this used?
+    def getAllProjectsAndTagsAsCSV(self,archived=1,RESPONSE=None):
+        """alle projekte auch die nicht getaggten"""
+        retList=[]
+        headers=['projectId','sortingNumber','projectName','scholars','startedAt','completedAt','lastChangeThesaurusAt','lastChangeProjectAt','projectCreatedAt','persons','places','objects']
+        headers.extend(list(self.thesaurus.tags.keys()))
+        retList.append("\t".join(headers))
+        if not hasattr(self,'thesaurus'):
+            return "NON thesaurus (there have to be a MPIWGthesaurus object, with object ID thesaurus)"
+        
+        projectTags = self.thesaurus.getProjectsAndTags()
+        for project in self.getProjectFields('WEB_title_or_short'):
+            proj = project[0]
+            p_name = project[1]
+            retProj=[]
+            #if (not proj.isArchivedProject() and archived==1) or (proj.isArchivedProject() and archived==2):
+            retProj.append(self.utf8ify(proj.getId()))
+            retProj.append(self.utf8ify(proj.getContent('xdata_05')))
+            retProj.append(self.utf8ify(p_name))  
+            retProj.append(self.utf8ify(proj.getContent('xdata_01')))
+            retProj.append(self.utf8ify(proj.getStartedAt()))
+            retProj.append(self.utf8ify(proj.getCompletedAt()))
+            changeDate=self.thesaurus.lastChangeInThesaurus.get(proj.getId(),'') 
+            n = re.sub("[:\- ]","",str(changeDate))
+            retProj.append(n)
+            retProj.append(self.utf8ify(getattr(proj,'creationTime','20050101000000')))  
+            retProj.append("")#TODO: project created at   
+            retProj.append(";".join([person[1] for person in self.thesaurus.getPersonsFromProject(proj.getId())]))
+            retProj.append(";".join([person[1] for person in self.thesaurus.getHistoricalPlacesFromProject(proj.getId())]))
+            retProj.append(";".join([person[1] for person in self.thesaurus.getObjectsFromProject(proj.getId())]))
+            retProj+=self.thesaurus.getTags(proj.getId(),projectTags)
+            retList.append("\t".join(retProj))
+        
+        if RESPONSE:
+            
+            RESPONSE.setHeader('Content-Disposition','attachment; filename="ProjectsAndTags.tsv"')
+            RESPONSE.setHeader('Content-Type', "application/octet-stream")
+      
+        return "\n".join(retList);
+    
+    
+        
     security.declareProtected('View management screens', 'updateAllProjectMembers')
     def updateAllProjectMembers(self, updateResponsibleScientistsList=False):
         """Re-create responsibleScientistsLists and projects_members table from all current projects."""
@@ -2028,16 +1864,19 @@
 
 
     security.declareProtected('View management screens', 'updateAllProjects')
-    def updateAllProjects(self, updateResponsibleScientistsList=False):
+    def updateAllProjects(self, updateResponsibleScientistsList=False, RESPONSE=None):
         """Patch all current projects for legacy problems."""
         cnt = 0
+        fulllog = ""
         # go through all projects
         for (id, project) in self.ZopeFind(self, obj_metatypes=['MPIWGProject'], search_sub=1):
+            log = ""
             cnt += 1
             #
             # hasRelatedPublicationsOldVersion
             #
             if project.hasRelatedPublicationsOldVersion():
+                log += "%s: update relatedPublicationsOldVersion!\n"%project.getId()
                 logging.debug("updateAllProjects(%s): update relatedPublicationsOldVersion!"%project.getId())
                 project.copyPublicationsToList()
                                 
@@ -2046,6 +1885,7 @@
             #
             memberlist = project.getResponsibleScientistsList()
             if len(memberlist) > 0 and isinstance(memberlist[0], tuple):
+                log += "%s: updating memberlist!\n"%project.getId()
                 logging.debug("updateAllProjects(%s): updating memberlist" % project.getId())
                 newScientists = {}
                 for m in memberlist:
@@ -2067,9 +1907,23 @@
                 project.setResponsibleScientistsList(newScientists)
 
             #
+            # old inline images
+            #
+            if project.hasInlineImage():
+                log += "%s: has inlineImage!\n"%project.getId()
+                logging.debug("updateAllProjects(%s): has inlineImage!"%project.getId())
+                try:
+                    project.copyImageToMargin()
+                except Exception, e:
+                    log += "%s: ERROR in copyImageToMargin!\n"%project.getId()
+                    logging.debug("updateAllProjects(%s): ERROR in copyImageToMargin: %s"%(project.getId(), e))
+                                    
+            
+            #
             # remove old attributes
             #
             if hasattr(project, 'definedFields'):
+                log += "%s: has definedFields!\n"%project.getId()
                 logging.debug("updateAllProjects(%s): has definedFields!"%project.getId())
                 delattr(project, 'definedFields')
                 
@@ -2077,13 +1931,35 @@
             # update extended bibliography
             #
             if hasattr(project, 'publicationList'):
+                log += "%s: has publicationList!\n"%project.getId()
                 logging.debug("updateAllProjects(%s): has publicationList!"%project.getId())
                 extpub = project.publicationList
                 if hasattr(extpub, 'connection_id'):
                     logging.debug("updateAllProjects(%s): extended publication %s has connection_id=%s!"%(project.getId(),extpub.getId(),extpub.connection_id))
             
+            #
+            # unicodify
+            #
+            for field in ('WEB_title', 'xdata_01', 'xdata_07', 'xdata_08', 'xdata_11', 'xdata_12', 'xdata_13', 
+                      'WEB_project_description', 'WEB_related_pub'):
+                text = getattr(project, field, None)
+                if isinstance(text, str):
+                    log += "%s: has non-unicode field %s\n"%(project.getId(), field)
+                    logging.debug("updateAllProjects(%s): has has non-unicode field %s\n"%(project.getId(), field))
+                    setattr(project, field, unicodify(text))
                 
-        return "updated %s projects!" % cnt
+            fulllog += log    
+            if RESPONSE is not None:
+                RESPONSE.write(log)
+                
+            
+        log += "\n DONE! updated %s projects!" % cnt
+        fulllog += log
+        if RESPONSE is not None:
+                RESPONSE.write(log)
+                RESPONSE.flush()
+        else:
+            return fulllog
                 
 
       
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MPIWGProjects_removed.py	Tue Apr 30 16:35:52 2013 +0200
@@ -0,0 +1,252 @@
+#
+# removed methods
+#
+class MPIWGProjects_notused:
+
+    def decode(self, str):
+        """return unicode object"""
+        return unicodify(str)
+
+    def isCheckField(self, fieldname):
+        """return chechfield"""
+        return (fieldname in checkFields)
+ 
+    def sortedByPlace(self, metatype):
+        """find metatype and sort by place"""
+        def sort(x, y):
+            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
+
+        logging.debug("MPIWGProjects begin: sorted by place: " + metatype)
+        founds = self.ZopeFind(self, obj_metatypes=[metatype]);
+        
+        founds.sort(sort)
+        logging.debug("MPIWGProjects end: sorted by place: " + metatype)
+        return founds
+    
+
+    def harvest_page(self, context=None, mode="normal"):
+        """seite fuer harvesting fuer die Projektsuche"""
+       
+        if not context:
+            context = self
+            
+        if self.isActiveProject() and self.isCurrentVersion():
+             templates = self.en.getHarvestCache()
+            
+             ext = getattr(self, "harvest_main", None)
+             if ext:
+                 rendered = getattr(self, ext.getId())()
+                 templates[self.absolute_url()] = rendered
+                 transaction.commit()
+                 return rendered
+                 
+
+             pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'harvest_main')).__of__(context)    
+             
+             rendered = pt()
+             templates[self.absolute_url()] = rendered
+             transaction.commit()
+             return rendered
+                 
+ 
+      
+    def index_html_old(self, request=True, context=None):
+        """show homepage"""
+    
+        bound_names = {}
+         
+        if not context:
+            context = self
+        if request:
+            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected', None) == None:
+                self.REQUEST.SESSION['MPI_redirected'] = 1
+                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date']) + "?date=" + self.REQUEST['date'])
+            else:
+                self.REQUEST.SESSION['MPI_redirected'] = None
+        
+        # ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
+      
+   
+        request2 = getattr(self, 'REQUEST', None)
+        
+        if request2 is not None:
+            response = request2.response
+            if not response.headers.has_key('content-type'):
+                response.setHeader('content-type', 'text/html')
+
+        security = getSecurityManager()
+        bound_names['user'] = security.getUser()
+      
+        # Retrieve the value from the cache.
+        keyset = None
+        if self.ZCacheable_isCachingEnabled():
+            
+            # Prepare a cache key.
+            keyset = {'here': self, 'params':request2['QUERY_STRING']}
+                      
+            result = self.ZCacheable_get(keywords=keyset)
+           
+            if result is not None:
+                # Got a cached value.
+                return result
+        
+        pt = getTemplate(self, "project_main")
+         # Execute the template in a new security context.
+        security.addContext(self)
+
+        try:
+            # logging.debug("index_html pt=%s"%repr(pt))
+            result = pt.pt_render(extra_context=bound_names)
+            # logging.debug("index_html result=%s"%repr(result))
+            if keyset is not None:
+                # Store the result in the cache.
+                self.ZCacheable_set(result, keywords=keyset)
+               
+            return result
+        finally:
+            security.removeContext(self)
+       
+
+      
+    def index_html_old2(self, request=True, context=None):
+        """show homepage"""
+        if not context:
+            context = self
+        if request:
+            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected', None) == None:
+                self.REQUEST.SESSION['MPI_redirected'] = 1
+                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date']) + "?date=" + self.REQUEST['date'])
+            else:
+                self.REQUEST.SESSION['MPI_redirected'] = None
+        
+        # ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
+      
+        ext = getattr(self, "project_main", None)
+        if ext:
+            return getattr(self, ext.getId())()
+        
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'project_main')).__of__(context)    
+
+        return pt()
+
+    
+    def no_project(self):
+        """warnung: project noch nicht existent"""
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'no_project')).__of__(self)
+        return pt()
+    
+  
+    def showImagesOfPage(self, imageUrl=None):
+        """show Images of project"""
+        self.getContent('WEB_project_description', filter='yes')  # get the content and store image infos into session
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'projectImageView.zpt')).__of__(self)
+        return pt()
+        
+    
+    def show_html(self):
+        """simple index"""
+        # return "HI"
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'MPIWGProject_index.zpt')).__of__(self)
+        return pt()
+
+    def getLabel_old(self):
+        """returns label (or title) of this project"""
+        l = self.getContent('xdata_07')
+        if l:
+            return l
+        l = self.getContent('WEB_title')
+        if l:
+            return l
+        return self.title
+
+    def getPersonKeyList(self):
+        """gibt die key Liste der beteiligten Personen zurueck (utf8 codiert)"""
+        # logging.error("getPersonKeyList:%s"%getattr(self,'responsibleScientistsList',[]))
+        try:
+            return [utf8ify(x[1]) for x in getattr(self, 'responsibleScientistsList', [])]
+        except:
+            return[]
+        
+       
+    def myCapitalize(self, txt):
+        """kapitalisiere auch Namen mit -"""
+        splitted = [x.capitalize() for x in txt.split("-")]
+        return "-".join(splitted)
+    
+    def getNamesOrdered(self, list):
+        """Sortiert die Liste nach der Reihenfolge in xdata_01"""
+        
+        nameList = self.getContent('xdata_01')
+        if nameList.find(";") > -1:  # rate Trenner ist ;
+            names = nameList.split(";")  
+        else:
+            names = nameList.split(",")
+            
+        self._v_names = []
+        for name in names:
+            self._v_names.append(name.rstrip().lstrip())
+            
+            
+        def sort(x, y):
+            try:
+                return cmp(self._v_names.index(x[0]), self._v_names.index(y[0]))
+            except:
+                return 0
+            
+        list.sort(sort)
+        
+        return list
+        
+    def getWebProject_description(self):
+        """get description"""
+        debug = self.REQUEST.cookies.get("MP_debug_code", None)
+        
+        if debug and debug == "western":
+            return """
+            <html>
+            <head>
+            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+            </head>
+            <body>%s</body>
+            </html>
+            """ % self.WEB_project_description[0]
+        
+        return """
+            <html>
+            <head>
+            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+            </head>
+            <body>%s</body>
+            </html>
+            """ % self.getContent('WEB_project_description')
+        
+        
+        
+    def isChecked(self, wert, list):
+        """check if wert is in ; seperated list"""
+
+        # felder sind manchmnal als liste mit einem element definiert
+        if type(list) is StringType or UnicodeType: 
+            splitted = list.split(";")
+        else:
+            splitted = list[0].split(";")
+
+        splitted = [y.rstrip().lstrip() for y in splitted]
+        
+        for x in splitted:
+            x = re.sub(r"[^A-z ]", "", x)
+            if (not x == u'') and x in wert:
+                return 1
+        return 0
+
+
+    def getRootProject(self):
+        """returns the root (=top level) project of the current project"""
+        ct = self.getContexts(parents=self.getContent('xdata_05'))
+        if len(ct) > 0:
+            return ct[-1][0]
+        else:
+            return self        
+
+
+
--- a/MPIWGRoot.py	Tue Apr 30 16:31:57 2013 +0200
+++ b/MPIWGRoot.py	Tue Apr 30 16:35:52 2013 +0200
@@ -121,23 +121,6 @@
         return bt
 
 
-    def versionHeaderEN(self):
-        """version header text"""
-        
-        date= self.REQUEST.get('date',None)
-        if date:
-            txt="""<h2>This pages shows the project which existed at %s</h2>"""%str(date)
-            return txt
-        return ""
-
-    def versionHeaderDE(self):
-        """version header text"""
-        date= self.REQUEST.get('date',None)
-        if date:
-            txt="""<h2>Auf dieser Seite finden Sie die Projekte mit Stand vom %s</h2>"""%str(date)
-        return ""
-    
-        
     def createOrUpdateId_raw(self):
         """create sequence to create ids for bibliography"""
         debug=None
@@ -165,22 +148,6 @@
         splitted=url.split("/")
         return splitted[4]
 
-    def generateUrlProject(self,url,project=None):
-        """erzeuge aus absoluter url, relative des Projektes"""
-        if project:
-            splitted=url.split("/")
-            length=len(splitted)
-            short=splitted[length-2:length]
-            
-            base=self.REQUEST['URL3']+"/"+"/".join(short)
-
-        else:
-            findPart=url.find("/projects/")
-            base=self.REQUEST['URL1']+"/"+url[findPart:]
-
-                
-        return base
-    
     def isNewCapital(self,text=None,reset=None):
         
         if text:
@@ -250,6 +217,13 @@
         else:
             return style    
 
+    def getPathStyle(self, path, selected, style=""):
+        """returns a string with the given style + 'sel' if path == selected."""
+        if path == selected:
+            return style + 'sel'
+        else:
+            return style    
+
     def getFeatures(self, num=None):
         """returns a list of the last num Features"""
         dir = getattr(self, 'features', None)
@@ -324,35 +298,6 @@
             return ""
         
 
-    # TODO: remove
-    def isActiveMember(self,key):
-        """tested ob Mitarbeiter key ist aktiv"""
-        key=utf8ify(key)
-        ret=getAt(self.ZSQLInlineSearch(_table='personal_www',
-                                            _op_key='eq',key=key,
-                                            _op_publish_the_data='eq',
-                                            publish_the_data='yes'), 0)
-        
-        logging.info("MPIWGROOT ACTIVE_MEMBER  %s"%ret)
-        if ret:
-            return True
-        else:
-            return False
-        
-    # TODO: remove
-    def isActual(self,project):
-        """checke if project is actual"""
-        actualTime=time.localtime()
-        
-        if hasattr(project,'getObject'): #obj ist aus einer catalogTrefferList
-            obj=project.getObject()
-        else:
-            obj=project
-            
-        if getattr(obj,'archiveTime',actualTime)< actualTime:
-            return False
-        else:
-            return True
         
     def redirectIndex_html(self,request):
         #return request['URL1']+'/index_html'
@@ -435,34 +380,6 @@
         """quote"""
         return urllib.unquote(str)
     
-        
-
-    def getProjectsByFieldContent(self,fieldName,fieldContentsEntry, date=None):
-        """gib alle Projekte aus mit Value von field mit fieldName enthaelt ein Element der Liste fieldContents"""
-        def sort(x,y):
-                return cmp(x.WEB_title[0],y.WEB_title[0])
-
-        if type(fieldContentsEntry) is StringType:
-            fieldContentsTmp=[fieldContentsEntry]
-        else:
-            fieldContentsTmp=fieldContentsEntry
-
-        fieldContents=[]
-        for x in fieldContentsTmp:
-            fieldContents.append(" AND ".join(x.split()))
-        projects=self.ProjectCatalog({fieldName:string.join(fieldContents,' AND')})
-        #print projects
-        #ret=[x for x in projects]
-        ret=[]
-        for x in projects:
-            obj=x.getObject()
-            obj=obj.getActualVersion(date)
-            if obj and (not getattr(obj,'invisible',None)):
-                #if not (x in ret):
-                    ret.append(x)
-
-        ret.sort(sort)
-        return ret
 
     def changeMPIWGRootForm(self):
         """edit"""
@@ -484,128 +401,6 @@
         if RESPONSE is not None:
             RESPONSE.redirect('manage_main')
 
-
-    def getContexts(self,childs=None,parents=None,depth=None,date=None,onlyActive=True):
-        """childs alle childs, alle parents"""
-        ret=[]
-    
-        if parents:
-            pnums=parents.split(".")
-            while len(pnums) > 1:
-                pnums.pop()
-                parentId=string.join(pnums,".")
-        
-                for project in self.getProjectFields('xdata_05',sort='int',date=date):
-                    if project[1]==parentId:
-                        ret.append(project)
-                
-                if (depth is not None) and (len(ret) >= depth):
-                    break
-
-        if childs:
-            for project in self.getProjectFields('xdata_05',sort='int',date=date):
-                searchStr=childs+"(\..*)"
-               
-                if (onlyActive and project[0].isActiveProject()) or (not onlyActive):
-                    if re.match(searchStr,project[1]):
-                        
-                        if depth:
-    
-                            if int(depth)>=len(project[1].split("."))-len(childs.split(".")):
-                        
-                                ret.append(project)
-                        else:
-                            ret.append(project)
-        
-        #logging.debug("getContexts: childs=%s parents=%s depth=%s => %s"%(childs,parents,depth,repr(ret)))
-     
-        return ret
-
-
-    def getAllProjectsAndTagsAsCSV(self,archived=1,RESPONSE=None):
-        """alle projekte auch die nicht getaggten"""
-        retList=[]
-        headers=['projectId','sortingNumber','projectName','scholars','startedAt','completedAt','lastChangeThesaurusAt','lastChangeProjectAt','projectCreatedAt','persons','places','objects']
-        headers.extend(list(self.thesaurus.tags.keys()))
-        retList.append("\t".join(headers))
-        if not hasattr(self,'thesaurus'):
-            return "NON thesaurus (there have to be a MPIWGthesaurus object, with object ID thesaurus)"
-        
-        projectTags = self.thesaurus.getProjectsAndTags()
-        for project in self.getProjectFields('WEB_title_or_short'):
-            proj = project[0]
-            p_name = project[1]
-            retProj=[]
-            #if (not proj.isArchivedProject() and archived==1) or (proj.isArchivedProject() and archived==2):
-            retProj.append(self.utf8ify(proj.getId()))
-            retProj.append(self.utf8ify(proj.getContent('xdata_05')))
-            retProj.append(self.utf8ify(p_name))  
-            retProj.append(self.utf8ify(proj.getContent('xdata_01')))
-            retProj.append(self.utf8ify(proj.getStartedAt()))
-            retProj.append(self.utf8ify(proj.getCompletedAt()))
-            changeDate=self.thesaurus.lastChangeInThesaurus.get(proj.getId(),'') 
-            n = re.sub("[:\- ]","",str(changeDate))
-            retProj.append(n)
-            retProj.append(self.utf8ify(getattr(proj,'creationTime','20050101000000')))  
-            retProj.append("")#TODO: project created at   
-            retProj.append(";".join([person[1] for person in self.thesaurus.getPersonsFromProject(proj.getId())]))
-            retProj.append(";".join([person[1] for person in self.thesaurus.getHistoricalPlacesFromProject(proj.getId())]))
-            retProj.append(";".join([person[1] for person in self.thesaurus.getObjectsFromProject(proj.getId())]))
-            retProj+=self.thesaurus.getTags(proj.getId(),projectTags)
-            retList.append("\t".join(retProj))
-        
-        if RESPONSE:
-            
-            RESPONSE.setHeader('Content-Disposition','attachment; filename="ProjectsAndTags.tsv"')
-            RESPONSE.setHeader('Content-Type', "application/octet-stream")
-      
-        return "\n".join(retList);
-    
-    
-    
-  
-    def getProjectFields(self,fieldName,date=None,folder=None,sort=None):
-        """getListofFieldNames"""
-        ret=[]
-    
-        objects=self.ZopeFind(self.projects,obj_metatypes=['MPIWGProject'],search_sub=0)
-
-                
-        for object in objects:
-            obj=object[1]
-            obj=obj.getActualVersion(date)
-            if obj and (not getattr(obj,'invisible',None)):
-                if fieldName=="WEB_title_or_short":
-
-                    if len(obj.getContent('xdata_07'))<3: # hack weil z.Z. manchmal noch ein Trennzeichen ; oder , im Feld statt leer
-                        fieldNameTmp="WEB_title"
-                    else:
-                        fieldNameTmp="xdata_07"
-                else:
-                    fieldNameTmp=fieldName
-
-                ret.append((obj,obj.getContent(fieldNameTmp)))
-
-        
-        if sort=="int":
-            ret.sort(sortI)
-        elif sort=="stopWords":
- 
-            ret.sort(sortStopWords(self))
-            
-        else:
-            ret.sort(sortF)
-        
-        return ret
-
-    def showNewProjects(self):
-        projects=[]
-        for objs in self.getProjectFields('WEB_title_or_short'): # Get all Projets
-            if objs[0].xdata_05 and (objs[0].xdata_05[0] == ""):
-                
-                projects.append(objs)
-                
-        return projects
     
         
     def updatePublicationDB(self,personId=None):
@@ -843,43 +638,6 @@
     
 
      
-    def reindexCatalogs(self,RESPONSE=None):
-        """reindex members and project catalog"""
-        
-        
-        try:
-            
-            self.ProjectCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
-            logger("MPIWG Root (reindexCatalog: projects)",logging.INFO,"DONE")
-        except:
-            logger("MPIWG Root (reindexCatalog: projects)",logging.WARNING," %s %s"%sys.exc_info()[:2])
-        
-        try:
-            
-            self.MembersCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
-            logger("MPIWG Root (reindexCatalog: members)",logging.INFO,"DONE")
-        except:
-            logger("MPIWG Root (reindexCatalog: members)",logging.WARNING," %s %s"%sys.exc_info()[:2])
-        
-        
-#        
-#        try:
-#            
-#            self.fulltextProjectsMembers.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
-#            logger("MPIWG Root (reindexCatalog: fulltextProjectsMembers)",logging.INFO,"DONE")
-#        except:
-#            logger("MPIWG Root (reindexCatalog: fulltextProjectsMembers)",logging.WARNING," %s %s"%sys.exc_info()[:2])
-#            
-#        
-#        
-#        
-        
-        
-        if RESPONSE:
-            RESPONSE.redirect('manage_main')
-
-        
-        
 
     def getAllMembers(self):
         #ret=[]
@@ -923,177 +681,14 @@
             rss+=linkStr%obj[3].getId()
             rss+="""</item>"""
             if hasattr(obj[3],'publicationList'):
-	        rss+="""<item>"""
+            rss+="""<item>"""
                 rss+=linkStr%(obj[3].getId()+"/publicationList");
                 rss+="""</item>"""
         rss+="""</channel>
         </rss>"""
 
-        
         return rss
 
-    def getTree(self,dep=None,date=None,onlyActive=0,onlyArchived=0):
-        """generate Tree from project list
-        als Liste, jeder Eintrag ist ein Tupel ,(Tiefe, ProjektNummer,ProjektObject
-        onlyActive = 0  : alle Projekte
-        onlyActive = 1 : nur active Projekte
-        onlyActive = 2: nur inactive Projekte
-        
-        onlyArchived=0: alle Projekte
-        onlyArchived= 1 : nur aktuelle Projekte
-        onlyArchived = 2: nur archivierte Projekte
-        
-        department fuer das Tree geholt werden soll
-        """
-        logging.debug("MPIWGRoot.getTree()")
-
-        returnListTmp=[]
-        returnList=[]
-        
-        for project in self.getProjectFields('xdata_05',sort="int",date=date): # get Projects sorted by xdata_05
-
-            for idNr in project[1].split(";"): # more than one number
-                if not idNr=="":
-                    splittedId=idNr.split(".")
-                    depth=len(splittedId)
-                    nr=idNr
-                    #title=project[0].WEB_title
-                    title=[project[0].getContent('WEB_title')]
-                    #print title
-                    
-                    if idNr[0]=="x": # kompatibilitaet mit alter Konvention, x vor der Nummer macht project inactive
-                        project[0].setActiveFlag(False)
-                   
-                    if (not dep) or (splittedId[0]==dep): #falls dep gesetzt ist nur dieses hinzufuegen.
-                        
-                        if (onlyActive==0):
-                            returnListTmp.append((depth,nr,title,project[0]))
-                        elif (onlyActive==1) and project[0].isActiveProject(): #nur active projekte
-                            returnListTmp.append((depth,nr,title,project[0]))
-                        elif (onlyActive==2) and (not project[0].isActiveProject()): #nur active projekte
-                            returnListTmp.append((depth,nr,title,project[0]))
-                   
-                   
-        #filter jetzt die Liste nach Archived oder nicht
-        for entry in returnListTmp:
-                    if (onlyArchived==0):
-                            returnList.append(entry)
-                    elif (onlyArchived==1) and (not entry[3].isArchivedProject()): #nur active projekte
-                            returnList.append(entry)
-                    elif (onlyArchived==2) and (entry[3].isArchivedProject()): #nur active projekte
-                            returnList.append(entry)
-                   
-        
-        return returnList
-
-
-        
-    def changePosition(self,treeId,select,RESPONSE=None):
-        """Change Postion Entry"""
-        numbers=[]
-
-        # Suche hoechste bisherige nummer
-        projects=self.getProjectFields('xdata_05') # get Projects sorted by xdata_05
-        #print "pj",projects
-        for project in projects: #suche alle subtrees der treeId
-            #print treeId
-            
-            founds=re.match(treeId+"\.(.*)",project[1].split(";")[0])
-            if founds:
-                #print "x",founds.group(0),len(founds.group(0).split("."))
-                if len(founds.group(0).split("."))==len(treeId.split("."))+1: # nur ein punkt mehr, d.h. untere ebene
-                    try:
-                        numbers.append(int(founds.group(0).split(".")[len(founds.group(0).split("."))-1]))
-                    except:
-                        numbers.append(int(0))
-
-        try:
-            highest=max(numbers)
-        except:
-            highest=0
-        projects=self.showNewProjects()
-        for i in self.makeList(select):
-            highest+=10
-            projects[int(i)][0].xdata_05=treeId+"."+str(highest)
-
-
-        if RESPONSE is not None:
-            RESPONSE.redirect('showTree')
-        
-    def changeTree(self,RESPONSE=None):
-        """change the complete tree"""
-        form=self.REQUEST.form
-        hashList={}
-        onlyArchived=int(form.get("onlyArchived",0))
-        onlyActive=int(form.get("onlyActive",0))
-        dep=form.get("dep",None)
-        
-        fields=self.getTree(dep=dep,onlyArchived=onlyArchived,onlyActive=onlyActive)
-        
-        logging.info("GOT TREE!----------------------------------------------------")
-        for field in form.keys():
-            
-            splitted=field.split('_')
-            if (len(splitted)>1) and (splitted[1]=="runningNumber"): #feld hat die Form Nummer_name und runnignNumber
-            
-                
-                nr=int(splitted[0]) # nummer des Datensatzes
-                currentEntry = fields[nr]
-            
-                if form.has_key(str(nr)+'_active'): # active flag is set
-                    fields[nr][3].setActiveFlag(True)
-                else:
-                    fields[nr][3].setActiveFlag(False)
-                    
-                #nummer hat sich geaendert
-                
-                entryChanged = False;
-                
-                if isinstance(fields[nr][3].xdata_05,list): #for some reasons somtimes the content of the field is a list with one entry.
-                    fields[nr][3].xdata_05=fields[nr][3].xdata_05[0]
-                    
-                if not (fields[nr][3].xdata_05==form[str(nr)+'_number']):
-                    logging.info("Changed!Number+++++++++++++++++++++++++++++++++")
-                    logging.info(repr(fields[nr][3].xdata_05)+" ---> "+ repr(form[str(nr)+'_number']))
-                    fields[nr][3].xdata_05=form[str(nr)+'_number']
-                    entryChanged = True
-                    
-                #completed har sich geaendert
-                          
-                td = fields[nr][3].transformDate # hole die funktion zum transformieren des datums
-                  
-                if not (td(fields[nr][3].getCompletedAt())==td(form[str(nr)+'_completed'])):
-                    fields[nr][3].setCompletedAt(form[str(nr)+'_completed'])
-                    logging.info(repr(td(fields[nr][3].getCompletedAt()))+" ---> "+ repr(td(form[str(nr)+'_completed'])))
-                    logging.info("Changed!Completed+++++++++++++++++++++++++++++++++")
-                    entryChanged = True
-                
-                if not (td(fields[nr][3].getStartedAt())==td(form[str(nr)+'_started'])):
-                    fields[nr][3].setStartedAt(form[str(nr)+'_started'])
-            
-                    logging.info(repr(td(fields[nr][3].getStartedAt()))+" ---> "+ repr(td(form[str(nr)+'_started'])))
-                    logging.info("Changed!Started+++++++++++++++++++++++++++++++++")
-                    entryChanged = True
-                
-                
-                if entryChanged:
-                    logging.info("Changed!+++++++++++++++++++++++++++++++++")
-                    fields[nr][3].copyObjectToArchive()
-                
-                    
-        if RESPONSE is not None:
-            RESPONSE.redirect('showTree')
-
-    def getProjectWithId(self,id):
-        fields=self.getProjectFields('xdata_05')
-        for field in fields:
-            if field[1]==id:
-                return field[0]
-
-        return None
-            
-        
-            
         
     def getRelativeUrlFromPerson(self,list):
         """get urls to person list"""
@@ -1143,202 +738,7 @@
 
             
 
-    def getProjectsOfMembers(self,date=None):
-        """give tuple member /projects"""
-        ret=[]
-        members=self.getAllMembers()
-        logging.debug("X %s"%repr(members))
-        #return str(members)
-        for x in members:
-            #logging.debug("X %s"%repr(x))
-            projects=self.getProjectsOfMember(key=x[1],date=date)
-            if len(projects)>0:
-                ret.append((x[0],projects))
-            
-        return ret
-
-    def getProjectsOfMember(self,key=None,date=None,onlyArchived=1,onlyActive=1):
-        """get projects of a member
-    
-        @param key: (optional) Key zur Idenfikation des Benutzer
-        @param date: (optional) Version die zum Zeitpunkt date gueltig war
-        @param onlyArchived: 
-        onlyArchived=0: alle Projekte
-        onlyArchived= 1 : nur aktuelle Projekte
-        onlyArchived = 2: nur archivierte Projekte
-        """
-        # TODO: Die ganze Loesung
-        def sortP(x,y):
-            """sort by sorting number"""
-            return cmp(x.WEB_title,y.WEB_title)
-        
-        ret=[]  
-        if key:     
-            logging.debug("MPIWGROOT (getProjectsOfMember):"+key)
-            proj=self.ProjectCatalog({'getPersonKeyList':utf8ify(key)})
-        else:
-            return ret # key muss definiert sein
-        
-        #logging.debug("MPIWGROOT (getProjectsOfMember):"+repr(proj))
-        if proj:
-            proj2=[]
-            for x in proj:
-                #logging.error("proj:%s"%repr(x.getPath()))
-                if (not getattr(x.getObject(),'invisible',None)) and (getattr(x.getObject(),'archiveTime','')==''):   
-                      proj2.append(x)
-
-        else:
-            proj2=[]
-            
-       
-       
-        proj2.sort(sortP)
-
-        projectListe=[]
-        #logging.error("getprojectsofmember proj2: %s"%repr(proj2))
-        for proj in proj2:   
-            obj=proj.getObject()
-            add=False
-            if onlyArchived==1: #nur aktuell projecte
-                if not obj.isArchivedProject():
-                    add=True
-            elif onlyArchived==2: #nur archivierte
-                if obj.isArchivedProject():
-                    add=True
-            else: #alle
-               add=True 
-               
-            if onlyActive==1: #nur active projecte
-                if obj.isActiveProject():
-                    add=add & True
-                else:
-                    add=add & False
-                
-            elif onlyArchived==2: #nur nicht aktvive
-                if not obj.isActiveProject():
-                    add=add & True
-            else: #alle
-               add=add & True
-                    
-            if add:
-                projectListe.append(obj)
-                
-        #logging.error("getprojectsofmember projectliste: %s"%repr(projectListe))
-        return projectListe
      
-    def givePersonList(self,name):
-        """check if person is in personfolder and return list of person objects"""
-        
-        splitted=name.split(",")
-        if len(splitted)==1:
-            splitted=name.lstrip().rstrip().split(" ")
-        splittedNew=[split.lstrip() for split in splitted]
-        
-        if splittedNew[0]=='':
-            del splittedNew[0]
-        search=string.join(splittedNew,' AND ')
-        
-        if not search=='':
-            proj=self.MembersCatalog({'title':search})
-
-        if proj:
-            return [[x.lastName,x.firstName] for x in proj]
-        else:
-            return []
-            
-##         splitted=name.split(",") # version nachname, vorname...
-##         if len(splitted)>1:
-##             lastName=splitted[0] 
-##             firstName=splitted[1]
-##         else: 
-##             splitted=name.split(" ") #version vorname irgenwas nachnamae
-        
-##             lastName=splitted[len(splitted)-1]
-##             firstName=string.join(splitted[0:len(splitted)-1])
-
-##         objs=[]
-
-        #print  self.members 
-      ##   for x in self.members.__dict__:
-##             obj=getattr(self.members,x)
-##             if hasattr(obj,'lastName') and hasattr(obj,'firstName'):
-                
-##                 if (re.match(".*"+obj.lastName+".*",lastName) or re.match(".*"+lastName+".*",obj.lastName)) and (re.match(".*"+obj.firstName+".*",firstName) or re.match(".*"+firstName+".*",obj.firstName)):
-                    
-##                     objs.append((obj,lastName+", "+firstName))
-
-        
-##        return objs
-
-
-    def personCheck(self,names):
-        """all persons for list"""
-        #print "names",names
-        splitted=names.split(";")
-        ret={}
-        for name in splitted:
-
-            if not (name==""):
-                try:
-                    ret[name]=self.givePersonList(name)
-                except:
-                    """NOTHIHN"""
-        #print "RET",ret
-        return ret
-
-    def giveCheckList(self,person,fieldname):
-        """return checklist"""
-        #print "GCL",fieldname
-        if fieldname=='xdata_01':
-            x=self.personCheck(person.getContent(fieldname))
-            #print "GCLBACKX",x
-            return x
-        
-
-    # TODO: do we need this here?
-    def isCheckField(self,fieldname):
-        """return chechfield"""
-        return (fieldname in checkFields)
-
-    
-
-    def sortResults(self,results):
-        """search the catalog and give results back sorted by meta_type"""
-        ret = {}
-        logging.debug(results())
-        for result in results():
-            metaType = result.meta_type
-            resultList= ret.get(metaType,[])
-            resultList.append(result)
-            ret[metaType]=resultList
-        
-        logging.debug(ret)
-        return ret
-    
-    
-    def getAllProjectPublications(self):
-            """get all publications"""
-            fw=file("/tmp/allProjectPublications","w")
-            projects =self.projects.getProjectsAsList(None,active=0,archived=0)
-           
-            for project in projects:
-                logging.debug(project)
-                if hasattr(project,'publicationList'):
-                    try:
-                        x =project.publicationList.bibliolist.data
-                    
-                    except:
-                        logging.error("Can't do: %s"%project.absolute_url())
-                        continue
-                
-                    id=project.getId()
-                    for l in x.split("\n"):
-                        fw.write("%s,%s\n"%(id,l))
-                    fw.flush()
-                
-            fw.close()
-                
-        
             
 def manage_addMPIWGRootForm(self):
     """form for adding the root"""
--- a/MPIWGRoot_deleted_methods.py	Tue Apr 30 16:31:57 2013 +0200
+++ b/MPIWGRoot_deleted_methods.py	Tue Apr 30 16:35:52 2013 +0200
@@ -1,3 +1,6 @@
+class MPIWGRoot_deleted:
+    
+    
     def removeStopWords(self,xo):
         """remove stop words from xo"""
         if not hasattr(self,'_v_stopWords'):
@@ -301,4 +304,549 @@
         """restore"""
         self.nameIndexEdited=self.nameIndex
         return "done"
+ 
+    def getProjectsOfMembers(self,date=None):
+        """give tuple member /projects"""
+        ret=[]
+        members=self.getAllMembers()
+        logging.debug("X %s"%repr(members))
+        #return str(members)
+        for x in members:
+            #logging.debug("X %s"%repr(x))
+            projects=self.getProjectsOfMember(key=x[1],date=date)
+            if len(projects)>0:
+                ret.append((x[0],projects))
+            
+        return ret
+
+    def getProjectsOfMember(self,key=None,date=None,onlyArchived=1,onlyActive=1):
+        """get projects of a member
     
+        @param key: (optional) Key zur Idenfikation des Benutzer
+        @param date: (optional) Version die zum Zeitpunkt date gueltig war
+        @param onlyArchived: 
+        onlyArchived=0: alle Projekte
+        onlyArchived= 1 : nur aktuelle Projekte
+        onlyArchived = 2: nur archivierte Projekte
+        """
+        # TODO: Die ganze Loesung
+        def sortP(x,y):
+            """sort by sorting number"""
+            return cmp(x.WEB_title,y.WEB_title)
+        
+        ret=[]  
+        if key:     
+            logging.debug("MPIWGROOT (getProjectsOfMember):"+key)
+            proj=self.ProjectCatalog({'getPersonKeyList':utf8ify(key)})
+        else:
+            return ret # key muss definiert sein
+        
+        #logging.debug("MPIWGROOT (getProjectsOfMember):"+repr(proj))
+        if proj:
+            proj2=[]
+            for x in proj:
+                #logging.error("proj:%s"%repr(x.getPath()))
+                if (not getattr(x.getObject(),'invisible',None)) and (getattr(x.getObject(),'archiveTime','')==''):   
+                      proj2.append(x)
+
+        else:
+            proj2=[]
+            
+       
+       
+        proj2.sort(sortP)
+
+        projectListe=[]
+        #logging.error("getprojectsofmember proj2: %s"%repr(proj2))
+        for proj in proj2:   
+            obj=proj.getObject()
+            add=False
+            if onlyArchived==1: #nur aktuell projecte
+                if not obj.isArchivedProject():
+                    add=True
+            elif onlyArchived==2: #nur archivierte
+                if obj.isArchivedProject():
+                    add=True
+            else: #alle
+               add=True 
+               
+            if onlyActive==1: #nur active projecte
+                if obj.isActiveProject():
+                    add=add & True
+                else:
+                    add=add & False
+                
+            elif onlyArchived==2: #nur nicht aktvive
+                if not obj.isActiveProject():
+                    add=add & True
+            else: #alle
+               add=add & True
+                    
+            if add:
+                projectListe.append(obj)
+                
+        #logging.error("getprojectsofmember projectliste: %s"%repr(projectListe))
+        return projectListe
+
+
+    def givePersonList(self,name):
+        """check if person is in personfolder and return list of person objects"""
+        
+        splitted=name.split(",")
+        if len(splitted)==1:
+            splitted=name.lstrip().rstrip().split(" ")
+        splittedNew=[split.lstrip() for split in splitted]
+        
+        if splittedNew[0]=='':
+            del splittedNew[0]
+        search=string.join(splittedNew,' AND ')
+        
+        if not search=='':
+            proj=self.MembersCatalog({'title':search})
+
+        if proj:
+            return [[x.lastName,x.firstName] for x in proj]
+        else:
+            return []
+            
+##         splitted=name.split(",") # version nachname, vorname...
+##         if len(splitted)>1:
+##             lastName=splitted[0] 
+##             firstName=splitted[1]
+##         else: 
+##             splitted=name.split(" ") #version vorname irgenwas nachnamae
+        
+##             lastName=splitted[len(splitted)-1]
+##             firstName=string.join(splitted[0:len(splitted)-1])
+
+##         objs=[]
+
+        #print  self.members 
+      ##   for x in self.members.__dict__:
+##             obj=getattr(self.members,x)
+##             if hasattr(obj,'lastName') and hasattr(obj,'firstName'):
+                
+##                 if (re.match(".*"+obj.lastName+".*",lastName) or re.match(".*"+lastName+".*",obj.lastName)) and (re.match(".*"+obj.firstName+".*",firstName) or re.match(".*"+firstName+".*",obj.firstName)):
+                    
+##                     objs.append((obj,lastName+", "+firstName))
+
+        
+##        return objs
+
+
+    def personCheck(self,names):
+        """all persons for list"""
+        #print "names",names
+        splitted=names.split(";")
+        ret={}
+        for name in splitted:
+
+            if not (name==""):
+                try:
+                    ret[name]=self.givePersonList(name)
+                except:
+                    """NOTHIHN"""
+        #print "RET",ret
+        return ret
+
+    def giveCheckList(self,person,fieldname):
+        """return checklist"""
+        #print "GCL",fieldname
+        if fieldname=='xdata_01':
+            x=self.personCheck(person.getContent(fieldname))
+            #print "GCLBACKX",x
+            return x
+        
+
+    # TODO: do we need this here?
+    def isCheckField(self,fieldname):
+        """return chechfield"""
+        return (fieldname in checkFields)
+
+    
+
+    def sortResults(self,results):
+        """search the catalog and give results back sorted by meta_type"""
+        ret = {}
+        logging.debug(results())
+        for result in results():
+            metaType = result.meta_type
+            resultList= ret.get(metaType,[])
+            resultList.append(result)
+            ret[metaType]=resultList
+        
+        logging.debug(ret)
+        return ret
+        
+    # TODO: remove
+    def isActiveMember(self,key):
+        """tested ob Mitarbeiter key ist aktiv"""
+        key=utf8ify(key)
+        ret=getAt(self.ZSQLInlineSearch(_table='personal_www',
+                                            _op_key='eq',key=key,
+                                            _op_publish_the_data='eq',
+                                            publish_the_data='yes'), 0)
+        
+        logging.info("MPIWGROOT ACTIVE_MEMBER  %s"%ret)
+        if ret:
+            return True
+        else:
+            return False
+        
+    # TODO: remove
+    def isActual(self,project):
+        """checke if project is actual"""
+        actualTime=time.localtime()
+        
+        if hasattr(project,'getObject'): #obj ist aus einer catalogTrefferList
+            obj=project.getObject()
+        else:
+            obj=project
+            
+        if getattr(obj,'archiveTime',actualTime)< actualTime:
+            return False
+        else:
+            return True
+   
+
+    def getTree(self,dep=None,date=None,onlyActive=0,onlyArchived=0):
+        """generate Tree from project list
+        als Liste, jeder Eintrag ist ein Tupel (Tiefe, ProjektNummer, Titel, ProjektObject)
+        onlyActive = 0  : alle Projekte
+        onlyActive = 1 : nur active Projekte
+        onlyActive = 2: nur inactive Projekte
+        
+        onlyArchived=0: alle Projekte
+        onlyArchived= 1 : nur aktuelle Projekte
+        onlyArchived = 2: nur archivierte Projekte
+        
+        department fuer das Tree geholt werden soll
+        """
+        logging.debug("MPIWGRoot.getTree()")
+
+        returnListTmp=[]
+        returnList=[]
+        
+        for project in self.getProjectFields('xdata_05',sort="int",date=date): # get Projects sorted by xdata_05
+
+            for idNr in project[1].split(";"): # more than one number
+                if not idNr=="":
+                    splittedId=idNr.split(".")
+                    depth=len(splittedId)
+                    nr=idNr
+                    #title=project[0].WEB_title
+                    title=[project[0].getContent('WEB_title')]
+                    #print title
+                    
+                    if idNr[0]=="x": # kompatibilitaet mit alter Konvention, x vor der Nummer macht project inactive
+                        project[0].setActiveFlag(False)
+                   
+                    if (not dep) or (splittedId[0]==dep): #falls dep gesetzt ist nur dieses hinzufuegen.
+                        
+                        if (onlyActive==0):
+                            returnListTmp.append((depth,nr,title,project[0]))
+                        elif (onlyActive==1) and project[0].isActiveProject(): #nur active projekte
+                            returnListTmp.append((depth,nr,title,project[0]))
+                        elif (onlyActive==2) and (not project[0].isActiveProject()): #nur active projekte
+                            returnListTmp.append((depth,nr,title,project[0]))
+                   
+                   
+        #filter jetzt die Liste nach Archived oder nicht
+        for entry in returnListTmp:
+                    if (onlyArchived==0):
+                            returnList.append(entry)
+                    elif (onlyArchived==1) and (not entry[3].isArchivedProject()): #nur active projekte
+                            returnList.append(entry)
+                    elif (onlyArchived==2) and (entry[3].isArchivedProject()): #nur active projekte
+                            returnList.append(entry)
+                   
+        
+        return returnList
+
+    def changePosition(self,treeId,select,RESPONSE=None):
+        """Change Postion Entry"""
+        numbers=[]
+
+        # Suche hoechste bisherige nummer
+        projects=self.getProjectFields('xdata_05') # get Projects sorted by xdata_05
+        #print "pj",projects
+        for project in projects: #suche alle subtrees der treeId
+            #print treeId
+            
+            founds=re.match(treeId+"\.(.*)",project[1].split(";")[0])
+            if founds:
+                #print "x",founds.group(0),len(founds.group(0).split("."))
+                if len(founds.group(0).split("."))==len(treeId.split("."))+1: # nur ein punkt mehr, d.h. untere ebene
+                    try:
+                        numbers.append(int(founds.group(0).split(".")[len(founds.group(0).split("."))-1]))
+                    except:
+                        numbers.append(int(0))
+
+        try:
+            highest=max(numbers)
+        except:
+            highest=0
+        projects=self.showNewProjects()
+        for i in self.makeList(select):
+            highest+=10
+            projects[int(i)][0].xdata_05=treeId+"."+str(highest)
+
+        if RESPONSE is not None:
+            RESPONSE.redirect('showTree')
+        
+    def changeTree(self,RESPONSE=None):
+        """change the complete tree"""
+        form=self.REQUEST.form
+        hashList={}
+        onlyArchived=int(form.get("onlyArchived",0))
+        onlyActive=int(form.get("onlyActive",0))
+        dep=form.get("dep",None)
+        
+        fields=self.getTree(dep=dep,onlyArchived=onlyArchived,onlyActive=onlyActive)
+        
+        logging.info("GOT TREE!----------------------------------------------------")
+        for field in form.keys():
+            
+            splitted=field.split('_')
+            if (len(splitted)>1) and (splitted[1]=="runningNumber"): #feld hat die Form Nummer_name und runnignNumber
+            
+                
+                nr=int(splitted[0]) # nummer des Datensatzes
+                currentEntry = fields[nr]
+            
+                if form.has_key(str(nr)+'_active'): # active flag is set
+                    fields[nr][3].setActiveFlag(True)
+                else:
+                    fields[nr][3].setActiveFlag(False)
+                    
+                #nummer hat sich geaendert
+                
+                entryChanged = False;
+                
+                if isinstance(fields[nr][3].xdata_05,list): #for some reasons somtimes the content of the field is a list with one entry.
+                    fields[nr][3].xdata_05=fields[nr][3].xdata_05[0]
+                    
+                if not (fields[nr][3].xdata_05==form[str(nr)+'_number']):
+                    logging.info("Changed!Number+++++++++++++++++++++++++++++++++")
+                    logging.info(repr(fields[nr][3].xdata_05)+" ---> "+ repr(form[str(nr)+'_number']))
+                    fields[nr][3].xdata_05=form[str(nr)+'_number']
+                    entryChanged = True
+                    
+                #completed har sich geaendert
+                          
+                td = fields[nr][3].transformDate # hole die funktion zum transformieren des datums
+                  
+                if not (td(fields[nr][3].getCompletedAt())==td(form[str(nr)+'_completed'])):
+                    fields[nr][3].setCompletedAt(form[str(nr)+'_completed'])
+                    logging.info(repr(td(fields[nr][3].getCompletedAt()))+" ---> "+ repr(td(form[str(nr)+'_completed'])))
+                    logging.info("Changed!Completed+++++++++++++++++++++++++++++++++")
+                    entryChanged = True
+                
+                if not (td(fields[nr][3].getStartedAt())==td(form[str(nr)+'_started'])):
+                    fields[nr][3].setStartedAt(form[str(nr)+'_started'])
+            
+                    logging.info(repr(td(fields[nr][3].getStartedAt()))+" ---> "+ repr(td(form[str(nr)+'_started'])))
+                    logging.info("Changed!Started+++++++++++++++++++++++++++++++++")
+                    entryChanged = True
+                
+                
+                if entryChanged:
+                    logging.info("Changed!+++++++++++++++++++++++++++++++++")
+                    fields[nr][3].copyObjectToArchive()
+                
+                    
+        if RESPONSE is not None:
+            RESPONSE.redirect('showTree')
+
+
+
+    def getProjectWithId(self,id):
+        fields=self.getProjectFields('xdata_05')
+        for field in fields:
+            if field[1]==id:
+                return field[0]
+
+        return None
+            
+        
+            
+    def reindexCatalogs(self,RESPONSE=None):
+        """reindex members and project catalog"""
+        
+        
+        try:
+            
+            self.ProjectCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
+            logger("MPIWG Root (reindexCatalog: projects)",logging.INFO,"DONE")
+        except:
+            logger("MPIWG Root (reindexCatalog: projects)",logging.WARNING," %s %s"%sys.exc_info()[:2])
+        
+        try:
+            
+            self.MembersCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
+            logger("MPIWG Root (reindexCatalog: members)",logging.INFO,"DONE")
+        except:
+            logger("MPIWG Root (reindexCatalog: members)",logging.WARNING," %s %s"%sys.exc_info()[:2])
+        
+        
+#        
+#        try:
+#            
+#            self.fulltextProjectsMembers.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
+#            logger("MPIWG Root (reindexCatalog: fulltextProjectsMembers)",logging.INFO,"DONE")
+#        except:
+#            logger("MPIWG Root (reindexCatalog: fulltextProjectsMembers)",logging.WARNING," %s %s"%sys.exc_info()[:2])
+#            
+#        
+#        
+#        
+        
+        
+        if RESPONSE:
+            RESPONSE.redirect('manage_main')
+
+                
+
+    def getProjectsByFieldContent(self,fieldName,fieldContentsEntry, date=None):
+        """gib alle Projekte aus mit Value von field mit fieldName enthaelt ein Element der Liste fieldContents"""
+        def sort(x,y):
+                return cmp(x.WEB_title[0],y.WEB_title[0])
+
+        if type(fieldContentsEntry) is StringType:
+            fieldContentsTmp=[fieldContentsEntry]
+        else:
+            fieldContentsTmp=fieldContentsEntry
+
+        fieldContents=[]
+        for x in fieldContentsTmp:
+            fieldContents.append(" AND ".join(x.split()))
+        projects=self.ProjectCatalog({fieldName:string.join(fieldContents,' AND')})
+        #print projects
+        #ret=[x for x in projects]
+        ret=[]
+        for x in projects:
+            obj=x.getObject()
+            obj=obj.getActualVersion(date)
+            if obj and (not getattr(obj,'invisible',None)):
+                #if not (x in ret):
+                    ret.append(x)
+
+        ret.sort(sort)
+        return ret
+
+  
+    def getProjectFields(self,fieldName,date=None,folder=None,sort=None):
+        """getListofFieldNames"""
+        ret=[]
+    
+        objects=self.ZopeFind(self.projects,obj_metatypes=['MPIWGProject'],search_sub=0)
+
+                
+        for object in objects:
+            obj=object[1]
+            obj=obj.getActualVersion(date)
+            if obj and (not getattr(obj,'invisible',None)):
+                if fieldName=="WEB_title_or_short":
+
+                    if len(obj.getContent('xdata_07'))<3: # hack weil z.Z. manchmal noch ein Trennzeichen ; oder , im Feld statt leer
+                        fieldNameTmp="WEB_title"
+                    else:
+                        fieldNameTmp="xdata_07"
+                else:
+                    fieldNameTmp=fieldName
+
+                ret.append((obj,obj.getContent(fieldNameTmp)))
+
+        
+        if sort=="int":
+            ret.sort(sortI)
+        elif sort=="stopWords":
+ 
+            ret.sort(sortStopWords(self))
+            
+        else:
+            ret.sort(sortF)
+        
+        return ret
+
+    def showNewProjects(self):
+        projects=[]
+        for objs in self.getProjectFields('WEB_title_or_short'): # Get all Projets
+            if objs[0].xdata_05 and (objs[0].xdata_05[0] == ""):
+                
+                projects.append(objs)
+                
+        return projects
+    
+    def generateUrlProject(self,url,project=None):
+        """erzeuge aus absoluter url, relative des Projektes"""
+        if project:
+            splitted=url.split("/")
+            length=len(splitted)
+            short=splitted[length-2:length]
+            
+            base=self.REQUEST['URL3']+"/"+"/".join(short)
+
+        else:
+            findPart=url.find("/projects/")
+            base=self.REQUEST['URL1']+"/"+url[findPart:]
+
+                
+        return base
+    
+
+    def versionHeaderEN(self):
+        """version header text"""
+        
+        date= self.REQUEST.get('date',None)
+        if date:
+            txt="""<h2>This pages shows the project which existed at %s</h2>"""%str(date)
+            return txt
+        return ""
+
+    def versionHeaderDE(self):
+        """version header text"""
+        date= self.REQUEST.get('date',None)
+        if date:
+            txt="""<h2>Auf dieser Seite finden Sie die Projekte mit Stand vom %s</h2>"""%str(date)
+        return ""
+    
+        
+    def getContexts(self,childs=None,parents=None,depth=None,date=None,onlyActive=True):
+        """childs alle childs, alle parents"""
+        ret=[]
+    
+        if parents:
+            pnums=parents.split(".")
+            while len(pnums) > 1:
+                pnums.pop()
+                parentId=string.join(pnums,".")
+        
+                for project in self.getProjectFields('xdata_05',sort='int',date=date):
+                    if project[1]==parentId:
+                        ret.append(project)
+                
+                if (depth is not None) and (len(ret) >= depth):
+                    break
+
+        if childs:
+            for project in self.getProjectFields('xdata_05',sort='int',date=date):
+                searchStr=childs+"(\..*)"
+               
+                if (onlyActive and project[0].isActiveProject()) or (not onlyActive):
+                    if re.match(searchStr,project[1]):
+                        
+                        if depth:
+    
+                            if int(depth)>=len(project[1].split("."))-len(childs.split(".")):
+                        
+                                ret.append(project)
+                        else:
+                            ret.append(project)
+        
+        #logging.debug("getContexts: childs=%s parents=%s depth=%s => %s"%(childs,parents,depth,repr(ret)))
+     
+        return ret
+
+
+      
--- a/SrvTxtUtils.py	Tue Apr 30 16:31:57 2013 +0200
+++ b/SrvTxtUtils.py	Tue Apr 30 16:35:52 2013 +0200
@@ -10,7 +10,9 @@
 import urllib2
 import logging
 
-srvTxtUtilsVersion = "1.6"
+import xml.etree.ElementTree as ET
+
+srvTxtUtilsVersion = "1.7"
 
 map_months = {'en': [u"",
                u"January",
@@ -76,7 +78,7 @@
         return s.encode('utf-8')
 
 def getText(node, recursive=0):
-    """returns all text content of a node and its subnodes"""
+    """returns all text content of a (etree) node and its subnodes"""
     if node is None:
         return ''
     
@@ -99,6 +101,18 @@
     
     return text
 
+
+def serialize(node):
+    """returns a string containing an XML snippet of (etree) node"""
+    s = ET.tostring(node, 'UTF-8')
+    # snip off XML declaration
+    if s.startswith('<?xml'):
+        i = s.find('?>')
+        return s[i+3:]
+
+    return s
+
+
 def getMonthName(mon, lang):
     """returns the name of the month mon in the language lang"""
     return map_months[lang][mon]
--- a/zpt/MPIWGProject_index.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-<html>
-<body>
-<table border="1">
-<tr tal:repeat="field here/getDefinedFields">
-<td valign="top" tal:content="field"/>
-<!--<td tal:repeat="attr python:here.getAttribute(field)" tal:content="structure python:attr.encode('ascii','ignore')"/>-->
-<td tal:repeat="attr python:here.getAttribute(field)" tal:content="structure python:attr"/>
-</tr>
-</table>
-</body>
-</html>
-
-
--- a/zpt/MPIWGProject_newfile.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<html>
-<head>
-   <title>The title</title>
-</head>
-<body>
-
-<div>
-
-<h1>Project-Upload</h1>
-<form method="post" action="loadNewFile" enctype="multipart/form-data">
-
-<p>File:</p>
-<input type="file" name="fileupload"/>
-<input type="submit">
-</form>
-</div>
-</body>
-</html>
--- a/zpt/MPIWGProject_versionManageForm.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-<h1>Set invisible</h1>
-<form action="versionManage">
-<input type="checkbox" name="invisible">Invisible<br/>
-<input type="submit" value="submit">
-</form>
--- a/zpt/edit_MPIWGBasis.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-</head>
-<body>
-<form method="POST" action="editMPIWGProject">
-<h2>Basis Information for <span tal:replace="here/getId"/></h2>
-<table>
-<tr>
-<td>Project Title</td>
-<td><input tal:attributes="name python:'WEB_title'; value python:here.getContent('WEB_title')" size=100/></td>
-</tr>
-<tal:block tal:repeat="field here/getDataFields">
-<tr>
-<td tal:content="python:here.fieldLabels[field]"/>
-<td> <input tal:attributes="name field; value python:here.getContent(field)" size=100/></td>
-</tr>
-<tr tal:condition="python:here.isCheckField(field)">
-<td colspan=2 height="20">
-<tal:block  tal:define="checkList python:here.giveCheckList(here,field)">
-<tal:block  repeat="item checkList/keys">
-<span tal:replace="item"/>:
-<tal:block tal:condition="python:len(checkList[item])>0">
-found
-</tal:block>
-<tal:block tal:condition="not:python:len(checkList[item])>0">
-<font color="#ff0000">not found</font>
-</tal:block>
-
-
-<!--<input tal:repeat="prop python:checkList[item]" 
-       type="radio" 
-       tal:attributes="name python:'val_%s'%field; value python:prop[0].getId()" 
-       tal:content="python:prop[1]"/>-->
-</tal:block>
-<br>
-</tal:block>
-</td>
-</tr>
-</tal:block>
-</table>
-
-  
-<input type="submit">
-</form>
-</body>
-</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zpt/project/description_only_html.zpt	Tue Apr 30 16:35:52 2013 +0200
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+</head>
+<body>
+  <div tal:replace="structure here/getDescription"/>
+</body>
+</html>
--- a/zpt/project/edit_basic.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ b/zpt/project/edit_basic.zpt	Tue Apr 30 16:35:52 2013 +0200
@@ -11,28 +11,15 @@
       <table>
         <tr>
           <td><b>Project Title</b></td>
-          <td><input tal:attributes="name python:'WEB_title'; value python:here.getContent('WEB_title')" size="80" /></td>
+          <td><input name="WEB_title" tal:attributes="value python:here.getProjectTitle()" size="80" /></td>
         </tr>
-        <tal:block tal:repeat="field here/getDataFields">
+        <tal:block tal:repeat="field here/getEditableFields">
           <tr>
             <td><b tal:content="python:here.fieldLabels[field]" /></td>
             <td><input tal:attributes="name field; value python:here.getContent(field)" size=80 /></td>
           </tr>
-          <tr tal:condition="python:here.isCheckField(field)">
-            <td />
-            <td><tal:block tal:define="checkList python:here.giveCheckList(here,field)">
-                <tal:block repeat="item checkList/keys">
-                  <span tal:replace="item" />: 
-                  <tal:block tal:condition="python:len(checkList[item])>0">found</tal:block>
-                  <tal:block tal:condition="not:python:len(checkList[item])>0">
-                    <font color="#ff0000">not found</font>
-                  </tal:block>
-                </tal:block>
-                <br />
-              </tal:block></td>
-          </tr>
         </tal:block>
-        <tr tal:define="hasChildren python:here.hasChildren()">
+        <tr tal:define="hasChildren here/getSubProjects">
           <td>Project is visible</td>
           <tal:x tal:condition="python:hasChildren and here.isActiveProject()">
             <td>visible (status cannot be changed, because the project has visible children.) <input
@@ -65,6 +52,9 @@
 
       <h2>Names</h2>
       <table tal:define="global count python:0">
+        <tr>
+          <th>Name in project</th><th>MPIWG member object</th>
+        </tr>
         <tr tal:repeat="identifiedName python:options.get('identifiedNames',{}).items()">
           <tal:x tal:define="global count python:count+1" />
           <td><input type="hidden"
--- a/zpt/project/edit_description.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ b/zpt/project/edit_description.zpt	Tue Apr 30 16:35:52 2013 +0200
@@ -3,7 +3,7 @@
 <html metal:use-macro="here/edit_template/macros/page" xmlns:metal="http://xml.zope.org/namespaces/metal" >
 <head>
 <metal:block metal:fill-slot="html_head">
-<metal:macros xmlns:metal="http://xml.zope.org/namespaces/metal" use-macro="here/kupuEditor/kupumacros/macros/head">
+<metal:macros use-macro="here/kupuEditor/kupumacros/macros/head">
   <metal:macros fill-slot="bootstrap-editor">
     <script type="text/javascript" src="/kupuEditor/kupuinit_form.js"> </script>
     <script type="text/javascript" src="/kupuEditor/kupustart_form.js"> </script>
@@ -54,11 +54,11 @@
       <metal:macros fill-slot="editorframe">
         <tal:block tal:condition="not:python:here.REQUEST.get('fromPreview',None)">
           <iframe class="kupu-editor-iframe" id="kupu-editor" frameborder="0" scrolling="auto" src="fulldoc"
-            tal:attributes="src python:here.absolute_url()+'/getWebProject_description'"> </iframe>
+            tal:attributes="src python:here.absolute_url()+'/description_only_html'"> </iframe>
         </tal:block>
         <tal:block tal:condition="python:here.REQUEST.get('fromPreview',None)">
           <iframe class="kupu-editor-iframe" id="kupu-editor" frameborder="0" scrolling="auto" src="fulldoc"
-            tal:attributes="src python:here.absolute_url()+'/previewTemplate/getWebProject_description'"> </iframe>
+            tal:attributes="src python:here.absolute_url()+'/previewTemplate/description_only_html'"> </iframe>
         </tal:block>
       </metal:macros>
     </metal:macros>
--- a/zpt/project/edit_related_projects.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ b/zpt/project/edit_related_projects.zpt	Tue Apr 30 16:35:52 2013 +0200
@@ -10,14 +10,14 @@
     <tal:block tal:repeat="publication here/getRelatedProjects">
       <tr>
         <td>
-          <a tal:attributes="href python:here.absolute_url()+'/manageRelatedProjects?pubName='+publication[0]+'&op=up'">up</a><br>
-          <a tal:attributes="href python:here.absolute_url()+'/manageRelatedProjects?pubName='+publication[0]+'&op=down'">down</a>
+          <a tal:attributes="href python:here.absolute_url()+'/manageRelatedProjects?pubName='+publication.getId()+'&op=up'">up</a><br>
+          <a tal:attributes="href python:here.absolute_url()+'/manageRelatedProjects?pubName='+publication.getId()+'&op=down'">down</a>
         </td>
-        <td tal:content="structure python:getattr(publication[1],'objid','')" />
-        <td tal:content="structure python:getattr(publication[1],'projectWEB_title','')" />
+        <td tal:content="structure python:getattr(publication,'objid','')" />
+        <td tal:content="structure python:getattr(publication,'projectWEB_title','')" />
         <td>
-          <a tal:attributes="href python:publication[1].getId()+'/editRelatedProject'">Edit</a><br/> 
-          <a tal:attributes="href python:'deleteRelatedProject?id='+publication[1].getId()">Delete</a>
+          <a tal:attributes="href python:publication.getId()+'/editRelatedProject'">Edit</a><br/> 
+          <a tal:attributes="href python:'deleteRelatedProject?id='+publication.getId()">Delete</a>
         </td>
       </tr>
     </tal:block>
--- a/zpt/project/edit_template.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ b/zpt/project/edit_template.zpt	Tue Apr 30 16:35:52 2013 +0200
@@ -1,6 +1,7 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html metal:define-macro="page">
+<html xmlns="http://www.w3.org/1999/xhtml"
+  metal:define-macro="page">
 <head tal:define="global onload nothing;">
 <metal:block metal:define-slot="html_head"/>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zpt/project/manage_newfile.zpt	Tue Apr 30 16:35:52 2013 +0200
@@ -0,0 +1,17 @@
+<html>
+<head>
+</head>
+<body>
+  <div tal:replace="structure here/manage_page_header">Header</div>
+  <!-- ZOPE management tabs -->
+  <h2 tal:define="manage_tabs_message options/manage_tabs_message | nothing" tal:replace="structure here/manage_tabs">Tabs</h2>
+  <!-- end of ZOPE management tabs -->
+
+  <h1>Upload new project</h1>
+  <form method="post" action="loadNewFile" enctype="multipart/form-data">
+
+    <p>File:</p>
+    <input type="file" name="fileupload" /> <input type="submit">
+  </form>
+</body>
+</html>
--- a/zpt/project/project_template.zpt	Tue Apr 30 16:31:57 2013 +0200
+++ b/zpt/project/project_template.zpt	Tue Apr 30 16:35:52 2013 +0200
@@ -30,8 +30,8 @@
     <h1 tal:content="here/getProjectTitle">History of Scientific Objectivity, 18th-19th Cs</h1>
     <p class="maintext_authors">
       <tal:block tal:repeat="person here/getResponsibleScientistsList">
-          <a tal:omit-tag="python:not (person['username'] and here.getStaffFolder().isActiveMember(key=person['key']))"
-            tal:attributes="href string:$root/${secmap/staff}/members/${person/username}" tal:content="person/name"> Name of
+          <a tal:define="username person/username|nothing" tal:omit-tag="python:not username or not here.getStaffFolder().isActiveMember(key=person.get('key',None))"
+            tal:attributes="href string:$root/${secmap/staff}/members/$username" tal:content="person/name"> Name of
             responsible person</a><tal:block tal:condition="not:repeat/person/end">, </tal:block>
       </tal:block>
     </p>
@@ -60,7 +60,7 @@
     </div>
     <!-- inline image -->
 
-    <div tal:content="structure python:here.getDescription()">Project description</div>
+    <div tal:content="structure python:here.getDescription(filter=True)">Project description</div>
 
   </div>