--- MPIWGWeb/MPIWGProjects.py 2008/08/22 06:09:28 1.47.2.87 +++ MPIWGWeb/MPIWGProjects.py 2010/09/13 11:23:58 1.47.2.117 @@ -7,20 +7,25 @@ $author dwinter - last change 26.06.2 from Products.PageTemplates.PageTemplateFile import PageTemplateFile from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate 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 os +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 xmlrpclib #import xml.dom.minidom import sys #from Ft.Xml.XPath import Evaluate @@ -38,7 +43,7 @@ import MPIWGRoot import MPIWGLink import MPIWGTemplate -# die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus KompatibilitŠtsgrŸnden, bleiben die Klassen hier noch drin. +# die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus Kompatibilitaetsgruenden, bleiben die Klassen hier noch drin. # Sonst funktionieren die alten Webseiten nicht mehr. class MPIWGRoot(MPIWGRoot.MPIWGRoot): @@ -50,24 +55,94 @@ class MPIWGLink(MPIWGLink.MPIWGLink): class MPIWGTemplate(MPIWGTemplate.MPIWGTemplate): """depricated""" -class MPIWGProject_publication(SimpleItem): +class MPIWGProject_publication(Folder): """publications object fuer project""" 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,RESPONSE=None): + def hasLinkToBookPage(self): + """teste ob eingebener link zu einer MPIWG Book page geht""" + + if (getattr(self,'link','')==''): + return False #es gibt keinen link + + server = xmlrpclib.ServerProxy(self.link) + + try: + server.getImageUrls() + return True + except: + return False + + + def getImageUrls(self): + """get the image urls""" + + if (getattr(self,'link','')==''): + return False #es gibt keinen link + + server = xmlrpclib.ServerProxy(self.link) + + try: + urls = server.getImageUrls() + ret=[] + for url in urls: + url = os.path.join(self.link,url) + ret.append(url) + + except: + return [] + + return ret + + def editPublication(self,text=None,image1=None,image2=None,description=None,link=None,RESPONSE=None): """edit a publication""" - if (not text): + 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:] + if text: + self.text=text[0:] + + if description: + self.description=description + + if link: + self.link=link[0:] + + 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: - RESPONSE.redirect("../managePublications") - + self.redirect(RESPONSE,"../managePublications") + class MPIWGProject_image(Image): """Images for Projects""" @@ -92,15 +167,30 @@ class MPIWGProject_image(Image): self.caption=caption[0:] if RESPONSE: - RESPONSE.redirect("../manageImages") + self.redirect(RESPONSE,"../manageImages") -class MPIWGProject(CatalogAware,Folder): +class MPIWGProject(CatalogAware,Folder,Cacheable): """Class for Projects""" - + + def _p_resolveConflict(self, oldState, savedState, newState): + return newState 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""" @@ -129,10 +219,46 @@ class MPIWGProject(CatalogAware,Folder): pubSplit=pubSplit.replace("
","") self.addPublication(pubSplit) + setattr(self,"WEB_related_pub_copied",True); + if RESPONSE: - RESPONSE.redirect('managePublications') + + 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 hasRelatedDigitalSources(self): + """test ob es digital sources gibt""" + + + ret = (self.getContent('xdata_11')=='' and self.getContent('xdata_13')=='') + + + + return not ret; + + def copyImageToMargin(self,RESPONSE=None): """copy inline images to marginal images""" @@ -199,7 +325,8 @@ class MPIWGProject(CatalogAware,Folder): obj.update_data(data) if RESPONSE: - RESPONSE.redirect('manageImages') + + self.redirect(RESPONSE,'manageImages') def manageImages(self,imageName=None,op=None): """managage images""" @@ -256,7 +383,31 @@ class MPIWGProject(CatalogAware,Folder): 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 getPublications(self): """get all Publications""" def sort_images(x,y): @@ -282,7 +433,8 @@ class MPIWGProject(CatalogAware,Folder): obj.id=name if RESPONSE is not None: - RESPONSE.redirect('managePublications') + + self.redirect(RESPONSE,'managePublications') def getLastPublicationNumber(self): @@ -297,7 +449,8 @@ class MPIWGProject(CatalogAware,Folder): """delete Publication id""" self.manage_delObjects([id]) if RESPONSE: - RESPONSE.redirect('managePublications') + + self.redirect(RESPONSE,'managePublications') def getImages(self): """get all Images""" @@ -329,13 +482,18 @@ class MPIWGProject(CatalogAware,Folder): def deleteImage(self,id,RESPONSE=None): """delete Image id""" - self.manage_delObjects([id]) + try: + self.manage_delObjects([id]) + except: + logging.error("ERROR MPIWG: %s %s"%sys.exc_info()[0:2]) if RESPONSE: - RESPONSE.redirect('manageImages') + self.redirect(RESPONSE,'manageImages') + 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) @@ -364,7 +522,8 @@ class MPIWGProject(CatalogAware,Folder): obj.id=filename if RESPONSE is not None: - RESPONSE.redirect('manageImages') + + self.redirect(RESPONSE,'manageImages') def PrincipiaSearchSource(self): """Return cataloguable key for ourselves.""" @@ -435,20 +594,31 @@ class MPIWGProject(CatalogAware,Folder): def copyObjectToArchive(self): """kopiere aktuelles objekt ins archiv""" + logging.info("copytoarchive 1") cb=self.aq_parent.manage_copyObjects(self.getId()) + logging.info("copytoarchive 2") self.manage_pasteObjects(cb) + logging.info("copytoarchive 3") actualTime=time.localtime() self.manage_renameObject(self.getId(),self.getId()+"_"+time.strftime("%Y%m%d%H%M%S",actualTime)) + logging.info("copytoarchive 4") 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)) + logging.info("copytoarchive 5") ids=[x[0] for x in self.ZopeFind(obj,obj_metatypes=['MPIWGProject'])] + logging.info("copytoarchive 6") obj.manage_delObjects(ids) + logging.info("copytoarchive 7") 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) @@ -459,7 +629,8 @@ class MPIWGProject(CatalogAware,Folder): self.invisible=invisible if RESPONSE is not None: - RESPONSE.redirect('manage_main') + + self.redirect(RESPONSE,'manage_main') def crossLinker(self): @@ -495,7 +666,7 @@ class MPIWGProject(CatalogAware,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=None): """initiere classe""" @@ -533,7 +704,7 @@ class MPIWGProject(CatalogAware,Folder): def isArchivedProject(self): """check if the project is archived""" - completed=getattr(self,'completedAt',0) + completed=self.getCompletedAt() #completed leer if completed=="" : @@ -551,9 +722,9 @@ class MPIWGProject(CatalogAware,Folder): 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)) + #logging.info("DATE:"+repr(date)) transformedDate=self.transformDate(date); - logging.info("transformed"+repr(transformedDate)) + #logging.info("transformed"+repr(transformedDate)) if transformedDate is not None: setattr(self,"completedAt",transformedDate) return True; @@ -562,24 +733,34 @@ class MPIWGProject(CatalogAware,Folder): 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)) + #logging.info("DATE:"+repr(date)) transformedDate=self.transformDate(date); - logging.info("transformed"+repr(transformedDate)) + #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 ''; + 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.""" + """gibt das transformierte Datum zurueck, an dem Projekt begonnen wurde.""" date=getattr(self,'startedAt','') if date: return self.reTransformDate(date); @@ -600,8 +781,8 @@ class MPIWGProject(CatalogAware,Folder): 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""" + """transformiert ein Datum von DD.MM.YYYY, MM.YYYY,YYYY nach YYYYMMDD, alle nicht angebenen Werte + werden auf 0 gesetzt, es wird null zurueckgegeben falls das Datum ungueltig ist""" if (date==None): return None; @@ -681,94 +862,8 @@ class MPIWGProject(CatalogAware,Folder): """warnung: project noch nicht existent""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','no_project')).__of__(self) return pt() - - def getGetNeighbourhood(self,wordStr, length=100,tagging=True): - """finde umgebung um die worte in wordStr, zurueckgegeben wird eine Array mit den Umgebungen von Fundstellen der Worte - alle Tags werden entfernt, die Fundstellen werden mit XX getaggt, die Umgebungen werden - case insensitive gesucht - @param wordStr: string mit Worten getrennt durch Leerzeichen, Phrasen sind mit " gekennzeichnet - "eine phrase", "*" bezeichnet wildcards und wird ignoriert" - @param length: optional, default wert 100, 2*length ist die groesse der Umgebung - @param tagging: optional default wert true, kein span tag wird erzweugt falls tag=false - """ - - ret=[] # nimmt das Array auf, dass spaeter zurueckgegeben wird - ranges=[] #Array mit tupeln x,y wobei x die Position des Anfang und y des Endes der i-ten Umgebung angiebt - - def isInRanges(nr,length): - """test ob eine gegeben Position nr schon irgendwo in einer Umgebung ist, gibt den Index des ersten Wertes aus ranges zurueck, - -1, wenn kein Treffer - - @param nr: Position die geprueft werden soll - @param length: Laenge des Wortes das geprueft werden soll - """ - for x in ranges: - if (x[0]<=nr) and (nr < (x[1]-length)): - return ranges.index(x) - return -1 - - # deal with phrases, in Phrasen werden die Leerzeichen durch "_" ersetzt. - def rep_empty(str): - x= re.sub(" ","_",str.group(0)) - return re.sub("\"","",x) - - wordStr=re.sub("\".*?\"", rep_empty,wordStr)#ersetze leerzeichen in " " durch "_" und loesche " - - #deal with wildcards, for our purposes it is enough to delete the wildcard - wordStr=wordStr.replace("*","") - - words=wordStr.split(" ") - #if not words is ListType: - # words=[words] - - txt=self.harvest_page() - if not txt: - return ret - txt=re.sub("<.*?>", "", txt) # loesche alle Tags - for word in words: - word=re.sub("_"," ",word) # ersetze zurueck "_" durch " " - pos=0 - - n=txt.lower().count(word.lower()) # wie oft tritt das Wort auf - - for i in range(n): - pos=txt.lower().find(word.lower(),pos) - - if pos > 0: - x=max(0,pos-length) - y=min(len(txt),pos+length) - - - #is word already in one of the results - nr=isInRanges(pos,len(word)) - if nr >=0:# word ist in einer schon gefunden Umgebung, dann vergroessere diese - x=min(ranges[nr][0],x) - y=max(ranges[nr][1],y) - - str=txt[x:y] - - if nr >=0: # word ist in einer schon gefunden Umgebung - ranges[nr]=(x,y) # neue Position der Umgebung - - ret[nr]=str # neue Umgebung - else: # andernfalls neue Umgebung hinzufuegen - ranges.append((x,y)) - - ret.append(str) - - pos=pos+len(word) - else: - break; - - # now highlight everything - if tagging: - for x in range(len(ret)): - for word in words: - repl=re.compile(word,re.IGNORECASE) - ret[x]=repl.sub(""" %s"""%word.upper(),ret[x]) - - return ret - + + def harvest_page(self,context=None): """seite fuer harvesting fuer die Projektsuche""" if not context: @@ -783,9 +878,67 @@ class MPIWGProject(CatalogAware,Folder): 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: + #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_old(self,request=True,context=None): + """show homepage""" if not context: context=self if request: @@ -796,10 +949,11 @@ class MPIWGProject(CatalogAware,Folder): 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() @@ -824,7 +978,14 @@ class MPIWGProject(CatalogAware,Folder): def getContent(self,field,filter=None): """Inhalt des Feldes""" + #logging.debug("getContent field=%s filter=%s"%(field,filter)) + if field=="short_title": + text = self.getContent("xdata_07") + if text=="": + text = self.getContent("WEB_title") + return text + text=u'' for x in getattr(self,field): @@ -844,11 +1005,14 @@ class MPIWGProject(CatalogAware,Folder): except: pass - if text=='': + 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'): @@ -899,9 +1063,9 @@ class MPIWGProject(CatalogAware,Folder): if (text5=="