--- MPIWGWeb/MPIWGProjects.py 2005/10/11 13:14:01 1.47.2.27 +++ MPIWGWeb/MPIWGProjects.py 2006/11/09 15:16:26 1.47.2.67 @@ -2,6 +2,10 @@ for organizing and maintaining the different project pages """ +#TODO: mechanismus fur links to personen ueberarbeiten, da jetzt alle e_mails als members auftauchen unabhaenig vom status publish_the_data +#TODO: was passiert wenn aenderungen von jochen im filemaker nicht mit den aenderungen im sql uebereinstimmen +#TODO: in einzelnen projecte steht als pfad auf die bilder noch wwwneu statt www + from Products.PageTemplates.PageTemplateFile import PageTemplateFile from Products.PageTemplates.PageTemplate import PageTemplate from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate @@ -23,13 +27,51 @@ from Products.ZSQLMethods.SQL import SQL from AccessControl import ClassSecurityInfo from bibliography import * import time +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 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'] checkFields = ['xdata_01'] +def getTextFromNode(nodename): + nodelist=nodename.childNodes + rc = "" + for node in nodelist: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc + +def sortStopWordsF(self,xo,yo): + if not hasattr(self,'_v_stopWords'): + self._v_stopWords=self.stopwords_en.data.split("\n") + + x=str(xo[1]) + y=str(yo[1]) + + strx=x.split(" ") + stry=y.split(" ") + + for tmp in strx: + if tmp.lower() in self._v_stopWords: + del strx[strx.index(tmp)] + + for tmp in stry: + if tmp.lower() in self._v_stopWords: + del stry[stry.index(tmp)] + + return cmp(" ".join(strx)," ".join(stry)) + +def sortStopWords(self): + return lambda x,y : sortStopWordsF(self,x,y) + def sortF(x,y): try: return cmp(x[1],y[1]) @@ -106,9 +148,9 @@ class MPIWGLink(SimpleItem): else: return self.getObj().weight - manage_options=SimpleItem.manage_options+( + manage_options=( {'label':'main config','action':'changeLinkForm'}, - ) + )+SimpleItem.manage_options def changeLinkForm(self): @@ -128,7 +170,10 @@ class MPIWGLink(SimpleItem): def index_html(self): """index""" - return self.getObj().pt_render(extra_context={'here':self}) + try: + return self.getObj().pt_render(extra_context={'here':self}) + except: + self.REQUEST.RESPONSE.redirect(self.getObj().absolute_url()) def manage_addMPIWGLinkForm(self): @@ -240,7 +285,7 @@ def manage_addMPIWGTemplate(self, MPIWGT class MPIWGRoot(ZSQLExtendFolder): - """Stammordner für den Web-Server""" + """Stammordner fuer den Web-Server""" fieldLabels={'WEB_title':'WEB_Title','xdata_01':'Responsible Scientists','xdata_02':'Department', 'xdata_03':'Historical Persons','xdata_04':'Time period', @@ -253,6 +298,65 @@ class MPIWGRoot(ZSQLExtendFolder): folders=['MPIWGProject','Folder','ECHO_Navigation'] meta_type='MPIWGRoot' + def harvestProjects(self): + """harvest""" + folder="/tmp" + try: + os.mkdir("/tmp/harvest_MPIWG") + except: + pass + founds=self.ZopeFind(self.aq_parent.projects,obj_metatypes=['MPIWGProject'],search_sub=1) + for found in founds: + txt=found[1].harvest_page() + + if txt and (txt != ""): + name=found[0].replace("/","_") + fh=file("/tmp/harvest_MPIWG/"+name,"w") + fh.write(txt) + fh.close() + + def decode(self,str): + """decoder""" + if not str: + return "" + if type(str) is StringType: + try: + return str.decode('utf-8') + except: + return str.decode('latin-1') + else: + + return str + + + def browserCheck(self): + """check the browsers request to find out the browser type""" + bt = {} + ua = self.REQUEST.get_header("HTTP_USER_AGENT") + bt['ua'] = ua + bt['isIE'] = False + bt['isN4'] = False + if string.find(ua, 'MSIE') > -1: + bt['isIE'] = True + else: + bt['isN4'] = (string.find(ua, 'Mozilla/4.') > -1) + + try: + nav = ua[string.find(ua, '('):] + ie = string.split(nav, "; ")[1] + if string.find(ie, "MSIE") > -1: + bt['versIE'] = string.split(ie, " ")[1] + except: pass + + bt['isMac'] = string.find(ua, 'Macintosh') > -1 + bt['isWin'] = string.find(ua, 'Windows') > -1 + bt['isIEWin'] = bt['isIE'] and bt['isWin'] + bt['isIEMac'] = bt['isIE'] and bt['isMac'] + bt['staticHTML'] = False + + return bt + + def versionHeaderEN(self): """version header text""" @@ -269,6 +373,25 @@ class MPIWGRoot(ZSQLExtendFolder): txt="""

