changeset 3:ee3eb9a6665a

MPIWGStaffFolder shows members from db now.
author casties
date Fri, 08 Feb 2013 20:42:18 +0100
parents ddf6c1a27a4b
children 1a895905f7ca
files MPIWGStaff.py zpt/staff/member_index_html.zpt
diffstat 2 files changed, 313 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/MPIWGStaff.py	Thu Feb 07 19:50:39 2013 +0100
+++ b/MPIWGStaff.py	Fri Feb 08 20:42:18 2013 +0100
@@ -3,6 +3,8 @@
 # TODO: pruefe ob die bibliographischen felder in publications noch benutzt werden
 # TODO: wird username gebraucht?
 
+from zExceptions import Redirect
+
 from OFS.Folder import Folder
 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
 from Products.PageTemplates.PageTemplate import PageTemplate
@@ -12,7 +14,10 @@
 from AccessControl import getSecurityManager
 
 from Products.ZSQLExtend.ZSQLExtend import ZSQLExtendFolder
+
 from Products.ZDBInterface.ZDBInterfaceFolder import ZDBInterfaceFolder
+from AccessControl import ClassSecurityInfo
+from App.class_init import InitializeClass
 
 import os
 import logging
@@ -20,7 +25,6 @@
 from Globals import package_home
 from Products.PythonScripts.standard import sql_quote
 from types import *
-from AccessControl import ClassSecurityInfo
 import time
 import logging
 import re
@@ -28,7 +32,7 @@
 import urllib2
 import transaction
 
-import SrvTxtUtils
+from SrvTxtUtils import getHttpData, getInt, unicodify, utf8ify
 import bibliography
 
 from MPIWGHelper import *
@@ -78,6 +82,8 @@
         #  self.ZSQLQuery(queryStr)
         
         return True,msg
+    
+    
 class MPIWGStaff(CatalogAware,ZSQLExtendFolder,Cacheable):
     """Staff"""
 
@@ -87,6 +93,20 @@
     #_v_cone=None;
     security=ClassSecurityInfo()
     
+    manage_options = Folder.manage_options+(
+        {'label':'Edit','action':'changeMPIWGStaffForm'},
+        {'label':'Change Publications Special','action':'changePublications_specialForm'},
+        ) + Cacheable.manage_options
+    
+    __manager_id = "ramCache"
+    def __init__(self,id, lastName,firstName,key):
+        """init"""
+        self.id=id
+        self.title=key
+        self.lastName=lastName
+        self.firstName=firstName
+        self.key=key
+    
     def redirect(self,RESPONSE,url):
         """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen"""
         
@@ -314,20 +334,6 @@
         """Return cataloguable key for ourselves."""
         return str(self)
 
