1: """This contains the class MPIWG Projects
2: for organizing and maintaining the different project pages
3:
4: $author dwinter - last change 26.06.2008
5:
6: """
7: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
8: from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
9: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
10: from Products.MPIWGBibliography.BibliographyManager import BibliographyManager
11: from OFS.Image import Image
12: from Globals import package_home
13: import urllib
14: import re
15: import os
16: from types import *
17: import logging
18: import xmlhelper # Methoden zur Verwaltung der projekt xml
19: from OFS.SimpleItem import SimpleItem
20: from OFS.Folder import Folder
21: from OFS.Image import Image
22: from AccessControl import ClassSecurityInfo
23: from AccessControl import getSecurityManager
24: from bibliography import *
25: import time
26: from OFS.Cache import Cacheable
27: #import xml.dom.minidom
28: import sys
29: #from Ft.Xml.XPath import Evaluate
30: #from Ft.Xml.XPath.Context import Context
31: #from Ft.Xml.Domlette import NonvalidatingReader,PrettyPrint, Print
32: #from Ft.Xml import EMPTY_NAMESPACE
33: #import copy
34: #import updatePersonalWWW
35:
36: #import MPIWGStaff
37:
38: from MPIWGHelper import *
39:
40: import MPIWGRoot
41: import MPIWGLink
42: import MPIWGTemplate
43:
44: # die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus Kompatibilitaetsgruenden, bleiben die Klassen hier noch drin.
45: # Sonst funktionieren die alten Webseiten nicht mehr.
46:
47: class MPIWGRoot(MPIWGRoot.MPIWGRoot):
48: """depricated"""
49:
50: class MPIWGLink(MPIWGLink.MPIWGLink):
51: """depricated"""
52:
53: class MPIWGTemplate(MPIWGTemplate.MPIWGTemplate):
54: """depricated"""
55:
56: class MPIWGProject_publication(Folder):
57: """publications object fuer project"""
58:
59: meta_type="MPIWGProject_publication"
60:
61: def editPublication(self,text=None,image1=None,image2=None,description=None,RESPONSE=None):
62: """edit a publication"""
63:
64: if (not text) and (not description):
65: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_publicationForm.zpt')).__of__(self)
66: return pt()
67:
68:
69: self.text=text[0:]
70: self.description=description
71:
72: if image1:
73: if hasattr(self,'publicationImage1'):
74: self.publicationImage1.manage_upload(image1)
75: else:
76: nO = Image('publicationImage1','',image1)
77: self._setObject('publicationImage1',nO)
78:
79: if image2:
80: if hasattr(self,'publicationImage2'):
81: self.publicationImage2.manage_upload(image2)
82: else:
83: nO = Image('publicationImage2','',image2)
84: self._setObject('publicationImage2',nO)
85:
86:
87: if RESPONSE:
88: RESPONSE.redirect("../managePublications")
89:
90: class MPIWGProject_image(Image):
91: """Images for Projects"""
92:
93: meta_type="MPIWGProject_image"
94:
95: def showImage(self,imageUrl=None):
96: """show Images at an extra page"""
97: self.getContent('WEB_project_description',filter='yes') #get the content and store image infos into session
98: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','projectImageView.zpt')).__of__(self)
99: return pt()
100:
101: def editImage(self,file=None,caption=None,RESPONSE=None):
102: """edit the Image"""
103: if (not file) and (not caption):
104: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_imageForm.zpt')).__of__(self)
105: return pt()
106:
107: if file and (not file.filename.lstrip().rstrip()==""):
108: self.manage_upload(file)
109:
110: if caption:
111: self.caption=caption[0:]
112:
113: if RESPONSE:
114: RESPONSE.redirect("../manageImages")
115:
116: class MPIWGProject(CatalogAware,Folder,Cacheable):
117: """Class for Projects"""
118:
119:
120: security=ClassSecurityInfo()
121: meta_type='MPIWGProject'
122: default_catalog='ProjectCatalog'
123:
124: def decode(self,str):
125: """return unicode object"""
126: return unicodify(str)
127:
128: def sortedByPlace(self,metatype):
129: """find metatype and sort by place"""
130: def sort(x,y):
131: return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0))
132:
133: founds=self.ZopeFind(self,obj_metatypes=[metatype]);
134:
135: founds.sort(sort)
136:
137: return founds
138:
139:
140: def copyPublicationsToList(self,RESPONSE=None):
141: """copy publications in to list"""
142:
143: publicationTxt=self.getContent('WEB_related_pub')
144:
145: pubSplits=publicationTxt.split("<p>")
146:
147: for pubSplit in pubSplits:
148: pubSplit=pubSplit.replace("</p>","")
149: self.addPublication(pubSplit)
150:
151: if RESPONSE:
152: RESPONSE.redirect('managePublications')
153:
154:
155: def copyImageToMargin(self,RESPONSE=None):
156: """copy inline images to marginal images"""
157:
158:
159: #getImages from WEB_project_description
160: description=self.getContent('WEB_project_description')
161:
162: text2=description
163: splitted=text2.split("""<p class="picture">""")
164:
165: imageURLs=[]
166: imageCaptions=[]
167: for split in splitted[1:]:
168: tmp=split.split("</p>")
169: #return repr(splitted[1])
170:
171: try:
172: imageURLs.append(tmp[0].split("\"")[1].encode('utf-8'))
173: except:
174:
175: try:
176: imageURLs.append(tmp[0].split("src=")[1].split(" ")[0].encode('utf-8'))
177: except:
178: imageURLs.append("")
179:
180: split2="</p>".join(tmp[1:])
181:
182:
183: splitted=split2.split("""<p class="picturetitle">""")
184: if len(splitted)>1:
185: tmp=splitted[1].split("</p>")
186: imageCaptions.append(tmp[0].encode('utf-8'))
187:
188:
189: else:
190: #keine caption
191:
192: imageCaptions.append("")
193:
194:
195: #eintragen:
196: for imageURL in imageURLs:
197: filename=imageURL.split("/")[-1]
198: #lege neues images object an, mit leerem bild
199:
200: if self.ZopeFind(self,obj_ids=[filename]):
201: #existiert das bild schon, dann neuen filenamen
202: filename="project_image_"+filename
203:
204: self.addImage(None,imageCaptions[imageURLs.index(imageURL)],filename=filename)
205: #hole die bilddaten aus der url
206: url=self.absolute_url()+"/"+imageURL
207: #url=self.absolute_url()+"/"+filename
208:
209: try:#relative url
210: data=urllib.urlopen(url).read()
211: except:
212: try:#absolute
213: data=urllib.urlopen(self.imageURL).read()
214: except:
215: logger("MPIWG Project",logging.ERROR,"can't open: %s"%url)
216:
217: obj=getattr(self,filename)
218: obj.update_data(data)
219:
220: if RESPONSE:
221: RESPONSE.redirect('manageImages')
222:
223: def manageImages(self,imageName=None,op=None):
224: """managage images"""
225:
226:
227: if imageName and op:
228: if op=='up':
229: images=self.getImages()
230: for image in images:
231: if image[0]==imageName:
232: nr=images.index(image)
233: if not nr==0:
234: images[nr-1][1].place+=1
235: images[nr][1].place-=1
236: pass
237: elif op=='down':
238: images=self.getImages()
239: for image in images:
240: if image[0]==imageName:
241: nr=images.index(image)
242: if not (nr==len(images)-1):
243: images[nr+1][1].place-=1
244: images[nr][1].place+=1
245: pass
246:
247:
248: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_manageImagesForm.zpt')).__of__(self)
249: return pt()
250:
251: def managePublications(self,pubName=None,op=None):
252: """managage images"""
253:
254:
255: if pubName and op:
256: if op=='up':
257: publications=self.getPublications()
258: for publication in publications:
259: if publication[0]==pubName:
260: nr=publications.index(publication)
261: if not nr==0:
262: publications[nr-1][1].place+=1
263: publications[nr][1].place-=1
264: pass
265: elif op=='down':
266: publications=self.getPublications()
267: for publication in publications:
268: if publication[0]==pubName:
269: nr=publications.index(publication)
270: if not (nr==len(publications)-1):
271: publications[nr+1][1].place-=1
272: publications[nr][1].place+=1
273: pass
274:
275:
276: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_managePublicationsForm.zpt')).__of__(self)
277: return pt()
278: def hasExtendedPublicationList(self):
279: """test if extended publication list exists"""
280: if not hasattr(self,"publicationList"):
281: return False
282: else:
283: return True
284:
285: def createExtendedPublicationList(self,RESPONSE=None):
286: """erzeuge erweiterte publications liste"""
287: pl = BibliographyManager("publicationList","","institutsbiblio",self.connection_id)
288: self._setObject("publicationList", pl)
289:
290:
291: zt=ZopePageTemplate('index.html')
292: pl._setObject('index.html',zt)
293: default_content_fn = os.path.join(package_home(globals()),
294: 'zpt/showExtendedProjectBibliography.zpt')
295: text = open(default_content_fn).read()
296: zt.pt_edit(text, 'text/html')
297:
298:
299: if RESPONSE:
300: RESPONSE.redirect("managePublications")
301:
302: def getPublications(self):
303: """get all Publications"""
304: def sort_images(x,y):
305: return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0))
306:
307: publications=self.ZopeFind(self,obj_metatypes=['MPIWGProject_publication'])
308:
309: publications.sort(sort_images)
310: return publications
311:
312: def addPublication(self,text,RESPONSE=None):
313: """add an MPIWG_Publication"""
314:
315: name="publication_"+str(self.getLastPublicationNumber()+1)
316:
317: newPublication=MPIWGProject_publication(name)
318:
319: self._setObject(name,newPublication)
320: obj=getattr(self,name)
321: obj.text=text[0:]
322: obj.enabled=True;
323: obj.place=self.getLastPublicationNumber()+1
324: obj.id=name
325:
326: if RESPONSE is not None:
327: RESPONSE.redirect('managePublications')
328:
329:
330: def getLastPublicationNumber(self):
331: publications=self.getPublications()
332:
333: if not publications:
334: return 0
335: else:
336: return getattr(publications[-1][1],'place',0)
337:
338: def deletePublication(self,id,RESPONSE=None):
339: """delete Publication id"""
340: self.manage_delObjects([id])
341: if RESPONSE:
342: RESPONSE.redirect('managePublications')
343:
344: def getImages(self):
345: """get all Images"""
346:
347: def sort_images(x,y):
348: return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0))
349:
350:
351: if (getattr(self,'imageURL','')!='') or (getattr(self,'imagecap','')!='') :
352: try:
353: self.addImage(None,getattr(self,'imagecap',''),RESPONSE=None,filename=getattr(self,'imageURL',''))
354: except:
355: pass
356: self.imageURL=''
357: self.imagecap=''
358:
359: images=self.ZopeFind(self,obj_metatypes=['MPIWGProject_image'])
360:
361: images.sort(sort_images)
362: return images
363:
364: def getLastImageNumber(self):
365: images=self.getImages()
366:
367: if not images:
368: return 0
369: else:
370: return getattr(images[-1][1],'place',0)
371:
372: def deleteImage(self,id,RESPONSE=None):
373: """delete Image id"""
374: try:
375: self.manage_delObjects([id])
376: except:
377: logging.error("ERROR MPIWG: %s %s"%sys.exc_info()[0:2])
378: if RESPONSE:
379: RESPONSE.redirect('manageImages')
380:
381:
382: def hasChildren(self,date=None,onlyActive=1,onlyArchived=1):
383: """check if project has children"""
384: ct=self.getContexts(childs=self.getContent('xdata_05'),
385: depth=1,date=date,onlyActive=onlyActive)
386:
387: if ct and len(ct)>0:
388: return True
389: else:
390: return False
391:
392:
393: def addImage(self,fileHd,caption,RESPONSE=None,filename=None):
394: """add an MPIWG_Project_image"""
395:
396: if not filename:
397: filename=fileHd.filename
398:
399: if not fileHd:
400: fileHd=file(os.path.join(package_home(globals()),'blank.gif'))
401:
402: newImage=MPIWGProject_image(filename,filename,fileHd)
403:
404: self._setObject(filename,newImage)
405: obj=getattr(self,filename)
406: obj.caption=caption[0:]
407: obj.enabled=True;
408: obj.place=self.getLastImageNumber()+1
409: obj.id=filename
410:
411: if RESPONSE is not None:
412: RESPONSE.redirect('manageImages')
413:
414: def PrincipiaSearchSource(self):
415: """Return cataloguable key for ourselves."""
416: return str(self)
417:
418: def versionHeader(self):
419: """version Header, gibt header text entsprechend der aktuellen version aus"""
420:
421: actualTime=time.localtime()
422: retTXT="""<h2>This is an outdated version, for the actual version please refer to <a href="%s">%s</a></h2>"""
423: s=self.aq_parent.absolute_url()
424: #print getattr(self,'archiveTime',actualTime)
425: if getattr(self,'archiveTime',actualTime)< actualTime:
426: return retTXT%(s,s)
427: else:
428: return ""
429:
430: def getActualVersion(self,date=None):
431: """actuelle version"""
432: def sortProjectsByTime(x,y):
433: return cmp(x[1].archiveTime,y[1].archiveTime)
434:
435: if not date:
436: if self.isActual():
437: return self
438: else:
439: return None
440:
441: #suche ob aeltere versionen vorhanden sind
442:
443: finds=self.ZopeFind(self,obj_metatypes=['MPIWGProject'])
444: if not finds: #wenn nicht dann teste ob die aktuelle version schon existiert hat.
445: ad=getattr(self,'creationTime','20050101000000')
446: if int(date)>int(ad):
447: return self
448: else:
449: return None
450:
451:
452: else:
453: finds.sort(sortProjectsByTime)
454:
455: for find in finds:
456: #gehe durch die alten Projekte und finde das entprechende
457: if (int(find[1].archiveTime) > int(date)) and (int(date)>int(getattr(find[1],'creationTime','20050101000000'))):
458: return find[1]
459:
460: #kein passendes gefunden, dann teste ob das aktuelle in frage kommt
461: ad=getattr(self,'creationTime','20050101000000')
462:
463: if int(date)>int(ad):
464:
465: return self
466: else:
467: return None
468:
469:
470: def isActual(self):
471: """gibt 1 zurueck wenn aktuell, 0 sonst"""
472: actualTime=time.localtime()
473:
474:
475: #print getattr(self,'archiveTime',actualTime)
476: if getattr(self,'archiveTime',actualTime)< actualTime:
477: return 0
478: else:
479: return 1
480:
481: def copyObjectToArchive(self):
482: """kopiere aktuelles objekt ins archiv"""
483: cb=self.aq_parent.manage_copyObjects(self.getId())
484: self.manage_pasteObjects(cb)
485: actualTime=time.localtime()
486:
487: self.manage_renameObject(self.getId(),self.getId()+"_"+time.strftime("%Y%m%d%H%M%S",actualTime))
488: obj=getattr(self,self.getId()+"_"+time.strftime("%Y%m%d%H%M%S",actualTime))
489: obj.setArchiveTime(time.strftime("%Y%m%d%H%M%S",actualTime))
490: ids=[x[0] for x in self.ZopeFind(obj,obj_metatypes=['MPIWGProject'])]
491: obj.manage_delObjects(ids)
492:
493: def setArchiveTime(self,time):
494: """set Archive Time"""
495: self.archiveTime=time[0:]
496:
497: def versionManageForm(self):
498: """version Manage form:currently only set to invisible"""
499: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_versionManageForm.zpt')).__of__(self)
500: return pt()
501:
502: def versionManage(self,invisible=None,RESPONSE=None):
503: """version Manage form:currently only set to invisible"""
504: self.invisible=invisible
505:
506: if RESPONSE is not None:
507: RESPONSE.redirect('manage_main')
508:
509:
510: def crossLinker(self):
511: """experimental crosslinker"""
512: splitted=self.WEB_project_description[0].split()
513: new=[]
514: for split in splitted:
515: try:
516: found=self.DescriptionCatalog({'fulltext':split})
517:
518: if len(found)>1:
519:
520: new.append("<a href=%s>%s</a>"%(split,split))
521: else:
522: new.append(split)
523: except:
524: new.append(split)
525: return " ".join(new)
526:
527:
528:
529:
530: def generateTemplate(self,RESPONSE=None):
531: """Erzeuge Template fuer defined fields not_used"""
532:
533: id="index_html"
534: title=id
535: if self._getOb('index_html'):
536: self._delObject('index_html')
537:
538:
539: newObj=ZopePageTemplate(id,'TEXT')
540: self._setObject(id,newObj)
541: #self.manage_addPageTemplate(id,title)
542: if RESPONSE is not None:
543: RESPONSE.redirect('manage_main')
544:
545: def __init__(self, id, argv=None):
546: """initiere classe"""
547:
548: self.creationTime=time.strftime("%Y%m%d%H%M%S",time.localtime())[0:]
549: self.id=id
550: self.title=id
551: self.isActiveFlag=True #Flag is true is the project is still active, False if accomplished
552: self.responsibleScientistsList=[] # enthaelt die Lister der verantwortlichen Wissenschaftler in der Form (NAME, KEY), key ist "" flass Wissenschaftler nicht an unserem Haus
553:
554: if argv:
555: for arg in definedFields:
556: try:
557: setattr(self,arg,argv[arg])
558: except:
559: setattr(self,arg,"")
560: else:
561: for arg in definedFields:
562: setattr(self,arg,'')
563:
564: manage_options = Folder.manage_options+(
565: {'label':'Load New File','action':'loadNewFileForm'},
566: {'label':'Edit ProjectInfo','action':'editMPIWGProjectForm'},
567: {'label':'Edit BasisInfo','action':'editMPIWGBasisForm'},
568: {'label':'Edit Publications','action':'editMPIWGRelatedPublicationsForm'},
569: {'label':'Edit Themes & Disciplines','action':'editMPIWGDisciplinesThemesForm'},
570: {'label':'Versionmanager','action':'versionManageForm'},
571: )
572:
573:
574: def isActiveProject(self):
575: """check if the project is still active, default is true, set to false is the project is accomplished"""
576: return getattr(self,'isActiveFlag',True)
577:
578: def isArchivedProject(self):
579: """check if the project is archived"""
580:
581: completed=self.getCompletedAt()
582:
583: #completed leer
584: if completed=="" :
585: return False;
586: if completed == 0:
587: return False;
588:
589:
590: return True
591:
592:
593: def setActiveFlag(self,status=True):
594: """set the active flag"""
595: self.isActiveFlag=status
596:
597: def setCompletedAt(self,date):
598: """set the date of completion, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY"""
599: #logging.info("DATE:"+repr(date))
600: transformedDate=self.transformDate(date);
601: #logging.info("transformed"+repr(transformedDate))
602: if transformedDate is not None:
603: setattr(self,"completedAt",transformedDate)
604: return True;
605: else:
606: return False;
607:
608: def setStartedAt(self,date):
609: """set the date of start, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY"""
610: #logging.info("DATE:"+repr(date))
611: transformedDate=self.transformDate(date);
612: #logging.info("transformed"+repr(transformedDate))
613: if transformedDate is not None:
614: setattr(self,"startedAt",transformedDate)
615: return True;
616: else:
617: return False;
618:
619: def getCompletedAt(self):
620: """gibt das transformierte Datum zurueck, an dem das Projekt beendet wurde."""
621: date=getattr(self,'completedAt','')
622: if date:
623: return self.reTransformDate(date);
624: else:
625: # test ob parent abgeschlossen ist
626: try: #TODO: ersetzte try except durch vernuenftige abfrage
627: ct=self.getContexts(parents=self.getContent('xdata_05'),depth=1)
628: if (len(ct)>0): #is there are parent
629:
630: return ct[0][0].getCompletedAt()
631: return '';
632: except:
633: return '';
634:
635: def getStartedAt(self):
636: """gibt das transformierte Datum zurŸck, an dem Projekt begonnen wurde."""
637: date=getattr(self,'startedAt','')
638: if date:
639: return self.reTransformDate(date);
640: else:
641: return '';
642:
643: def reTransformDate(self,date):
644: """transformiert , transformdate zurueck"""
645: year=int(date/10000)
646: month=int((date-year*10000)/100)
647: day=int((date-year*10000-month*100))
648: if (day==0) and (month==0):
649: return """%s"""%year;
650: if day==0 :
651: return """%s.%s"""%(month,year);
652:
653: return """%s.%s.%s"""%(day,month,year);
654:
655:
656: def transformDate(self,date):
657: """transformiert ein Datum von DD.MM.YYYY, MM.YYYY,YYYY nach YYYYMMDD, alle nicht angebebenn Werte
658: werden auf 0 gesetzt, es wird null zurŸckgegeben falls das Datum ungueltig ist"""
659:
660: if (date==None):
661: return None;
662:
663:
664: if (date.lstrip().rstrip()=="" ) :
665: return "";
666:
667: splitted=date.split(".")
668: length=len(splitted)
669: year=0
670: month=0
671: day=0
672: if length > 3:
673: return "";
674: if length==3:
675: day = int(splitted[0])
676: if length>1:
677: month=int(splitted[length-2])
678:
679: if length > 0:
680: try:
681: year = int(splitted[length-1])
682: except:
683: pass
684:
685: ## logging.info("month:"+(month))
686: if not (0<=month<13):
687: return None;
688:
689: if not(0<=day<32):
690: return None;
691:
692: if (year>0) and (year<1900): #jahr nicht vierstellig eingegeben
693: year=2000+year;
694: return year*10000+month*100+day
695:
696:
697:
698: def checkDate(self,date):
699: """teste ob zum Zeitpunkt date eine andere version existierte"""
700:
701:
702: def sortProjectsByTime(x,y):
703: return cmp(x[1].archiveTime,y[1].archiveTime)
704:
705: #suche ob aeltere versionen vorhanden sind
706:
707: finds=self.ZopeFind(self,obj_metatypes=['MPIWGProject'])
708: if not finds: #wenn nicht dann teste ob die aktuelle version schon existiert hat.
709: ad=getattr(self,'creationTime','20050101000000')
710: if int(date)>int(ad):
711: return self.REQUEST['URL1']+"/"+self.getId()
712: else:
713: return self.REQUEST['URL1']+"/no_project"
714:
715:
716: else:
717: finds.sort(sortProjectsByTime)
718:
719: for find in finds:
720: #gehe durch die alten Projekte und finde das entprechende
721: if (int(find[1].archiveTime) > int(date)) and (int(date)>int(getattr(find[1],'creationTime','20050101000000'))):
722: return self.REQUEST['URL1']+"/"+find[1].getId()
723:
724: #kein passendes gefunden, dann teste ob das aktuelle in frage kommt
725: ad=getattr(self,'creationTime','20050101000000')
726:
727: if int(date)>int(ad):
728:
729: return self.REQUEST['URL1']+"/"+self.getId()
730: else:
731: return self.REQUEST['URL1']+"/no_project"
732:
733:
734: def no_project(self):
735: """warnung: project noch nicht existent"""
736: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','no_project')).__of__(self)
737: return pt()
738:
739:
740: def harvest_page(self,context=None):
741: """seite fuer harvesting fuer die Projektsuche"""
742: if not context:
743: context=self
744:
745: if self.isActiveProject() and self.isActual():
746: ext=getattr(self,"harvest_main",None)
747: if ext:
748: return getattr(self,ext.getId())()
749:
750: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','harvest_main')).__of__(context)
751:
752:
753: return pt()
754:
755: def index_html(self,request=True,context=None):
756: """show homepage"""
757:
758: bound_names={}
759:
760: if not context:
761: context=self
762: if request:
763: if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected',None)==None:
764: self.REQUEST.SESSION['MPI_redirected']=1
765: self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date'])+"?date="+self.REQUEST['date'])
766: else:
767: self.REQUEST.SESSION['MPI_redirected']=None
768:
769: #ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
770:
771:
772: request2=getattr(self,'REQUEST',None)
773:
774: if request2 is not None:
775: response = request2.response
776: if not response.headers.has_key('content-type'):
777: response.setHeader('content-type', 'text/html')
778:
779: security = getSecurityManager()
780: bound_names['user'] = security.getUser()
781:
782:
783: # Retrieve the value from the cache.
784: keyset = None
785: if self.ZCacheable_isCachingEnabled():
786:
787: # Prepare a cache key.
788: keyset = {'here': self, 'params':request2['QUERY_STRING']}
789:
790: result = self.ZCacheable_get(keywords=keyset)
791:
792: if result is not None:
793: # Got a cached value.
794: return result
795:
796: pt = getTemplate(self, "project_main")
797: # Execute the template in a new security context.
798: security.addContext(self)
799:
800: try:
801: result = pt.pt_render(extra_context=bound_names)
802: if keyset is not None:
803: # Store the result in the cache.
804: self.ZCacheable_set(result, keywords=keyset)
805:
806: return result
807: finally:
808: security.removeContext(self)
809:
810:
811:
812: def index_html_old(self,request=True,context=None):
813: """show homepage"""
814: if not context:
815: context=self
816: if request:
817: if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected',None)==None:
818: self.REQUEST.SESSION['MPI_redirected']=1
819: self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date'])+"?date="+self.REQUEST['date'])
820: else:
821: self.REQUEST.SESSION['MPI_redirected']=None
822:
823: #ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
824:
825: ext=getattr(self,"project_main",None)
826: if ext:
827: return getattr(self,ext.getId())()
828:
829: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','project_main')).__of__(context)
830:
831: return pt()
832:
833:
834: def getDataFields(self):
835: """giveListofDatafields"""
836: ret=[]
837: for x in range(1,14):
838: if not x in [6,10,9]: # not used fields
839: ret.append('xdata_%02i'%x)
840: return ret
841:
842: def getDefinedFields(self):
843: """show all defined fields"""
844:
845: return definedFields
846:
847: def getAttribute(self,field):
848: """get attrbiute"""
849: return getattr(self,field)
850:
851: def getContent(self,field,filter=None):
852: """Inhalt des Feldes"""
853:
854: if field=="short_title":
855: text = self.getContent("xdata_07")
856: if text=="":
857: text = self.getContent("WEB_title")
858: return text
859:
860: text=u''
861:
862: for x in getattr(self,field):
863:
864: try:
865: text +=x
866: except:
867: text = x
868:
869:
870:
871: try:
872: if text[len(text)-1]==";":
873: text=text[0:len(text)-1]
874:
875:
876: except:
877: pass
878:
879: if text=='': ## wozu die folgenden Zeilen??
880: text2=text
881: else:
882: text2=re.sub(r';([^\s])','; \g<1>',text)
883:
884: if field=="WEB_project_description":##Jedenfalls darf letzteres nicht gemacht werden, falls normaler text
885: text2=text
886:
887: #teste ob ergebnis leer und header dann nehme title
888:
889: if (text2=='') and (field=='WEB_project_header'):
890: return self.getContent('WEB_title')
891:
892: if filter:
893: splitted=text2.split("""<p class="picture">""")
894: if len(splitted)>1:
895: tmp=splitted[1].split("</p>")
896: #return repr(splitted[1])
897: try:
898: self.imageURL=tmp[0].split("\"")[1].encode('utf-8')
899: except:
900: try:
901: self.imageURL=tmp[0].split("src=")[1].split(" ")[0].encode('utf-8')
902: except:
903: self.imageURL=""
904:
905: split2="</p>".join(tmp[1:])
906:
907: text3=splitted[0]+split2
908:
909: splitted=text3.split("""<p class="picturetitle">""")
910: if len(splitted)>1:
911: tmp=splitted[1].split("</p>")
912: self.imagecap=tmp[0].encode('utf-8')
913:
914: split4="".join(tmp[1:])
915:
916: text5=splitted[0]+split4
917: else:
918: #keine caption
919: text5=text3
920: else:
921: #kein bild
922: text5=text2
923: else:
924: text5=text2
925:
926: #teste ob WEB_project_description und keine fuehrenden p tags
927: if (len(text5)>4) and (not text5[0:3]=='<p>') and (field=='WEB_project_description'):
928: text5= "<p>"+text5+"</p>"
929:
930:
931: #filter image
932:
933: text5=text5.lstrip().rstrip() #loescher leerzeichen und einzelndes br
934: if (text5=="<br>") or (text5=="<br/>"):
935: text5=""
936:
937: #logging.debug("getcontent: field=%s filter=%s -> %s"%(field,filter,repr(text5)))
938: return unicodify(text5)
939: #return utf8ify(text5) # return as utf-8 byte string
940:
941:
942: def showImagesOfPage(self,imageUrl=None):
943: """show Images of project"""
944: self.getContent('WEB_project_description',filter='yes') #get the content and store image infos into session
945: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','projectImageView.zpt')).__of__(self)
946: return pt()
947:
948:
949: def show_html(self):
950: """simple index"""
951: #return "HI"
952: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_index.zpt')).__of__(self)
953: return pt()
954:
955: def saveFromPreview(self):
956: """save content aus preview"""
957: self.WEB_project_description=self.previewTemplate.WEB_project_description[0:]
958: self.REQUEST.RESPONSE.redirect("./index.html")
959:
960: def saveEditedContent(self,kupu=None,preview=None):
961: """save Edited content"""
962:
963: if preview:
964: kupu=preview
965: #find content of body tags
966: start=kupu.find("<body>")
967: end=kupu.find("</body>")
968: newcontent= kupu[start+6:end]
969:
970: if preview:
971:
972: return self.preview(newcontent)
973:
974: self.copyObjectToArchive()
975: self.ZCacheable_invalidate()
976: self.WEB_project_description=newcontent[0:]
977:
978: self.REQUEST.RESPONSE.redirect("./index.html")
979:
980: return True
981:
982: security.declareProtected('View management screens','edit')
983: def edit(self,western=None):
984: """Edit pages"""
985: if western:
986: self.REQUEST.RESPONSE.setCookie("MP_debug_code","western",path="/")
987:
988:
989: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGProjectNeu.zpt')).__of__(self)
990: return pt()
991:
992: edit_MPIWGProject_main = PageTemplateFile('zpt/edit_MPIWGProject_main', globals())
993:
994: def getPathStyle(self, path, selected, style=""):
995: """returns a string with the given style + 'sel' if path == selected."""
996:
997: if path == selected:
998: return style + 'sel'
999: else:
1000: return style
1001:
1002: def getLabel(self):
1003: """returns label (or title) of this project"""
1004: l = self.getContent('xdata_07')
1005: if l:
1006: return l
1007: l = self.getContent('WEB_title')
1008: if l:
1009: return l
1010: return self.title
1011:
1012: def getBreadcrumbs(self):
1013: """return list of breadcrumbs from here to the root"""
1014: crumbs = []
1015: # skip direct parent Folder /projects/
1016: parent = self.aq_parent.aq_parent
1017: # get parents breadcrumbs
1018: if hasattr(parent, 'getBreadcrumbs'):
1019: crumbs = parent.getBreadcrumbs()
1020:
1021: # try to get acquisition URL from parent
1022: if hasattr(parent, 'absolute_url'):
1023: baseUrl = "%s/%s/"%(parent.absolute_url(), 'projects')
1024: else:
1025: baseUrl = "/en/research/projects/"
1026:
1027: # add in the internal project hierarchy
1028: ct=self.getContexts(parents=self.getContent('xdata_05'))
1029: # start with grandparents
1030: ct.reverse()
1031: for c in ct:
1032: label = shortenString(c[0].getLabel(), 13)
1033: crumbs.append((label, baseUrl+c[0].getId(), c[0]))
1034:
1035: # add this project
1036: crumbs.append((self.getLabel(), baseUrl+self.getId(), self))
1037:
1038: return crumbs
1039:
1040: def getRootProject(self):
1041: """returns the root (=top level) project of the current project"""
1042: ct=self.getContexts(parents=self.getContent('xdata_05'))
1043: if len(ct) > 0:
1044: return ct[-1][0]
1045: else:
1046: return self
1047:
1048:
1049: def preview(self,description):
1050: """preview"""
1051: tmpPro=getattr(self,"previewTemplate",None)
1052: if not tmpPro:
1053: tmpPro=MPIWGProject("previewTemplate")
1054: self._setObject("previewTemplate",tmpPro)
1055: for field in definedFields:
1056: setattr(tmpPro,field,getattr(self,field))
1057: tmpPro.WEB_project_description=description[0:]
1058: tmpPro.invisible=True
1059: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','previewFrame.zpt')).__of__(self)
1060: return pt()
1061:
1062: #return self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+"/previewTemplate")
1063:
1064:
1065: def getWebProject_description(self):
1066: """get description"""
1067: debug= self.REQUEST.cookies.get("MP_debug_code",None)
1068:
1069: if debug and debug=="western":
1070: return """
1071: <html>
1072: <head>
1073: <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
1074: </head>
1075: <body>%s
1076: </html></body>
1077: """%self.WEB_project_description[0]
1078:
1079: return """
1080: <html>
1081: <head>
1082: <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
1083: </head>
1084: <body>%s
1085: </html></body>
1086: """%self.getContent('WEB_project_description')
1087:
1088:
1089:
1090: def editMPIWGProjectForm(self):
1091: """editform"""
1092: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGProject.zpt')).__of__(self)
1093: return pt()
1094:
1095: def isResponsibleScientist(self,key):
1096: """teste ob eine Person in der Liste der respl. scientists auftaucht"""
1097: #logging.info("XXXXXXXXXXXXX"+repr(self.responsibleScientistsList))
1098:
1099:
1100: keys = [unicodify(x[1]) for x in getattr(self,"responsibleScientistsList",[])]
1101: #logging.error("RESP. SCIEN:%s"%getattr(self,"responsibleScientistsList",[]))
1102: #logging.error("RESP. SCIEN:%s"%unicodify(key))
1103:
1104: if unicodify(key) in keys:
1105: return True
1106: else:
1107: return False
1108:
1109: def getPersonKeyList(self):
1110: """gibt die key Liste der beteiligten Personen zurŸck (utf8 codiert)"""
1111: #logging.error("getPersonKeyList:%s"%getattr(self,'responsibleScientistsList',[]))
1112: try:
1113: return [utf8ify(x[1]) for x in getattr(self,'responsibleScientistsList',[])]
1114: except:
1115: return[]
1116:
1117:
1118: def myCapitalize(self,txt):
1119: """kapitalisiere auch Namen mit -"""
1120: splitted=[x.capitalize() for x in txt.split("-")]
1121: return "-".join(splitted)
1122:
1123: def getNamesOrdered(self,list):
1124: """Sortiert die Liste nach der Reihenfolge in xdata_01"""
1125:
1126: nameList=self.getContent('xdata_01')
1127: if nameList.find(";")>-1: # rate Trenner ist ;
1128: names=nameList.split(";")
1129: else:
1130: names=nameList.split(",")
1131:
1132: self._v_names=[]
1133: for name in names:
1134: self._v_names.append(name.rstrip().lstrip())
1135:
1136:
1137: def sort(x,y):
1138: try:
1139: return cmp(self._v_names.index(x[0]),self._v_names.index(y[0]))
1140: except:
1141: return 0
1142:
1143: list.sort(sort)
1144:
1145: return list
1146:
1147: ##nameList=nameList.replace(";",",") # falls ; als Trenner ersetze
1148:
1149:
1150:
1151:
1152: def identifyNames(self,nameList):
1153: """Bekommt eine Komma oder Semikolon getrennte Liste mit Name der Form Vorname MittelName(n) Nachname
1154: und ordnet diese dann Mitarbeiter IDs zu falls es schone eine Liste gibt wird im Projekte gibt wird diese Upgedated.
1155: @param nameList
1156: """
1157:
1158: if nameList.find(";")>-1: # rate Trenner ist ;
1159: names=nameList.split(";")
1160:
1161: else:
1162: names=nameList.split(",")
1163:
1164: ##nameList=nameList.replace(";",",") # falls ; als Trenner ersetze
1165: returnNamesDict={}
1166:
1167:
1168: for name in names:
1169: name=name.lstrip().rstrip()
1170: nameSplitted = name.split(" ")
1171: if len(nameSplitted)>1: #vor und nachname angegeben)
1172:
1173: lastname=nameSplitted[-1]
1174: firstname=nameSplitted[0]
1175: else:
1176: firstname =""
1177: lastname=nameSplitted[0]
1178:
1179: #finde Mitarbeiter mit den entsprechenden Name
1180:
1181: firstname=self.myCapitalize(firstname).encode('utf-8')
1182: lastname=self.myCapitalize(lastname).encode('utf-8')
1183: logging.info("Search: %s %s %s"%(name,repr(firstname),repr(lastname)))
1184: try:
1185: cataloggedNames=self.MembersCatalog(firstName=firstname,lastName=lastname)
1186: except:
1187: cataloggedNames=[]
1188: logging.error("ERROR: identifyNames %s %s"%sys.exc_info()[0:2])
1189:
1190: #Teste ob die ensprechenden Namen schon der Liste zu geordnet sind
1191: #if not hasattr(self,'responsibleScientistsList'):
1192: # self.responsibleScientistsList={}
1193: #
1194: # if name in self.responsibleScientistsList.values()
1195:
1196: if len(cataloggedNames)>0:
1197: returnNamesDict[name]=cataloggedNames
1198: else:
1199: returnNamesDict[name]=[]
1200:
1201: logging.error("id: %s"%repr(returnNamesDict))
1202: return returnNamesDict
1203:
1204: def editMPIWGProject(self,RESPONSE=None,fromEdit=None):
1205: """edit the project and archive the old version"""
1206:
1207: self.copyObjectToArchive() # archive the object
1208: self.ZCacheable_invalidate()
1209:
1210: for x in definedFields:
1211: if self.REQUEST.has_key(x):
1212:
1213: setattr(self,x,[self.REQUEST[x].decode('utf-8')])
1214:
1215:
1216:
1217:
1218: completedAt = self.REQUEST.get('completedAt')
1219: if not self.setCompletedAt(completedAt):
1220: RESPONSE.redirect('./editMPIWGBasisEditor?error="dateWrong')
1221:
1222: startedAt = self.REQUEST.get('startedAt')
1223: if not self.setStartedAt(startedAt):
1224: RESPONSE.redirect('./editMPIWGBasisEditor?error="dateWrong')
1225:
1226: if self.REQUEST.has_key('historicalNames'):
1227: self.en.changeHistoricalNames(self.getId(),self.REQUEST['historicalNames'].split("\n"))
1228:
1229: if self.REQUEST.has_key('active'):
1230: self.setActiveFlag(True)
1231: else:
1232: self.setActiveFlag(False)
1233:
1234: self.responsibleScientistsList=[] # setze die Liste der verantwortlichen Wissenschaftler zurueck
1235:
1236: names={}
1237: keys={}
1238: tmpList=[]
1239: for key in self.REQUEST.keys(): #gehe durch das Formular
1240: splitted=key.split("_")
1241: if splitted[0]=="responsibleScientist": #wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt
1242: nr=splitted[2]
1243: if splitted[1]=="name":
1244: names[nr]=self.REQUEST[key]
1245: elif splitted[1]=="key":
1246: keys[nr]=self.REQUEST[key]
1247:
1248:
1249: for nr in names.keys():#schreibe keys und namen in die Liste, stelle ausserdem sicher, dass name unicode
1250: tmpList.append((unicodify(names[nr]),unicodify(keys.get(nr,""))))
1251:
1252: self.responsibleScientistsList=tmpList
1253: if fromEdit and (RESPONSE is not None):
1254: #RESPONSE.redirect('./editMPIWGBasisEditor')
1255: return self.editMPIWGBasisEditor(identifiedNames=self.identifyNames(self.decode(self.REQUEST.get('xdata_01',''))))
1256:
1257: else:
1258: if RESPONSE is not None:
1259: RESPONSE.redirect('manage_main')
1260:
1261:
1262:
1263: security.declareProtected('View managment screens','editMPIWGDisciplinesThemesEditor')
1264: def editMPIWGDisciplinesThemesEditor(self):
1265: """edit from edit"""
1266: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGDisciplinesThemesNeu.zpt')).__of__(self)
1267: return pt()
1268:
1269:
1270: def editMPIWGDisciplinesThemesForm(self):
1271: """edit the disciplines and themes Form"""
1272:
1273: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGDisciplinesThemes.zpt')).__of__(self)
1274: return pt()
1275:
1276: def editMPIWGDisciplinesThemes(self,disciplines=None,themes=None,RESPONSE=None,fromEdit=None):
1277: """edit disciplin and form"""
1278: if disciplines:
1279: if type(disciplines) is StringType:
1280: self.xdata_09=disciplines
1281: else:
1282: self.xdata_09=";".join(disciplines)
1283: else:
1284: self.xdata_09=""
1285: if themes:
1286: if type(themes) is StringType:
1287: self.xdata_10=themes
1288: else:
1289: self.xdata_10=";".join(themes)
1290: else:
1291: self.xdata_10=""
1292:
1293: if fromEdit and (RESPONSE is not None):
1294: RESPONSE.redirect('./editMPIWGDisciplinesThemesEditor')
1295:
1296: else:
1297: if RESPONSE is not None:
1298: RESPONSE.redirect('manage_main')
1299:
1300:
1301: def isChecked(self,wert,list):
1302: """check if wert is in ; seperated list"""
1303:
1304: #felder sind manchmnal als liste mit einem element definiert
1305: if type(list) is StringType or UnicodeType:
1306: splitted=list.split(";")
1307: else:
1308: splitted=list[0].split(";")
1309:
1310: splitted=[y.rstrip().lstrip() for y in splitted]
1311:
1312: for x in splitted:
1313: x=re.sub(r"[^A-z ]","",x)
1314: if (not x==u'') and x in wert:
1315: return 1
1316: return 0
1317:
1318: security.declareProtected('View management screens','editMPIWGBasisEditor')
1319: def editMPIWGBasisEditor(self, identifiedNames=None):
1320:
1321: """editform"""
1322: if not identifiedNames:
1323: identifiedNames=self.identifyNames(self.getContent('xdata_01'))
1324: # identifiedNames=self.getFullNameEntries()
1325:
1326: logging.error("IdentifiedNames: %s"% repr(identifiedNames))
1327: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGBasisNeu.zpt')).__of__(self)
1328: return pt(identifiedNames=identifiedNames)
1329:
1330: security.declareProtected('View management screens','editMPIWGBasisForm')
1331: def editMPIWGBasisForm(self):
1332: """editform"""
1333: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGBasis.zpt')).__of__(self)
1334: return pt()
1335:
1336: security.declareProtected('View management screens','editMPIWGRelatedPublicationsForm')
1337: def editMPIWGRelatedPublicationsForm(self):
1338: """Edit related Publications"""
1339: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGRelatedPublications.zpt')).__of__(self)
1340: return pt()
1341:
1342:
1343: def loadNewFileForm(self):
1344: """Neues XML-File einlesen"""
1345: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_newfile.zpt')).__of__(self)
1346: return pt()
1347:
1348: def loadNewFile(self,RESPONSE=None):
1349: """einlesen des neuen files"""
1350: fileupload=self.REQUEST['fileupload']
1351: if fileupload:
1352: file_name=fileupload.filename
1353: filedata=fileupload.read()
1354:
1355: argv=xmlhelper.proj2hash(filedata)
1356: #print argv.keys()
1357: for arg in definedFields:
1358:
1359: #print arg,argv[arg],getattr(self,arg)
1360: try:
1361: temp=argv[arg][0:]
1362: #old=getattr(self,arg)
1363: setattr(self,arg,temp)
1364: #print old,getattr(self,arg)
1365: except:
1366: """nothing"""
1367:
1368: if RESPONSE is not None:
1369: RESPONSE.redirect('manage_main')
1370:
1371: def manage_addMPIWGProjectForm(self):
1372: """form for adding the project"""
1373: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGProjectForm.zpt')).__of__(self)
1374: return pt()
1375:
1376: def manage_addMPIWGProject(self,id,RESPONSE=None):
1377: """method to add a project"""
1378: #print argv
1379: fileupload=self.REQUEST.get('fileupload',None)
1380: if fileupload:
1381:
1382: file_name=fileupload.filename
1383: filedata=fileupload.read()
1384:
1385: argv=xmlhelper.proj2hash(filedata)
1386:
1387: #print argv
1388: newObj=MPIWGProject(id,argv)
1389: else:
1390: newObj=MPIWGProject(id)
1391:
1392: self._setObject(id,newObj)
1393:
1394:
1395: if RESPONSE is not None:
1396: RESPONSE.redirect('manage_main')
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>