--- MPIWGWeb/MPIWGProjects.py 2004/02/09 08:57:27 1.3 +++ MPIWGWeb/MPIWGProjects.py 2009/12/15 13:16:47 1.47.2.111 @@ -1,221 +1,555 @@ -"""This files contains the class MPIWG Projects""" +"""This contains the class MPIWG Projects +for organizing and maintaining the different project pages + +$author dwinter - last change 26.06.2008 + +""" from Products.PageTemplates.PageTemplateFile import PageTemplateFile -from Products.PageTemplates.PageTemplate import PageTemplate from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate - -import MPIWGStaff -import string +from Products.ZCatalog.CatalogPathAwareness import CatalogAware +from Products.MPIWGBibliography.BibliographyManager import BibliographyManager +from OFS.Image import Image +from Globals import package_home +import urllib import re - -import xmlhelper # Methoden zur Verwaltung der projekt xmls +import os +import email +from types import * +import logging +import xmlhelper # Methoden zur Verwaltung der projekt xml from OFS.SimpleItem import SimpleItem from OFS.Folder import Folder +from OFS.Image import Image +from AccessControl import ClassSecurityInfo +from AccessControl import getSecurityManager +from bibliography import * +import time +from OFS.Cache import Cacheable +#import xml.dom.minidom +import sys +#from Ft.Xml.XPath import Evaluate +#from Ft.Xml.XPath.Context import Context +#from Ft.Xml.Domlette import NonvalidatingReader,PrettyPrint, Print +#from Ft.Xml import EMPTY_NAMESPACE +#import copy +#import updatePersonalWWW + +#import MPIWGStaff + +from MPIWGHelper import * + +import MPIWGRoot +import MPIWGLink +import MPIWGTemplate -definedFields=['WEB_title','xdata_01','xdata_02','xdata_03','xdata_04','xdata_05','xdata_06','xdata_07','xdata_08','xdata_09','xdata_10','xdata_11','xdata_12','xdata_13','WEB_project_header','WEB_project_description','WEB_related_pub'] +# die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus Kompatibilitaetsgruenden, bleiben die Klassen hier noch drin. +# Sonst funktionieren die alten Webseiten nicht mehr. -checkFields = ['xdata_01'] +class MPIWGRoot(MPIWGRoot.MPIWGRoot): + """depricated""" + +class MPIWGLink(MPIWGLink.MPIWGLink): + """depricated""" + +class MPIWGTemplate(MPIWGTemplate.MPIWGTemplate): + """depricated""" + +class MPIWGProject_publication(Folder): + """publications object fuer project""" -def sortF(x,y): + meta_type="MPIWGProject_publication" + def redirect(self,RESPONSE,url): + """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen""" + + timeStamp=time.time() + + if url.find("?")>-1: #giebt es schon parameter + addStr="&time=%s" + else: + addStr="?time=%s" + + RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT') + logging.debug(email.Utils.formatdate()+' GMT') + RESPONSE.redirect(url+addStr%timeStamp) + + def editPublication(self,text=None,image1=None,image2=None,description=None,RESPONSE=None): + """edit a publication""" + + if (not text) and (not description): + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_publicationForm.zpt')).__of__(self) + return pt() + + + self.text=text[0:] + self.description=description + + if image1: + if hasattr(self,'publicationImage1'): + self.publicationImage1.manage_upload(image1) + else: + nO = Image('publicationImage1','',image1) + self._setObject('publicationImage1',nO) + + if image2: + if hasattr(self,'publicationImage2'): + self.publicationImage2.manage_upload(image2) + else: + nO = Image('publicationImage2','',image2) + self._setObject('publicationImage2',nO) + + + if RESPONSE: + self.redirect(RESPONSE,"../managePublications") + +class MPIWGProject_image(Image): + """Images for Projects""" + + meta_type="MPIWGProject_image" + + def showImage(self,imageUrl=None): + """show Images at an extra page""" + 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 editImage(self,file=None,caption=None,RESPONSE=None): + """edit the Image""" + if (not file) and (not caption): + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_imageForm.zpt')).__of__(self) + return pt() + + if file and (not file.filename.lstrip().rstrip()==""): + self.manage_upload(file) + + if caption: + self.caption=caption[0:] + + if RESPONSE: + + self.redirect(RESPONSE,"../manageImages") - return cmp(x[1],y[1]) +class MPIWGProject(CatalogAware,Folder,Cacheable): + """Class for Projects""" + + def _p_resolveConflict(self, oldState, savedState, newState): + return newState -class MPIWGRoot(Folder): - """Stammordner für den Web-Server""" + security=ClassSecurityInfo() + meta_type='MPIWGProject' + default_catalog='ProjectCatalog' + def redirect(self,RESPONSE,url): + """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen""" + + timeStamp=time.time() + + if url.find("?")>-1: #giebt es schon parameter + addStr="&time=%s" + else: + addStr="?time=%s" + + RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT') + logging.debug(email.Utils.formatdate()+' GMT') + RESPONSE.redirect(url+addStr%timeStamp) + + def decode(self,str): + """return unicode object""" + return unicodify(str) + + 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)) - folders=['MPIWGProject','Folder'] - meta_type='MPIWGRoot' + founds=self.ZopeFind(self,obj_metatypes=[metatype]); + + founds.sort(sort) + + return founds - def __init__(self, id, title): - """init""" - self.id=id - self.title=title - def getProjectFields(self,fieldName,folder=None): - """getListofFieldNames""" - ret=[] - #print "FN",fieldName - if not folder: - folder=self - for object in folder.__dict__: + def copyPublicationsToList(self,RESPONSE=None): + """copy publications in to list""" + + publicationTxt=self.getContent('WEB_related_pub') - obj=getattr(folder,object) - if hasattr(obj,'meta_type'): + pubSplits=publicationTxt.split("

