Mercurial > hg > MPIWGWeb
view MPIWGStaff.py @ 156:a9ad7dd7a8b2
clean up projects.
author | casties |
---|---|
date | Wed, 05 Jun 2013 13:12:42 +0200 |
parents | 0d9eb2a859d3 |
children | ee79f6ba8d01 |
line wrap: on
line source
"""This file contains the classes for the organization of the staff""" from zExceptions import Redirect from OFS.Folder import Folder from Products.PageTemplates.PageTemplateFile import PageTemplateFile from AccessControl import ClassSecurityInfo from App.class_init import InitializeClass from Products.ExtFile.ExtFile import * from Globals import package_home from Products.PythonScripts.standard import sql_quote from Products.ExtFile import ExtFile import os import logging import email import re from Products.ZDBInterface.ZDBInterfaceFolder import ZDBInterfaceFolder from SrvTxtUtils import getInt, unicodify, utf8ify import MPIWGHelper # # compatibility # TODO: should be removed when done import MPIWGStaff_old createNewDBEntry = MPIWGStaff_old.createNewDBEntry class MPIWGStaff(MPIWGStaff_old.MPIWGStaff): """Staff""" pass manage_addMPIWGStaffForm = MPIWGStaff_old.manage_addMPIWGStaffForm manage_addMPIWGStaff = MPIWGStaff_old.manage_addMPIWGStaff class MPIWGStaffFolder(ZDBInterfaceFolder): """Folder of staff objects""" meta_type="MPIWGStaffFolder" security=ClassSecurityInfo() # # templates # member_index_html = PageTemplateFile('zpt/staff/member_index_html', globals()) # # hook into traversal to create folder of virtual staff objects # like /members/$username/index_html # def __before_publishing_traverse__(self, object, request): stack = request.TraversalRequestNameStack logging.debug("MPIWGStaffFolder: traverse stack=%s self=%s"%(repr(stack),repr(self))) # TODO: should we do more checks? if stack and len(stack) > 0: try: # id is the first path component id = stack[-1] logging.debug(id) member = self.getMember(username=id) if member is not None: member = member.__of__(self) request.set('MPIWGStaffMember', member) stack.pop(-1) #weitere parameter if len(stack)> 0: mode = stack[-1] request.set('MPIWGStaffMode', mode) stack.pop(-1) except (IndexError, ValueError): # missing context or not an integer id; perhaps some URL hacking going on? logging.error("error traversing user id!") raise Redirect(self.absolute_url()) # redirects to `/members`, adjust as needed def index_html(self,REQUEST,RESPONSE): """show homepage""" logging.debug("MPIWGStaffFolder: index_html!") member = REQUEST.get('MPIWGStaffMember', None) mode = REQUEST.get('MPIWGStaffMode', None) if member is not None: if mode is not None: return member.execute(mode,REQUEST); logging.debug("member: key=%s"%(member.getKey())) pt = None try: # get template /template/member_index_html pt = getattr(self.template, 'member_index_html', None) except: logging.error("No template /template/member_index_html") # TODO: error page? return "No template /template/member_index_html" if pt is not None: return pt(member=member) return REQUEST def getMember(self, username=None, key=None): """returns a MPIWGStaffMember object if the username exists""" member = None if username is not None: # TODO: we should have a username column email = '%s@mpiwg-berlin.mpg.de'%username content = self.executeZSQL("select * from personal_www where e_mail = %s", [email]) if len(content) > 0: member = MPIWGStaffMember(self, dbresult=content[0]) elif key is not None: # TODO: sometimes key is lowercased (e.g. responsibleScientistsList), we should fix the data content = self.executeZSQL("select * from personal_www where lower(key) = %s", [key.lower()]) if len(content) > 0: member = MPIWGStaffMember(self, dbresult=content[0]) return member def isActiveMember(self, key): """returns if member key is active""" res = self.executeZSQL("select * from personal_www where lower(key) = %s and publish_the_data = 'yes'", [key.lower()]) return len(res) > 0 def getMemberList(self, department=None, sortBy='last_name', onlyCurrent=False, limit=0): """Return the list of members. Returns a list of MPIWGStaffMember objects. """ members = [] query = "select * from personal_www_list where publish_the_data = 'yes' and is_scholar='yes'" args = [] if department is not None: query += " and department ilike %s" args.append('%%%s%%'%department) if onlyCurrent: query += " and date_from < CURRENT_DATE" if sortBy == 'last_name': query += " order by lower(last_name)" elif sortBy == 'date_from': query += " order by date_from DESC" if limit > 0: query += " limit %s"%int(limit) result = self.executeZSQL(query, args) for res in result: members.append(MPIWGStaffMember(self, dbresult=res)) return members def sortPriority(self,list): def sort(x,y): try: xInt=int(x.priority) except: xInt=0 try: yInt=int(y.priority) except: yInt=0 return cmp(xInt,yInt) if not list: return [] tmp=[x for x in list] tmp.sort(sort) return tmp def importSortingModeFromOldStaff(self): """ only used for the migration to the new website """ ret=[] for member in self.getMemberList(): email = member.content.e_mail un = email.split("@")[0] logging.debug(un) olduser = self.members_old.get(un) if not olduser is None: mode =olduser.getSortingMode() if mode.startswith("year"): mode="year" query="UPDATE personal_www SET publications_mode=%s WHERE key=%s" self.executeZSQL(query,[mode,member.getKey()]) return ret def importPublishFotoFromOldStaff(self): """ only used for the migration to the new website """ ret=[] for member in self.getMemberList(): email = member.content.e_mail un = email.split("@")[0] logging.debug(un) olduser = self.members_old.get(un) if not olduser is None: mode =olduser.getPublishImage() query="UPDATE personal_www SET image_p=%s WHERE key=%s" self.executeZSQL(query,[mode,member.getKey()]) return ret def showDownloadableFiles(self): """copy df to the new""" logging.debug("huh") ret=[] for member in self.getMemberList(onlyCurrent=True): email = member.content.e_mail un = email.split("@")[0] logging.debug(un) olduser = self.www_neu.members.get(un) if olduser is None: continue; df = olduser.get('downloadableFiles') if df is not None: ret.append(olduser) return ret,len(ret) def manage_addMPIWGStaffFolderForm(self): """form for adding the project""" pt=PageTemplateFile('zpt/addMPIWGStaffFolderForm', globals()).__of__(self) return pt() def manage_addMPIWGStaffFolder(self,id,title,RESPONSE=None): """add it""" newObj=MPIWGStaffFolder(id,title) self._setObject(id,newObj) if RESPONSE is not None: RESPONSE.redirect('manage_main') class MPIWGStaffMember(Folder): """MPIWG staff member object from database""" security = ClassSecurityInfo() # templates mainEditFile=PageTemplateFile('zpt/staff/edit_main', globals()) talks_full_html = PageTemplateFile('zpt/staff/talks_full_html', globals()) teaching_full_html = PageTemplateFile('zpt/staff/teaching_full_html', globals()) def __init__(self, folder, dbresult): """constructor: takes parent MPIWGStaffFolder and content (DB row)""" self.folder = folder self.content = dbresult def isValid(self): """returns if this member exists""" return len(self.content) > 0 def isActive(self): """Return if this member is visible (published).""" return (self.content.publish_the_data == 'yes') def getKey(self): """returns the db key""" return self.content.key def getUsername(self): """returns the username""" id = re.sub('@mpiwg-berlin\.mpg\.de', '', self.content.e_mail) return id getId = getUsername def getConeId(self): """return cone ID""" results= self.folder.executeZSQL("SELECT coneid FROM keys WHERE key_main = %s",[self.content.key]) for res in results: return res.coneid return None def getPublishedImageUrl(self): """returns the URL to the image if it is published""" if self.content.image_p == 'yes': url = 'http://digilib.mpiwg-berlin.mpg.de/digitallibrary/Scaler?fn=permanent/mpiwg/staff/%s'%self.getUsername() return url return None def getContent(self): """returns the db content of this object""" return self.content # TODO: ugly! security.declarePublic('sortBibliography') def sortBibliography(self, bib, sortingMode=None, max=None): """sort bibliography""" if not sortingMode: sortingMode= "priority" l = [x for x in bib] if sortingMode == "year": l.sort(key=lambda x: getInt(x.year)) else: l.sort(key=lambda x: getInt(x.priority)) if max: return l[0:max] else: return l def execute(self,mode,REQUEST=None): method = getattr(self,mode,None) if method is not None: return method(REQUEST); else: return "NOT FOUND" getUrl = MPIWGHelper.getUrl def getTalks(self, published=True, sortBy='priority'): """Return the list of talks""" query = "SELECT oid,* FROM talks WHERE key_main = %s" if published: query += " and published = 'yes'" if sortBy == 'priority': query += " order by priority" return self.folder.executeZSQL(query, [self.content.key]) def getTeaching(self, published=True, sortBy='priority'): """Return the list of teaching activities""" query = "SELECT oid,* FROM teaching WHERE key_main = %s" if published: query += " AND published = 'yes'" if sortBy == 'priority': query += " ORDER BY priority" return self.folder.executeZSQL(query,[self.content.key]) def getLastUpdateCV(self): """getDate of Last Update""" try: fname="%s_cv.pdf"%self.getUsername().encode('utf-8') logging.debug(fname) ob=self.folder._getOb("downloadableFiles")._getOb(fname) return ob.bobobase_modification_time() except: return "No file yet!" def getLastUpdatePublications(self): """getDate of Last Update""" try: ob=self.folder._getOb("downloadableFiles")._getOb("%s_publications.pdf"%self.getUsername().encode('utf-8')) return ob.bobobase_modification_time() except: return "No file yet!" def downloadCV(self,REQUEST): fname="%s_cv.pdf"%self.getUsername().encode('utf-8') logging.debug(fname) ob=self.folder._getOb("downloadableFiles")._getOb(fname) REQUEST.RESPONSE.redirect(ob.absolute_url()) def downloadPublications(self,REQUEST): ob=self.folder._getOb("downloadableFiles")._getOb("%s_publications.pdf"%self.getUsername().encode('utf-8')) REQUEST.RESPONSE.redirect(ob.absolute_url()) def getAdditionalLinks(self): return self.folder.executeZSQL("SELECT oid,* FROM additionalLink WHERE key_main = %s",[self.content.key]) #return self.folder.ZSQLInlineSearch(_table='talks',key_main=self.content.key) #return self.folder.ZSQLInlineSearch(_table='talks',key_main=self.content.key) def getPathStyle(self, path, selected, style=""): """returns a string with the given style + 'sel' if path == selected.""" if path == selected: return style + 'sel' else: return style security.declareProtected('View management screens','edit') def edit(self,REQUEST=None): """Edit the basic information""" if REQUEST: argv=REQUEST.form if argv.has_key('last_name'): #got data to change self.invalidate_cache() self.changeData(argv); pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_basic.zpt')).__of__(self) return pt() security.declareProtected('View management screens','edit') def editShortEntry(self,REQUEST=None): """Edit the basic information""" if REQUEST: argv=REQUEST.form if argv.has_key('current_work'): #got data to change self.invalidate_cache() self.changeData(argv); pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_shortEntry.zpt')).__of__(self) return pt() security.declareProtected('View management screens','editProfile') def editProfile(self, REQUEST=None): """edit Profile, new entry replaces CD, current work and research interests""" if REQUEST: kupu=REQUEST.form.get('kupu',None); preview=REQUEST.form.get('preview',None); if kupu: start=kupu.find("<body>") end=kupu.find("</body>") newcontent= kupu[start+6:end] query="UPDATE personal_www SET profile=%s WHERE key='%s'" self.executeZSQL(query%(self.ZSQLQuote(newcontent),self.content.key)) logging.error("PROFILE:"+query%(self.ZSQLQuote(newcontent),self.content.key)) if preview: pass #TODO: not supported yet #if RESPONSE: # self.redirect(RESPONSE,"editProfile") #return self.preview(newcontent) pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_profile.zpt')).__of__(self) return pt() security.declareProtected('View management screens','editTalks') def editTalks(self,REQUEST): """edit talks""" if REQUEST: argv=REQUEST.form if argv.has_key('main_fields'): #got data to change self.invalidate_cache() self.changeAdditionalData(argv); pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_talks.zpt')).__of__(self) return pt() security.declareProtected('View management screens','editTeaching') def editTeaching(self,REQUEST): """edit teaching""" if REQUEST: argv=REQUEST.form if argv.has_key('main_fields'): #got data to change self.invalidate_cache() self.changeAdditionalData(argv); pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_teaching.zpt')).__of__(self) return pt() security.declareProtected('View management screens','editAdditionalLinks.zpt') def editAdditionalLinks(self,REQUEST): """editiere die additiona link von der Webseite""" if REQUEST: argv=REQUEST.form if argv.has_key('main_fields'): #got data to change self.invalidate_cache() self.changeAdditionalData(argv); pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_additionalLinks.zpt')).__of__(self) return pt() security.declareProtected('View management screens','editDownloads') def editDownloads(self,REQUEST): """editiere die Downloads von der Webseite""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_downloads.zpt')).__of__(self) return pt() def editPublications(self,REQUEST): """editiere die Publications von der Webseite""" data=REQUEST.form if data.has_key('selectionMode'): query="UPDATE personal_www SET publications_mode=%s WHERE key=%s" self.executeZSQL(query,[data['selectionMode'],self.getKey()]) self.refresh_content() pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff','edit_publications.zpt')).__of__(self) return pt() def refresh_content(self,): self.content = self.folder.executeZSQL("select * from personal_www where key = %s", [self.getKey()])[0] def changeDownloads(self,REQUEST): """"change the downloadable files""" self.invalidate_cache(); data=REQUEST.form ob = self.folder._getOb("downloadableFiles") if data.get('cv_publish',None): self.changeData({'cv_p':data['cv_publish']}) if data.get('publications_publish',None): self.changeData({'publications_p':data['publications_publish']}) if data.get('cv_pdf',None): cvName ="%s_cv.pdf"%self.getUsername() cvName=cvName.encode('utf-8') logging.debug("CCC") if not hasattr(ob,cvName): cvFile = ExtFile(cvName,cvName) ob._setObject(cvName,cvFile) cvFile = getattr(ob,cvName) cvFile.manage_upload(file=data['cv_pdf']) if data.get('publications_pdf',None): pdfName="%s_publications.pdf"%self.getUsername() pdfName=pdfName.encode('utf-8') if not hasattr(ob,pdfName): cvFile = ExtFile(pdfName,pdfName) ob._setObject(pdfName,cvFile) cvFile = getattr(ob,pdfName) cvFile.manage_upload(file=data['publications_pdf']) #REQUEST.response.redirect(self.REQUEST['HTTP_REFERER']) def changeData(self,changeSet): """changes the data in the database, changeset expects field --> value.""" for field in changeSet.keys(): if hasattr(self.content,field): logging.debug("Changing: %s"%field) results = self.folder.executeZSQL("update personal_www set "+field+" = %s where key = %s ", [changeSet.get(field),self.getKey().encode('utf-8')]); logging.debug(results) security.declareProtected('View management screens','changeAdditionalData') def changeAdditionalData(self,data): """change the research entries""" self.invalidate_cache(); newEntries={} mainfieldL=data['main_fields'].split(",") #fields to be changed # format DATABASE__FIELDNAME mainfield={} for x in mainfieldL: tmp=x.split('__') mainfield[tmp[0]]=tmp[1] for field in data: splittedField=field.split("__") if len(splittedField)<3: pass #kein datenbank eintrag elif splittedField[2]=='new': # store new entries if not newEntries.has_key(splittedField[0]): newEntries[splittedField[0]]={} newEntries[splittedField[0]][splittedField[1]]=data[field] else: query="UPDATE %s "%splittedField[0] query+="SET %s = '%s' "%(splittedField[1],sql_quote(data[field])) query+="WHERE oid = '%s' "%sql_quote(splittedField[2]) self.executeZSQL(query) #new entries for newEntry in newEntries.keys(): query="INSERT INTO %s "%newEntry keys=['key_main'] values=["'"+sql_quote(self.getKey())+"'"] for key in newEntries[newEntry].keys(): keys.append(key) values.append("'"+sql_quote(newEntries[newEntry][key])+"'") keystring=",".join(keys) valuestring=",".join(values) query+=" (%s) "%keystring query+="VALUES (%s)"%valuestring if not (newEntries[newEntry][mainfield[newEntry]].lstrip().rstrip()==""): self.executeZSQL(query) def deleteField(self,REQUEST): """delete entry""" table = REQUEST.form.get('table',None); oid = REQUEST.form.get('oid',None); if table is None or oid is None: return query="DELETE FROM %s WHERE oid = '%s'"%(table,oid) self.executeZSQL(query) REQUEST.response.redirect(self.REQUEST['HTTP_REFERER']) def invalidate_cache(self): #TODO: How to invalidate the varnish cache from the member object pass; # TODO: compat, is this used? getStaffURL = getUsername def getPublicationsFromPubman(self,limit=None,publicationType=None): """Return list of publications.""" if self.content.publications_mode=="year": coneId = self.getConeId(); if coneId: pubs = self.folder.mpiwgPubman.getPublications(coneId,limit=limit,publicationType=publicationType) #pubs= self.folder.getPublicationsFromPubman(coneId,limit=limit,publicationType=publicationType) return pubs elif self.content.publications_mode=="priority": selPubs= self.getSelectedPublications() pubs=[] count =0 for selPub in selPubs: if limit and count >= limit: break logging.debug("searchFor:%s"%selPub.escidocid) entry = self.mpiwgPubman.getEntryFromPubman(selPub.escidocid,extendedData=True); #TODO getEntryFromPubmanShould return long texts typesLongShort={'http://purl.org/eprint/type/Book':'book', 'http://purl.org/eprint/type/BookItem':'book-item', 'http://purl.org/escidoc/metadata/ves/publication-types/article':'article'}; if publicationType is not None: #publicaitions typ ist gesetzt if not ((entry[1] == publicationType) or (entry[1] == typesLongShort.get(publicationType,''))) : #stimmt nicht dann weiter continue; pubs.append((selPub.escidocid,entry[0],entry[2],entry[3],entry[4])); count+=1 return pubs return [] def publications_full_html(self, REQUEST): """show publication""" pt=PageTemplateFile('zpt/staff/pubman/show_publications.zpt', globals()).__of__(self) return pt(member=self.content) 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/staff/pubman','add_publications.zpt')).__of__(self) return pt() if data.get("method") == "search": entries= self.mpiwgPubman.search(data,contexts=["escidoc:85274","escidoc:38279"]) pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff/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 (key_main,escidocId) values (%s,%s)" if data.get(key)=="add": self.executeZSQL(query,[self.getKey(),key]) #selectedPublications = self.getSelectedPublications() #pt = PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff/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 = PageTemplateFile(os.path.join(package_home(globals()),'zpt/staff/pubman','change_publications.zpt')).__of__(self) return pt() def deleteFromPublicationList(self,escidocid): """Loessche publication with escidoc id from publication list""" query ="DELETE FROM pubmanbiblio WHERE escidocid=%s and lower(key_main)=%s" self.executeZSQL(query,[escidocid,self.getKey().lower()]); def setPublicationPriority(self,escidocid,value): try: query="update pubmanbiblio set priority=%s where escidocid=%s and lower(key_main)=%s" self.executeZSQL(query,[value,escidocid,self.getKey().lower()]); except: logging.error("couldn't change:") logging.error(escidocid) logging.error(value) def getSelectedPublications(self): """hole publications aus der datenbank""" query="select * from pubmanbiblio where lower(key_main) = lower(%s) order by priority ASC" return self.executeZSQL(query,[self.getKey()]) def getProfile(self,REQUEST): """get the profile""" self.REQUEST.RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT') html="""<html><body>%s</body></html>""" if self.content.profile and self.content.profile != "": return html%self.content.profile else: return html%"" def generateProfileForPerson(self,REQUEST=None): """erzeugt ein automatisches Profil aus den alten Eintraegen CV, Current work, und research interests""" ret="" #founds=self.ZSQLInlineSearch(_table='research_interest',key_main=person.getKeyUTF8()) founds=self.executeZSQL('select * from research_interest where lower(key_main) = %s', [self.getKey().lower()]) if founds: ret="<p class=\"bio_section_header\">Research interests: </p><br/>" for found in self.sortPriority(founds): ret+=found.interest+"<br/>" if (self.content.current_work) and (not self.content.current_work==""): ret+="<p class=\"bio_section_header\">Current work: </p><br/>" ret+=self.content.current_work+"<br/>" if (self.content.cv) and (not self.content.cv==""): ret+="<p class=\"bio_section_header\">Curriculum Vitae: </p><br/>" ret+=self.formatAscii(self.content.cv) return ret InitializeClass(MPIWGStaffMember)