Mercurial > hg > MPIWGWeb
view MPIWGProjects.py @ 61:04fb655633ef
more cleaning up projects.
author | casties |
---|---|
date | Thu, 02 May 2013 18:32:01 +0200 |
parents | dc41deabc8f8 |
children | 64be5db08495 |
line wrap: on
line source
"""This contains the class MPIWG Projects for organizing and maintaining the different project pages $author dwinter 26.06.2008 """ from Products.PageTemplates.PageTemplateFile import PageTemplateFile from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate from Products.ZCatalog.CatalogPathAwareness import CatalogAware from OFS.Image import Image from App.ImageFile import ImageFile from OFS.SimpleItem import SimpleItem from OFS.Folder import Folder from OFS.Image import Image from OFS.Cache import Cacheable from AccessControl import ClassSecurityInfo from AccessControl import getSecurityManager from Globals import package_home import urllib import re import os import email import xmlhelper # Methoden zur Verwaltung der projekt xml import xmlrpclib import sys from types import * import logging import time import xml.etree.ElementTree as ET from SrvTxtUtils import getInt, unicodify, utf8ify, serialize, refreshingImageFileIndexHtml from Products.MPIWGBibliography.BibliographyManager import BibliographyManager from bibliography import * from Products.ZDBInterface.ZDBInterfaceFolder import ZDBInterfaceFolder # import xml.dom.minidom # from Ft.Xml.XPath import Evaluate # from Ft.Xml.XPath.Context import Context # from Ft.Xml.Domlette import NonvalidatingReader,PrettyPrint, Print # from Ft.Xml import EMPTY_NAMESPACE # import copy # import updatePersonalWWW # import MPIWGStaff from HashTree import HashTree from MPIWGHelper import * import MPIWGRoot import MPIWGLink import MPIWGTemplate import transaction # TODO: better names for the fields fieldLabels = {'WEB_title':'WEB_Title', 'xdata_01':'Responsible Scientists', 'xdata_02':'Department', 'xdata_03':'Historical Persons', 'xdata_04':'Time period', 'xdata_05':'Sorting number', 'xdata_06':'Keywords', 'xdata_07':'Short title', 'xdata_08':'Other involved scholars' , 'xdata_09':'Disciplines', 'xdata_10':'Themes', 'xdata_11':'Object Digitallibrary', 'xdata_12':'Cooperation partners', 'xdata_13':'Funding institutions', 'WEB_project_header':'WEB_project_header', 'WEB_project_description':'WEB_project_description', 'WEB_related_pub':'WEB_related_pub'} definedFields = fieldLabels.keys() # TODO: should this be sorted? editableFields = ('xdata_01', 'xdata_05', 'xdata_07', 'xdata_08', 'xdata_11', 'xdata_12', 'xdata_13') # die folgenden Klassen sind jetzt in einzelne Files ausgelagert aus Kompatibilitaetsgruenden, bleiben die Klassen hier noch drin. # Sonst funktionieren die alten Webseiten nicht mehr. class MPIWGRoot(MPIWGRoot.MPIWGRoot): """depricated""" class MPIWGLink(MPIWGLink.MPIWGLink): """depricated""" class MPIWGTemplate(MPIWGTemplate.MPIWGTemplate): """depricated""" class MPIWGProject_publication(Folder): """publications object fuer project""" meta_type = "MPIWGProject_publication" text = None link = None bookId = None editForm = PageTemplateFile('zpt/project/related_publication/edit_basic', globals()) def redirect(self, RESPONSE, url): """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen""" timeStamp = time.time() if url.find("?") > -1: # giebt es schon parameter addStr = "&time=%s" else: addStr = "?time=%s" RESPONSE.setHeader('Last-Modified', email.Utils.formatdate().split("-")[0] + 'GMT') logging.debug(email.Utils.formatdate() + ' GMT') RESPONSE.redirect(url + addStr % timeStamp) def hasLinkToBookPage(self): """teste ob eingebener link zu einer MPIWG Book page geht""" logging.debug("MPIWGProject_publication - begin hasLinkToBookPage") if not self.link: return False # es gibt keinen link paths = self.link.split('/') if len(paths) > 2: # book page should be in folder books bookid = None try: idx = paths.index('books') bookid = paths[idx + 1] book = self.en.books[bookid] self.bookId = bookid return True except: logging.debug("hasLinkToBookPage: not a book page link=%s"%self.link) self.bookId = None return False def getBookId(self): """Return the book page id.""" return self.bookId def editPublication(self, text=None, description=None, link=None, RESPONSE=None): """edit a publication""" if (not text) and (not description): pt = self.editForm return pt() if text: self.text = text if description: self.description = description if link: self.link = link self.hasLinkToBookPage() if RESPONSE: self.redirect(RESPONSE, "../managePublications") class MPIWGProject_relatedProject(Folder): """publications object fuer project""" meta_type = "MPIWGProject_relatedProject" objid = None projectLabel = None editForm = PageTemplateFile('zpt/project/related_project/edit_basic', globals()) def redirect(self, RESPONSE, url): """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen""" timeStamp = time.time() if url.find("?") > -1: # giebt es schon parameter addStr = "&time=%s" else: addStr = "?time=%s" RESPONSE.setHeader('Last-Modified', email.Utils.formatdate().split("-")[0] + 'GMT') logging.debug(email.Utils.formatdate() + ' GMT') RESPONSE.redirect(url + addStr % timeStamp) def getProjectId(self): """Return the related project id.""" return self.objid def getProject(self): """Return the related project object.""" return getattr(self.projects, self.objid, None) def getProjectTitle(self): """Return the title of the related project.""" return getattr(self, 'projectWEB_title', None) def getProjectLabel(self): """Return the label of the related project.""" label = getattr(self, 'projectLabel', None) if not label: proj = self.getProject() if proj is not None: label = proj.getLabel() self.projectLabel = label return label def editRelatedProject(self, link=None, RESPONSE=None): """edit a publication""" if (not link): pt = self.editForm return pt() # hole die id des projektes splitted = link.split("/") # teste ob es das project gibt if len(splitted) < 1: self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link) objid = splitted[-1] object = getattr(self.projects, objid, None) if object is None: self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link) self.orginallink = link[0:] self.objid = objid[0:] self.projectWEB_title = object.getProjectTitle() self.projectLabel = object.getLabel() self.enabled = True; if RESPONSE: self.redirect(RESPONSE, "../manageRelatedProjects") class MPIWGProject_image(Image): """Images for Projects""" meta_type = "MPIWGProject_image" def showImage(self, imageUrl=None): """show Images at an extra page""" #self.getContent('WEB_project_description', filter='yes') # get the content and store image infos into session pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'projectImageView.zpt')).__of__(self) return pt() def editImage(self, file=None, caption=None, RESPONSE=None): """edit the Image""" if (not file) and (not caption): pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_imageForm.zpt')).__of__(self) return pt() if file and (not file.filename.lstrip().rstrip() == ""): self.manage_upload(file) if caption: self.caption = caption[0:] if RESPONSE: self.redirect(RESPONSE, "../manageImages") class MPIWGProject(CatalogAware, Folder, Cacheable): """Class for Projects""" security = ClassSecurityInfo() meta_type = 'MPIWGProject' manage_options = Folder.manage_options + ( {'label':'Load New File', 'action':'loadNewFileForm'}, {'label':'Edit', 'action':'editForm'}, ) # {'label':'Edit ProjectInfo','action':'editMPIWGProjectForm'}, # {'label':'Edit BasisInfo','action':'editMPIWGBasisForm'}, # {'label':'Edit Publications','action':'editMPIWGRelatedPublicationsForm'}, # {'label':'Edit Themes & Disciplines','action':'editMPIWGDisciplinesThemesForm'}, # {'label':'Versionmanager','action':'versionManageForm'}, # list of responsible scientists. entries are dicts with name, key, and username. responsibleScientistsList = [] # thumbnail image projectThumb = None # # templates # project_template = PageTemplateFile('zpt/project/project_template', globals()) # edit templates edit_css = ImageFile('css/edit.css', globals()) # make css refreshable for development edit_css.index_html = refreshingImageFileIndexHtml # user-accessible editing templates edit_basic = PageTemplateFile('zpt/project/edit_basic', globals()) editForm = PageTemplateFile('zpt/project/edit_description', globals()) edit_template = PageTemplateFile('zpt/project/edit_template', globals()) editRelatedProjectsForm = PageTemplateFile('zpt/project/edit_related_projects', globals()) editRelatedProjectsError = PageTemplateFile('zpt/project/edit_related_projects_error', globals()) editImagesForm = PageTemplateFile('zpt/project/edit_images', globals()) editPublicationsForm = PageTemplateFile('zpt/project/edit_publications', globals()) editAdditionalPublicationsForm = PageTemplateFile('zpt/project/pubman/change_publications', globals()) # management templates loadNewFileForm = PageTemplateFile('zpt/project/manage_newfile', globals()) description_only_html = PageTemplateFile('zpt/project/description_only_html', globals()) # additional pages additionalPublications = PageTemplateFile('zpt/project/pubman/show_publications', globals()) # TODO: this should go away extendedBibliography = PageTemplateFile('zpt/project/extendedBibliography_template', globals()) # TODO: compat edit_MPIWGProject_main = edit_template def __init__(self, id, argv=None): """initiere classe""" self.creationTime = time.strftime("%Y%m%d%H%M%S", time.localtime())[0:] self.id = id self.title = id self.isActiveFlag = True # Flag is true is the project is still active, False if accomplished self.responsibleScientistsList = [] # enthaelt die Lister der verantwortlichen Wissenschaftler in der Form (NAME, KEY), key ist "" flass Wissenschaftler nicht an unserem Haus if argv: for arg in definedFields: try: setattr(self, arg, argv[arg]) except: setattr(self, arg, "") else: for arg in definedFields: setattr(self, arg, '') def index_html(self): """default html representation""" # TODO: do we need to do date-stuff? # get template pt = getattr(self, 'project_template') # render template return pt() def redirect(self, RESPONSE, url): """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen""" timeStamp = time.time() if url.find("?") > -1: # giebt es schon parameter addStr = "&time=%s" else: addStr = "?time=%s" RESPONSE.setHeader('Last-Modified', email.Utils.formatdate().split("-")[0] + 'GMT') logging.debug(email.Utils.formatdate() + ' GMT') RESPONSE.redirect(url + addStr % timeStamp) def getDefinedFields(self): """show all defined fields.""" return definedFields def getFieldLabels(self): """Return the field labels dict.""" return fieldLabels def getEditableFields(self): """giveListofDatafields""" return editableFields def getNumber(self): """returns sorting number""" n = getattr(self, 'xdata_05', None) if isinstance(n, list): # compat with old lists return n[0] else: return n def getProjectTitle(self): """returns the project title""" t = getattr(self, 'WEB_title', None) if isinstance(t, list): # compat with old lists return t[0] else: return t def getLabel(self): """returns label (or title) of this project""" l = getattr(self, 'xdata_07', None) if isinstance(l, list): # compat with old lists l = l[0] if l: return l else: return self.getProjectTitle() def getResponsibleScientists(self): """returns the responsible scientists as string""" t = getattr(self, 'xdata_01', None) if isinstance(t, list): # compat with old lists return t[0] else: return t def getResponsibleScientistsList(self): """returns a list with the responsible scientists as dicts with name, key, and shortname""" return self.responsibleScientistsList def setResponsibleScientistsList(self, nameDict): """sets the responsibleScientistsList from nameDict. List will be ordered like the responsible scientists field.""" names = self.getResponsibleScientists() if names.find(";") > -1: # rate Trenner ist ; nameList = names.split(";") else: nameList = names.split(",") scientistsList = [] for name in nameList: name = unicodify(name.strip()) logging.debug("setResponsibleScientistsList: name=%s"%repr(name)) if name in nameDict: # found in data data = nameDict[name] scientistsList.append({'name': name, 'key': data['key'], 'username': data['username']}) else: scientistsList.append({'name': name}) logging.debug("setResponsibleScientistsList: nameDict=%s new list=%s"%(repr(nameDict),repr(scientistsList))) self.responsibleScientistsList = scientistsList def getInvolvedScholars(self): """returns the other involved scholars""" t = getattr(self, 'xdata_08', None) if isinstance(t, list): # compat with old lists return t[0] else: return t def getCooperationPartners(self): """returns the cooperation partners""" t = getattr(self, 'xdata_12', None) if isinstance(t, list): # compat with old lists return t[0] else: return t def getMPIWGProjectUrl(self): """Return this project for acquisition.""" return self.absolute_url() def getUrl(self, baseUrl=None): """returns URL to this Project""" if baseUrl is None: return self.absolute_url() return '%s/%s' % (baseUrl, self.getId()) def getThumbUrl(self, default='http://defaultthumb.jpg'): """returns the URL of the project thumbnail image""" thumb = self.projectThumb if thumb is None: # get thumb from list (thumb is last image) imgs = self.getImageList() url = default if len(imgs) > 0: thumb = imgs[-1] self.projectThumb = thumb if thumb is None: return default return thumb.absolute_url() def getImageList(self): """returns the sorted list of images for this project""" items = self.objectValues(spec='MPIWGProject_image') # sort by place return sorted(items, key=lambda x:int(getattr(x, 'place', 0))) def getDepartment(self): """returns the department of this project""" num = self.getNumber() pp = num.find('.') if pp > 0: num = num[:pp] return self.getMPIWGRoot().getDepartment(projectNumber=num) def getDepartmentId(self): """returns the id of the department of this project""" dep = self.getDepartment() if dep is not None: return dep.getId() return None def getDescription(self, filter=False): """returns the project description""" text = getattr(self, 'WEB_project_description', None) if isinstance(text, list): # compat with old lists text = text[0] return text def getSuperProjects(self): """returns a list of ancestor projects to the root""" tree = self.getProjectTree() return tree.getAncestorsOf(self.getNumber()) def getSubProjects(self, active=1): """returns a list of child projects""" tree = self.getProjectTree() return [p for p in tree.getChildrenOf(self.getNumber()) if p.checkActive(active)] def getRelatedProjectList(self): """returns the list of related projects""" items = self.objectValues(spec='MPIWGProject_relatedProject') # sort by place items.sort(key=lambda x:int(getattr(x, 'place', 0))) return items def getPublicationList(self): """returns the list of related publications""" items = self.objectValues(spec='MPIWGProject_publication') # sort by place items.sort(key=lambda x:int(getattr(x, 'place', 0))) return items def getRelatedDigitalSources(self): """returns the related digital sources""" t = getattr(self, 'xdata_11', None) if isinstance(t, list): # compat with old lists return t[0] else: return t def getFundingInstitutions(self): """returns the funding institutions""" t = getattr(self, 'xdata_13', None) if isinstance(t, list): # compat with old lists return t[0] else: return t def moveObjectPlace(self, objectList, objectId, direction): """Move object with objectId from objectList in direction by changing its place attribute.""" if not objectId or not direction: return for idx in range(len(objectList)): object = objectList[idx] if object.getId() == objectId: if direction == 'up': if idx > 0: # move up objectList[idx -1].place += 1 objectList[idx].place -= 1 elif direction == 'down': if idx < len(objectList) - 1: # move down objectList[idx + 1].place -= 1 objectList[idx].place += 1 return def manageImages(self, name=None, op=None): """manage images""" self.moveObjectPlace(self.getImageList(), name, op) # invalidate thumbnail self.projectThumb = None pt = self.editImagesForm return pt() def managePublications(self, name=None, op=None): """manage publications""" self.moveObjectPlace(self.getPublicationList(), name, op) pt = self.editPublicationsForm return pt() def manageRelatedProjects(self, name=None, op=None): """manage related projects""" self.moveObjectPlace(self.getRelatedProjectList(), name, op) pt = self.editRelatedProjectsForm return pt() def addPublication(self, text, RESPONSE=None): """add an MPIWG_Publication""" number = self.getLastPublicationNumber() + 1 name = "publication_" + str(number) while hasattr(self, name): number += 1 name = "publication_" + str(number) newPublication = MPIWGProject_publication(name) self._setObject(name, newPublication) obj = getattr(self, name) obj.text = text[0:] obj.enabled = True; obj.place = self.getLastPublicationNumber() + 1 obj.id = name if RESPONSE is not None: self.redirect(RESPONSE, 'managePublications') def errorRelatedProjects(self, link): """error creating a related project""" pt = self.editRelatedProjectsError return pt(link=link) def addRelatedProject(self, link, RESPONSE=None): """add a MPIWGProject_relatedProject""" number = self.getLastRelatedProjectNumber() + 1 name = "related_project_" + str(number) while hasattr(self, name): number += 1 name = "related_project_" + str(number) # hole die id des projektes splitted = link.split("/") # teste ob es das project gibt if len(splitted) < 1: self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link) objid = splitted[-1] object = getattr(self.projects, objid, None) if object == None: self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link) return newPublication = MPIWGProject_relatedProject(name) self._setObject(name, newPublication) obj = getattr(self, name) obj.orginallink = link[0:] obj.objid = objid[0:] logging.debug("add relobj:objid" + repr(obj.objid)) obj.projectWEB_title = object.getProjectTitle() logging.debug("add relobj:webtitle" + repr(obj.projectWEB_title)) obj.enabled = True; obj.place = self.getLastRelatedProjectNumber() + 1 obj.id = name if RESPONSE is not None: self.redirect(RESPONSE, 'manageRelatedProjects') def getLastImageNumber(self): items = self.getImageList() if not items: return 0 else: return getattr(items[-1], 'place', 0) def getLastPublicationNumber(self): items = self.getPublicationList() if not items: return 0 else: return getattr(items[-1], 'place', 0) def getLastRelatedProjectNumber(self): items = self.getRelatedProjectList() if not items: return 0 else: return getattr(items[-1], 'place', 0) def deletePublication(self, id, RESPONSE=None): """delete Publication id""" self.manage_delObjects([id]) if RESPONSE: self.redirect(RESPONSE, 'managePublications') def deleteRelatedProject(self, id, RESPONSE=None): """delete Publication id""" self.manage_delObjects([id]) if RESPONSE: self.redirect(RESPONSE, 'manageRelatedProjects') def deleteImage(self, id, RESPONSE=None): """delete Image id""" try: self.manage_delObjects([id]) except: logging.error("ERROR MPIWG: %s %s" % sys.exc_info()[0:2]) # invalidate thumbnail self.projectThumb = None if RESPONSE: self.redirect(RESPONSE, 'manageImages') def addImage(self, fileHd, caption, RESPONSE=None, filename=None): """add an MPIWG_Project_image""" if not filename: filename = fileHd.filename if not fileHd: fileHd = file(os.path.join(package_home(globals()), 'blank.gif')) newImage = MPIWGProject_image(filename, filename, fileHd) self._setObject(filename, newImage) obj = getattr(self, filename) obj.caption = caption[:] obj.enabled = True; obj.place = self.getLastImageNumber() + 1 obj.id = filename # invalidate thumbnail self.projectThumb = None if RESPONSE is not None: self.redirect(RESPONSE, 'manageImages') def getActualVersion(self, date=None): """actuelle version""" def sortProjectsByTime(x, y): return cmp(x[1].archiveTime, y[1].archiveTime) if not date: if self.isCurrentVersion(): return self else: return None # suche ob aeltere versionen vorhanden sind finds = self.ZopeFind(self, obj_metatypes=['MPIWGProject']) if not finds: # wenn nicht dann teste ob die aktuelle version schon existiert hat. ad = getattr(self, 'creationTime', '20050101000000') if int(date) > int(ad): return self else: return None else: finds.sort(sortProjectsByTime) for find in finds: # gehe durch die alten Projekte und finde das entprechende if (int(find[1].archiveTime) > int(date)) and (int(date) > int(getattr(find[1], 'creationTime', '20050101000000'))): return find[1] # kein passendes gefunden, dann teste ob das aktuelle in frage kommt ad = getattr(self, 'creationTime', '20050101000000') if int(date) > int(ad): return self else: return None def isCurrentVersion(self): """Return if project is the current version.""" currentTime = time.localtime() # print getattr(self,'archiveTime',currentTime) return (getattr(self, 'archiveTime', currentTime) >= currentTime) def copyObjectToArchive(self): """kopiere aktuelles objekt ins archiv""" logging.info("copytoarchive 1") cb = self.aq_parent.manage_copyObjects(self.getId()) logging.info("copytoarchive 2") self.manage_pasteObjects(cb) logging.info("copytoarchive 3") actualTime = time.localtime() self.manage_renameObject(self.getId(), self.getId() + "_" + time.strftime("%Y%m%d%H%M%S", actualTime)) logging.info("copytoarchive 4") obj = getattr(self, self.getId() + "_" + time.strftime("%Y%m%d%H%M%S", actualTime)) obj.setArchiveTime(time.strftime("%Y%m%d%H%M%S", actualTime)) logging.info("copytoarchive 5") ids = [x[0] for x in self.ZopeFind(obj, obj_metatypes=['MPIWGProject'])] logging.info("copytoarchive 6") obj.manage_delObjects(ids) logging.info("copytoarchive 7") def setArchiveTime(self, time): """set Archive Time""" self.archiveTime = time[0:] def delArchiveTime(self): """delete archive time""" del self.archiveTime def isActiveProject(self): """check if the project is still active, default is true.""" return getattr(self, 'isActiveFlag', True) def checkActive(self, active): """returns if the project state matches the active state. active = 0 : all projects active = 1 : active projects active = 2 : inactive projects """ act = getattr(self, 'isActiveFlag', True) return (active == 1 and act) or (active == 0) or (active == 2 and not act) def isArchivedProject(self): """check if the project is archived""" completed = self.getCompletedAt() # completed leer if completed == "" : return False; if completed == 0: return False; return True def checkArchived(self, archived): """returns if the project state matches the archived state. archived = 0 : all projects archived = 1 : current projects archived = 2 : archived projects """ arch = self.isArchivedProject() return (archived == 1 and not arch) or (archived == 0) or (archived == 2 and arch) def setActiveFlag(self, status=True): """set the active flag""" self.isActiveFlag = status def setCompletedAt(self, date): """set the date of completion, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY""" # logging.info("DATE:"+repr(date)) transformedDate = self.transformDate(date); # logging.info("transformed"+repr(transformedDate)) if transformedDate is not None: setattr(self, "completedAt", transformedDate) return True; else: return False; def setStartedAt(self, date): """set the date of start, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY""" # logging.info("DATE:"+repr(date)) transformedDate = self.transformDate(date); # logging.info("transformed"+repr(transformedDate)) if transformedDate is not None: setattr(self, "startedAt", transformedDate) return True; else: return False; def getCompletedAt(self): """gibt das transformierte Datum zurueck, an dem das Projekt beendet wurde.""" date = getattr(self, 'completedAt', '') if date: return self.reTransformDate(date); else: return "" def getStartedAt(self): """gibt das transformierte Datum zurueck, an dem Projekt begonnen wurde.""" date = getattr(self, 'startedAt', '') if date: return self.reTransformDate(date); else: return ''; def reTransformDate(self, date): """transformiert , transformdate zurueck""" year = int(date / 10000) month = int((date - year * 10000) / 100) day = int((date - year * 10000 - month * 100)) if (day == 0) and (month == 0): return """%s""" % year; if day == 0 : return """%s.%s""" % (month, year); return """%s.%s.%s""" % (day, month, year); def transformDate(self, date): """transformiert ein Datum von DD.MM.YYYY, MM.YYYY,YYYY nach YYYYMMDD, alle nicht angebenen Werte werden auf 0 gesetzt, es wird null zurueckgegeben falls das Datum ungueltig ist""" if (date == None): return None; if (date.lstrip().rstrip() == "") : return ""; splitted = date.split(".") length = len(splitted) year = 0 month = 0 day = 0 if length > 3: return ""; if length == 3: day = int(splitted[0]) if length > 1: month = int(splitted[length - 2]) if length > 0: try: year = int(splitted[length - 1]) except: pass # # logging.info("month:"+(month)) if not (0 <= month < 13): return None; if not(0 <= day < 32): return None; if (year > 0) and (year < 1900): # jahr nicht vierstellig eingegeben year = 2000 + year; return year * 10000 + month * 100 + day def checkDate(self, date): """teste ob zum Zeitpunkt date eine andere version existierte""" def sortProjectsByTime(x, y): return cmp(x[1].archiveTime, y[1].archiveTime) # suche ob aeltere versionen vorhanden sind finds = self.ZopeFind(self, obj_metatypes=['MPIWGProject']) if not finds: # wenn nicht dann teste ob die aktuelle version schon existiert hat. ad = getattr(self, 'creationTime', '20050101000000') if int(date) > int(ad): return self.REQUEST['URL1'] + "/" + self.getId() else: return self.REQUEST['URL1'] + "/no_project" else: finds.sort(sortProjectsByTime) for find in finds: # gehe durch die alten Projekte und finde das entprechende if (int(find[1].archiveTime) > int(date)) and (int(date) > int(getattr(find[1], 'creationTime', '20050101000000'))): return self.REQUEST['URL1'] + "/" + find[1].getId() # kein passendes gefunden, dann teste ob das aktuelle in frage kommt ad = getattr(self, 'creationTime', '20050101000000') if int(date) > int(ad): return self.REQUEST['URL1'] + "/" + self.getId() else: return self.REQUEST['URL1'] + "/no_project" def saveFromPreview(self): """save content aus preview""" self.WEB_project_description = self.previewTemplate.WEB_project_description[0:] self.REQUEST.RESPONSE.redirect("./index.html") def saveEditedContent(self, kupu=None, preview=None): """save Edited content""" # logging.debug("saveEditedContent kupu=%s preview=%s"%(kupu,preview)) if preview: kupu = preview # find content of body tags start = kupu.find("<body>") end = kupu.find("</body>") newcontent = kupu[start + 6:end] if preview: return self.preview(newcontent) self.copyObjectToArchive() self.ZCacheable_invalidate() self.WEB_project_description = newcontent[0:] self.REQUEST.RESPONSE.redirect("./index.html") return True security.declareProtected('View management screens', 'edit') def edit(self, western=None): """Edit pages""" if western: self.REQUEST.RESPONSE.setCookie("MP_debug_code", "western", path="/") # pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGProjectNeu.zpt')).__of__(self) pt = self.editForm return pt() def getBreadcrumbs(self): """return list of breadcrumbs from here to the root""" crumbs = [] # skip direct parent Folder /projects/ parent = self.aq_parent.aq_parent # get parents breadcrumbs if hasattr(parent, 'getBreadcrumbs'): crumbs = parent.getBreadcrumbs() # try to get acquisition URL from parent if hasattr(parent, 'absolute_url'): baseUrl = "%s/%s/" % (parent.absolute_url(), 'projects') else: baseUrl = "/en/research/projects/" # add in the internal project hierarchy tree = self.getProjectTree() ap = tree.getAncestorsOf(self.getNumber()) # start with grandparents for p in ap: label = shortenString(p.getLabel(), 13) crumbs.append((label, p.getUrl(baseUrl=baseUrl), p)) # add this project crumbs.append((self.getLabel(), self.getUrl(baseUrl=baseUrl), self)) return crumbs # TODO: is this used? def preview(self, description): """preview""" # logging.debug("preview description=%s"%description) tmpPro = getattr(self, "previewTemplate", None) if not tmpPro: tmpPro = MPIWGProject("previewTemplate") self._setObject("previewTemplate", tmpPro) for field in definedFields: setattr(tmpPro, field, getattr(self, field)) tmpPro.WEB_project_description = description[0:] tmpPro.invisible = True pt = PageTemplateFile('zpt/previewFrame.zpt', globals()).__of__(self) return pt() # return self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+"/previewTemplate") def editMPIWGProjectForm(self): """editform""" pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_MPIWGProject.zpt')).__of__(self) return pt() def isResponsibleScientist(self, key): """teste ob eine Person in der Liste der respl. scientists auftaucht""" #key = utf8ify(key) for resp in self.getResponsibleScientistsList(): logging.debug("resp=%s key=%s"%(repr(resp),repr(key))) if resp.get('key', '').lower() == key.lower(): return True return False def identifyNames(self, nameList): """Bekommt eine Komma oder Semikolon getrennte Liste mit Name der Form Vorname MittelName(n) Nachname und ordnet diese dann Mitarbeiter IDs zu. Returns a dict with full names as keys and a row of person objects from the database as values. @param nameList """ if nameList.find(";") > -1: # rate Trenner ist ; names = nameList.split(";") else: names = nameList.split(",") # #nameList=nameList.replace(";",",") # falls ; als Trenner ersetze returnNamesDict = {} for name in names: name = name.strip() nameSplitted = name.split(" ") if len(nameSplitted) > 1: # vor und nachname angegeben) lastname = nameSplitted[-1] firstname = nameSplitted[0] else: firstname = "" lastname = nameSplitted[0] # finde Mitarbeiter mit den entsprechenden Name # firstname=self.myCapitalize(firstname).encode('utf-8') # lastname=self.myCapitalize(lastname).encode('utf-8') logging.debug("Search: %s %s %s" % (name, repr(firstname), repr(lastname))) try: # cataloggedNames=self.MembersCatalog(firstName=firstname,lastName=lastname) # TODO: I think this does not work without firstname # try to find names in members db by searching for sub-words cataloggedNames = self.executeZSQL("select * from personal_www where first_name ~* ('\m'||%s||'\M') and last_name ~* ('\m'||%s||'\M')", (firstname, lastname)) if len(cataloggedNames) == 0: # PostgreSQL has a bug with \m and words ending in non-ASCII :-( cataloggedNames = self.executeZSQL("select * from personal_www where %s in (select regexp_split_to_table(lower(first_name), '\s+')) and %s in (select regexp_split_to_table(lower(last_name), '\s+'))", (firstname.lower(), lastname.lower())) except: cataloggedNames = [] logging.error("ERROR: identifyNames %s %s" % sys.exc_info()[0:2]) if len(cataloggedNames) > 0: returnNamesDict[name] = cataloggedNames else: returnNamesDict[name] = [] logging.debug("identified names: %s" % repr(returnNamesDict)) return returnNamesDict def editMPIWGProject(self, fromEdit=None, createNewVersion=True, RESPONSE=None): """edit the project and archive the old version""" logging.debug("editMPIWGProject(fromEdit=%s, createNewVersion=%s)"%(fromEdit,createNewVersion)) if createNewVersion: self.copyObjectToArchive() # archive the object formdata = self.REQUEST.form # set all definedFields for x in definedFields: if formdata.has_key(x): setattr(self, x, unicodify(formdata[x])) # TODO: What does this do? completedAt = formdata.get('completedAt') if not self.setCompletedAt(completedAt): RESPONSE.redirect('./editMPIWGBasisEditor?error=dateWrong') startedAt = formdata.get('startedAt') if not self.setStartedAt(startedAt): RESPONSE.redirect('./editMPIWGBasisEditor?error=dateWrong') if self.REQUEST.has_key('active'): self.setActiveFlag(True) else: self.setActiveFlag(False) # make dict of responsible scientists checkedScientists = {} names = {} keys = {} for key in formdata: # gehe durch das Formular keyParts = key.split("_") if keyParts[0] == "responsibleScientist": # wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt nr = keyParts[2] if keyParts[1] == "name": names[nr] = unicodify(formdata[key]) elif keyParts[1] == "key": keys[nr] = formdata[key] for nr in names: name = names[nr] key = keys.get(nr, None) username = None if key: # get username from db member = self.getMPIWGRoot().getStaffFolder().getMember(key=key) if member is not None: username = member.getUsername() # schreibe keys und namen in die Liste checkedScientists[names[nr]] = {'name' : name, 'key' : key, 'username' : username} # update responsibleScientistsList self.setResponsibleScientistsList(checkedScientists) self.updateProjectMembers() if fromEdit and (RESPONSE is not None): return self.editBasic() if RESPONSE is not None: RESPONSE.redirect('manage_main') security.declareProtected('View management screens', 'editBasic') def editBasic(self, identifiedNames=None): """editform""" if not identifiedNames: identifiedNames = self.identifyNames(self.getResponsibleScientists()) logging.debug("editBasic: IdentifiedNames=%s" % repr(identifiedNames)) pt = self.edit_basic return pt(identifiedNames=identifiedNames) def getContent(self, field, filter=None): """Inhalt des Feldes""" val = getattr(self, field, '') if isinstance(val, list): val = val[0] return val def loadNewFile(self, RESPONSE=None): """einlesen des neuen files""" fileupload = self.REQUEST['fileupload'] if fileupload: file_name = fileupload.filename filedata = fileupload.read() argv = xmlhelper.proj2hash(filedata) # print argv.keys() for arg in definedFields: # print arg,argv[arg],getattr(self,arg) try: temp = argv[arg][0:] # old=getattr(self,arg) setattr(self, arg, temp) # print old,getattr(self,arg) except: """nothing""" if RESPONSE is not None: RESPONSE.redirect('manage_main') def tagTheProject(self, RESPONSE=None): """TAG""" id = self.getId(); tmpl = getattr(self.thesaurus, "main.html") if RESPONSE: RESPONSE.redirect("./thesaurus/main.html?project=" + id) return def hasRelatedPublicationsOldVersion(self): """teste ob es related publications gibt""" ret = True; if (getattr(self, 'WEB_related_pub', '') == ''): ret = False; # nichts im alten feld logging.debug("webrel:" + repr(ret)) if (getattr(self, 'WEB_related_pub_copied', False)): ret = False; # alte daten sind schon kopiert worden logging.debug("webrel_copied:" + repr(ret)) publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_publication']); if(len(publications) > 0): ret = False; # es gibt publicationen in der neuen liste logging.debug("len(publ)" + repr(ret)) return ret; def copyPublicationsToList(self, RESPONSE=None): """copy publications in to list""" publicationTxt = getattr(self, 'WEB_related_pub', '') if isinstance(publicationTxt, list): publicationTxt = publicationTxt[0] pubSplits = publicationTxt.split("<p>") for pubSplit in pubSplits: pubSplit = pubSplit.replace("</p>", "") self.addPublication(pubSplit) setattr(self, "WEB_related_pub_copied", True); if RESPONSE: self.redirect(RESPONSE, 'managePublications') def hasInlineImage(self): """Return the number of inline images in the description.""" text = self.getDescription() cnt = text.count('<p class="picture">') return cnt def copyImageToMargin(self, RESPONSE=None): """copy inline images to marginal images""" # getImages from WEB_project_description description = self.getDescription() text2 = description splitted = text2.split("""<p class="picture">""") imageURLs = [] imageCaptions = [] for split in splitted[1:]: tmp = split.split("</p>") # return repr(splitted[1]) try: imageURLs.append(tmp[0].split("\"")[1].encode('utf-8')) except: try: imageURLs.append(tmp[0].split("src=")[1].split(" ")[0].encode('utf-8')) except: imageURLs.append("") split2 = "</p>".join(tmp[1:]) splitted = split2.split("""<p class="picturetitle">""") if len(splitted) > 1: tmp = splitted[1].split("</p>") imageCaptions.append(tmp[0].encode('utf-8')) else: # keine caption imageCaptions.append("") # eintragen: for imageURL in imageURLs: if not imageURL: # no URL - no image continue filename = imageURL.split("/")[-1] # lege neues images object an, mit leerem bild if filename in self: # existiert das bild schon, dann neuen filenamen filename = "project_image_" + filename if filename in self: # exists too - assume its already converted logging.warn("copyImageToMargin: image %s exists - skipping!"%filename) continue self.addImage(None, imageCaptions[imageURLs.index(imageURL)], filename=filename) # hole die bilddaten aus der url url = self.absolute_url() + "/" + imageURL # url=self.absolute_url()+"/"+filename try: # relative url data = urllib.urlopen(url).read() except: try: # absolute data = urllib.urlopen(self.imageURL).read() except: logging.error("copyImageToMargin: can't open: %s" % url) obj = getattr(self, filename) obj.update_data(data) # clean description logging.debug("copyImageToMargin: description:%s"%repr(description)) dom = ET.fromstring(utf8ify("<html>%s</html>"%description)) for e in dom.findall(".//p[@class='picture']"): # remove contents e.clear() # remove tag e.tag = None for e in dom.findall(".//p[@class='picturetitle']"): # remove contents e.clear() # remove tag e.tag = None # remove html tag dom.tag = None # set as new description description = unicodify(serialize(dom)) logging.debug("copyImageToMargin: new description:%s"%repr(description)) setattr(self, 'WEB_project_description', description) if RESPONSE: self.redirect(RESPONSE, 'manageImages') def updateProjectMembers(self, updateResponsibleScientistsList=False): """Update project-member table.""" # projects are identified by id pid = self.getId() # clear projects_members table self.executeZSQL("delete from projects_members where project_id = %s", [pid]) for m in self.getResponsibleScientistsList(): memberKey = m.get('key', None) if not memberKey or not isinstance(memberKey, basestring): logging.error("updateProjectMembers: not a valid member key: %s" % repr(memberKey)) continue # fill projects_members table self.executeZSQL("insert into projects_members (project_id, member_key) values (%s, %s)", (pid, memberKey)) def addPublicationsFromPubman(self,REQUEST): """addPublications from pubman""" data=REQUEST.form if data.get("method",None) is None: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/project/pubman','add_publications.zpt')).__of__(self) return pt() if data.get("method") == "search": entries= self.mpiwgPubman.search(data) pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/project/pubman','add_publications.zpt')).__of__(self) return pt(values=entries) if data.get("method") == "add": return self.addEntriesToPublicationList(data) #pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff/pubman','add_publications.zpt')).__of__(self) def addEntriesToPublicationList(self,data): """fuege eintrage aus data zur publications liste, @param data Map mit escidocID --> value value muss "add" sein damit hinzugefuegt wird""" for key in data.keys(): if key.startswith('escidoc:'): query="INSERT INTO pubmanbiblio_projects (key_main,escidocId) values (%s,%s)" if data.get(key)=="add": self.executeZSQL(query,[self.getId(),key]) #selectedPublications = self.getSelectedPublications() #pt = PageTemplateFile(os.path.join(package_home(globals()),'zpt/project/pubman','change_publications.zpt')).__of__(self) #return pt() if hasattr(self,'REQUEST'): return self.REQUEST.response.redirect("changePublications") def changePublications(self,REQUEST): """change published publications""" data=REQUEST.form if data.get("method","change"): for key in data.keys(): splitted=key.split("__") #format escidoc_id__p fuer priority, nur escidocid value=data[key] if len(splitted)==1: self.deleteFromPublicationList(key); elif(splitted[1]) == "p": self.setPublicationPriority(splitted[0],value); pt = self.editAdditionalPublicationsForm return pt() def deleteFromPublicationList(self,escidocid): """Loessche publication with escidoc id from publication list""" query ="DELETE FROM pubmanbiblio_projects WHERE escidocid=%s and key_main=%s" self.executeZSQL(query,[escidocid,self.getId()]); def setPublicationPriority(self,escidocid,value): query="update pubmanbiblio_projects set priority=%s where escidocid=%s and key_main=%s" try: value = int(value) self.executeZSQL(query,[value,escidocid,self.getId()]); except: logging.error("couldn't change:") logging.error(escidocid) logging.error(value) def getAdditionalPublicationList(self): """hole publications aus der datenbank""" query="select * from pubmanbiblio_projects where lower(key_main) = lower(%s) order by priority DESC" return self.executeZSQL(query,[self.getId()]) def hasAdditionalPublications(self): """test if extended publication list exists""" query="select count(*) from pubmanbiblio_projects where lower(key_main) = lower(%s)" res= self.executeZSQL(query,[self.getId()]) if res[0].count > 0: return True else: return False def manage_addMPIWGProjectForm(self): """form for adding the project""" pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'addMPIWGProjectForm.zpt')).__of__(self) return pt() def manage_addMPIWGProject(self, id, RESPONSE=None): """method to add a project""" # print argv fileupload = self.REQUEST.get('fileupload', None) if fileupload: file_name = fileupload.filename filedata = fileupload.read() argv = xmlhelper.proj2hash(filedata) # print argv newObj = MPIWGProject(id, argv) else: newObj = MPIWGProject(id) self._setObject(id, newObj) if RESPONSE is not None: RESPONSE.redirect('manage_main') class MPIWGProjectFolder(ZDBInterfaceFolder): """Folder of project objects""" meta_type = "MPIWGProjectFolder" security = ClassSecurityInfo() # cached HashTree with project hierarchy _v_projectTree = None def getProjectTree(self): """Return the project hierarchy tree (and cache it). Returns HashTree instance.""" tree = self._v_projectTree if tree is None: tree = HashTree(keySeparator='.', keyFn=getInt) for p in self.objectValues(spec='MPIWGProject'): # add all projects tree.add(p.getNumber(), p) self._v_projectTree = tree # logging.debug("getProjectTree: tree=%s"%(tree.root.getSubtreeAsText())) return tree def getProjectsAsList(self, start=None, active=1, archived=1): """Return flattened list of projects, starting from start. active = 0 : all projects active = 1 : active projects active = 2 : inactive projects archived = 0 : all projects archived = 1 : current projects archived = 2 : archived projects """ # logging.debug("getProjectsAsList(start=%s,active=%s,archived=%s)"%(repr(start),active,archived)) tree = self.getProjectTree() node = tree.getNode(start) if node is None: return [] pl = node.getSubtreeAsList() # logging.debug("getProjectsAsList: node=(%s,%s) pl=%s"%(node.key,node.value,pl)) # return filtered list return [p for p in pl if (p.checkActive(active) and p.checkArchived(archived))] def getProject(self, projectNumber=None): """Return the matching project""" tree = self.getProjectTree() if projectNumber is not None: return tree.get(projectNumber) return None def getProjectsOfMember(self, key, active=1, archived=1): """Return a list of all projects of a member. @param key: member's key active = 0 : all projects active = 1 : active projects active = 2 : inactive projects archived = 0 : all projects archived = 1 : current projects archived = 2 : archived projects """ projects = [] # search project numbers res = self.executeZSQL("select * from projects_members where lower(member_key) = %s", [key.lower()]) tree = self.getProjectTree() # find projects in tree for r in res: p = tree.get(r.project_number) # check if active if p is not None and p.checkActive(active) and p.checkArchived(archived): projects.append(p) projects.sort(key=lambda p:[int(n) for n in p.getNumber().split('.')]) return projects security.declareProtected('View management screens', 'changeProjectTree') def changeProjectTree(self, RESPONSE=None): """change the complete tree""" form=self.REQUEST.form hashList={} onlyArchived=int(form.get("onlyArchived",0)) onlyActive=int(form.get("onlyActive",0)) dep=form.get("dep",None) fields = self.getProjectsAsList(start=dep, archived=onlyArchived, active=onlyActive) logging.info("GOT TREE!----------------------------------------------------") for field in form.keys(): splitted=field.split('_') if (len(splitted)>1) and (splitted[1]=="runningNumber"): #feld hat die Form Nummer_name und runnignNumber nr=int(splitted[0]) # nummer des Datensatzes project = fields[nr] # # change active # if form.has_key('%s_active'%nr): # active flag is set project.setActiveFlag(True) else: project.setActiveFlag(False) # # nummer hat sich geaendert # entryChanged = False; pronum = project.getNumber() formnum = form['%s_number'%nr] if not (pronum == formnum): logging.debug("Changed!Number+++++++++++++++++++++++++++++++++") logging.debug(repr(fields[nr].xdata_05)+" ---> "+ repr(form[str(nr)+'_number'])) entryChanged = True # # completed hat sich geaendert # td = project.transformDate # hole die funktion zum transformieren des datums formstarted = form[str(nr)+'_started'] formcompleted = form[str(nr)+'_completed'] if not (td(project.getCompletedAt()) == td(formcompleted)): logging.info(repr(td(project.getCompletedAt()))+" ---> "+ repr(td(form[str(nr)+'_completed']))) logging.info("Changed!Completed+++++++++++++++++++++++++++++++++") entryChanged = True if not (td(project.getStartedAt()) == td(formstarted)): logging.info(repr(td(project.getStartedAt()))+" ---> "+ repr(td(form[str(nr)+'_started']))) logging.info("Changed!Started+++++++++++++++++++++++++++++++++") entryChanged = True if entryChanged: logging.info("Changed!+++++++++++++++++++++++++++++++++") project.copyObjectToArchive() project.xdata_05 = formnum project.setCompletedAt(formcompleted) project.setStartedAt(formstarted) # reset tree self._v_projectTree = None if RESPONSE is not None: RESPONSE.redirect(self.en.MPIWGrootURL()+'/admin/showTree') # TODO: this is broken. is this used? def getAllProjectsAndTagsAsCSV(self,archived=1,RESPONSE=None): """alle projekte auch die nicht getaggten""" retList=[] headers=['projectId','sortingNumber','projectName','scholars','startedAt','completedAt','lastChangeThesaurusAt','lastChangeProjectAt','projectCreatedAt','persons','places','objects'] headers.extend(list(self.thesaurus.tags.keys())) retList.append("\t".join(headers)) if not hasattr(self,'thesaurus'): return "NON thesaurus (there have to be a MPIWGthesaurus object, with object ID thesaurus)" projectTags = self.thesaurus.getProjectsAndTags() for project in self.getProjectFields('WEB_title_or_short'): proj = project[0] p_name = project[1] retProj=[] #if (not proj.isArchivedProject() and archived==1) or (proj.isArchivedProject() and archived==2): retProj.append(self.utf8ify(proj.getId())) retProj.append(self.utf8ify(proj.getContent('xdata_05'))) retProj.append(self.utf8ify(p_name)) retProj.append(self.utf8ify(proj.getContent('xdata_01'))) retProj.append(self.utf8ify(proj.getStartedAt())) retProj.append(self.utf8ify(proj.getCompletedAt())) changeDate=self.thesaurus.lastChangeInThesaurus.get(proj.getId(),'') n = re.sub("[:\- ]","",str(changeDate)) retProj.append(n) retProj.append(self.utf8ify(getattr(proj,'creationTime','20050101000000'))) retProj.append("")#TODO: project created at retProj.append(";".join([person[1] for person in self.thesaurus.getPersonsFromProject(proj.getId())])) retProj.append(";".join([person[1] for person in self.thesaurus.getHistoricalPlacesFromProject(proj.getId())])) retProj.append(";".join([person[1] for person in self.thesaurus.getObjectsFromProject(proj.getId())])) retProj+=self.thesaurus.getTags(proj.getId(),projectTags) retList.append("\t".join(retProj)) if RESPONSE: RESPONSE.setHeader('Content-Disposition','attachment; filename="ProjectsAndTags.tsv"') RESPONSE.setHeader('Content-Type', "application/octet-stream") return "\n".join(retList); security.declareProtected('View management screens', 'updateAllProjectMembers') def updateAllProjectMembers(self, updateResponsibleScientistsList=False): """Re-create responsibleScientistsLists and projects_members table from all current projects.""" # empty table self.executeZSQL('truncate table projects_members') cnt = 0 # go through all projects for p in self.objectValues(spec='MPIWGProject'): cnt += 1 memberlist = [] logging.debug("updateAllProjectMembers: updating project %s" % p) p.updateProjectMembers(updateResponsibleScientistsList=updateResponsibleScientistsList) return "updated %s projects!" % cnt security.declareProtected('View management screens', 'updateAllProjects') def updateAllProjects(self, updateResponsibleScientistsList=False, RESPONSE=None): """Patch all current projects for legacy problems.""" cnt = 0 fulllog = "" # go through all projects for (id, project) in self.ZopeFind(self, obj_metatypes=['MPIWGProject'], search_sub=1): log = "" cnt += 1 # # hasRelatedPublicationsOldVersion # if project.hasRelatedPublicationsOldVersion(): log += "%s: update relatedPublicationsOldVersion!\n"%project.getId() logging.debug("updateAllProjects(%s): update relatedPublicationsOldVersion!"%project.getId()) project.copyPublicationsToList() # # create responsibleScientistsList automatically # if updateResponsibleScientistsList: newScientists = {} names = project.identifyNames(p.getResponsibleScientists()) for name in names: logging.debug("updateAllProjectMembers: name=%s" % repr(name)) members = names[name] if len(members) > 0: # take the first matching name newScientists[name] = {'name': name, 'key' : members[0].key, 'username' : re.sub('@mpiwg-berlin\.mpg\.de', '', members[0].e_mail)} project.setResponsibleScientistsList(newScientists) else: # # old format responsibleScientistsList # memberlist = project.getResponsibleScientistsList() if len(memberlist) > 0 and isinstance(memberlist[0], tuple): log += "%s: updating memberlist!\n"%project.getId() logging.debug("updateAllProjects(%s): updating memberlist" % project.getId()) newScientists = {} for m in memberlist: name = m[0] key = m[1] username = None if key: if isinstance(key, list): key = key[0] # get username from db member = self.getMPIWGRoot().getStaffFolder().getMember(key=key) if member is not None: username = member.getUsername() newScientists[name] = {'name': name, 'key' : key, 'username' : username} # set new list project.setResponsibleScientistsList(newScientists) # # old inline images # if project.hasInlineImage(): log += "%s: has inlineImage!\n"%project.getId() logging.debug("updateAllProjects(%s): has inlineImage!"%project.getId()) try: project.copyImageToMargin() except Exception, e: log += "%s: ERROR in copyImageToMargin!\n"%project.getId() logging.debug("updateAllProjects(%s): ERROR in copyImageToMargin: %s"%(project.getId(), e)) # # remove old attributes # if hasattr(project, 'definedFields'): log += "%s: has definedFields!\n"%project.getId() logging.debug("updateAllProjects(%s): has definedFields!"%project.getId()) delattr(project, 'definedFields') # # update related publications # for pub in project.getPublicationList(): pub.hasLinkToBookPage() # # unicodify # for field in ('WEB_title', 'xdata_01', 'xdata_07', 'xdata_08', 'xdata_11', 'xdata_12', 'xdata_13', 'WEB_project_description', 'WEB_related_pub'): text = getattr(project, field, None) if isinstance(text, str): log += "%s: has non-unicode field %s\n"%(project.getId(), field) logging.debug("updateAllProjects(%s): has has non-unicode field %s\n"%(project.getId(), field)) setattr(project, field, unicodify(text)) fulllog += log if RESPONSE is not None: RESPONSE.write(log) log += "\n DONE! updated %s projects!" % cnt fulllog += log if RESPONSE is not None: RESPONSE.write(log) RESPONSE.flush() else: return fulllog def manage_addMPIWGProjectFolderForm(self): """form for adding a MPIWGProjectFolder""" pt = PageTemplateFile('zpt/project/manage_add_MPIWGProjectFolder', globals()).__of__(self) return pt() def manage_addMPIWGProjectFolder(self, id, title, RESPONSE=None): """add a MPIWGProjectFolder""" newObj = MPIWGProjectFolder(id, title) self._setObject(id, newObj) if RESPONSE is not None: RESPONSE.redirect('manage_main')