") + + for pubSplit in pubSplits: + pubSplit=pubSplit.replace("

","") + self.addPublication(pubSplit) + + if RESPONSE: + + self.redirect(RESPONSE,'managePublications') + + + 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("""

""") + + imageURLs=[] + imageCaptions=[] + for split in splitted[1:]: + tmp=split.split("

") + #return repr(splitted[1]) - if obj.meta_type=='MPIWGProject': - - ret.append((obj,obj.getContent(fieldName))) - if obj.meta_type in self.folders: + try: + imageURLs.append(tmp[0].split("\"")[1].encode('utf-8')) + except: - ret += self.getProjectFields(fieldName,obj) + try: + imageURLs.append(tmp[0].split("src=")[1].split(" ")[0].encode('utf-8')) + except: + imageURLs.append("") + + split2="

".join(tmp[1:]) + + + splitted=split2.split("""

""") + if len(splitted)>1: + tmp=splitted[1].split("

") + 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 - ret.sort(sortF) + 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) - return ret + if RESPONSE: + + self.redirect(RESPONSE,'manageImages') + + def manageImages(self,imageName=None,op=None): + """managage images""" - manage_options = Folder.manage_options+( - {'label':'Import Persons','action':'importNamesForm'}, - ) - - def importNamesForm(self): - """Form""" - pt=PageTemplateFile('Products/MPIWGWeb/zpt/MPIWGNamesForm.zpt').__of__(self) + + 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(os.path.join(package_home(globals()),'zpt','MPIWGProject_manageImagesForm.zpt')).__of__(self) return pt() - def importNames(self,fileupload,folderName,RESPONSE=None): - """import komma-sep list email,lastName,firstName""" - project=getattr(self,folderName) - - for line in fileupload.readlines(): - print line - splitted=line.split(",") - if not (splitted[0]==""): - newObj=MPIWGStaff.MPIWGStaff(splitted[0],splitted[1],splitted[2]) - try: - project._setObject(splitted[0],newObj) - except: - print "not done:",splitted[0] - if RESPONSE is not None: - RESPONSE.redirect('manage_main') + def managePublications(self,pubName=None,op=None): + """managage images""" - def getAllMembers(self): - """give list of all members""" - ret=[] - for x in self.members.objectValues('MPIWGStaff'): - print x.title - ret.append(x.title) - - ret.sort() - return ret + 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(os.path.join(package_home(globals()),'zpt','MPIWGProject_managePublicationsForm.zpt')).__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 getUrlFromPerson(self,list): - """get urls to person list""" - ret=[] - persons=list.split(";") - for person in persons: - splitted=person.split(",") - if len(splitted)==1: - splitted=person.split(" ") - splittedNew=[re.sub(r'\s(.*)','$1',split) for split in splitted] - if splittedNew[0]=='': - del splittedNew[0] - search=string.join(splittedNew,' AND ') - if not search=='': - proj=self.MembersCatalog({'title':search}) - print search,"PER",person,splittedNew,proj - - if proj: - ret.append("%s"%(proj[0].absolute_url,person)) - else: - ret.append("%s"%person) - return string.join(ret,";") - - def getProjectsOfMembers(self): - """give tuple member /projects""" - ret=[] - members=self.getAllMembers() - for x in members: - splitted=x.split(",") - - proj=self.ProjectCatalog({'xdata_01':string.join(splitted,' AND')}) - if proj: - ret.append((x,proj)) - return ret - def givePersonList(self,name): - """check if person is in personfolder and return list of person objects""" + 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']) - splitted=name.split(",") - if len(splitted)==1: - splitted=name.split(" ") - splittedNew=[re.sub(r'\s(.*)','$1',split) 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)) + publications.sort(sort_images) + return publications + + def addPublication(self,text,RESPONSE=None): + """add an MPIWG_Publication""" + name="publication_"+str(self.getLastPublicationNumber()+1) - return objs + 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 + + if RESPONSE is not None: + + self.redirect(RESPONSE,'managePublications') - def personCheck(self,names): - """all persons for list""" - print "names",names - splitted=names.split(";") - ret={} - for name in splitted: + + def getLastPublicationNumber(self): + publications=self.getPublications() + + 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]) + if RESPONSE: + + self.redirect(RESPONSE,'managePublications') + + def getImages(self): + """get all Images""" - if not (name==""): - try: - ret[name]=self.givePersonList(name) - except: - """NOTHIHN""" - print "RET",ret - return ret + def sort_images(x,y): + return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0)) + + + if (getattr(self,'imageURL','')!='') or (getattr(self,'imagecap','')!='') : + try: + self.addImage(None,getattr(self,'imagecap',''),RESPONSE=None,filename=getattr(self,'imageURL','')) + except: + pass + self.imageURL='' + self.imagecap='' - 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 + images=self.ZopeFind(self,obj_metatypes=['MPIWGProject_image']) + images.sort(sort_images) + return images - def isCheckField(self,fieldname): - """return chechfield""" + def getLastImageNumber(self): + images=self.getImages() + + if not images: + return 0 + else: + return getattr(images[-1][1],'place',0) - return (fieldname in checkFields) + def deleteImage(self,id,RESPONSE=None): + """delete Image id""" + try: + self.manage_delObjects([id]) + except: + logging.error("ERROR MPIWG: %s %s"%sys.exc_info()[0:2]) + if RESPONSE: + self.redirect(RESPONSE,'manageImages') - - + + + def hasChildren(self,date=None,onlyActive=1,onlyArchived=1): + """check if project has children""" -def manage_addMPIWGRootForm(self): - """form for adding the root""" - pt=PageTemplateFile('Products/MPIWGWeb/zpt/addMPIWGRootForm.zpt').__of__(self) - return pt() + 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 manage_addMPIWGRoot(self,id,title,RESPONSE=None): - """add a root folder""" - newObj=MPIWGRoot(id,title) - self._setObject(id,newObj) + + def addImage(self,fileHd,caption,RESPONSE=None,filename=None): + """add an MPIWG_Project_image""" - if RESPONSE is not None: - RESPONSE.redirect('manage_main') + if not filename: + filename=fileHd.filename + + if not fileHd: + fileHd=file(os.path.join(package_home(globals()),'blank.gif')) + + newImage=MPIWGProject_image(filename,filename,fileHd) + + self._setObject(filename,newImage) + obj=getattr(self,filename) + obj.caption=caption[0:] + obj.enabled=True; + obj.place=self.getLastImageNumber()+1 + obj.id=filename + + if RESPONSE is not None: + + self.redirect(RESPONSE,'manageImages') + + def PrincipiaSearchSource(self): + """Return cataloguable key for ourselves.""" + return str(self) + + def versionHeader(self): + """version Header, gibt header text entsprechend der aktuellen version aus""" + actualTime=time.localtime() + retTXT="""