-    manage_options = Folder.manage_options+(
-        {'label':'Edit','action':'changeMPIWGStaffForm'},
-        {'label':'Change Publications Special','action':'changePublications_specialForm'},
-        ) + Cacheable.manage_options
-    
-    __manager_id = "ramCache"
-    def __init__(self,id, lastName,firstName,key):
-        """init"""
-        self.id=id
-        self.title=key
-        self.lastName=lastName
-        self.firstName=firstName
-        self.key=key
-    
     def getPersonID(self):
         """gibt den ID fuer die Person zurueck"
         im Moment ist personID = id, i.e. e-mail
@@ -343,7 +349,7 @@
         if getattr(self,'_v_cone',None)==None:
             try:  
                 
-                self._v_cone=SrvTxtUtils.getHttpData(self.coneService+self.getPersonID())
+                self._v_cone=getHttpData(self.coneService+self.getPersonID())
                 #cone = urllib2.urlopen(self.coneService+self.getPersonID())              
                 #self._v_cone=cone.read()
                 if self._v_cone==None:
@@ -911,18 +917,6 @@
         # TODO: remove all occurences of getDBId and replaces it by getKey
         return self.getKey()
         
-#        search=self.ZSQLInlineSearch(_table='personal_www',key=self.getKey(),publish_the_data='yes')
-#        if search:#name existiert und published, dann nimm diesen falls es mehrereeventuell nich publizierte datensaetze gibt.
-#            return search[0].id
-#        else:#nicht publiziert dann nimm einen davon
-#            search2=self.ZSQLInlineSearch(_table='personal_www',username=self.getId())
-#            if search2:
-#                return search2[0].id
-#            else:
-#                return None
-        
-    
-    
     formatBiblHelp=bibliography.formatBiblHelp
     
     def sortBibliography(self,list,sortingMode=None,max=None):
@@ -1002,17 +996,83 @@
     if RESPONSE is not None:
         self.redirect(RESPONSE,'manage_main')
 
+
     
 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]
+                member = self.getMember(id)
+                if member is not None:
+                    request.set('MPIWGStaffMember', member)
+                    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)
+        if member is not None:
+            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)
+        
+        elif key is not None:
+            content = folder.executeZSQL("select * from personal_www where key = %s", [key])
+            if len(content) > 0:
+                member = MPIWGStaffMember(self, dbresult=content)             
+         
+        return member
+    
 
 def manage_addMPIWGStaffFolderForm(self):
     """form for adding the project"""
@@ -1028,3 +1088,60 @@
     if RESPONSE is not None:
         RESPONSE.redirect('manage_main')
 
+
+class MPIWGStaffMember():
+    """MPIWG staff member object from database"""
+    
+    security = ClassSecurityInfo()
+
+    def __init__(self, folder, dbresult):
+        """constructor: takes parent MPIWGStaffFolder and content"""
+        self.folder = folder
+        self.content = dbresult[0]
+            
+    def isValid(self):
+        """returns if this member exists"""
+        return len(self.content) > 0
+
+    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
+    
+    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:min(len(l),max)]
+        else:
+            return l
+
+       
+InitializeClass(MPIWGStaffMember) 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zpt/staff/member_index_html.zpt	Fri Feb 08 20:42:18 2013 +0100
@@ -0,0 +1,166 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+	  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html metal:use-macro="here/main_template/macros/page">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<metal:block metal:fill-slot="head">
+  <tal:x
+    tal:define="global member options/member; global key member/getKey;
+      global username member/getUsername; global content member/getContent;
+      global baseUrl string:$root/${secmap/staff}/members/$username" />
+</metal:block>
+</head>
+<body>
+  <!-- center text -->
+  <div class="center" metal:fill-slot="center">
+    <div>
+      <!-- image -->
+      <tal:block tal:define="imgUrl member/getPublishedImageUrl" tal:condition="imgUrl">
+        <img tal:attributes="src python:'%s&dw=165'%imgUrl" style="float: left; margin-right: 22px;" />
+      </tal:block>
+      <!-- name and title -->
+      <h1>
+        <span tal:replace="content/first_name" /> <span tal:replace="content/last_name" />
+      </h1>
+      <!-- status -->
+      <h3 tal:content="content/status" />
+      <h3 tal:content="content/titles_new" />
+      <h3 tal:condition="content/funded_by">
+        Funded by the <span tal:replace="content/funded_by" />
+      </h3>
+      <p>
+        Residence: <span tal:replace="content/date_stay_at_mpiwg" />
+      </p>
+    </div>
+    <!-- profile -->
+    <div>
+      <tal:x tal:condition="python:not content.profile">
+        <tal:y tal:replace="structure python:here.generateProfileForPerson(member)" />
+      </tal:x>
+      <tal:x tal:condition="content/profile">
+        <h2>Profile</h2>
+        <tal:x tal:content="structure content/profile"> [FMP-Field: CV] </tal:x>
+      </tal:x>
+    </div>
+    <!-- publications -->
+    <tal:block tal:define="publications python:here.ZDBInlineSearch(_table='publications',key_main=key,_op_key_main='eq',publish='yes')"
+      tal:condition="publications">
+      <h2>Selected publications</h2>
+      <p tal:repeat="publication python:member.sortBibliography(publications,content.publications_sort,max=5)">
+        <a tal:omit-tag="not:publication/link" tal:attributes="href publication/link"
+          tal:content="structure python:here.formatBibliography(here,publication)" />
+      </p>
+      <p tal:condition="python:len(publications)>5">
+        <a class="internal" tal:attributes="href string:$baseUrl/publications_full">more</a>
+      </p>
+    </tal:block>
+    <!-- Talks -->
+    <tal:block tal:define="talks python:here.ZDBInlineSearch(_table='talks',key_main=key,_op_key_main='eq',_sort='priority',published='yes')"
+      tal:condition="talks">
+      <h2>Talks and presentations</h2>
+      <div class="namelist">
+        <tal:block tal:repeat="talk python:here.ZDBSlice(talks,size=5)">
+          <div class="name">
+            <a tal:omit-tag="not:talk/link" tal:attributes="href talk/link" tal:content="talk/date" />
+          </div>
+          <div class="definition">
+            <a tal:omit-tag="not:talk/link" tal:attributes="href talk/link"> <span tal:replace="talk/place" /> &#150; <i><span
+                tal:replace="talk/title" /></i>
+            </a>
+          </div>
+        </tal:block>
+      </div>
+      <p tal:condition="python:len(talks)>5">
+        <a tal:attributes="href string:$baseUrl/talks_full">more</a>
+      </p>
+    </tal:block>
+    <!-- Teaching activities -->
+    <tal:block tal:define="teachings python:here.ZDBInlineSearch(_table='teaching',key_main=key,_op_key_main='eq',_sort='priority')"
+      tal:condition="teachings">
+      <h2>Teaching activities</h2>
+      <div class="namelist">
+        <tal:block tal:repeat="teaching python:here.ZDBSlice(teachings, size=5)">
+          <div class="name">
+            <a tal:omit-tag="not:teaching/link" tal:attributes="href teaching/link"> <span tal:replace="teaching/date" />
+            </a>
+          </div>
+          <div class="definition">
+            <a tal:omit-tag="not:teaching/link" tal:attributes="href teaching/link"> <span tal:replace="teaching/place" />
+              &#150; <i><span tal:replace="teaching/title" /></i>
+            </a>
+          </div>
+        </tal:block>
+        <p tal:condition="python:len(teachings)>5">
+          <a tal:attributes="href string:$baseUrl/teaching_full">more</a>
+        </p>
+      </div>
+    </tal:block>
+  </div>
+  <!-- center -->
+
+
+  <!--sidebar content -->
+  <div class="sidebar" metal:fill-slot="sidebar">
+    <div class="sideblock">
+      <h2>Contact</h2>
+      <div class="item noline">
+        Max Planck Institute for the History of Science
+        <br />
+        Boltzmannstra&szlig;e 22
+        <br />
+        14195 Berlin
+        <br />
+        Germany
+      </div>
+      <div class="item" tal:condition="python:content.telefon_p=='yes'">
+        tel.:<span tal:content="content/telefon">[FMP-Field: telefon]</span>
+        <br />
+      </div>
+      <div class="item" tal:condition="python:content.fax_p=='yes'">
+        fax:<span tal:content="content/fax">[FMP-Field: fax]</span>
+        <br />
+      </div>
+      <div class="item internal" tal:condition="python:content.e_mail_p=='yes'">
+        <a class="maillink" tal:attributes="href string:mailto:${content/e_mail}" tal:content="content/e_mail">[FMP-Field:
+          e_mail]</a>
+      </div>
+      <div class="item external" tal:condition="python:content.e_mail2_p=='yes'">
+        <a class="maillink" tal:attributes="href string:mailto:${content/e_mail2}" tal:content="content/e_mail2">[FMP-Field:
+          e_mail2]</a> (external)
+      </div>
+    </div>
+
+    <div class="sideblock" tal:condition="python:here.getProjectsOfMember(key=key)">
+      <h2>Projects</h2>
+      <div class="project" tal:repeat="project python:here.getProjectsOfMember(key=key)">
+        <tal:x tal:condition="python:here.isActual(project)">
+          <a tal:attributes="href python:root+'/'+secmap['research']+'/projects/'+project.getId()+'/index.html'"
+            tal:content="python:here.decode(project.getContent('WEB_title'))" />
+        </tal:x>
+      </div>
+    </div>
+
+    <div class="sideblock">
+      <h2>Related Material</h2>
+      <div class="item download" tal:condition="python:getattr(here,'cv_publish','no')=='yes'">
+        <a target="_blank" href="downloadCV">Download Curriculum Vitae</a>
+      </div>
+      <div class="item download" tal:condition="python:getattr(here,'publications_publish','no')=='yes'">
+        <a target="_blank" href="downloadPublications">Download Publication List</a>
+        <br />
+      </div>
+      <div class="item internal">
+        <a target="_blank"
+          tal:attributes="href python:'http://edoc.mpg.de/display.epl?nmbF=2&nmbK=9&cntDate=5&allType=1&moreFields=less&field1=all&field2=persons&persType2=all&personValue2=%s&wts=arc&scol=11&smode=AND&phrase=similar&nohp=10&outfor=bib&mode=admSearch'%content.last_name">
+          See publications on Edoc-Server</a>
+      </div>
+      <div class="item internal"
+        tal:repeat="addLink python:here.ZDBInlineSearch(_table='additionallink',key_main=key,_op_key_main='eq',_sort='priority',published='yes')">
+        <a target="_blank" tal:content="addLink/title" tal:attributes="href addLink/link"> Daston on the History of Science
+          (listen to CBC-Interview, Fall 2007)</a>
+      </div>
+    </div>
+  </div>
+  <!-- sidebar -->
+</body>
+</html>
\ No newline at end of file