1: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
2: from Products.PageTemplates.PageTemplate import PageTemplate
3: from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
4: from Products.ZSQLExtend.ZSQLExtend import ZSQLExtendFolder
5: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
6: from OFS.Image import Image
7: from Globals import package_home
8: import urllib
9: import MPIWGStaff
10: import string
11: import re
12: import os
13: from types import *
14: import logging
15: import xmlhelper # Methoden zur Verwaltung der projekt xml
16: from OFS.SimpleItem import SimpleItem
17: from OFS.Folder import Folder
18: from Products.ZSQLMethods.SQL import SQLConnectionIDs
19: from AccessControl import ClassSecurityInfo
20: from bibliography import *
21: import time
22: import xml.dom.minidom
23: import sys
24: from Ft.Xml.XPath import Evaluate
25: from Ft.Xml.XPath.Context import Context
26: from Ft.Xml.Domlette import NonvalidatingReader,PrettyPrint, Print
27: from Ft.Xml import EMPTY_NAMESPACE
28: import copy
29: import updatePersonalWWW
30: import MPIWGStaff
31: from MPIWGHelper import *
32:
33:
34: def sortWeight(x,y):
35: x1=int(getattr(x[1],'weight','0'))
36: y1=int(getattr(y[1],'weight','0'))
37: return cmp(x1,y1)
38:
39:
40: class MPIWGRoot(ZSQLExtendFolder):
41: """Stammordner fuer den Web-Server"""
42:
43: fieldLabels={'WEB_title':'WEB_Title',
44: 'xdata_01':'Responsible Scientists',
45: 'xdata_02':'Department',
46: 'xdata_03':'Historical Persons',
47: 'xdata_04':'Time period',
48: 'xdata_05':'Sorting number',
49: 'xdata_06':'Keywords',
50: 'xdata_07':'Short title',
51: 'xdata_08':'Other involved scholars' ,
52: 'xdata_09':'Disciplines',
53: 'xdata_10':'Themes',
54: 'xdata_11':'Object Digitallibrary',
55: 'xdata_12':'Cooperation partners',
56: 'xdata_13':'Funding institutions',
57: 'WEB_project_header':'WEB_project_header',
58: 'WEB_project_description':'WEB_project_description',
59: 'WEB_related_pub':'WEB_related_pub'}
60:
61: folders=['MPIWGProject','Folder','ECHO_Navigation']
62: meta_type='MPIWGRoot'
63:
64: def getGetNeighbourhood(self,obj, wordStr, length=100,tagging=True):
65: """finde umgebung um die worte in wordStr, zurueckgegeben wird eine Array mit den Umgebungen von Fundstellen der Worte
66: alle Tags werden entfernt, die Fundstellen werden mit <span class="found">XX</span> getaggt, die Umgebungen werden
67: case insensitive gesucht
68: @param wordStr: string mit Worten getrennt durch Leerzeichen, Phrasen sind mit " gekennzeichnet
69: "eine phrase", "*" bezeichnet wildcards und wird ignoriert"
70: @param length: optional, default wert 100, 2*length ist die groesse der Umgebung
71: @param tagging: optional default wert true, kein span tag wird erzweugt falls tag=false
72: """
73:
74: ret=[] # nimmt das Array auf, dass spaeter zurueckgegeben wird
75: ranges=[] #Array mit tupeln x,y wobei x die Position des Anfang und y des Endes der i-ten Umgebung angiebt
76:
77: def isInRanges(nr,length):
78: """test ob eine gegeben Position nr schon irgendwo in einer Umgebung ist, gibt den Index des ersten Wertes aus ranges zurueck,
79: -1, wenn kein Treffer
80:
81: @param nr: Position die geprueft werden soll
82: @param length: Laenge des Wortes das geprueft werden soll
83: """
84: for x in ranges:
85: if (x[0]<=nr) and (nr < (x[1]-length)):
86: return ranges.index(x)
87: return -1
88:
89: # deal with phrases, in Phrasen werden die Leerzeichen durch "_" ersetzt.
90: def rep_empty(str):
91: x= re.sub(" ","_",str.group(0))
92: return re.sub("\"","",x)
93:
94: wordStr=re.sub("\".*?\"", rep_empty,wordStr)#ersetze leerzeichen in " " durch "_" und loesche "
95:
96: #deal with wildcards, for our purposes it is enough to delete the wildcard
97: wordStr=wordStr.replace("*","")
98:
99: words=wordStr.split(" ")
100: #if not words is ListType:
101: # words=[words]
102:
103: txt=obj.harvest_page()
104: if not txt:
105: return ret
106: txt=re.sub("<.*?>", "", txt) # loesche alle Tags
107: for word in words:
108: word=re.sub("_"," ",word) # ersetze zurueck "_" durch " "
109: pos=0
110:
111: n=txt.lower().count(word.lower()) # wie oft tritt das Wort auf
112:
113: for i in range(n):
114: pos=txt.lower().find(word.lower(),pos)
115:
116: if pos > 0:
117: x=max(0,pos-length)
118: y=min(len(txt),pos+length)
119:
120:
121: #is word already in one of the results
122: nr=isInRanges(pos,len(word))
123: if nr >=0:# word ist in einer schon gefunden Umgebung, dann vergroessere diese
124: x=min(ranges[nr][0],x)
125: y=max(ranges[nr][1],y)
126:
127: str=txt[x:y]
128:
129: if nr >=0: # word ist in einer schon gefunden Umgebung
130: ranges[nr]=(x,y) # neue Position der Umgebung
131:
132: ret[nr]=str # neue Umgebung
133: else: # andernfalls neue Umgebung hinzufuegen
134: ranges.append((x,y))
135:
136: ret.append(str)
137:
138: pos=pos+len(word)
139: else:
140: break;
141:
142: # now highlight everything
143: if tagging:
144: for x in range(len(ret)):
145: for word in words:
146: repl=re.compile(word,re.IGNORECASE)
147: ret[x]=repl.sub(""" <span class="found">%s</span>"""%word.upper(),ret[x])
148:
149: return ret
150: def copyAllImagesToMargin(self):
151: """tranformiere alle Bilder in die Margins"""
152: projects=self.getTree()
153: ret=""
154: for project in projects:
155: proj=project[3]
156: try:
157: persons=proj.copyImageToMargin();
158: except:
159: logging.error("Cannnot do: %s"%repr(project))
160:
161: def transformProjectsToId(self):
162: """trnasformiere zu ID, Hilfsfunktion die die alten Templates analysiert und mit der neuen Liste
163: verantwortlicher Personen versieht"""
164: projects=self.getTree()
165: ret=""
166: for project in projects:
167:
168: proj=project[3]
169: persons=proj.identifyNames(proj.getContent('xdata_01'))
170: if not hasattr(proj,'responsibleScientistsList'):
171: proj.responsibleScientistsList=[]
172:
173: for person in persons.items():
174:
175: if len(person[1]) >1: #nicht eindeutig
176: ret+="nicht eindeutig --- %s: %s\n"%(proj.getId(),person[0])
177:
178: elif len(person[1]) ==0: #kein eintrage
179: ret+="kein eintrag--- %s: %s\n"%(proj.getId(),person[0])
180: proj.responsibleScientistsList.append((person[0],""))
181: else:
182: proj.responsibleScientistsList.append((person[0],person[1][0].getObject().getKey()))
183:
184: return ret
185:
186:
187: def harvestProjects(self):
188: """harvest"""
189: folder="/tmp"
190: try:
191: os.mkdir("/tmp/harvest_MPIWG")
192: except:
193: pass
194: founds=self.ZopeFind(self.aq_parent.projects,obj_metatypes=['MPIWGProject'],search_sub=1)
195: for found in founds:
196: txt=found[1].harvest_page()
197:
198: if txt and (txt != ""):
199: name=found[0].replace("/","_")
200: fh=file("/tmp/harvest_MPIWG/"+name,"w")
201: fh.write(txt)
202: fh.close()
203:
204: def decode(self,str):
205: """decoder"""
206:
207: if not str:
208: return ""
209: if type(str) is StringType:
210: try:
211: return str.decode('utf-8')
212: except:
213: return str.decode('latin-1')
214: else:
215: return str
216:
217:
218: def getat(self,array,idx=0,default=None):
219: """return array element idx or default (but no exception)"""
220: if len(array) <= idx:
221: return default
222: else:
223: return array[idx]
224:
225:
226: def browserCheck(self):
227: """check the browsers request to find out the browser type"""
228: bt = {}
229: ua = self.REQUEST.get_header("HTTP_USER_AGENT")
230: bt['ua'] = ua
231: bt['isIE'] = False
232: bt['isN4'] = False
233: if string.find(ua, 'MSIE') > -1:
234: bt['isIE'] = True
235: else:
236: bt['isN4'] = (string.find(ua, 'Mozilla/4.') > -1)
237:
238: try:
239: nav = ua[string.find(ua, '('):]
240: ie = string.split(nav, "; ")[1]
241: if string.find(ie, "MSIE") > -1:
242: bt['versIE'] = string.split(ie, " ")[1]
243: except: pass
244:
245: bt['isMac'] = string.find(ua, 'Macintosh') > -1
246: bt['isWin'] = string.find(ua, 'Windows') > -1
247: bt['isIEWin'] = bt['isIE'] and bt['isWin']
248: bt['isIEMac'] = bt['isIE'] and bt['isMac']
249: bt['staticHTML'] = False
250:
251: return bt
252:
253:
254: def versionHeaderEN(self):
255: """version header text"""
256:
257: date= self.REQUEST.get('date',None)
258: if date:
259: txt="""<h2>This pages shows the project which existed at %s</h2>"""%str(date)
260: return txt
261: return ""
262:
263: def versionHeaderDE(self):
264: """version header text"""
265: date= self.REQUEST.get('date',None)
266: if date:
267: txt="""<h2>Auf dieser Seite finden Sie die Projekte mit Stand vom %s</h2>"""%str(date)
268: return ""
269:
270:
271: def createOrUpdateId_raw(self):
272: """create sequence to create ids for bibliography"""
273: debug=None
274: #suche groesste existierende id
275: founds=self.ZSQLQuery("select id from bibliography")
276:
277: if founds:
278: ids=[int(x.id[1:]) for x in founds]
279: maximum=max(ids)
280:
281: id_raw=self.ZSQLQuery("select nextval('id_raw')",debug=debug)
282:
283: if id_raw:
284: self.ZSQLQuery("drop sequence id_raw",debug=debug)
285:
286: self.ZSQLQuery("create sequence id_raw start %i"%(maximum+1),debug=debug)
287:
288:
289: def queryLink(self,link):
290: """append querystring to the link"""
291: return "%s?%s"%(link,self.REQUEST.get('QUERY_STRING',''))
292:
293: def getKategory(self,url):
294: """kategorie"""
295: splitted=url.split("/")
296: return splitted[4]
297:
298: def generateUrlProject(self,url,project=None):
299: """erzeuge aus absoluter url, relative des Projektes"""
300: if project:
301: splitted=url.split("/")
302: length=len(splitted)
303: short=splitted[length-2:length]
304:
305: base=self.REQUEST['URL3']+"/"+"/".join(short)
306:
307: else:
308: findPart=url.find("/projects/")
309: base=self.REQUEST['URL1']+"/"+url[findPart:]
310:
311:
312: return base
313:
314: def isNewCapital(self,text=None,reset=None):
315: if reset:
316: self.REQUEST['capital']="A"
317: return True
318: else:
319: if len(text)>0 and not (text[0]==self.REQUEST['capital']):
320: self.REQUEST['capital']=text[0]
321: return True
322: else:
323: return False
324:
325: def subNavStatic(self,obj):
326: """subnav" von self"""
327: def sortWeight(x,y):
328: x1=int(getattr(x[1],'weight','0'))
329: y1=int(getattr(y[1],'weight','0'))
330: return cmp(x1,y1)
331:
332: subs=self.ZopeFind(obj,obj_metatypes=['MPIWGTemplate','MPIWGLink'])
333: subret=[]
334:
335: for x in subs:
336: if not(x[1].title==""):
337: subret.append(x)
338: subret.sort(sortWeight)
339: return subret
340:
341: def subNav(self,obj):
342: """return subnav elemente"""
343: def sortWeight(x,y):
344: x1=int(getattr(x[1],'weight','0'))
345: y1=int(getattr(y[1],'weight','0'))
346: return cmp(x1,y1)
347: #if obj.meta_type in ['MPIWGTemplate','MPIWGLink']:
348: # id=obj.aq_parent.getId()
349: #else:
350:
351: #id=obj.getId()
352:
353:
354: #suche die zweite ebene
355:
356: if not obj.aq_parent.getId() in ['de','en']:
357: obj=obj.aq_parent
358:
359: while not self.ZopeFind(self,obj_ids=[obj.getId()]):
360: obj=obj.aq_parent
361:
362:
363: if hasattr(self,obj.getId()):
364:
365: subs=self.ZopeFind(getattr(self,obj.getId()),obj_metatypes=['MPIWGTemplate','MPIWGLink'])
366: subret=[]
367:
368: for x in subs:
369: if not(x[1].title==""):
370: subret.append(x)
371: subret.sort(sortWeight)
372: return subret
373: else:
374: return None
375:
376: def isType(self,object,meta_type):
377: """teste ob ein object vom meta_type ist."""
378: return (object.meta_type==meta_type)
379:
380: def isActive(self,name):
381: """teste ob subnavigation aktiv"""
382: for part in self.REQUEST['URL'].split("/"):
383: if part==name:
384: return True
385: return False
386:
387:
388: def getSections(self):
389: """returns a list of all sections i.e. top-level MPIWGFolders"""
390: secs = self.objectItems(['MPIWGFolder'])
391: secs.sort(sortWeight)
392: #logging.debug("root: %s secs: %s"%(repr(self.absolute_url()), repr(secs)))
393: # return pure list of objects
394: return [s[1] for s in secs]
395:
396: def getSectionStyle(self, name, style=""):
397: """returns a string with the given style + '-sel' if the current section == name"""
398: if self.getSection() == name:
399: return style + '-sel'
400: else:
401: return style
402:
403: def getFeatures(self):
404: """returns a list of all Features"""
405: dir = getattr(self, 'features')
406: features = dir.objectItems(['MPIWGFeature'])
407: features.sort(sortWeight)
408: # return pure list of objects
409: return [f[1] for f in features]
410:
411:
412: def MPIWGrootURL(self):
413: """returns the URL to the root"""
414: return self.absolute_url()
415:
416: def upDateSQL(self,fileName):
417: """updates SQL databases using fm.jar"""
418: fmJarPath=os.path.join(package_home(globals()), 'updateSQL/fm.jar')
419: xmlPath=os.path.join(package_home(globals()), "updateSQL/%s"%fileName)
420: logger("MPIWG Web",logging.INFO,"java -classpath %s -Djava.awt.headless=true Convert %s"%(fmJarPath,xmlPath))
421: ret=os.popen("java -classpath %s -Djava.awt.headless=true Convert %s"%(fmJarPath,xmlPath),"r").read()
422: logger("MPIWG Web",logging.INFO,"result convert: %s"%ret)
423: return 1
424:
425: def patchProjects(self,RESPONSE):
426: """patch"""
427: projects=self.ZopeFind(self.projects,obj_metatypes=['MPIWGProject'])
428: for project in projects:
429: tmp=project[1].WEB_project_description[0].replace("/CD/projects/","")[0:]
430: setattr(project[1],'WEB_project_description',[tmp[0:]])
431: RESPONSE.write("<p>%s</p>\n"%project[0])
432:
433: def replaceNotEmpty(self,format,field):
434: """replace not empty"""
435: if field and (not field.lstrip()==''):
436: return self.decode(format%field)
437: else:
438: return ""
439:
440:
441: def isActiveMember(self,key):
442: """tested ob Mitarbeiter key ist aktiv"""
443: key=utf8ify(key)
444: ret=self.getat(self.ZSQLInlineSearch(_table='personal_www',
445: _op_key='eq',key=key,
446: _op_publish_the_data='eq',
447: publish_the_data='yes'))
448:
449: logging.info("ACTIVE_MEMBER %s"%ret)
450: if ret:
451: return True
452: else:
453: return False
454:
455: def isActual(self,project):
456: """checke if project is actual"""
457: actualTime=time.localtime()
458:
459: if hasattr(project,'getObject'): #obj ist aus einer catalogTrefferList
460: obj=project.getObject()
461: else:
462: obj=project
463:
464: if getattr(obj,'archiveTime',actualTime)< actualTime:
465: return False
466: else:
467: return True
468:
469: def redirectIndex_html(self,request):
470: #return request['URL1']+'/index_html'
471:
472: return urllib.urlopen(request['URL1']+'/index_html').read()
473:
474:
475: def formatBibliography(self,here,found):
476: """format"""
477: return formatBibliography(here,found)
478:
479: def getValue(self,fieldStr):
480: """Inhalt des Feldes"""
481:
482: if type(fieldStr)==StringType:
483: field=fieldStr
484: else:
485: field=fieldStr[0]
486: try:
487: if field[len(field)-1]==";":
488: field=field[0:len(field)-1]
489: except:
490:
491: """nothing"""
492: field=re.sub(r';([^\s])','; \g<1>',field)
493: return field.encode('utf-8')
494:
495:
496:
497: def sortedNames(self,list):
498: """sort names"""
499:
500: def sortLastName(x_c,y_c):
501: try:
502: x=urllib.unquote(x_c).encode('utf-8','ignore')
503: except:
504: x=urllib.unquote(x_c)
505:
506: try:
507: y=urllib.unquote(y_c).encode('utf-8','ignore')
508: except:
509: x=urllib.unquote(y_c)
510:
511:
512:
513: try:
514: last_x=x.split()[len(x.split())-1]
515: last_y=y.split()[len(y.split())-1]
516:
517: except:
518:
519: last_x=""
520: last_y=""
521:
522:
523:
524: if last_x<last_y:
525: return 1
526: elif last_x>last_y:
527: return -1
528: else:
529: return 0
530:
531: list.sort(sortLastName)
532: list.reverse()
533:
534: return list
535:
536: def __init__(self, id, title):
537: """init"""
538: self.id=id
539: self.title=title
540:
541: def removeStopWords(self,xo):
542: """remove stop words from xo"""
543: if not hasattr(self,'_v_stopWords'):
544: self._v_stopWords=self.stopwords_en.data.split("\n")
545:
546: x=str(xo)
547:
548: strx=x.split(" ")
549:
550: for tmp in strx:
551:
552: if tmp.lower() in self._v_stopWords:
553: del strx[strx.index(tmp)]
554:
555: return " ".join(strx)
556:
557: def urlQuote(self,str):
558: """quote"""
559: return urllib.quote(str)
560:
561: def urlUnQuote(self,str):
562: """quote"""
563: return urllib.unquote(str)
564:
565:
566:
567: def getProjectsByFieldContent(self,fieldName,fieldContentsEntry, date=None):
568: """gib alle Projekte aus mit Value von field mit fieldName enthaelt ein Element der Liste fieldContents"""
569: def sort(x,y):
570: return cmp(x.WEB_title[0],y.WEB_title[0])
571:
572: if type(fieldContentsEntry) is StringType:
573: fieldContentsTmp=[fieldContentsEntry]
574: else:
575: fieldContentsTmp=fieldContentsEntry
576:
577: fieldContents=[]
578: for x in fieldContentsTmp:
579: fieldContents.append(" AND ".join(x.split()))
580: projects=self.ProjectCatalog({fieldName:string.join(fieldContents,' AND')})
581: #print projects
582: #ret=[x for x in projects]
583: ret=[]
584: for x in projects:
585: obj=x.getObject()
586: obj=obj.getActualVersion(date)
587: if obj and (not getattr(obj,'invisible',None)):
588: #if not (x in ret):
589: ret.append(x)
590:
591: ret.sort(sort)
592: return ret
593:
594: def changeMPIWGRootForm(self):
595: """edit"""
596: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeMPIWGRootForm')).__of__(self)
597: return pt()
598:
599: def changeMPIWGRoot(self,title,disciplineList,themesList,connection_id,RESPONSE=None):
600: """change"""
601: self.title=title
602: self.connection_id=connection_id
603: self.disciplineList=disciplineList
604: self.themesList=themesList
605:
606: if RESPONSE is not None:
607: RESPONSE.redirect('manage_main')
608:
609:
610: def getContexts(self,childs=None,parents=None,depth=None,date=None,onlyActive=True):
611: """childs alle childs, alle parents"""
612: ret=[]
613:
614: if parents:
615: pnums=parents.split(".")
616: while len(pnums) > 1:
617: pnums.pop()
618: parentId=string.join(pnums,".")
619:
620: for project in self.getProjectFields('xdata_05',sort='int',date=date):
621: if project[1]==parentId:
622: ret.append(project)
623:
624: if (depth is not None) and (len(ret) >= depth):
625: break
626:
627: if childs:
628: for project in self.getProjectFields('xdata_05',sort='int',date=date):
629: searchStr=childs+"(\..*)"
630:
631: if (onlyActive and project[0].isActiveProject()) or (not onlyActive):
632: if re.match(searchStr,project[1]):
633:
634: if depth:
635:
636: if int(depth)>=len(project[1].split("."))-len(childs.split(".")):
637:
638: ret.append(project)
639: else:
640: ret.append(project)
641:
642: #logging.debug("getContexts: childs=%s parents=%s depth=%s => %s"%(childs,parents,depth,repr(ret)))
643: return ret
644:
645:
646: def getProjectFields(self,fieldName,date=None,folder=None,sort=None):
647: """getListofFieldNames"""
648: ret=[]
649:
650: objects=self.ZopeFind(self.projects,obj_metatypes=['MPIWGProject'],search_sub=0)
651:
652:
653: for object in objects:
654: obj=object[1]
655: obj=obj.getActualVersion(date)
656: if obj and (not getattr(obj,'invisible',None)):
657: if fieldName=="WEB_title_or_short":
658:
659: if len(obj.getContent('xdata_07'))<3: # hack weil z.Z. manchmal noch ein Trennzeichen ; oder , im Feld statt leer
660: fieldNameTmp="WEB_title"
661: else:
662: fieldNameTmp="xdata_07"
663: else:
664: fieldNameTmp=fieldName
665:
666: ret.append((obj,obj.getContent(fieldNameTmp)))
667:
668:
669: if sort=="int":
670: ret.sort(sortI)
671: elif sort=="stopWords":
672:
673: ret.sort(sortStopWords(self))
674:
675: else:
676: ret.sort(sortF)
677:
678: return ret
679:
680: def showNewProjects(self):
681: projects=[]
682: for objs in self.getProjectFields('WEB_title_or_short'): # Get all Projets
683: if objs[0].xdata_05 and (objs[0].xdata_05[0] == ""):
684:
685: projects.append(objs)
686:
687: return projects
688:
689:
690: manage_options = Folder.manage_options+(
691: {'label':'Update personal homepages','action':'updatePersonalwww_html'},
692: {'label':'Reindex catalogs','action':'reindexCatalogs'},
693: {'label':'Main config','action':'changeMPIWGRootForm'},
694: {'label':'add e-mails','action':'showNewDBEntries'},
695: {'label':'update the institutsbibliography','action':'updateInstitutsbiliography'},
696: #{'label':'Edit Historical Persons','action':'editHistoricalPersonsForm'},
697: #{'label':'Store Historical Persons','action':'storeHistoricalPersons'},
698: )
699:
700:
701: def updatePublicationDB(self,personId=None):
702: """updates the publication db, i.e. copy year and type into the main table"""
703:
704: if personId:
705: founds = self.ZSQLInlineSearch(_table="publications",key_main=personId)
706: else:
707: founds = self.ZSQLInlineSearch(_table="publications")
708:
709: for found in founds:
710:
711: if found.id_institutsbibliographie and (not found.id_institutsbibliographie =="") and (not found.id_institutsbibliographie =="0"):
712:
713: entries = self.ZSQLInlineSearch(_table="institutsbiblio",id=found.id_institutsbibliographie)
714: for entry in entries:
715: self.ZSQLChange(_table='publications',_identify='oid=%s' % found.oid,year=entry.year,referencetype=entry.reference_type)
716:
717: if found.id_gen_bib and (not found.id_gen_bib ==""):
718: entries = self.ZSQLInlineSearch(_table="bibliography",id=found.id_gen_bib)
719: for entry in entries:
720: self.ZSQLChange(_table='publications',_identify='oid=%s' % found.oid,year=entry.year,referencetype=entry.reference_type)
721:
722: return True
723:
724: def showNewDBEntries(self):
725: """zeige neue Eintraege in der Datenbank ohne e-mail adressen bzw. fuer die noch kein Object angelegt wurde"""
726:
727: qstr="select * from personal_www where web_object_created='no' and not key=''"
728: res=self.ZSQLQuery(qstr)
729:
730: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','showNewDBEntries.zpt')).__of__(self)
731: return pt(newEntries=res)
732:
733: def createNewStaffObjects(self,RESPONSE):
734: """create new staff object"""
735:
736: memberFolder=getattr(self,'members')
737: args=self.REQUEST.form
738: arg_k=args.keys()
739: arg_k.remove("submit")
740: ret=""
741: for key in arg_k:
742: k=self.urlUnQuote(key)
743:
744: qstr="select * from personal_www where key=%s"%self.ZSQLQuote(k)
745: res=self.ZSQLQuery(qstr)[0]
746: if args[key]!="": #email-adresse wurde eingetragen
747: #create the object
748: e_mail=args[key]
749: try:
750: newObj=MPIWGStaff.MPIWGStaff(e_mail,res.last_name,res.first_name,k)
751: memberFolder._setObject(e_mail,newObj)
752: obj=getattr(memberFolder,e_mail)
753: obj.reindex_object()
754: ret+="Created %s \n"%e_mail
755: created=True
756: except:
757: msg="Cannot create new user %s (%s %s)"%(e_mail,sys.exc_info()[0],sys.exc_info()[1])
758: logging.error(msg)
759: ret+=msg+"\n"
760: created=False
761:
762: if created:
763: qstr="update personal_www set web_object_created='yes',e_mail='%s@mpiwg-berlin.mpg.de' where key=%s"%(e_mail,self.ZSQLQuote(k))
764: self.ZSQLQuery(qstr)
765:
766: return ret
767:
768:
769: def generateNewPersonEntry(self,data):
770: """generate a new person entry for data, neue personen werden zunaechst nur in der datenbank angelegt """
771:
772: #memberFolder=getattr(self,'members')
773: #create the object
774:
775: # try:
776: # newObj=MPIWGStaff.MPIWGStaff(urllib.quote(data['key']),data['last_name'].encode('utf-8'),data['first_name'].encode('utf-8'))
777: # memberFolder._setObject(urllib.quote(data['key']),newObj)
778: # except:
779: # return False, "Cannot create new user %s (%s %s)"%(data['key'],sys.exc_info()[0],sys.exc_info()[1])
780: #
781:
782: #create the new entry in the database
783:
784:
785: result,msg=MPIWGStaff.createNewDBEntry(self,data['publish_the_data'],data['key'],data['last_name'],
786: data['first_name'],data['title'],data['status'],"",
787: "",data['date_from'],data['date_to'],
788: data['department'],data['home_inst'],data['funded_by'],
789: data['e_mail2'],data['current_work'],"yes",data['date_stay_at_mpiwg'],data['group'],"no",data['current_work'])
790:
791: return result,msg
792:
793: def updatePersonEntry(self,data,ignoreEntries=[]):
794: """update an person entry from data. but ignore all fields in ignore Entries"""
795:
796: ignoreEntries.append('current_work') # TODO:updatecurrent work
797:
798: if data['date_to']=="": # wenn date_to leer
799: data['date_to']="date_none"
800:
801: if data['date_from']=="": # wenn date_fromleer
802: data['date_from']="date_none"
803: msg=""
804:
805:
806: #eintragen
807:
808: columns=data.keys()
809: for x in ignoreEntries:
810: logging.info("ign rem: %s"%x)
811: try: #falls in ignore entries felder sind, die nicht in columns sind, fange den fehler ab
812: columns.remove(x)
813: except:
814: pass
815:
816:
817: insert=[]
818: for key in columns:
819: if data[key]=="date_none": # date_none eintrag wird zu null uebersetzt
820: insert.append('%s=null'%key)
821: else:
822: insert.append(""" "%s"=%s"""%(key,self.ZSQLQuote(data[key])))
823:
824: insertStr=",".join(insert)
825: queryStr="update personal_www SET %s where key='%s'"%(insertStr,data['key'])
826: self.ZSQLQuery("SET DATESTYLE TO 'German'")
827: self.ZSQLQuery(queryStr)
828:
829: #currentwork
830: #if not (txt==""):
831: # queryStr="INSERT INTO current_work (id_main,current,publish) VALUES ('%s','%s','%s')"%(id,txt,txt_p)
832: #
833: # self.ZSQLQuery(queryStr)
834:
835: return True,msg
836:
837:
838: def updatePersonalwww_doIt(self):
839: """do the update"""
840: args=self.REQUEST.form
841: resultSet=self.REQUEST.SESSION['personal_www']['resultSet']
842: news=self.REQUEST.SESSION['personal_www']['news']
843: conflicts=self.REQUEST.SESSION['personal_www']['conflicts']
844: ret="<html><body>"
845: # generate the new entry
846:
847: if news and (len(news)>0):
848: ret+="<h2>Hinzugefügt</h2>"
849: ret+="<p>Neueinträge erscheinen erst auf der Homepage, wenn ihnen eine e-mail Adresse zugeordnet wurde.</p>"
850: ret+="<ul>"
851: for new in news:
852:
853: if args.has_key(self.urlQuote(new.encode('utf-8'))): # entry was selected
854: result,msg=self.generateNewPersonEntry(resultSet[new])
855: if not result:
856: logging.error("Error (generateNewPersonEntry) %s"%msg)
857: ret+="<li>ERROR: %s %s"%(new.encode('utf-8'),msg)
858: else:
859: ret+="<li>OK: %s"%(new.encode('utf-8'))
860: if news and (len(news)>0):
861: ret+="<p>Neueinträge erscheinen erst auf der Homepage, wenn ihnen eine e-mail Adresse zugeordnet wurde.</p>"
862: ret+="</ul>"
863:
864: # update
865:
866: if len(conflicts.keys())>0:
867: ret+="<h2>Änderung des Benutzers übernehmen</h2>"
868: ret+="<p>Wenn nötig in Filemaker-db ändern:</p>"
869:
870: # konflicte
871: for conflict in conflicts.keys():
872: ignoreEntries=[]
873: displayIgnored=[]
874: for cf in conflicts[conflict]:
875: if args[conflict.encode('utf-8')+'_'+cf[0]]=="stored": #use the stored one
876: ignoreEntries.append(cf[0]) #so ignore field cf[0]
877: displayIgnored.append(cf)
878: if len(displayIgnored)>0:
879: ret+="<h3>%s</h3>"%conflict.encode('utf-8')
880:
881: ret+="<table border='1'>"
882: for iE in displayIgnored:
883: ret+="<tr><td>%s</td><td>%s</td><td>%s</td>"%(iE[0].encode('utf-8'),iE[1].encode('utf-8'),iE[2].encode('utf-8'))
884: ret+="</tabel>"
885:
886: self.updatePersonEntry(resultSet[conflict],ignoreEntries=ignoreEntries)
887:
888: # rest
889: cl=list(conflicts.keys())
890:
891: for key in resultSet.keys():
892: if key not in cl:
893: self.updatePersonEntry(resultSet[key])
894: return ret+"</body></html>"
895:
896:
897: def updateInstitutsbiliography(self):
898: """update the Institutsbibliogrpahy"""
899: self.upDateSQL('personalwww.xml')
900: return "<html><body>DONE</body></html>"
901:
902:
903:
904:
905: def updatePersonalwww_html(self):
906: """update form for the homepages web form"""
907: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','updatePersonalwww.zpt')).__of__(self)
908: return pt()
909:
910:
911: def updatePersonalwww(self,uploadfile):
912: """update personalwww
913: @param uploadfile: file handle auf das file
914: """
915: dsn=self.getConnectionObj().connection_string
916: #dsn="dbname=personalwww"
917: resultSet=updatePersonalWWW.importFMPXML(uploadfile)
918: news,conflicts=updatePersonalWWW.checkImport(dsn, resultSet)
919:
920: self.REQUEST.SESSION['personal_www']={}
921: self.REQUEST.SESSION['personal_www']['resultSet']=resultSet
922: self.REQUEST.SESSION['personal_www']['news']=news
923: self.REQUEST.SESSION['personal_www']['conflicts']=conflicts
924:
925: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','updatePersonalwww_check.zpt')).__of__(self)
926: return pt()
927:
928:
929:
930: def reindexCatalogs(self,RESPONSE=None):
931: """reindex members and project catalog"""
932:
933:
934: try:
935:
936: self.ProjectCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
937: except:
938: logger("MPIWG Root (updatehomepage)",logging.WARNING," %s %s"%sys.exc_info()[:2])
939:
940:
941:
942:
943:
944: if RESPONSE:
945: RESPONSE.redirect('manage_main')
946:
947:
948:
949:
950: def getAllMembers(self):
951: #ret=[]
952:
953: def sorter(x,y):
954: return cmp(x[0],y[0])
955:
956: results=self.MembersCatalog({'isPublished':True})
957:
958: ret=[(", ".join([proj.lastName, proj.firstName]).decode('utf-8'),proj.getKey) for proj in results]
959:
960: ret.sort(sorter)
961: return ret
962:
963:
964: def printAllMembers(self):
965: """print"""
966: members=self.getAllMembers()
967: ret=""
968: for x in members:
969: ret+="<p>%s</p>"%x
970: return ret
971:
972:
973: def makeList(self,entry):
974: """makes a list out of one entry or repeat a list"""
975: if type(entry) is StringType:
976: return [entry]
977: else:
978: return entry
979:
980: def getTreeRSS(self,dep=None,date=None,onlyActive=1,onlyArchived=0):
981: """generateTree"""
982: rss="""<?xml version="1.0" encoding="utf-8"?>
983: <rss version="2.0">
984: <channel>"""
985:
986: for obj in self.getTree(dep, date, onlyActive, onlyArchived):
987: linkStr="""<link>http://wwwneu.mpiwg-berlin.mpg.de/en/research/projects/%s</link>"""
988: rss+="""<item>"""
989: rss+=linkStr%obj[3].getId()
990: rss+="""</item>"""
991: if hasattr(obj[3],'publicationList'):
992: rss+="""<item>"""
993: rss+=linkStr%(obj[3].getId()+"/publicationList");
994: rss+="""</item>"""
995: rss+="""</channel>
996: </rss>"""
997:
998:
999: return rss
1000:
1001: def getTree(self,dep=None,date=None,onlyActive=0,onlyArchived=0):
1002: """generate Tree from project list
1003: als Liste, jeder Eintrag ist ein Tupel ,(Tiefe, ProjektNummer,ProjektObject
1004: onlyActive = 0 : alle Projekte
1005: onlyActive = 1 : nur active Projekte
1006: onlyActive = 2: nur inactive Projekte
1007:
1008: onlyArchived=0: alle Projekte
1009: onlyArchived= 1 : nur aktuelle Projekte
1010: onlyArchived = 2: nur archivierte Projekte
1011: """
1012:
1013: returnListTmp=[]
1014: returnList=[]
1015:
1016: for project in self.getProjectFields('xdata_05',sort="int",date=date): # get Projects sorted by xdata_05
1017:
1018: for idNr in project[1].split(";"): # more than one number
1019: if not idNr=="":
1020: splittedId=idNr.split(".")
1021: depth=len(splittedId)
1022: nr=idNr
1023: #title=project[0].WEB_title
1024: title=[project[0].getContent('WEB_title')]
1025: #print title
1026:
1027: if idNr[0]=="x": # kompatibilitaet mit alter Konvention, x vor der Nummer macht project inactive
1028: project[0].setActiveFlag(False)
1029:
1030: if (not dep) or (idNr[0]==dep): #falls dep gesetzt ist nur dieses hinzufuegen.
1031:
1032: if (onlyActive==0):
1033: returnListTmp.append((depth,nr,title,project[0]))
1034: elif (onlyActive==1) and project[0].isActiveProject(): #nur active projekte
1035: returnListTmp.append((depth,nr,title,project[0]))
1036: elif (onlyActive==2) and (not project[0].isActiveProject()): #nur active projekte
1037: returnListTmp.append((depth,nr,title,project[0]))
1038:
1039:
1040: #filter jetzt die Liste nach Archived oder nicht
1041: for entry in returnListTmp:
1042: if (onlyArchived==0):
1043: returnList.append(entry)
1044: elif (onlyArchived==1) and (not entry[3].isArchivedProject()): #nur active projekte
1045: returnList.append(entry)
1046: elif (onlyArchived==2) and (entry[3].isArchivedProject()): #nur active projekte
1047: returnList.append(entry)
1048:
1049:
1050: return returnList
1051:
1052:
1053:
1054: def changePosition(self,treeId,select,RESPONSE=None):
1055: """Change Postion Entry"""
1056: numbers=[]
1057:
1058: # Suche hoechste bisherige nummer
1059: projects=self.getProjectFields('xdata_05') # get Projects sorted by xdata_05
1060: #print "pj",projects
1061: for project in projects: #suche alle subtrees der treeId
1062: #print treeId
1063:
1064: founds=re.match(treeId+"\.(.*)",project[1].split(";")[0])
1065: if founds:
1066: #print "x",founds.group(0),len(founds.group(0).split("."))
1067: if len(founds.group(0).split("."))==len(treeId.split("."))+1: # nur ein punkt mehr, d.h. untere ebene
1068: try:
1069: numbers.append(int(founds.group(0).split(".")[len(founds.group(0).split("."))-1]))
1070: except:
1071: numbers.append(int(0))
1072:
1073: try:
1074: highest=max(numbers)
1075: except:
1076: highest=0
1077: projects=self.showNewProjects()
1078: for i in self.makeList(select):
1079: highest+=10
1080: projects[int(i)][0].xdata_05=treeId+"."+str(highest)
1081:
1082:
1083: if RESPONSE is not None:
1084: RESPONSE.redirect('showTree')
1085:
1086: def changeTree(self,RESPONSE=None):
1087: """change the complete tree"""
1088: form=self.REQUEST.form
1089: hashList={}
1090: onlyArchived=int(form.get("onlyArchived",0))
1091: onlyActive=int(form.get("onlyActive",0))
1092:
1093:
1094: fields=self.getTree(onlyArchived=onlyArchived,onlyActive=onlyActive)
1095:
1096: logging.info("GOT TREE!----------------------------------------------------")
1097: for field in form.keys():
1098:
1099: splitted=field.split('_')
1100: if (len(splitted)>1) and (splitted[1]=="runningNumber"): #feld hat die Form Nummer_name und runnignNumber
1101:
1102:
1103: nr=int(splitted[0]) # nummer des Datensatzes
1104: currentEntry = fields[nr]
1105:
1106: if form.has_key(str(nr)+'_active'): # active flag is set
1107: fields[nr][3].setActiveFlag(True)
1108: else:
1109: fields[nr][3].setActiveFlag(False)
1110:
1111: #nummer hat sich geŠndert
1112:
1113: entryChanged = False;
1114:
1115:
1116: if not (fields[nr][3].xdata_05==form[str(nr)+'_number']):
1117: logging.info("Changed!Number+++++++++++++++++++++++++++++++++")
1118: fields[nr][3].xdata_05=form[str(nr)+'_number']
1119: entryChanged = True
1120:
1121: #completed har sich geaendert
1122:
1123: if not (fields[nr][3].getCompletedAt()==fields[nr][3].transformDate(form[str(nr)+'_completed'])):
1124: fields[nr][3].setCompletedAt(form[str(nr)+'_completed'])
1125: logging.info("Changed!Completed+++++++++++++++++++++++++++++++++")
1126: entryChanged = True
1127:
1128: if not (fields[nr][3].getStartedAt()==fields[nr][3].transformDate(form[str(nr)+'_started'])):
1129: fields[nr][3].setStartedAt(form[str(nr)+'_started'])
1130: logging.info("Changed!Started+++++++++++++++++++++++++++++++++")
1131: entryChanged = True
1132:
1133:
1134: if entryChanged:
1135: logging.info("Changed!+++++++++++++++++++++++++++++++++")
1136: fields[nr][3].copyObjectToArchive()
1137:
1138:
1139: if RESPONSE is not None:
1140: RESPONSE.redirect('showTree')
1141:
1142: def getProjectWithId(self,id):
1143: fields=self.getProjectFields('xdata_05')
1144: for field in fields:
1145: if field[1]==id:
1146: return field[0]
1147:
1148: return None
1149:
1150:
1151:
1152:
1153: def getRelativeUrlFromPerson(self,list):
1154: """get urls to person list"""
1155: ret=[]
1156: persons=list.split(";")
1157: for person in persons:
1158:
1159: if len(person)>1: #nicht nur Trennzeichen
1160: splitted=person.split(",")
1161: if len(splitted)==1:
1162: splitted=person.split(" ")
1163: splittedNew=[re.sub(r'\s(.*)','$1',split) for split in splitted]
1164: if splittedNew[0]=='':
1165: del splittedNew[0]
1166: search=string.join(splittedNew,' AND ')
1167:
1168: if not search=='':
1169:
1170: try:
1171: proj=self.MembersCatalog({'title':search})
1172: except:
1173: proj=None
1174:
1175: if proj:
1176: #ret.append("<a href=%s >%s</a>"%(proj[0].absolute_url,person.encode('utf-8')))
1177: ret.append("<a href=%s >%s</a>"%('members/'+proj[0].id+'/index.html',person))
1178: else:
1179: #ret.append("%s"%person.encode('utf-8'))
1180: ret.append("%s"%person)
1181: return string.join(ret,";")
1182:
1183: def getMemberIdFromKey(self,key):
1184: """gibt die ensprechende id im members Ordner zum key"""
1185:
1186: if key=="":
1187: return ""
1188: key=utf8ify(key)
1189: catalogged=self.MembersCatalog({'getKey':key})
1190: if len(catalogged)==0:
1191: return ""
1192: else:
1193: return catalogged[0].getObject().getId()
1194:
1195:
1196:
1197:
1198: def getProjectsOfMembers(self,date=None):
1199: """give tuple member /projects"""
1200: ret=[]
1201: members=self.getAllMembers()
1202: logging.error("X %s"%repr(members))
1203: #return str(members)
1204: for x in members:
1205: logging.error("X %s"%repr(x))
1206: projects=self.getProjectsOfMember(key=x[1],date=date)
1207: if len(projects)>0:
1208: ret.append((x[0],projects))
1209:
1210: return ret
1211:
1212: def getProjectsOfMember(self,key=None,date=None,onlyArchived=1,onlyActive=1):
1213: """get projects of a member
1214:
1215: @param key: (optional) Key zur Idenfikation des Benutzer
1216: @param date: (optional) Version die zum Zeitpunkt date gueltig war
1217: @param onlyArchived:
1218: onlyArchived=0: alle Projekte
1219: onlyArchived= 1 : nur aktuelle Projekte
1220: onlyArchived = 2: nur archivierte Projekte
1221: """
1222: # TODO: Die ganze Loesung
1223: def sortP(x,y):
1224: """sort by sorting number"""
1225: return cmp(x.WEB_title,y.WEB_title)
1226:
1227: ret=[]
1228: if key:
1229: proj=self.ProjectCatalog({'getPersonKeyList':utf8ify(key)})
1230: else:
1231: return ret # key muss definiert sein
1232:
1233:
1234: if proj:
1235: proj2=[]
1236: for x in proj:
1237: #logging.error("proj:%s"%repr(x.getPath()))
1238: if (not getattr(x.getObject(),'invisible',None)) and (getattr(x.getObject(),'archiveTime','')==''):
1239: proj2.append(x)
1240:
1241: else:
1242: proj2=[]
1243:
1244:
1245:
1246: proj2.sort(sortP)
1247:
1248: projectListe=[]
1249: #logging.error("getprojectsofmember proj2: %s"%repr(proj2))
1250: for proj in proj2:
1251: obj=proj.getObject()
1252: add=False
1253: if onlyArchived==1: #nur aktuell projecte
1254: if not obj.isArchivedProject():
1255: add=True
1256: elif onlyArchived==2: #nur archivierte
1257: if obj.isArchivedProject():
1258: add=True
1259: else: #alle
1260: add=True
1261:
1262: if onlyActive==1: #nur active projecte
1263: if obj.isActiveProject():
1264: add=add & True
1265: else:
1266: add=add & False
1267:
1268: elif onlyArchived==2: #nur nicht aktvive
1269: if not obj.isActiveProject():
1270: add=add & True
1271: else: #alle
1272: add=add & True
1273:
1274: if add:
1275: projectListe.append(obj)
1276:
1277: #logging.error("getprojectsofmember projectliste: %s"%repr(projectListe))
1278: return projectListe
1279:
1280: def givePersonList(self,name):
1281: """check if person is in personfolder and return list of person objects"""
1282:
1283: splitted=name.split(",")
1284: if len(splitted)==1:
1285: splitted=name.lstrip().rstrip().split(" ")
1286: splittedNew=[split.lstrip() for split in splitted]
1287:
1288: if splittedNew[0]=='':
1289: del splittedNew[0]
1290: search=string.join(splittedNew,' AND ')
1291:
1292: if not search=='':
1293: proj=self.MembersCatalog({'title':search})
1294:
1295: if proj:
1296: return [[x.lastName,x.firstName] for x in proj]
1297: else:
1298: return []
1299:
1300: ## splitted=name.split(",") # version nachname, vorname...
1301: ## if len(splitted)>1:
1302: ## lastName=splitted[0]
1303: ## firstName=splitted[1]
1304: ## else:
1305: ## splitted=name.split(" ") #version vorname irgenwas nachnamae
1306:
1307: ## lastName=splitted[len(splitted)-1]
1308: ## firstName=string.join(splitted[0:len(splitted)-1])
1309:
1310: ## objs=[]
1311:
1312: #print self.members
1313: ## for x in self.members.__dict__:
1314: ## obj=getattr(self.members,x)
1315: ## if hasattr(obj,'lastName') and hasattr(obj,'firstName'):
1316:
1317: ## if (re.match(".*"+obj.lastName+".*",lastName) or re.match(".*"+lastName+".*",obj.lastName)) and (re.match(".*"+obj.firstName+".*",firstName) or re.match(".*"+firstName+".*",obj.firstName)):
1318:
1319: ## objs.append((obj,lastName+", "+firstName))
1320:
1321:
1322: ## return objs
1323:
1324:
1325: def personCheck(self,names):
1326: """all persons for list"""
1327: #print "names",names
1328: splitted=names.split(";")
1329: ret={}
1330: for name in splitted:
1331:
1332: if not (name==""):
1333: try:
1334: ret[name]=self.givePersonList(name)
1335: except:
1336: """NOTHIHN"""
1337: #print "RET",ret
1338: return ret
1339:
1340: def giveCheckList(self,person,fieldname):
1341: """return checklist"""
1342: #print "GCL",fieldname
1343: if fieldname=='xdata_01':
1344: x=self.personCheck(person.getContent(fieldname))
1345: #print "GCLBACKX",x
1346: return x
1347:
1348:
1349: def isCheckField(self,fieldname):
1350: """return chechfield"""
1351:
1352: return (fieldname in checkFields)
1353:
1354:
1355: def generateNameIndex(self):
1356: """erzeuge einen index verwendeter personen"""
1357: import psycopg
1358: o = psycopg.connect('dbname=authorities user=dwinter password=3333',serialize=0)
1359: results={}
1360: print self.fulltext.historicalNames.items()
1361: for nameItem in self.fulltext.historicalNames.items(): #gehe durch alle namen des lexikons
1362:
1363: c = o.cursor()
1364: name=nameItem[0]
1365: print "check",name
1366: c.execute("select lastname,firstname from persons where lower(lastname) = '%s'"%quote(name))
1367: tmpres=c.fetchall()
1368: firstnames=[result[1] for result in tmpres] # find all firstnames
1369: if tmpres:
1370: lastname=tmpres[0][0]
1371:
1372: for found in self.fulltext({'names':name}):
1373: if found.getObject().isActual():
1374: for nh in found.getObject().getGetNeighbourhood(name, length=50,tagging=False): #hole umgebung
1375: #schaue nun ob der vorname hinter oder vor dem name ist
1376: position=nh.find(lastname)
1377: # vorher
1378: #print "NH",nh
1379: bevorS=nh[0:position].split()
1380: #print "BV",bevorS
1381: if len(bevorS)>1:
1382: try:
1383: bevor=[bevorS[-1],bevorS[-2]]
1384: except:
1385: bevor=[bevorS[0]]
1386: else:
1387: bevor=[]
1388: #nachher
1389: behindS= re.split("[,|;| ]",nh[position:])
1390: #print "BH",behindS
1391: if len(behindS)>2:
1392: try:
1393: behind=behindS[1:3]
1394: except:
1395: behind=[bevorS[1]]
1396: else:
1397: behind=[]
1398: for firstname in firstnames:
1399: if firstname in bevor+behind: #Namen wie mit Adelspraedikaten werden so erstmal nich gefunden
1400: id="%s,%s"%(lastname,firstname)
1401: if not results.has_key(id):
1402: results[id]=[]
1403: objId=found.getObject().getId()
1404: if not (objId in results[id]):
1405: print "d %s for %s"%(id,objId)
1406: results[id].append(objId)
1407: self.nameIndex=results
1408: return results
1409:
1410: def editNameIndexHTML(self):
1411: """edit the name index"""
1412: if not hasattr(self,'nameIndexEdited'): # falls editierter index noch nicht existiert, kopiere automatisch erstellten
1413: self.nameIndexEdited=copy.copy(self.nameIndex)
1414: print "huh"
1415: #self.nameIndexEdited=copy.copy(self.nameIndex)
1416: #print self.nameIndexEdited
1417: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editHistoricalNames.zpt')).__of__(self)
1418: return pt()
1419:
1420: def getNamesInProject(self,projectId):
1421: """get all names ofnameIndexEdited which are references in projec with projectId"""
1422:
1423: ret=[]
1424: for name in self.nameIndexEdited.keys():
1425: if projectId in self.nameIndexEdited[name]:
1426: ret.append(name)
1427:
1428: return ret
1429:
1430: def editNameIndex(self,RESPONSE=None,name=None,occurrances=None,submit=None):
1431: """edit the index"""
1432: nI=self.nameIndexEdited # mI introduced to make sure that changes to nameIndexEdited are know to ZODB
1433: if submit=="delete":
1434:
1435:
1436: dh=getattr(self,'deletedHistoricalNames',{})
1437:
1438: if type(dh) is ListType:
1439: dh={}
1440: if not dh.has_key(name):
1441: dh[name]=occurrances.split("\n")
1442: else:
1443: dh[name]+=occurrances.split("\n")
1444:
1445: self.deletedHistoricalNames=dh
1446:
1447: del self.nameIndexEdited[name]
1448:
1449:
1450: elif (submit=="change"):
1451:
1452: nI[name]=occurrances.split("\n")[0:]
1453:
1454: elif (submit=="add"):
1455: if not nI.has_key(name):
1456: nI[name]=occurrances.split("\n")
1457: else:
1458: nI[name]+=occurrances.split("\n")
1459:
1460: self.nameIndexEdited=nI
1461:
1462:
1463: if RESPONSE is not None:
1464: RESPONSE.redirect('editNameIndexHTML')
1465:
1466:
1467:
1468: def restoreIndex(self):
1469: """restore"""
1470: self.nameIndexEdited=self.nameIndex
1471: return "done"
1472:
1473:
1474:
1475: def manage_addMPIWGRootForm(self):
1476: """form for adding the root"""
1477: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGRootForm.zpt')).__of__(self)
1478: return pt()
1479:
1480: def manage_addMPIWGRoot(self,id,title,connection_id="",RESPONSE=None):
1481: """add a root folder"""
1482: newObj=MPIWGRoot(id,title)
1483: self._setObject(id,newObj)
1484: ob=getattr(self,id)
1485: setattr(ob,'connection_id',connection_id)
1486: if RESPONSE is not None:
1487: RESPONSE.redirect('manage_main')
1488:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>