Auf dieser Seite finden Sie die Projekte mit Stand vom %s

"""%str(date) return "" + + def createOrUpdateId_raw(self): + """create sequence to create ids for bibliography""" + debug=None + #suche groesste existierende id + founds=self.ZSQLQuery("select id from bibliography") + + if founds: + ids=[int(x.id[1:]) for x in founds] + maximum=max(ids) + + id_raw=self.ZSQLQuery("select nextval('id_raw')",debug=debug) + + if id_raw: + self.ZSQLQuery("drop sequence id_raw",debug=debug) + + self.ZSQLQuery("create sequence id_raw start %i"%(maximum+1),debug=debug) + + def queryLink(self,link): """append querystring to the link""" return "%s?%s"%(link,self.REQUEST.get('QUERY_STRING','')) @@ -304,7 +427,23 @@ class MPIWGRoot(ZSQLExtendFolder): return True else: return False - + + def subNavStatic(self,obj): + """subnav" von self""" + def sortWeight(x,y): + x1=int(getattr(x[1],'weight','0')) + y1=int(getattr(y[1],'weight','0')) + return cmp(x1,y1) + + subs=self.ZopeFind(obj,obj_metatypes=['MPIWGTemplate','MPIWGLink']) + subret=[] + + for x in subs: + if not(x[1].title==""): + subret.append(x) + subret.sort(sortWeight) + return subret + def subNav(self,obj): """return subnav elemente""" def sortWeight(x,y): @@ -319,12 +458,14 @@ class MPIWGRoot(ZSQLExtendFolder): #suche die zweite ebene + if not obj.aq_parent.getId() in ['de','en']: obj=obj.aq_parent - + while not self.ZopeFind(self,obj_ids=[obj.getId()]): obj=obj.aq_parent + if hasattr(self,obj.getId()): subs=self.ZopeFind(getattr(self,obj.getId()),obj_metatypes=['MPIWGTemplate','MPIWGLink']) @@ -345,6 +486,30 @@ class MPIWGRoot(ZSQLExtendFolder): return True return False + def getSection(self): + """returns the current section name""" + root = self.absolute_url() + url = self.REQUEST['URL'] + path = string.replace(url, root, '') + paths = path.split('/') + if len(paths) > 0: + sec = paths[1] + if sec.find('.') < 0: + return sec + else: + return None + return None + + def getSectionStyle(self, name, style=""): + """returns a string with the given style + '-sel' if the current section == name""" + if self.getSection() == name: + return style + '-sel' + else: + return style + + def MPIWGrootURL(self): + """returns the URL to the root""" + return self.absolute_url() def upDateSQL(self,fileName): """updates SQL databases using fm.jar""" @@ -453,6 +618,22 @@ class MPIWGRoot(ZSQLExtendFolder): self.id=id self.title=title + def removeStopWords(self,xo): + """remove stop words from xo""" + if not hasattr(self,'_v_stopWords'): + self._v_stopWords=self.stopwords_en.data.split("\n") + + x=str(xo) + + strx=x.split(" ") + + for tmp in strx: + + if tmp.lower() in self._v_stopWords: + del strx[strx.index(tmp)] + + return " ".join(strx) + def urlQuote(self,str): """quote""" return urllib.quote(str) @@ -461,89 +642,10 @@ class MPIWGRoot(ZSQLExtendFolder): """quote""" return urllib.unquote(str) - def harvestHistoricalPersons(self): - """erstelle liste aller erwaehnten actors""" - - def normalize(str): - """loesche fuhrendes space""" - if (len(str)>1) and (str[0]==" "): - ret=str[1:] - else: - ret=str - return ret - list={} - projects=self.ZopeFind(self.projects,obj_metatypes=['MPIWGProject']) - - for project in projects: - lg=len(project[1].xdata_03[0])-1 - - if (lg>1) and (project[1].xdata_03[0][lg]==";"): - project[1].xdata_03[0]=project[1].xdata_03[0][0:lg] - - - - - try: - if len(project[1].xdata_03[0].split(";"))>1: # guess if separator is ; - for person in project[1].xdata_03[0].split(";"): - personNormal=normalize(person) - if personNormal in list.keys(): - list[urllib.quote(personNormal)][1].append(project[1]) - else: - list[urllib.quote(personNormal)]=(personNormal,[project[1]]) - else: #guess , is sepeator - for person in project[1].xdata_03[0].split(","): - personNormal=normalize(person) - if urllib.quote(personNormal) in list.keys(): - list[urllib.quote(personNormal)][1].append(project[1]) - else: - list[urllib.quote(personNormal)]=(personNormal,[project[1]]) - - except: - zLOG.LOG("MPIWG Web (harvestHistoricalPerson)",zLOG.ERROR,"cannot annalyize: %s"%repr(project)) - - - return list - - def storeHistoricalPersons(self,RESPONSE=None): - """store persons""" - self.personDict={} - personDict=self.harvestHistoricalPersons() - for person in personDict.keys(): - for project in personDict[person][1]: - if person in self.personDict.keys(): - self.personDict[person][1].append((project.absolute_url(),project.WEB_title[0],project.xdata_01[0])) - else: - self.personDict[person]=(personDict[person][0],[(project.absolute_url(),project.WEB_title[0],project.xdata_01[0])]) - - if RESPONSE is not None: - RESPONSE.redirect("showHistoricalPersons") - - - def getPersonDict(self,name): - """name von dict""" - - try: - return self.personDict[name][0].encode('utf-8') - except: - return self.personDict[name][0] - return self.personDict[name][0].decode('latin-1').encode('utf-8') - - - def showHistoricalPersons(self): - """show persons""" - pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','showHistoricalPersons')).__of__(self) - return pt() - - - def editHistoricalPersonsForm(self): - """edit historical persons for consistency""" - pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editHistoricalPersonsForm')).__of__(self) - return pt() def getProjectsByFieldContent(self,fieldName,fieldContentsEntry, date=None): - """gib alle Projekte aus mit Value von field mit fieldName enthält ein Element der Liste fieldContents""" + """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]) @@ -598,7 +700,7 @@ class MPIWGRoot(ZSQLExtendFolder): """test""" return self.getProjectsByFieldContent('xdata_09',['biology'])[0].absolute_url - def getContexts(self,childs=None,parents=None,depth=None,date=None): + def getContexts(self,childs=None,parents=None,depth=None,date=None,onlyActive=True): """childs alle childs, alle parents""" ret=[] @@ -613,15 +715,17 @@ class MPIWGRoot(ZSQLExtendFolder): if childs: for project in self.getProjectFields('xdata_05',sort='int',date=date): searchStr=childs+"(\..*)" - if re.match(searchStr,project[1]): - - if depth: - - if int(depth)>=len(project[1].split("."))-len(childs.split(".")): - + + 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) - else: - ret.append(project) return ret def getProjectFields(self,fieldName,date=None,folder=None,sort=None): @@ -649,6 +753,10 @@ class MPIWGRoot(ZSQLExtendFolder): if sort=="int": ret.sort(sortI) + elif sort=="stopWords": + + ret.sort(sortStopWords(self)) + else: ret.sort(sortF) @@ -665,10 +773,11 @@ class MPIWGRoot(ZSQLExtendFolder): manage_options = Folder.manage_options+( - {'label':'Update Personal Homepages','action':'updateHomepages'}, + {'label':'Update personal homepages','action':'updateHomepages'}, + {'label':'Reindex catalogs','action':'reindexCatalogs'}, {'label':'Main config','action':'changeMPIWGRootForm'}, - {'label':'Edit Historical Persons','action':'editHistoricalPersonsForm'}, - {'label':'Store Historical Persons','action':'storeHistoricalPersons'}, + #{'label':'Edit Historical Persons','action':'editHistoricalPersonsForm'}, + #{'label':'Store Historical Persons','action':'storeHistoricalPersons'}, ) def importNamesForm(self): @@ -709,8 +818,9 @@ class MPIWGRoot(ZSQLExtendFolder): founds = self.ZSQLInlineSearch(_table="publications") for found in founds: - print found - if found.id_institutsbibliographie and (not found.id_institutsbibliographie ==""): + + if found.id_institutsbibliographie and (not found.id_institutsbibliographie =="") and (not found.id_institutsbibliographie =="0"): + entries = self.ZSQLInlineSearch(_table="institutsbiblio",id=found.id_institutsbibliographie) for entry in entries: self.ZSQLChange(_table='publications',_identify='oid=%s' % found.oid,year=entry.year,referencetype=entry.reference_type) @@ -722,10 +832,147 @@ class MPIWGRoot(ZSQLExtendFolder): return True + def updateHomepages(self,RESPONSE=None): + """ update""" + + RESPONSE.setHeader('Content-type', 'text/html') + RESPONSE.write("\n") + RESPONSE.write("Update Institutsbibliography\n") + ret=self.upDateSQL('personalwww.xml') + RESPONSE.write("done Insitutsbibliography:%s\n"%ret) + url="http://itgroup.mpiwg-berlin.mpg.de:8050/FMPro?-db=personal-www&-format=-dso_xml&-lay=sql_export&-max=20000&-findall" + dom = NonvalidatingReader.parseUri(url) + #fh=urllib.urlopen(url) + #dom=xml.dom.minidom.parse(fh) + + RESPONSE.write("got_xml_File\n") + + + memberFolder=getattr(self,'members') + members=memberFolder.ZopeFind(memberFolder,obj_metatypes=["MPIWGStaff"]) + + memberList=[x[0] for x in members] + #print dom + #ctx=Context(dom,processorNss={EMPTY_NAMESPACE:'http://www.filemaker.com/fmpdsoresult'}) + # Evaluate(u".//dn:ROW",contextNode=dom,explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'}) + #print dom.xpath(u'.//dn:ROW',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'}) + for row in dom.xpath(u'.//dn:ROW',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'}): + + username=getTextFromNode(row.xpath('./dn:username',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + id=getTextFromNode(row.xpath('./dn:ID',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + name=getTextFromNode(row.xpath('./dn:Name',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + vorname=getTextFromNode(row.xpath('./dn:Vorname',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + title=getTextFromNode(row.xpath('./dn:Title',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + position=getTextFromNode(row.xpath('./dn:Position',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + e_mail=getTextFromNode(row.xpath('./dn:e_mail',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + e_mail_p=getTextFromNode(row.xpath('./dn:e_mail_p',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + date_from=getTextFromNode(row.xpath('./dn:Date_from',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + date_to=getTextFromNode(row.xpath('./dn:Date_to',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + abteilung=getTextFromNode(row.xpath('./dn:Abteilung',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + heimat_inst=getTextFromNode(row.xpath('./dn:heimat_inst',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + funded_by=getTextFromNode(row.xpath('./dn:funded_by',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + e_mail2=getTextFromNode(row.xpath('./dn:e_mail2',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + publish_the_data=getTextFromNode(row.xpath('./dn:publish_the_data',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + stay_at_mpiwg=getTextFromNode(row.xpath('./dn:stay_at_mpiwg',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) + #cwNode=row.xpath('./dn:current_work.current',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0] + cw=row.xpath('./dn:current_work/dn:DATA',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'}) + if cw: + txt=getTextFromNode(cw[0]) + else: + txt="" + + #cwNode=row.xpath('.//dn:current_work.publish',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0] + cw=row.xpath('./dn:current_work/dn:DATA',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'}) + + if cw: + txt_p=getTextFromNode(cw[0]) + else: + txt_p="" + + project=getattr(self,'members') + + if not (username in memberList):#neuer eintrag + + try: + newObj=MPIWGStaff.MPIWGStaff(str(username),name.encode('utf-8'),vorname.encode('utf-8')) + memberFolder._setObject(str(username),newObj) + RESPONSE.write("

