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