comparison MPIWGProjects.py @ 48:f59bdd5f4890

Merge with 5c6ad316e1ceef48e323907ab81dd50e7ef743b2
author dwinter
date Mon, 29 Apr 2013 16:02:24 +0200
parents 5c6ad316e1ce
children e40ff9829108 e718d9a72f19
comparison
equal deleted inserted replaced
47:225179dfd892 48:f59bdd5f4890
1 """This contains the class MPIWG Projects 1 """This contains the class MPIWG Projects
2 for organizing and maintaining the different project pages 2 for organizing and maintaining the different project pages
3 3
4 $author dwinter - last change 26.06.2008 4 $author dwinter 26.06.2008
5 5
6 """ 6 """
7 from Products.PageTemplates.PageTemplateFile import PageTemplateFile 7 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
8 from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate 8 from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
9 from Products.ZCatalog.CatalogPathAwareness import CatalogAware 9 from Products.ZCatalog.CatalogPathAwareness import CatalogAware
49 import MPIWGTemplate 49 import MPIWGTemplate
50 50
51 import transaction 51 import transaction
52 52
53 53
54 # TODO: fix this 54 # TODO: better names for the fields
55 definedFields = ['WEB_title',
56 'xdata_01',
57 'xdata_02',
58 'xdata_03',
59 'xdata_04',
60 'xdata_05',
61 'xdata_06',
62 'xdata_07',
63 'xdata_08',
64 'xdata_09',
65 'xdata_10',
66 'xdata_11',
67 'xdata_12',
68 'xdata_13',
69 'WEB_project_header',
70 'WEB_project_description',
71 'WEB_related_pub']
72
73 fieldLabels = {'WEB_title':'WEB_Title', 55 fieldLabels = {'WEB_title':'WEB_Title',
74 'xdata_01':'Responsible Scientists', 56 'xdata_01':'Responsible Scientists',
75 'xdata_02':'Department', 57 'xdata_02':'Department',
76 'xdata_03':'Historical Persons', 58 'xdata_03':'Historical Persons',
77 'xdata_04':'Time period', 59 'xdata_04':'Time period',
86 'xdata_13':'Funding institutions', 68 'xdata_13':'Funding institutions',
87 'WEB_project_header':'WEB_project_header', 69 'WEB_project_header':'WEB_project_header',
88 'WEB_project_description':'WEB_project_description', 70 'WEB_project_description':'WEB_project_description',
89 'WEB_related_pub':'WEB_related_pub'} 71 'WEB_related_pub':'WEB_related_pub'}
90 72
73 definedFields = fieldLabels.keys() # TODO: should this be sorted?
74
91 checkFields = ['xdata_01'] 75 checkFields = ['xdata_01']
92 76
93 77
94 # die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus Kompatibilitaetsgruenden, bleiben die Klassen hier noch drin. 78 # die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus Kompatibilitaetsgruenden, bleiben die Klassen hier noch drin.
95 # Sonst funktionieren die alten Webseiten nicht mehr. 79 # Sonst funktionieren die alten Webseiten nicht mehr.
144 return True 128 return True
145 except: 129 except:
146 logging.debug("MPIWGProject_publication - end FALSE ") 130 logging.debug("MPIWGProject_publication - end FALSE ")
147 self._v_hasLinkToBookPage = True 131 self._v_hasLinkToBookPage = True
148 return False 132 return False
149
150 133
151 134
152 def getImageUrls(self, mode="not_cached"): 135 def getImageUrls(self, mode="not_cached"):
153 """get the image urls""" 136 """get the image urls"""
154 137
173 except: 156 except:
174 self._v_imageUrls = [] 157 self._v_imageUrls = []
175 return [] 158 return []
176 self._v_imageUrls = ret[0:] 159 self._v_imageUrls = ret[0:]
177 return ret 160 return ret
161
178 162
179 def editPublication(self, text=None, image1=None, image2=None, description=None, link=None, RESPONSE=None): 163 def editPublication(self, text=None, image1=None, image2=None, description=None, link=None, RESPONSE=None):
180 """edit a publication""" 164 """edit a publication"""
181 165
182 if (not text) and (not description): 166 if (not text) and (not description):
204 if hasattr(self, 'publicationImage2'): 188 if hasattr(self, 'publicationImage2'):
205 self.publicationImage2.manage_upload(image2) 189 self.publicationImage2.manage_upload(image2)
206 else: 190 else:
207 nO = Image('publicationImage2', '', image2) 191 nO = Image('publicationImage2', '', image2)
208 self._setObject('publicationImage2', nO) 192 self._setObject('publicationImage2', nO)
209 193
210
211 self.ZCacheable_invalidate() 194 self.ZCacheable_invalidate()
212 if RESPONSE: 195 if RESPONSE:
213 self.redirect(RESPONSE, "../managePublications") 196 self.redirect(RESPONSE, "../managePublications")
214 197
198
215 class MPIWGProject_relatedProject(Folder): 199 class MPIWGProject_relatedProject(Folder):
216 """publications object fuer project""" 200 """publications object fuer project"""
217 201
218 meta_type = "MPIWGProject_relatedProject" 202 meta_type = "MPIWGProject_relatedProject"
219 def redirect(self, RESPONSE, url): 203 def redirect(self, RESPONSE, url):
235 """edit a publication""" 219 """edit a publication"""
236 220
237 if (not link): 221 if (not link):
238 pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_relatedProjectForm.zpt')).__of__(self) 222 pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_relatedProjectForm.zpt')).__of__(self)
239 return pt() 223 return pt()
240
241
242
243
244 224
245 # hole die id des projektes 225 # hole die id des projektes
246 splitted = link.split("/") 226 splitted = link.split("/")
247 227
248 # teste ob es das project gibt 228 # teste ob es das project gibt
252 objid = splitted[-1] 232 objid = splitted[-1]
253 object = getattr(self.projects, objid, None) 233 object = getattr(self.projects, objid, None)
254 234
255 if object == None: 235 if object == None:
256 self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link) 236 self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
257
258
259
260
261 237
262 self.orginallink = link[0:] 238 self.orginallink = link[0:]
263 self.objid = objid[0:] 239 self.objid = objid[0:]
264 240
265 self.projectWEB_title = object.getContent('WEB_title')[0:] 241 self.projectWEB_title = object.getContent('WEB_title')[0:]
267 self.enabled = True; 243 self.enabled = True;
268 self.ZCacheable_invalidate() 244 self.ZCacheable_invalidate()
269 245
270 if RESPONSE: 246 if RESPONSE:
271 self.redirect(RESPONSE, "../manageRelatedProjects") 247 self.redirect(RESPONSE, "../manageRelatedProjects")
248
272 249
273 class MPIWGProject_image(Image): 250 class MPIWGProject_image(Image):
274 """Images for Projects""" 251 """Images for Projects"""
275 252
276 meta_type = "MPIWGProject_image" 253 meta_type = "MPIWGProject_image"
327 edit_css.index_html = refreshingImageFileIndexHtml 304 edit_css.index_html = refreshingImageFileIndexHtml
328 edit_basic = PageTemplateFile('zpt/project/edit_basic', globals()) 305 edit_basic = PageTemplateFile('zpt/project/edit_basic', globals())
329 editForm = PageTemplateFile('zpt/project/edit_description', globals()) 306 editForm = PageTemplateFile('zpt/project/edit_description', globals())
330 edit_template = PageTemplateFile('zpt/project/edit_template', globals()) 307 edit_template = PageTemplateFile('zpt/project/edit_template', globals())
331 project_template = PageTemplateFile('zpt/project/project_template', globals()) 308 project_template = PageTemplateFile('zpt/project/project_template', globals())
309 # TODO: this should go away
310 extendedBibliography = PageTemplateFile('zpt/project/extendedBibliography_template', globals())
332 311
333 # TODO: compat 312 # TODO: compat
334 edit_MPIWGProject_main = edit_template 313 edit_MPIWGProject_main = edit_template
335 314
336 315
432 411
433 logging.debug("len(publ)" + repr(ret)) 412 logging.debug("len(publ)" + repr(ret))
434 413
435 return ret; 414 return ret;
436 415
437 def hasRelatedDigitalSources(self):
438 """test ob es digital sources gibt"""
439
440
441 ret = (self.getContent('xdata_11').lstrip().rstrip() == '')
442
443
444
445 return not ret;
446
447
448
449
450 def copyImageToMargin(self, RESPONSE=None): 416 def copyImageToMargin(self, RESPONSE=None):
451 """copy inline images to marginal images""" 417 """copy inline images to marginal images"""
452
453
454 # getImages from WEB_project_description 418 # getImages from WEB_project_description
455 description = self.getContent('WEB_project_description') 419 description = self.getContent('WEB_project_description')
456 420
457 text2 = description 421 text2 = description
458 splitted = text2.split("""<p class="picture">""") 422 splitted = text2.split("""<p class="picture">""")
478 splitted = split2.split("""<p class="picturetitle">""") 442 splitted = split2.split("""<p class="picturetitle">""")
479 if len(splitted) > 1: 443 if len(splitted) > 1:
480 tmp = splitted[1].split("</p>") 444 tmp = splitted[1].split("</p>")
481 imageCaptions.append(tmp[0].encode('utf-8')) 445 imageCaptions.append(tmp[0].encode('utf-8'))
482 446
483
484 else: 447 else:
485 # keine caption 448 # keine caption
486 449
487 imageCaptions.append("") 450 imageCaptions.append("")
488
489 451
490 # eintragen: 452 # eintragen:
491 for imageURL in imageURLs: 453 for imageURL in imageURLs:
492 filename = imageURL.split("/")[-1] 454 filename = imageURL.split("/")[-1]
493 # lege neues images object an, mit leerem bild 455 # lege neues images object an, mit leerem bild
511 473
512 obj = getattr(self, filename) 474 obj = getattr(self, filename)
513 obj.update_data(data) 475 obj.update_data(data)
514 476
515 if RESPONSE: 477 if RESPONSE:
516
517 self.redirect(RESPONSE, 'manageImages') 478 self.redirect(RESPONSE, 'manageImages')
479
518 480
519 def manageImages(self, imageName=None, op=None): 481 def manageImages(self, imageName=None, op=None):
520 """managage images""" 482 """managage images"""
521 if imageName and op: 483 if imageName and op:
522 if op == 'up': 484 if op == 'up':
604 566
605 def createExtendedPublicationList(self, RESPONSE=None): 567 def createExtendedPublicationList(self, RESPONSE=None):
606 """erzeuge erweiterte publications liste""" 568 """erzeuge erweiterte publications liste"""
607 pl = BibliographyManager("publicationList", "", "institutsbiblio", self.connection_id) 569 pl = BibliographyManager("publicationList", "", "institutsbiblio", self.connection_id)
608 self._setObject("publicationList", pl) 570 self._setObject("publicationList", pl)
609
610 571
611 zt = ZopePageTemplate('index.html') 572 zt = ZopePageTemplate('index.html')
612 pl._setObject('index.html', zt) 573 pl._setObject('index.html', zt)
613 default_content_fn = os.path.join(package_home(globals()), 574 default_content_fn = os.path.join(package_home(globals()),
614 'zpt/showExtendedProjectBibliography.zpt') 575 'zpt/showExtendedProjectBibliography.zpt')
615 text = open(default_content_fn).read() 576 text = open(default_content_fn).read()
616 zt.pt_edit(text, 'text/html') 577 zt.pt_edit(text, 'text/html')
617
618 578
619 if RESPONSE: 579 if RESPONSE:
620 self.redirect(RESPONSE, "managePublications") 580 self.redirect(RESPONSE, "managePublications")
621 581
622 582
623 def getPublications(self): 583 def getPublications(self):
624 """get all Publications""" 584 """get all Publications"""
625 def sort_images(x, y): 585 def sort_images(x, y):
626 return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0)) 586 return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
627 587
725 def deletePublication(self, id, RESPONSE=None): 685 def deletePublication(self, id, RESPONSE=None):
726 """delete Publication id""" 686 """delete Publication id"""
727 self.manage_delObjects([id]) 687 self.manage_delObjects([id])
728 self.ZCacheable_invalidate() 688 self.ZCacheable_invalidate()
729 if RESPONSE: 689 if RESPONSE:
730
731 self.redirect(RESPONSE, 'managePublications') 690 self.redirect(RESPONSE, 'managePublications')
732 691
733 def deleteRelatedProject(self, id, RESPONSE=None): 692 def deleteRelatedProject(self, id, RESPONSE=None):
734 """delete Publication id""" 693 """delete Publication id"""
735 self.manage_delObjects([id]) 694 self.manage_delObjects([id])
736 self.ZCacheable_invalidate() 695 self.ZCacheable_invalidate()
737 if RESPONSE: 696 if RESPONSE:
738
739 self.redirect(RESPONSE, 'manageRelatedProjects') 697 self.redirect(RESPONSE, 'manageRelatedProjects')
740 698
741 699
742 def getNumber(self): 700 def getNumber(self):
743 """returns sorting number""" 701 """returns sorting number"""
755 if isinstance(t, list): 713 if isinstance(t, list):
756 # compat with old lists 714 # compat with old lists
757 return t[0] 715 return t[0]
758 else: 716 else:
759 return t 717 return t
718
719
720 def getLabel(self):
721 """returns label (or title) of this project"""
722 l = getattr(self, 'xdata_07', None)
723 if isinstance(l, list):
724 # compat with old lists
725 l = l[0]
726
727 if l:
728 return l
729 else:
730 return self.getProjectTitle()
731
760 732
761 def getResponsibleScientists(self): 733 def getResponsibleScientists(self):
762 """returns the responsible scientists as string""" 734 """returns the responsible scientists as string"""
763 t = getattr(self, 'xdata_01', None) 735 t = getattr(self, 'xdata_01', None)
764 if isinstance(t, list): 736 if isinstance(t, list):
793 else: 765 else:
794 scientistsList.append({'name': name}) 766 scientistsList.append({'name': name})
795 767
796 logging.debug("setResponsibleScientistsList: nameDict=%s new list=%s"%(repr(nameDict),repr(scientistsList))) 768 logging.debug("setResponsibleScientistsList: nameDict=%s new list=%s"%(repr(nameDict),repr(scientistsList)))
797 self.responsibleScientistsList = scientistsList 769 self.responsibleScientistsList = scientistsList
770
771
772 def getInvolvedScholars(self):
773 """returns the other involved scholars"""
774 t = getattr(self, 'xdata_08', None)
775 if isinstance(t, list):
776 # compat with old lists
777 return t[0]
778 else:
779 return t
780
781
782 def getCooperationPartners(self):
783 """returns the cooperation partners"""
784 t = getattr(self, 'xdata_12', None)
785 if isinstance(t, list):
786 # compat with old lists
787 return t[0]
788 else:
789 return t
798 790
799 791
800 def getUrl(self, baseUrl=None): 792 def getUrl(self, baseUrl=None):
801 """returns URL to this Project""" 793 """returns URL to this Project"""
802 if baseUrl is None: 794 if baseUrl is None:
822 return thumb.absolute_url() 814 return thumb.absolute_url()
823 815
824 816
825 def getImageList(self): 817 def getImageList(self):
826 """returns the sorted list of images for this project""" 818 """returns the sorted list of images for this project"""
827 items = self.objectValues(spec='MPIWGProject_image')[:] 819 items = self.objectValues(spec='MPIWGProject_image')
820 # sort by place
821 return sorted(items, key=lambda x:int(getattr(x, 'place', 0)))
822
823
824 def getDepartment(self):
825 """returns the department of this project"""
826 num = self.getNumber()
827 pp = num.find('.')
828 if pp > 0:
829 num = num[:pp]
830
831 return self.getMPIWGRoot().getDepartment(projectNumber=num)
832
833
834 def getDepartmentId(self):
835 """returns the id of the department of this project"""
836 dep = self.getDepartment()
837 if dep is not None:
838 return dep.getId()
839
840 return None
841
842
843 def getDescription(self, filter=False):
844 """returns the project description"""
845 t = getattr(self, 'WEB_project_description', None)
846 if isinstance(t, list):
847 # compat with old lists
848 return t[0]
849 else:
850 return t
851
852
853 def getSuperProjects(self):
854 """returns a list of ancestor projects to the root"""
855 tree = self.getProjectTree()
856 return tree.getAncestorsOf(self.getNumber())
857
858
859 def getSubProjects(self, active=1):
860 """returns a list of child projects"""
861 tree = self.getProjectTree()
862 return [p for p in tree.getChildrenOf(self.getNumber()) if p.checkActive(active)]
863
864
865 def getRelatedProjects(self):
866 """returns the list of related projects"""
867 items = self.objectValues(spec='MPIWGProject_relatedProject')
828 # sort by place 868 # sort by place
829 items.sort(key=lambda x:int(getattr(x, 'place', 0))) 869 items.sort(key=lambda x:int(getattr(x, 'place', 0)))
830 return items 870 return items
871
872
873 def getRelatedPublications(self):
874 """returns the list of related publications"""
875 items = self.objectValues(spec='MPIWGProject_publication')
876 # sort by place
877 items.sort(key=lambda x:int(getattr(x, 'place', 0)))
878 return items
879
880
881 def getRelatedDigitalSources(self):
882 """returns the related digital sources"""
883 t = getattr(self, 'xdata_11', None)
884 if isinstance(t, list):
885 # compat with old lists
886 return t[0]
887 else:
888 return t
889
890
891 def getFundingInstitutions(self):
892 """returns the funding institutions"""
893 t = getattr(self, 'xdata_13', None)
894 if isinstance(t, list):
895 # compat with old lists
896 return t[0]
897 else:
898 return t
831 899
832 900
833 def getImages(self): 901 def getImages(self):
834 """get all Images""" 902 """get all Images"""
835 903
862 """delete Image id""" 930 """delete Image id"""
863 try: 931 try:
864 self.manage_delObjects([id]) 932 self.manage_delObjects([id])
865 except: 933 except:
866 logging.error("ERROR MPIWG: %s %s" % sys.exc_info()[0:2]) 934 logging.error("ERROR MPIWG: %s %s" % sys.exc_info()[0:2])
935
936 # invalidate thumbnail
937 self.projectThumb = None
938
867 if RESPONSE: 939 if RESPONSE:
868 self.redirect(RESPONSE, 'manageImages') 940 self.redirect(RESPONSE, 'manageImages')
869 941
870 942
871 943
872 def hasChildren(self, date=None, onlyActive=1, onlyArchived=1): 944 def hasChildren(self, date=None, onlyActive=1, onlyArchived=1):
873 """check if project has children""" 945 """check if project has children"""
874
875 ct = self.getContexts(childs=self.getContent('xdata_05'), 946 ct = self.getContexts(childs=self.getContent('xdata_05'),
876 depth=1, date=date, onlyActive=onlyActive) 947 depth=1, date=date, onlyActive=onlyActive)
877 948
878 if ct and len(ct) > 0: 949 if ct and len(ct) > 0:
879 return True 950 return True
897 obj.caption = caption[0:] 968 obj.caption = caption[0:]
898 obj.enabled = True; 969 obj.enabled = True;
899 obj.place = self.getLastImageNumber() + 1 970 obj.place = self.getLastImageNumber() + 1
900 obj.id = filename 971 obj.id = filename
901 972
973 # invalidate thumbnail
974 self.projectThumb = None
975
902 if RESPONSE is not None: 976 if RESPONSE is not None:
903 977
904 self.redirect(RESPONSE, 'manageImages') 978 self.redirect(RESPONSE, 'manageImages')
905 979
906 def versionHeader(self): 980 def versionHeader(self):
919 """actuelle version""" 993 """actuelle version"""
920 def sortProjectsByTime(x, y): 994 def sortProjectsByTime(x, y):
921 return cmp(x[1].archiveTime, y[1].archiveTime) 995 return cmp(x[1].archiveTime, y[1].archiveTime)
922 996
923 if not date: 997 if not date:
924 if self.isActual(): 998 if self.isCurrentVersion():
925 return self 999 return self
926 else: 1000 else:
927 return None 1001 return None
928 1002
929 # suche ob aeltere versionen vorhanden sind 1003 # suche ob aeltere versionen vorhanden sind
952 return self 1026 return self
953 else: 1027 else:
954 return None 1028 return None
955 1029
956 1030
957 def isActual(self): 1031 def isCurrentVersion(self):
958 """gibt 1 zurueck wenn aktuell, 0 sonst""" 1032 """Return if project is the current version."""
959 actualTime = time.localtime() 1033 currentTime = time.localtime()
960 1034 # print getattr(self,'archiveTime',currentTime)
961 1035 return (getattr(self, 'archiveTime', currentTime) >= currentTime)
962 # print getattr(self,'archiveTime',actualTime) 1036
963 if getattr(self, 'archiveTime', actualTime) < actualTime:
964 return 0
965 else:
966 return 1
967 1037
968 def copyObjectToArchive(self): 1038 def copyObjectToArchive(self):
969 """kopiere aktuelles objekt ins archiv""" 1039 """kopiere aktuelles objekt ins archiv"""
970 logging.info("copytoarchive 1") 1040 logging.info("copytoarchive 1")
971 cb = self.aq_parent.manage_copyObjects(self.getId()) 1041 cb = self.aq_parent.manage_copyObjects(self.getId())
1003 1073
1004 if RESPONSE is not None: 1074 if RESPONSE is not None:
1005 self.redirect(RESPONSE, 'manage_main') 1075 self.redirect(RESPONSE, 'manage_main')
1006 1076
1007 1077
1008 def crossLinker(self):
1009 """experimental crosslinker"""
1010 splitted = self.WEB_project_description[0].split()
1011 new = []
1012 for split in splitted:
1013 try:
1014 found = self.DescriptionCatalog({'fulltext':split})
1015
1016 if len(found) > 1:
1017
1018 new.append("<a href=%s>%s</a>" % (split, split))
1019 else:
1020 new.append(split)
1021 except:
1022 new.append(split)
1023 return " ".join(new)
1024
1025
1026
1027
1028 def generateTemplate(self, RESPONSE=None):
1029 """Erzeuge Template fuer defined fields not_used"""
1030
1031 id = "index_html"
1032 title = id
1033 if self._getOb('index_html'):
1034 self._delObject('index_html')
1035
1036
1037 newObj = ZopePageTemplate(id, 'TEXT')
1038 self._setObject(id, newObj)
1039 # self.manage_addPageTemplate(id,title)
1040 if RESPONSE is not None:
1041 self.redirect(RESPONSE, 'manage_main')
1042
1043 def isActiveProject(self): 1078 def isActiveProject(self):
1044 """check if the project is still active, default is true, set to false is the project is accomplished""" 1079 """check if the project is still active, default is true."""
1045 return getattr(self, 'isActiveFlag', True) 1080 return getattr(self, 'isActiveFlag', True)
1046 1081
1047 def checkActive(self, active): 1082 def checkActive(self, active):
1048 """returns if the project state matches the active state. 1083 """returns if the project state matches the active state.
1049 active = 0 : all projects 1084 active = 0 : all projects
1100 return False; 1135 return False;
1101 1136
1102 def getCompletedAt(self): 1137 def getCompletedAt(self):
1103 """gibt das transformierte Datum zurueck, an dem das Projekt beendet wurde.""" 1138 """gibt das transformierte Datum zurueck, an dem das Projekt beendet wurde."""
1104 date = getattr(self, 'completedAt', '') 1139 date = getattr(self, 'completedAt', '')
1105
1106 if date: 1140 if date:
1107 return self.reTransformDate(date); 1141 return self.reTransformDate(date);
1108 else: 1142 else:
1109 return "" 1143 return ""
1110 # test ob parent abgeschlossen ist
1111 try: # TODO: ersetzte try except durch vernuenftige abfrage
1112 ct = self.getContexts(parents=self.getContent('xdata_05'), depth=1)
1113 if (len(ct) > 0): # is there are parent
1114 return ct[0][0].getCompletedAt()
1115 return '';
1116 except:
1117 return '';
1118 1144
1119 def getStartedAt(self): 1145 def getStartedAt(self):
1120 """gibt das transformierte Datum zurueck, an dem Projekt begonnen wurde.""" 1146 """gibt das transformierte Datum zurueck, an dem Projekt begonnen wurde."""
1121 date = getattr(self, 'startedAt', '') 1147 date = getattr(self, 'startedAt', '')
1122 if date: 1148 if date:
1225 """seite fuer harvesting fuer die Projektsuche""" 1251 """seite fuer harvesting fuer die Projektsuche"""
1226 1252
1227 if not context: 1253 if not context:
1228 context = self 1254 context = self
1229 1255
1230 if self.isActiveProject() and self.isActual(): 1256 if self.isActiveProject() and self.isCurrentVersion():
1231 templates = self.en.getHarvestCache() 1257 templates = self.en.getHarvestCache()
1232 1258
1233 ext = getattr(self, "harvest_main", None) 1259 ext = getattr(self, "harvest_main", None)
1234 if ext: 1260 if ext:
1235 rendered = getattr(self, ext.getId())() 1261 rendered = getattr(self, ext.getId())()
1335 ret.append('xdata_%02i' % x) 1361 ret.append('xdata_%02i' % x)
1336 return ret 1362 return ret
1337 1363
1338 def getDefinedFields(self): 1364 def getDefinedFields(self):
1339 """show all defined fields""" 1365 """show all defined fields"""
1340
1341 return definedFields 1366 return definedFields
1342 1367
1343 def getAttribute(self, field): 1368 def getAttribute(self, field):
1344 """get attrbiute""" 1369 """get attrbiute"""
1345 return getattr(self, field) 1370 return getattr(self, field)
1494 if path == selected: 1519 if path == selected:
1495 return style + 'sel' 1520 return style + 'sel'
1496 else: 1521 else:
1497 return style 1522 return style
1498 1523
1499 def getLabel(self): 1524 def getLabel_old(self):
1500 """returns label (or title) of this project""" 1525 """returns label (or title) of this project"""
1501 l = self.getContent('xdata_07') 1526 l = self.getContent('xdata_07')
1502 if l: 1527 if l:
1503 return l 1528 return l
1504 l = self.getContent('WEB_title') 1529 l = self.getContent('WEB_title')
1535 1560
1536 return crumbs 1561 return crumbs
1537 1562
1538 def getRootProject(self): 1563 def getRootProject(self):
1539 """returns the root (=top level) project of the current project""" 1564 """returns the root (=top level) project of the current project"""
1540
1541 ct = self.getContexts(parents=self.getContent('xdata_05')) 1565 ct = self.getContexts(parents=self.getContent('xdata_05'))
1542 if len(ct) > 0: 1566 if len(ct) > 0:
1543 return ct[-1][0] 1567 return ct[-1][0]
1544 else: 1568 else:
1545 return self 1569 return self
1721 1745
1722 # make dict of responsible scientists 1746 # make dict of responsible scientists
1723 checkedScientists = {} 1747 checkedScientists = {}
1724 names = {} 1748 names = {}
1725 keys = {} 1749 keys = {}
1726 for key in formdata.keys(): 1750 for key in formdata:
1727 # gehe durch das Formular 1751 # gehe durch das Formular
1728 keyParts = key.split("_") 1752 keyParts = key.split("_")
1729 if keyParts[0] == "responsibleScientist": 1753 if keyParts[0] == "responsibleScientist":
1730 # wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt 1754 # wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt
1731 nr = keyParts[2] 1755 nr = keyParts[2]
1732 if keyParts[1] == "name": 1756 if keyParts[1] == "name":
1733 names[nr] = formdata[key] 1757 names[nr] = formdata[key]
1734 elif keyParts[1] == "key": 1758 elif keyParts[1] == "key":
1735 keys[nr] = formdata[key] 1759 keys[nr] = formdata[key]
1736 1760
1737 for nr in names.keys(): 1761 for nr in names:
1738 name = names[nr] 1762 name = names[nr]
1739 key = keys.get(nr, None) 1763 key = keys.get(nr, None)
1740 username = None 1764 username = None
1741 if key: 1765 if key:
1742 # get username from db 1766 # get username from db
1743 member = self.executeZSQL("select * from personal_www where lower(key) = %s", [key.lower()]) 1767 member = self.getMPIWGRoot().getStaffFolder().getMember(key=key)
1744 if len(member) > 0: 1768 if member is not None:
1745 username = re.sub('@mpiwg-berlin\.mpg\.de', '', member[0].e_mail) 1769 username = member.getUsername()
1746 1770
1747 # schreibe keys und namen in die Liste 1771 # schreibe keys und namen in die Liste
1748 checkedScientists[names[nr]] = {'name' : name, 'key' : key, 'username' : username} 1772 checkedScientists[names[nr]] = {'name' : name, 'key' : key, 'username' : username}
1749 1773
1774 # update responsibleScientistsList
1750 self.setResponsibleScientistsList(checkedScientists) 1775 self.setResponsibleScientistsList(checkedScientists)
1776 self.updateProjectMembers()
1751 1777
1752 if fromEdit and (RESPONSE is not None): 1778 if fromEdit and (RESPONSE is not None):
1753 return self.editBasic() 1779 return self.editBasic()
1754 1780
1755 else: 1781 else:
1839 """updates project-member table""" 1865 """updates project-member table"""
1840 if updateResponsibleScientistsList: 1866 if updateResponsibleScientistsList:
1841 # create responsibleScientistsList automatically 1867 # create responsibleScientistsList automatically
1842 newScientists = {} 1868 newScientists = {}
1843 names = p.identifyNames(p.getResponsibleScientists()) 1869 names = p.identifyNames(p.getResponsibleScientists())
1844 for name in names.keys(): 1870 for name in names:
1845 logging.debug("updateAllProjectMembers: name=%s" % repr(name)) 1871 logging.debug("updateAllProjectMembers: name=%s" % repr(name))
1846 members = names[name] 1872 members = names[name]
1847 if len(members) > 0: 1873 if len(members) > 0:
1848 # take the first matching name 1874 # take the first matching name
1849 newScientists[name] = {'name': name, 'key' : members[0].key, 'username' : re.sub('@mpiwg-berlin\.mpg\.de', '', members[0].e_mail)} 1875 newScientists[name] = {'name': name, 'key' : members[0].key, 'username' : re.sub('@mpiwg-berlin\.mpg\.de', '', members[0].e_mail)}
1859 return 1885 return
1860 1886
1861 if len(memberlist) == 0: 1887 if len(memberlist) == 0:
1862 return 1888 return
1863 1889
1864 # update old format responsibleScientistsList
1865 if isinstance(memberlist[0], tuple):
1866 logging.debug("updateAllProjectMembers: updating memberlist for project %s" % self)
1867 newScientists = {}
1868 for m in memberlist:
1869 name = m[0]
1870 key = m[1]
1871 username = None
1872 if key:
1873 if isinstance(key, list):
1874 key = key[0]
1875
1876 # get username from db
1877 member = self.executeZSQL("select * from personal_www where lower(key) = %s", [key.lower()])
1878 if len(member) > 0:
1879 username = re.sub('@mpiwg-berlin\.mpg\.de', '', member[0].e_mail)
1880
1881 newScientists[name] = {'name': name, 'key' : key, 'username' : username}
1882
1883 # set and re-read new list
1884 self.setResponsibleScientistsList(newScientists)
1885 memberlist = self.getResponsibleScientistsList()
1886
1887 # fill projects_members table 1890 # fill projects_members table
1888 self.executeZSQL("delete from projects_members where project_number = %s", [pNum]) 1891 self.executeZSQL("delete from projects_members where project_number = %s", [pNum])
1889 for m in memberlist: 1892 for m in memberlist:
1890 memberKey = m.get('key') 1893 memberKey = m.get('key', None)
1891 if not memberKey or not isinstance(memberKey, basestring): 1894 if not memberKey or not isinstance(memberKey, basestring):
1892 logging.error("updateProjectMembers: not a valid member key: %s" % repr(memberKey)) 1895 logging.error("updateProjectMembers: not a valid member key: %s" % repr(memberKey))
1893 continue 1896 continue
1894 1897
1895 self.executeZSQL("insert into projects_members (project_number, member_key) values (%s, %s)", (pNum, memberKey)) 1898 self.executeZSQL("insert into projects_members (project_number, member_key) values (%s, %s)", (pNum, memberKey))
1932 # cached HashTree with project hierarchy 1935 # cached HashTree with project hierarchy
1933 _v_projectTree = None 1936 _v_projectTree = None
1934 1937
1935 1938
1936 def getProjectTree(self): 1939 def getProjectTree(self):
1937 """returns the project hierarchy tree (and caches it). 1940 """Return the project hierarchy tree (and cache it).
1938 1941
1939 returns HashTree instance.""" 1942 Returns HashTree instance."""
1940 tree = self._v_projectTree 1943 tree = self._v_projectTree
1941 if tree is None: 1944 if tree is None:
1942 tree = HashTree(keySeparator='.', keyFn=lambda x:getInt(x)) 1945 tree = HashTree(keySeparator='.', keyFn=getInt)
1943 for p in self.objectValues(spec='MPIWGProject'): 1946 for p in self.objectValues(spec='MPIWGProject'):
1944 tree.add(p.getNumber(), p) 1947 tree.add(p.getNumber(), p)
1945 1948
1946 self._v_projectTree = tree 1949 self._v_projectTree = tree
1947 # logging.debug("getProjectTree: tree=%s"%(tree.root.getSubtreeAsText())) 1950 # logging.debug("getProjectTree: tree=%s"%(tree.root.getSubtreeAsText()))
1948 1951
1949 return tree 1952 return tree
1950 1953
1951 1954
1952 def getProjectsAsList(self, start, active=1, archived=1): 1955 def getProjectsAsList(self, start, active=1, archived=1):
1953 """returns flattened list of projects, starting from start. 1956 """Return flattened list of projects, starting from start.
1954 1957
1955 active = 0 : all projects 1958 active = 0 : all projects
1956 active = 1 : active projects 1959 active = 1 : active projects
1957 active = 2 : inactive projects 1960 active = 2 : inactive projects
1958 archived = 0 : all projects 1961 archived = 0 : all projects
1968 pl = node.getSubtreeAsList() 1971 pl = node.getSubtreeAsList()
1969 # logging.debug("getProjectsAsList: node=(%s,%s) pl=%s"%(node.key,node.value,pl)) 1972 # logging.debug("getProjectsAsList: node=(%s,%s) pl=%s"%(node.key,node.value,pl))
1970 # return filtered list 1973 # return filtered list
1971 return [p for p in pl if (p.checkActive(active) and p.checkArchived(archived))] 1974 return [p for p in pl if (p.checkActive(active) and p.checkArchived(archived))]
1972 1975
1976
1977 def getProject(self, projectNumber=None):
1978 """Return the matching project"""
1979 tree = self.getProjectTree()
1980 if projectNumber is not None:
1981 return tree.get(projectNumber)
1982
1983 return None
1984
1973 1985
1974 def getProjectsOfMember(self, key, active=1, archived=1): 1986 def getProjectsOfMember(self, key, active=1, archived=1):
1975 """returns a list of all projects of a member. 1987 """Return a list of all projects of a member.
1976 1988
1977 @param key: member's key 1989 @param key: member's key
1978 active = 0 : all projects 1990 active = 0 : all projects
1979 active = 1 : active projects 1991 active = 1 : active projects
1980 active = 2 : inactive projects 1992 active = 2 : inactive projects
1987 res = self.executeZSQL("select * from projects_members where lower(member_key) = %s", [key.lower()]) 1999 res = self.executeZSQL("select * from projects_members where lower(member_key) = %s", [key.lower()])
1988 tree = self.getProjectTree() 2000 tree = self.getProjectTree()
1989 # find projects in tree 2001 # find projects in tree
1990 for r in res: 2002 for r in res:
1991 p = tree.get(r.project_number) 2003 p = tree.get(r.project_number)
2004 # check if active
1992 if p is not None and p.checkActive(active) and p.checkArchived(archived): 2005 if p is not None and p.checkActive(active) and p.checkArchived(archived):
1993 projects.append(p) 2006 projects.append(p)
1994 2007
2008 projects.sort(key=lambda p:[int(n) for n in p.getNumber().split('.')])
1995 return projects 2009 return projects
1996 2010
1997 2011
1998 security.declareProtected('View management screens', 'updateAllProjectMembers') 2012 security.declareProtected('View management screens', 'updateAllProjectMembers')
1999 def updateAllProjectMembers(self, updateResponsibleScientistsList=False): 2013 def updateAllProjectMembers(self, updateResponsibleScientistsList=False):
2000 """re-creates responsibleScientistsLists and projects_members table from all current projects""" 2014 """Re-create responsibleScientistsLists and projects_members table from all current projects."""
2001 # empty table 2015 # empty table
2002 self.executeZSQL('truncate table projects_members') 2016 self.executeZSQL('truncate table projects_members')
2003 cnt = 0 2017 cnt = 0
2004 # go through all projects 2018 # go through all projects
2005 for p in self.objectValues(spec='MPIWGProject'): 2019 for p in self.objectValues(spec='MPIWGProject'):
2008 logging.debug("updateAllProjectMembers: updating project %s" % p) 2022 logging.debug("updateAllProjectMembers: updating project %s" % p)
2009 p.updateProjectMembers(updateResponsibleScientistsList=updateResponsibleScientistsList) 2023 p.updateProjectMembers(updateResponsibleScientistsList=updateResponsibleScientistsList)
2010 2024
2011 return "updated %s projects!" % cnt 2025 return "updated %s projects!" % cnt
2012 2026
2027
2028 security.declareProtected('View management screens', 'updateAllProjects')
2029 def updateAllProjects(self, updateResponsibleScientistsList=False):
2030 """Patch all current projects for legacy problems."""
2031 cnt = 0
2032 # go through all projects
2033 for (id, project) in self.ZopeFind(self, obj_metatypes=['MPIWGProject'], search_sub=1):
2034 cnt += 1
2035 #
2036 # hasRelatedPublicationsOldVersion
2037 #
2038 if project.hasRelatedPublicationsOldVersion():
2039 logging.debug("updateAllProjects(%s): update relatedPublicationsOldVersion!"%project.getId())
2040 project.copyPublicationsToList()
2041
2042 #
2043 # old format responsibleScientistsList
2044 #
2045 memberlist = project.getResponsibleScientistsList()
2046 if len(memberlist) > 0 and isinstance(memberlist[0], tuple):
2047 logging.debug("updateAllProjects(%s): updating memberlist" % project.getId())
2048 newScientists = {}
2049 for m in memberlist:
2050 name = m[0]
2051 key = m[1]
2052 username = None
2053 if key:
2054 if isinstance(key, list):
2055 key = key[0]
2056
2057 # get username from db
2058 member = self.getMPIWGRoot().getStaffFolder().getMember(key=key)
2059 if member is not None:
2060 username = member.getUsername()
2061
2062 newScientists[name] = {'name': name, 'key' : key, 'username' : username}
2063
2064 # set new list
2065 project.setResponsibleScientistsList(newScientists)
2066
2067 #
2068 # remove old attributes
2069 #
2070 if hasattr(project, 'definedFields'):
2071 logging.debug("updateAllProjects(%s): has definedFields!"%project.getId())
2072 delattr(project, 'definedFields')
2073
2074 #
2075 # update extended bibliography
2076 #
2077 if hasattr(project, 'publicationList'):
2078 logging.debug("updateAllProjects(%s): has publicationList!"%project.getId())
2079 extpub = project.publicationList
2080 if hasattr(extpub, 'connection_id'):
2081 logging.debug("updateAllProjects(%s): extended publication %s has connection_id=%s!"%(project.getId(),extpub.getId(),extpub.connection_id))
2082
2083
2084 return "updated %s projects!" % cnt
2085
2086
2013 2087
2014 def manage_addMPIWGProjectFolderForm(self): 2088 def manage_addMPIWGProjectFolderForm(self):
2015 """form for adding a MPIWGProjectFolder""" 2089 """form for adding a MPIWGProjectFolder"""
2016 pt = PageTemplateFile('zpt/project/manage_add_MPIWGProjectFolder', globals()).__of__(self) 2090 pt = PageTemplateFile('zpt/project/manage_add_MPIWGProjectFolder', globals()).__of__(self)
2017 return pt() 2091 return pt()