new:%s

\n"%username.encode('utf-8')) + obj=getattr(memberFolder,username) + ret=obj.createNewDBEntry(publish_the_data,id,name, + vorname,username,title,position,e_mail, + e_mail_p,date_from,date_to, + abteilung,heimat_inst,funded_by, + e_mail2,txt,txt_p,stay_at_mpiwg) + RESPONSE.write("""

%s

"""%ret[1].encode('utf-8')) + except: + RESPONSE.write("

ERROR:%s %s %s

\n"%(username.encode('utf-8'),name.encode('utf-8'),vorname.encode('utf-8'))) + RESPONSE.write("

: %s %s"%sys.exc_info()[:2]) + else: + RESPONSE.write("

update:%s

\n"%username.encode('utf-8')) + + xquery=".//dn:ROW[dn:username='%s']"%username + results=dom.xpath(xquery,explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'}) + if len(results)>1: + RESPONSE.write("

WARNING (update): username %s not unique

\n"%username.encode('utf-8')) + xquery=".//dn:ROW[dn:publish_the_data='yes' and dn:username='%s']"%username + rd=dom.xpath(xquery,explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'}) + if len(rd)>1:#mehrere published + RESPONSE.write("

ERROR (update): username %s not unique and more then one date set to be published

\n"%username.encode('utf-8')) +# elif len(rd)==1:#nur einer published, kein published dann mache nichts +# publish_the_data=getTextFromNode(rd[0].xpath('./dn:publish_the_data',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) +# date_from=getTextFromNode(rd[0].xpath('./dn:Date_from',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) +# date_to=getTextFromNode(rd[0].xpath('./dn:Date_to',explicitNss={'dn':'http://www.filemaker.com/fmpdsoresult'})[0]) +# + + obj=getattr(memberFolder,username) + + done= obj.updateDBEntry(DBid=id,publish_the_data=publish_the_data, + date_from=date_from, + date_to=date_to,stay_at_mpiwg=stay_at_mpiwg,position=position,abteilung=abteilung) + if not done and (publish_the_data=='yes'): + + ret=obj.createNewDBEntry(publish_the_data,id,name, + vorname,username,title,position,e_mail, + e_mail_p,date_from,date_to, + abteilung,heimat_inst,funded_by, + e_mail2,txt,txt_p,stay_at_mpiwg) + if not ret[0]: + + RESPONSE.write("

Error: %s

\n"%repr(ret[1])) + else: + RESPONSE.write("

New: %s

\n"%repr(ret[1])) + + #TODO: reindexCatlogs and updatePublications wieder einbaue + #self.reindexCatalogs(RESPONSE) + + #self.updatePublicationDB() + + #self.ZSQLResetConnection() + RESPONSE.write("

Done

") + + return True + def reindexCatalogs(self,RESPONSE=None): + """reindex members and project catalog""" + + + try: + self.MembersCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1']) + self.ProjectCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1']) + except: + zLOG.LOG("MPIWG Root (updatehomepage)",zLOG.WARNING," %s %s"%sys.exc_info()[:2]) + - def updateHomepages(self,RESPONSE): - """lege members an""" + + + + if RESPONSE: + RESPONSE.redirect('manage_main') + + + + def updateHomepages_old(self,RESPONSE): + """lege members an, alte version vollstaendige kopie aller fm-dateien per fm.jar""" self.upDateSQL('personalwww.xml') founds=self.ZSQLInlineSearch(_table='personal_www',publish_the_data='yes') project=getattr(self,'members') @@ -763,24 +1010,35 @@ class MPIWGRoot(ZSQLExtendFolder): RESPONSE.redirect('manage_main') - def getAllMembers(self): - """give list of all members""" - ret=[] - - #for x in self.members.objectValues('MPIWGStaff'): - #print x.title - # ret.append(x.title.decode('utf-8')) +# def getAllMembers(self,reset=None): +# """give list of all members""" +# ret=[] +# +# +# if reset or (getattr(self,'_v_membersList',None) is None): +# for member in self.members._objects: +# if member['meta_type']=='MPIWGStaff': +# memberObj=getattr(self.members,member['id']) +# if memberObj.isPublished(): +# ret.append(memberObj.title.decode('utf-8')) +# +# ret.sort() +# self._v_membersList=ret[0:] +# print ret +# +# return self._v_membersList - for x in self.ZopeFind(self.members,obj_metatypes=['MPIWGStaff']): - ret.append(x[1].title.decode('utf-8')) - - ret.sort() - #print ret - + def getAllMembers(self): + #ret=[] + + results=self.MembersCatalog({'isPublished':True}) + + ret=[", ".join([proj.lastName, proj.firstName]).decode('utf-8') for proj in results] + + ret.sort() return ret - def printAllMembers(self): - """prin""" + """print""" members=self.getAllMembers() ret="" for x in members: @@ -796,7 +1054,7 @@ class MPIWGRoot(ZSQLExtendFolder): return entry - def getTree(self,date=None): + def getTree(self,dep=None,date=None,onlyActive=None): """generate Tree from project list""" returnList=[] @@ -810,12 +1068,18 @@ class MPIWGRoot(ZSQLExtendFolder): #title=project[0].WEB_title title=[project[0].getContent('WEB_title')] #print title - if idNr[0]!="x": - returnList.append((depth,nr,title,project[0])) - + + if idNr[0]=="x": # kompatibilitaet mit alter Konvention, x vor der Nummer macht project inactive + project[0].setActiveFlag(False) + + if (not dep) or (idNr[0]==dep): #falls dep gesetzt ist nur dieses hinzufuegen. + if onlyActive and project[0].isActiveProject(): #nur active projekte + returnList.append((depth,nr,title,project[0])) + elif not onlyActive: + returnList.append((depth,nr,title,project[0])) return returnList - def formatElementsAsList(self,elements): + def formatElementsAsList(self,elements,onlyOneDept=False): """formatiere tree als liste""" actualDepth=0 @@ -859,9 +1123,10 @@ class MPIWGRoot(ZSQLExtendFolder): ret+="""
  • \n""" if actualDepth==1: - departmentName={'1':'Department I','2':'Department II','3':'Department III', '4':'Ind. Research Group','5':'Ind. Research Group'} + departmentName={'1':'Department I','2':'Department II','3':'Department III', '4':'Ind. Research Group','5':'Ind. Research Group','6':'Ind. Research Group','7':'Research Network'} department=element[3].getContent('xdata_05') - ret+="""
    %s: """%(department,departmentName[department]) + if not onlyOneDept: + ret+="""
    %s: """%(department,departmentName[department]) if self.REQUEST.has_key('date'): ret+="""%s"""%(self.generateUrlProject(element[3].absolute_url())+"/index.html",self.REQUEST['date'],element[3].getContent('WEB_title')) @@ -877,6 +1142,8 @@ class MPIWGRoot(ZSQLExtendFolder): return """

    Ind. Research Group I: %s

    """%(element[3].absolute_url()+"/index.html",element[3].getContent('WEB_title')) if element[3].getContent('xdata_05') == "5": return """

    Ind. Research Group II: %s

    """%(element[3].absolute_url()+"/index.html",element[3].getContent('WEB_title')) + if element[3].getContent('xdata_05') == "6": + return """

    Research Network "History of Scientific Objects": %s

    """%(element[3].absolute_url()+"/index.html",element[3].getContent('WEB_title')) return """

    Department %s: %s

    """%(element[3].absolute_url()+"/index.html",element[3].getContent('xdata_05'),element[3].getContent('WEB_title')) @@ -927,11 +1194,21 @@ class MPIWGRoot(ZSQLExtendFolder): for idNr in form.keys(): - if not (fields[int(idNr)][3].xdata_05==form[idNr]): - fields[int(idNr)][3].xdata_05=form[idNr] - fields[int(idNr)][3].copyObjectToArchive() - - + + splitted=idNr.split('_') + + if len(splitted)==1: # name des Feldes = idNr, dann Aendere id_nr + if not (fields[int(idNr)][3].xdata_05==form[idNr]): + fields[int(idNr)][3].xdata_05=form[idNr] + fields[int(idNr)][3].copyObjectToArchive() + + if form.has_key(idNr+'_active'): # active flag is set + + fields[int(splitted[0])][3].setActiveFlag(True) + else: + + fields[int(splitted[0])][3].setActiveFlag(False) + if RESPONSE is not None: RESPONSE.redirect('showTree') @@ -977,6 +1254,36 @@ class MPIWGRoot(ZSQLExtendFolder): return string.join(ret,";") + def getMembersFromList(self,list): + """get member names from person full text list""" + memberlist=[] + persons=list.split(";") + for person in persons: + if len(person)>1: #nicht nur Trennzeichen + splitted=person.split(",") + if len(splitted)==1: + splitted=person.lstrip().rstrip().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=='': + try: + member=self.MembersCatalog({'title':search}) + except: + member=None + + if member and (member[0].getObject().isPublished()): + if person =="Otto Sibum" : person="H. Otto Sibum" + if person =="Norton Wise" : person="M. Norton Wise" + #memberlist.append("%s"%(member[0].absolute_url,person.encode('utf-8'))) + memberlist.append((person, member[0].getObject().getId())) + else: + #memberlist.append("%s"%person.encode('utf-8')) + memberlist.append((person,None)) + return memberlist + def getUrlFromPerson(self,list): """get urls to person list""" ret=[] @@ -999,11 +1306,15 @@ class MPIWGRoot(ZSQLExtendFolder): except: proj=None - if proj: + if proj and (proj[0].getObject().isPublished()): if person =="Otto Sibum" : person="H. Otto Sibum" if person =="Norton Wise" : person="M. Norton Wise" #ret.append("%s"%(proj[0].absolute_url,person.encode('utf-8'))) - ret.append("%s"%(proj[0].absolute_url+"/index.html",person)) + if self.MPIWGrootURL().split("/")[-1]=='en': + tmpPath="/en/staff/members/" + else: + tmpPath="/de/mitarbeiter/members/" + ret.append("%s"%(tmpPath+proj[0].getObject().getId()+"/index.html",person)) else: #ret.append("%s"%person.encode('utf-8')) ret.append("%s"%person) @@ -1013,8 +1324,10 @@ class MPIWGRoot(ZSQLExtendFolder): """give tuple member /projects""" ret=[] members=self.getAllMembers() + #return str(members) for x in members: + ret+=self.getProjectsOfMember(name=x,date=date) return ret @@ -1082,6 +1395,7 @@ class MPIWGRoot(ZSQLExtendFolder): if splittedNew[0]=='': del splittedNew[0] search=string.join(splittedNew,' AND ') + if not search=='': proj=self.MembersCatalog({'title':search}) @@ -1144,10 +1458,156 @@ class MPIWGRoot(ZSQLExtendFolder): return (fieldname in checkFields) + + def generateNameIndex(self): + """erzeuge einen index verwendeter personen""" + import psycopg + o = psycopg.connect('dbname=authorities user=dwinter password=3333',serialize=0) + results={} + print self.fulltext.historicalNames.items() + for nameItem in self.fulltext.historicalNames.items(): #gehe durch alle namen des lexikons + + c = o.cursor() + name=nameItem[0] + print "check",name + c.execute("select lastname,firstname from persons where lower(lastname) = '%s'"%quote(name)) + tmpres=c.fetchall() + firstnames=[result[1] for result in tmpres] # find all firstnames + if tmpres: + lastname=tmpres[0][0] + + for found in self.fulltext({'names':name}): + if found.getObject().isActual(): + for nh in found.getObject().getGetNeighbourhood(name, length=50,tagging=False): #hole umgebung + #schaue nun ob der vorname hinter oder vor dem name ist + position=nh.find(lastname) + # vorher + #print "NH",nh + bevorS=nh[0:position].split() + #print "BV",bevorS + if len(bevorS)>1: + try: + bevor=[bevorS[-1],bevorS[-2]] + except: + bevor=[bevorS[0]] + else: + bevor=[] + #nachher + behindS= re.split("[,|;| ]",nh[position:]) + #print "BH",behindS + if len(behindS)>2: + try: + behind=behindS[1:3] + except: + behind=[bevorS[1]] + else: + behind=[] + for firstname in firstnames: + if firstname in bevor+behind: #Namen wie mit Adelspraedikaten werden so erstmal nich gefunden + id="%s,%s"%(lastname,firstname) + if not results.has_key(id): + results[id]=[] + objId=found.getObject().getId() + if not (objId in results[id]): + print "d %s for %s"%(id,objId) + results[id].append(objId) + self.nameIndex=results + return results + + def editNameIndexHTML(self): + """edit the name index""" + if not hasattr(self,'nameIndexEdited'): # falls editierter index noch nicht existiert, kopiere automatisch erstellten + self.nameIndexEdited=copy.copy(self.nameIndex) + print "huh" + #self.nameIndexEdited=copy.copy(self.nameIndex) + #print self.nameIndexEdited + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editHistoricalNames.zpt')).__of__(self) + return pt() + + def getNamesInProject(self,projectId): + """get all names ofnameIndexEdited which are references in projec with projectId""" + + ret=[] + for name in self.nameIndexEdited.keys(): + if projectId in self.nameIndexEdited[name]: + ret.append(name) + + return ret + + def editNameIndex(self,RESPONSE=None,name=None,occurrances=None,submit=None): + """edit the index""" + nI=self.nameIndexEdited # mI introduced to make sure that changes to nameIndexEdited are know to ZODB + if submit=="delete": + + dh=getattr(self,'deletedHistoricalNames',{}) + if not dh.has_key(name): + dh=occurrances.split("\n") + else: + dh+=occurrances.split("\n") + + self.deletedHistoricalNames=dh + + del self.nameIndexEdited[name] + + + elif (submit=="change"): + + nI[name]=occurrances.split("\n")[0:] + + elif (submit=="add"): + if not nI.has_key(name): + nI[name]=occurrances.split("\n") + else: + nI[name]+=occurrances.split("\n") + + self.nameIndexEdited=nI + + + if RESPONSE is not None: + RESPONSE.redirect('editNameIndexHTML') + + + def restoreIndex(self): + """restore""" + self.nameIndexEdited=self.nameIndex + return "done" + def changeHistoricalNames(self,projId,nameListTmp): + """add resp change nameIndexEdited b + y adding/changing names menitionen in project projId""" + #clear namelist from blanks + nameList=[x.lstrip().rstrip() for x in nameListTmp] + + nI=self.nameIndexEdited + for name in nameList: + if not nI.has_key(name): #neuer Name + nI[name]=[projId] + + for name in nI.keys(): + + if name in nameList: #checke if name in name List + + if not(projId in nI[name]): #nicht in listt -> hinzufuegen + + nI[name].append(projId) + + """loesche falls projekt in nI list aber der name nicht mehr + in der namensliste des projectes auftaucht + """ + + for pr in nI[name]: + + if (pr==projId) and (not name in nameList): + + nI[name].remove(pr) + + self.nameIndexEdited=nI + + + def manage_addMPIWGRootForm(self): """form for adding the root""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGRootForm.zpt')).__of__(self) @@ -1215,6 +1675,7 @@ class MPIWGProject(CatalogAware,Folder): meta_type='MPIWGProject' default_catalog='ProjectCatalog' + def sortedByPlace(self,metatype): """find metatype and sort by place""" def sort(x,y): @@ -1242,23 +1703,70 @@ class MPIWGProject(CatalogAware,Folder): RESPONSE.redirect('managePublications') - def copyImageToMargin(self,RESPONSE=None): + def copyImageToMargin(self,RESPONSE=None): """copy inline images to marginal images""" - self.getContent('WEB_project_description',filter='yes') + + + #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]) + try: + imageURLs.append(tmp[0].split("\"")[1].encode('utf-8')) + except: + imageURLs.append(tmp[0].split("src=")[1].split(" ")[0].encode('utf-8')) + + split2="

    ".join(tmp[1:]) - filename=self.imageURL.split("/")[-1] - #lege neues images object an, mit leerem bild - if self.ZopeFind(self,obj_ids=[filename]): - #existiert das bild schon, dann neueun filenamen - filename="project_image_"+filename - - self.addImage(None,self.imagecap,filename=filename) - #hole die bilddaten aus der url - data=urllib.urlopen(self.absolute_url()+"/"+self.imageURL).read() + splitted=split2.split("""

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

    ") + imageCaptions.append(tmp[0].encode('utf-8')) + - obj=getattr(self,filename) - obj.update_data(data) + 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: + zLOG.LOG("MPIWG Project",zLOG.ERROR,"can't open: %s"%url) + + obj=getattr(self,filename) + obj.update_data(data) if RESPONSE: RESPONSE.redirect('manageImages') @@ -1385,6 +1893,17 @@ class MPIWGProject(CatalogAware,Folder): if RESPONSE: RESPONSE.redirect('manageImages') + + def hasChildren(self,date=None,onlyActive=True): + """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""" @@ -1522,7 +2041,7 @@ class MPIWGProject(CatalogAware,Folder): 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 @@ -1542,6 +2061,8 @@ class MPIWGProject(CatalogAware,Folder): self.creationTime=time.strftime("%Y%m%d%H%M%S",time.localtime())[0:] self.id=id self.title=id + self.isActiveFlag=True #Flag is true is the project is still active, False if accomplished + if argv: for arg in definedFields: try: @@ -1562,6 +2083,14 @@ class MPIWGProject(CatalogAware,Folder): ) + 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 setActiveFlag(self,status=True): + """set the active flag""" + self.isActiveFlag=status + def checkDate(self,date): """teste ob zum Zeitpunkt date eine andere version existierte""" @@ -1602,7 +2131,109 @@ 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: + 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""" if not context: @@ -1704,7 +2335,7 @@ class MPIWGProject(CatalogAware,Folder): else: text5=text2 - #teste ob WEB_project_description und keine führenden p tags + #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+"

    " @@ -1741,7 +2372,7 @@ class MPIWGProject(CatalogAware,Folder): start=kupu.find("") end=kupu.find("") newcontent= kupu[start+6:end] - + if preview: return self.preview(newcontent) @@ -1753,7 +2384,7 @@ class MPIWGProject(CatalogAware,Folder): return True - security.declareProtected('View managment screens','edit') + security.declareProtected('View management screens','edit') def edit(self,western=None): """Edit pages""" if western: @@ -1762,6 +2393,16 @@ class MPIWGProject(CatalogAware,Folder): 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 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 preview(self,description): """preview""" @@ -1772,7 +2413,7 @@ class MPIWGProject(CatalogAware,Folder): 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() @@ -1821,6 +2462,14 @@ class MPIWGProject(CatalogAware,Folder): setattr(self,x,[self.REQUEST[x].decode('utf-8')]) + + 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) if fromEdit and (RESPONSE is not None): RESPONSE.redirect('./editMPIWGBasisEditor') @@ -1880,6 +2529,7 @@ class MPIWGProject(CatalogAware,Folder): 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 @@ -1890,13 +2540,13 @@ class MPIWGProject(CatalogAware,Folder): pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGBasisNeu.zpt')).__of__(self) return pt() - + 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)