This is an outdated version, for the actual version please refer to %s

""" + s=self.aq_parent.absolute_url() + #print getattr(self,'archiveTime',actualTime) + if getattr(self,'archiveTime',actualTime)< actualTime: + return retTXT%(s,s) + else: + return "" -class MPIWGProject(Folder): - """Class for Projects""" + def getActualVersion(self,date=None): + """actuelle version""" + def sortProjectsByTime(x,y): + return cmp(x[1].archiveTime,y[1].archiveTime) + + if not date: + if self.isActual(): + return self + else: + return None - meta_type='MPIWGProject' + #suche ob aeltere versionen vorhanden sind + + finds=self.ZopeFind(self,obj_metatypes=['MPIWGProject']) + if not finds: #wenn nicht dann teste ob die aktuelle version schon existiert hat. + ad=getattr(self,'creationTime','20050101000000') + if int(date)>int(ad): + return self + else: + return None + + + else: + finds.sort(sortProjectsByTime) + + for find in finds: + #gehe durch die alten Projekte und finde das entprechende + if (int(find[1].archiveTime) > int(date)) and (int(date)>int(getattr(find[1],'creationTime','20050101000000'))): + return find[1] + + #kein passendes gefunden, dann teste ob das aktuelle in frage kommt + ad=getattr(self,'creationTime','20050101000000') + + if int(date)>int(ad): + + return self + else: + return None + + + def isActual(self): + """gibt 1 zurueck wenn aktuell, 0 sonst""" + actualTime=time.localtime() + + + #print getattr(self,'archiveTime',actualTime) + if getattr(self,'archiveTime',actualTime)< actualTime: + return 0 + else: + return 1 + + def copyObjectToArchive(self): + """kopiere aktuelles objekt ins archiv""" + cb=self.aq_parent.manage_copyObjects(self.getId()) + self.manage_pasteObjects(cb) + actualTime=time.localtime() + + self.manage_renameObject(self.getId(),self.getId()+"_"+time.strftime("%Y%m%d%H%M%S",actualTime)) + obj=getattr(self,self.getId()+"_"+time.strftime("%Y%m%d%H%M%S",actualTime)) + obj.setArchiveTime(time.strftime("%Y%m%d%H%M%S",actualTime)) + ids=[x[0] for x in self.ZopeFind(obj,obj_metatypes=['MPIWGProject'])] + obj.manage_delObjects(ids) + + def setArchiveTime(self,time): + """set Archive Time""" + self.archiveTime=time[0:] + + 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 crossLinker(self): """experimental crosslinker""" splitted=self.WEB_project_description[0].split() @@ -231,13 +565,13 @@ class MPIWGProject(Folder): new.append(split) except: new.append(split) - return string.join(new) + return " ".join(new) def generateTemplate(self,RESPONSE=None): - """Erzeuge Template für defined fields not_used""" + """Erzeuge Template fuer defined fields not_used""" id="index_html" title=id @@ -249,29 +583,304 @@ class MPIWGProject(Folder): self._setObject(id,newObj) #self.manage_addPageTemplate(id,title) if RESPONSE is not None: - RESPONSE.redirect('manage_main') + self.redirect(RESPONSE,'manage_main') - def __init__(self, id, argv): - """initieriere classe""" - + def __init__(self, id, argv=None): + """initiere classe""" + + self.creationTime=time.strftime("%Y%m%d%H%M%S",time.localtime())[0:] self.id=id self.title=id - for arg in definedFields: + self.isActiveFlag=True #Flag is true is the project is still active, False if accomplished + self.responsibleScientistsList=[] # enthaelt die Lister der verantwortlichen Wissenschaftler in der Form (NAME, KEY), key ist "" flass Wissenschaftler nicht an unserem Haus + + if argv: + for arg in definedFields: + try: + setattr(self,arg,argv[arg]) + except: + setattr(self,arg,"") + else: + for arg in definedFields: + setattr(self,arg,'') - setattr(self,arg,argv[arg]) - """NP""" manage_options = Folder.manage_options+( {'label':'Load New File','action':'loadNewFileForm'}, {'label':'Edit ProjectInfo','action':'editMPIWGProjectForm'}, {'label':'Edit BasisInfo','action':'editMPIWGBasisForm'}, {'label':'Edit Publications','action':'editMPIWGRelatedPublicationsForm'}, + {'label':'Edit Themes & Disciplines','action':'editMPIWGDisciplinesThemesForm'}, + {'label':'Versionmanager','action':'versionManageForm'}, ) + + def isActiveProject(self): + """check if the project is still active, default is true, set to false is the project is accomplished""" + return getattr(self,'isActiveFlag',True) + + def isArchivedProject(self): + """check if the project is archived""" + + completed=self.getCompletedAt() + + #completed leer + if completed=="" : + return False; + if completed == 0: + return False; + + + return True + + + def setActiveFlag(self,status=True): + """set the active flag""" + self.isActiveFlag=status + + def setCompletedAt(self,date): + """set the date of completion, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY""" + #logging.info("DATE:"+repr(date)) + transformedDate=self.transformDate(date); + #logging.info("transformed"+repr(transformedDate)) + if transformedDate is not None: + setattr(self,"completedAt",transformedDate) + return True; + else: + return False; + + def setStartedAt(self,date): + """set the date of start, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY""" + #logging.info("DATE:"+repr(date)) + transformedDate=self.transformDate(date); + #logging.info("transformed"+repr(transformedDate)) + if transformedDate is not None: + setattr(self,"startedAt",transformedDate) + return True; + else: + return False; + + def getCompletedAt(self): + """gibt das transformierte Datum zurueck, an dem das Projekt beendet wurde.""" + date=getattr(self,'completedAt','') + + if date: + return self.reTransformDate(date); + else: + return "" + # test ob parent abgeschlossen ist + try: #TODO: ersetzte try except durch vernuenftige abfrage + ct=self.getContexts(parents=self.getContent('xdata_05'),depth=1) + if (len(ct)>0): #is there are parent + return ct[0][0].getCompletedAt() + return ''; + except: + return ''; + + def getStartedAt(self): + """gibt das transformierte Datum zurŸck, an dem Projekt begonnen wurde.""" + date=getattr(self,'startedAt','') + if date: + return self.reTransformDate(date); + else: + return ''; + + def reTransformDate(self,date): + """transformiert , transformdate zurueck""" + year=int(date/10000) + month=int((date-year*10000)/100) + day=int((date-year*10000-month*100)) + if (day==0) and (month==0): + return """%s"""%year; + if day==0 : + return """%s.%s"""%(month,year); + + return """%s.%s.%s"""%(day,month,year); + + + def transformDate(self,date): + """transformiert ein Datum von DD.MM.YYYY, MM.YYYY,YYYY nach YYYYMMDD, alle nicht angebebenn Werte + werden auf 0 gesetzt, es wird null zurŸckgegeben falls das Datum ungueltig ist""" + + if (date==None): + return None; + + + if (date.lstrip().rstrip()=="" ) : + return ""; + + splitted=date.split(".") + length=len(splitted) + year=0 + month=0 + day=0 + if length > 3: + return ""; + if length==3: + day = int(splitted[0]) + if length>1: + month=int(splitted[length-2]) + + if length > 0: + try: + year = int(splitted[length-1]) + except: + pass + + ## logging.info("month:"+(month)) + if not (0<=month<13): + return None; + + if not(0<=day<32): + return None; + + if (year>0) and (year<1900): #jahr nicht vierstellig eingegeben + year=2000+year; + return year*10000+month*100+day + + + + def checkDate(self,date): + """teste ob zum Zeitpunkt date eine andere version existierte""" + + + def sortProjectsByTime(x,y): + return cmp(x[1].archiveTime,y[1].archiveTime) + + #suche ob aeltere versionen vorhanden sind + + finds=self.ZopeFind(self,obj_metatypes=['MPIWGProject']) + if not finds: #wenn nicht dann teste ob die aktuelle version schon existiert hat. + ad=getattr(self,'creationTime','20050101000000') + if int(date)>int(ad): + return self.REQUEST['URL1']+"/"+self.getId() + else: + return self.REQUEST['URL1']+"/no_project" + + + else: + finds.sort(sortProjectsByTime) + + for find in finds: + #gehe durch die alten Projekte und finde das entprechende + if (int(find[1].archiveTime) > int(date)) and (int(date)>int(getattr(find[1],'creationTime','20050101000000'))): + return self.REQUEST['URL1']+"/"+find[1].getId() + + #kein passendes gefunden, dann teste ob das aktuelle in frage kommt + ad=getattr(self,'creationTime','20050101000000') + + if int(date)>int(ad): + + return self.REQUEST['URL1']+"/"+self.getId() + else: + 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): + """seite fuer harvesting fuer die Projektsuche""" + if not context: + context=self + + if self.isActiveProject() and self.isActual(): + ext=getattr(self,"harvest_main",None) + if ext: + return getattr(self,ext.getId())() + + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','harvest_main')).__of__(context) + + + return pt() + + def index_html(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: + result = pt.pt_render(extra_context=bound_names) + 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_old(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): - ret.append('xdata_%02i'%x) + if not x in [6,10,9]: # not used fields + ret.append('xdata_%02i'%x) return ret def getDefinedFields(self): @@ -283,60 +892,503 @@ class MPIWGProject(Folder): """get attrbiute""" return getattr(self,field) - def getContent(self,field): + def getContent(self,field,filter=None): """Inhalt des Feldes""" + if field=="short_title": + text = self.getContent("xdata_07") + if text=="": + text = self.getContent("WEB_title") + return text + text=u'' - #print "FIELD",field + for x in getattr(self,field): - #print "HIHIIII" try: text +=x except: + text = x + + + + try: + if text[len(text)-1]==";": + text=text[0:len(text)-1] + + + except: + pass + + if text=='': ## wozu die folgenden Zeilen?? + text2=text + else: + text2=re.sub(r';([^\s])','; \g<1>',text) + + if field=="WEB_project_description":##Jedenfalls darf letzteres nicht gemacht werden, falls normaler text + text2=text + + #teste ob ergebnis leer und header dann nehme title + + if (text2=='') and (field=='WEB_project_header'): + return self.getContent('WEB_title') + + if filter: + splitted=text2.split("""

