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