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