""") + if len(splitted)>1: + tmp=splitted[1].split("

") + #return repr(splitted[1]) try: - text =x + self.imageURL=tmp[0].split("\"")[1].encode('utf-8') except: - text="ERROR" - #print "TEXT",text - return text + try: + self.imageURL=tmp[0].split("src=")[1].split(" ")[0].encode('utf-8') + except: + self.imageURL="" + + split2="

".join(tmp[1:]) + + text3=splitted[0]+split2 + + splitted=text3.split("""

""") + if len(splitted)>1: + tmp=splitted[1].split("

") + self.imagecap=tmp[0].encode('utf-8') + + split4="".join(tmp[1:]) + + text5=splitted[0]+split4 + else: + #keine caption + text5=text3 + else: + #kein bild + text5=text2 + else: + text5=text2 + + #teste ob WEB_project_description und keine fuehrenden p tags + if (len(text5)>4) and (not text5[0:3]=='

') and (field=='WEB_project_description'): + text5= "

"+text5+"

" + + + #filter image + + text5=text5.lstrip().rstrip() #loescher leerzeichen und einzelndes br + if (text5=="
") or (text5=="
"): + text5="" + + #logging.debug("getcontent: field=%s filter=%s -> %s"%(field,filter,repr(text5))) + return unicodify(text5) + #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('Products/MPIWGWeb/zpt/MPIWGProject_index.zpt').__of__(self) + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_index.zpt')).__of__(self) return pt() - def editMPIWGProjectForm(self): - """editform""" - pt=PageTemplateFile('Products/MPIWGWeb/zpt/edit_MPIWGProject.zpt').__of__(self) + def saveFromPreview(self): + """save content aus preview""" + self.WEB_project_description=self.previewTemplate.WEB_project_description[0:] + self.REQUEST.RESPONSE.redirect("./index.html") + + def saveEditedContent(self,kupu=None,preview=None): + """save Edited content""" + + if preview: + kupu=preview + #find content of body tags + start=kupu.find("") + end=kupu.find("") + newcontent= kupu[start+6:end] + + if preview: + + return self.preview(newcontent) + + self.copyObjectToArchive() + self.ZCacheable_invalidate() + self.WEB_project_description=newcontent[0:] + + self.REQUEST.RESPONSE.redirect("./index.html") + + return True + + security.declareProtected('View management screens','edit') + def edit(self,western=None): + """Edit pages""" + if western: + self.REQUEST.RESPONSE.setCookie("MP_debug_code","western",path="/") + + + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGProjectNeu.zpt')).__of__(self) return pt() + + edit_MPIWGProject_main = PageTemplateFile('zpt/edit_MPIWGProject_main', globals()) - def editMPIWGBasisForm(self): - """editform""" - pt=PageTemplateFile('Products/MPIWGWeb/zpt/edit_MPIWGBasis.zpt').__of__(self) + 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(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 = [] + # skip direct parent Folder /projects/ + parent = self.aq_parent.aq_parent + # get parents breadcrumbs + if hasattr(parent, 'getBreadcrumbs'): + crumbs = parent.getBreadcrumbs() + + # try to get acquisition URL from parent + if hasattr(parent, 'absolute_url'): + baseUrl = "%s/%s/"%(parent.absolute_url(), 'projects') + else: + baseUrl = "/en/research/projects/" + + # add in the internal project hierarchy + + ct=self.getContexts(parents=self.getContent('xdata_05')) + # start with grandparents + ct.reverse() + for c in ct: + label = shortenString(c[0].getLabel(), 13) + crumbs.append((label, baseUrl+c[0].getId(), c[0])) + + # add this project + crumbs.append((self.getLabel(), baseUrl+self.getId(), 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 + + + def preview(self,description): + """preview""" + tmpPro=getattr(self,"previewTemplate",None) + if not tmpPro: + tmpPro=MPIWGProject("previewTemplate") + self._setObject("previewTemplate",tmpPro) + for field in definedFields: + setattr(tmpPro,field,getattr(self,field)) + tmpPro.WEB_project_description=description[0:] + tmpPro.invisible=True + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','previewFrame.zpt')).__of__(self) return pt() - def editMPIWGRelatedPublicationsForm(self): - """Edit related Publications""" - pt=PageTemplateFile('Products/MPIWGWeb/zpt/edit_MPIWGRelatedPublications.zpt').__of__(self) + + #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 """ + + + + + %s + + """%self.WEB_project_description[0] + + return """ + + + + + %s + + """%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""" + #logging.info("XXXXXXXXXXXXX"+repr(self.responsibleScientistsList)) + + + keys = [unicodify(x[1]) for x in getattr(self,"responsibleScientistsList",[])] + #logging.error("RESP. SCIEN:%s"%getattr(self,"responsibleScientistsList",[])) + #logging.error("RESP. SCIEN:%s"%unicodify(key)) + + if unicodify(key) in keys: + return True + else: + return False + + def getPersonKeyList(self): + """gibt die key Liste der beteiligten Personen zurŸck (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 + + ##nameList=nameList.replace(";",",") # falls ; als Trenner ersetze - def editMPIWGProject(self,RESPONSE=None): - """edit the project""" - #return self.REQUEST + + + def identifyNames(self,nameList): + """Bekommt eine Komma oder Semikolon getrennte Liste mit Name der Form Vorname MittelName(n) Nachname + und ordnet diese dann Mitarbeiter IDs zu falls es schone eine Liste gibt wird im Projekte gibt wird diese Upgedated. + @param nameList + """ + + if nameList.find(";")>-1: # rate Trenner ist ; + names=nameList.split(";") + + else: + names=nameList.split(",") + + ##nameList=nameList.replace(";",",") # falls ; als Trenner ersetze + returnNamesDict={} + + + for name in names: + name=name.lstrip().rstrip() + nameSplitted = name.split(" ") + if len(nameSplitted)>1: #vor und nachname angegeben) + + lastname=nameSplitted[-1] + firstname=nameSplitted[0] + else: + firstname ="" + lastname=nameSplitted[0] + + #finde Mitarbeiter mit den entsprechenden Name + + firstname=self.myCapitalize(firstname).encode('utf-8') + lastname=self.myCapitalize(lastname).encode('utf-8') + logging.info("Search: %s %s %s"%(name,repr(firstname),repr(lastname))) + try: + cataloggedNames=self.MembersCatalog(firstName=firstname,lastName=lastname) + except: + cataloggedNames=[] + logging.error("ERROR: identifyNames %s %s"%sys.exc_info()[0:2]) + + #Teste ob die ensprechenden Namen schon der Liste zu geordnet sind + #if not hasattr(self,'responsibleScientistsList'): + # self.responsibleScientistsList={} + # + # if name in self.responsibleScientistsList.values() + + if len(cataloggedNames)>0: + returnNamesDict[name]=cataloggedNames + else: + returnNamesDict[name]=[] + + logging.error("id: %s"%repr(returnNamesDict)) + return returnNamesDict + + def editMPIWGProject(self,RESPONSE=None,fromEdit=None): + """edit the project and archive the old version""" + + self.copyObjectToArchive() # archive the object + self.ZCacheable_invalidate() + for x in definedFields: if self.REQUEST.has_key(x): - setattr(self,x,[self.REQUEST[x]]) + setattr(self,x,[self.REQUEST[x].decode('utf-8')]) + + + + + completedAt = self.REQUEST.get('completedAt') + if not self.setCompletedAt(completedAt): + RESPONSE.redirect('./editMPIWGBasisEditor?error="dateWrong') + + startedAt = self.REQUEST.get('startedAt') + if not self.setStartedAt(startedAt): + RESPONSE.redirect('./editMPIWGBasisEditor?error="dateWrong') + + if self.REQUEST.has_key('historicalNames'): + self.en.changeHistoricalNames(self.getId(),self.REQUEST['historicalNames'].split("\n")) + + if self.REQUEST.has_key('active'): + self.setActiveFlag(True) + else: + self.setActiveFlag(False) + + self.responsibleScientistsList=[] # setze die Liste der verantwortlichen Wissenschaftler zurueck + + names={} + keys={} + tmpList=[] + for key in self.REQUEST.keys(): #gehe durch das Formular + splitted=key.split("_") + if splitted[0]=="responsibleScientist": #wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt + nr=splitted[2] + if splitted[1]=="name": + names[nr]=self.REQUEST[key] + elif splitted[1]=="key": + keys[nr]=self.REQUEST[key] + + + for nr in names.keys():#schreibe keys und namen in die Liste, stelle ausserdem sicher, dass name unicode + tmpList.append((unicodify(names[nr]),unicodify(keys.get(nr,"")))) + + self.responsibleScientistsList=tmpList + if fromEdit and (RESPONSE is not None): + #RESPONSE.redirect('./editMPIWGBasisEditor') + return self.editMPIWGBasisEditor(identifiedNames=self.identifyNames(self.decode(self.REQUEST.get('xdata_01','')))) - if RESPONSE is not None: - RESPONSE.redirect('manage_main') + else: + if RESPONSE is not None: + RESPONSE.redirect('manage_main') + + + security.declareProtected('View managment screens','editMPIWGDisciplinesThemesEditor') + def editMPIWGDisciplinesThemesEditor(self): + """edit from edit""" + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGDisciplinesThemesNeu.zpt')).__of__(self) + return pt() + + def editMPIWGDisciplinesThemesForm(self): + """edit the disciplines and themes Form""" + + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGDisciplinesThemes.zpt')).__of__(self) + return pt() + + def editMPIWGDisciplinesThemes(self,disciplines=None,themes=None,RESPONSE=None,fromEdit=None): + """edit disciplin and form""" + if disciplines: + if type(disciplines) is StringType: + self.xdata_09=disciplines + else: + self.xdata_09=";".join(disciplines) + else: + self.xdata_09="" + if themes: + if type(themes) is StringType: + self.xdata_10=themes + else: + self.xdata_10=";".join(themes) + else: + self.xdata_10="" + + if fromEdit and (RESPONSE is not None): + self.redirect(RESPONSE,'./editMPIWGDisciplinesThemesEditor') + + else: + if RESPONSE is not None: + 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','editMPIWGBasisEditor') + def editMPIWGBasisEditor(self, identifiedNames=None): + + """editform""" + if not identifiedNames: + identifiedNames=self.identifyNames(self.getContent('xdata_01')) + # identifiedNames=self.getFullNameEntries() + + logging.error("IdentifiedNames: %s"% repr(identifiedNames)) + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGBasisNeu.zpt')).__of__(self) + 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('Products/MPIWGWeb/zpt/MPIWGProject_newfile.zpt').__of__(self) + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_newfile.zpt')).__of__(self) return pt() def loadNewFile(self,RESPONSE=None): @@ -364,25 +1416,27 @@ class MPIWGProject(Folder): def manage_addMPIWGProjectForm(self): """form for adding the project""" - pt=PageTemplateFile('Products/MPIWGWeb/zpt/addMPIWGProjectForm.zpt').__of__(self) + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGProjectForm.zpt')).__of__(self) return pt() def manage_addMPIWGProject(self,id,RESPONSE=None): """method to add a project""" #print argv - fileupload=self.REQUEST['fileupload'] + fileupload=self.REQUEST.get('fileupload',None) if fileupload: + file_name=fileupload.filename - filedata=fileupload.read() + filedata=fileupload.read() argv=xmlhelper.proj2hash(filedata) - + #print argv - - newObj=MPIWGProject(id,argv) + newObj=MPIWGProject(id,argv) + else: + newObj=MPIWGProject(id) self._setObject(id,newObj) - + if RESPONSE is not None: RESPONSE.redirect('manage_main')