Mercurial > hg > MPIWGWeb
view MPIWGRoot.py @ 52:1ed79b33200c
more work on projects and cleanup.
author | casties |
---|---|
date | Tue, 30 Apr 2013 16:00:56 +0200 |
parents | d456fe185649 |
children | 4600e31a0431 |
line wrap: on
line source
from Products.PageTemplates.PageTemplateFile import PageTemplateFile from App.ImageFile import ImageFile from Products.ZSQLExtend.ZSQLExtend import ZSQLExtendFolder from Products.ZCatalog.CatalogPathAwareness import CatalogAware from OFS.Image import Image from Globals import package_home import urllib import string import re import os from types import * import logging from OFS.SimpleItem import SimpleItem from OFS.Folder import Folder from AccessControl import ClassSecurityInfo import time import xml.dom.minidom import sys import transaction import copy from BeautifulSoup import BeautifulSoup, Comment from ZODB import FileStorage, DB from ZEO import ClientStorage from MPIWGHelper import * import updatePersonalWWW from bibliography import * import MPIWGStaff from SrvTxtUtils import getInt, getAt, utf8ify, refreshingImageFileIndexHtml def sortWeight(x,y): x1=int(getattr(x[1],'weight','0')) y1=int(getattr(y[1],'weight','0')) return cmp(x1,y1) class MPIWGRoot(ZSQLExtendFolder): """Stammordner fuer den Web-Server""" _v_harvestCache=None meta_type='MPIWGRoot' manage_options = Folder.manage_options+( {'label':'Update personal homepages','action':'updatePersonalwww_html'}, {'label':'Reindex catalogs','action':'reindexCatalogs'}, {'label':'Main config','action':'changeMPIWGRootForm'}, {'label':'add e-mails','action':'showNewDBEntries'}, #{'label':'update the institutsbibliography','action':'updateInstitutsbiliography'}, #{'label':'Edit Historical Persons','action':'editHistoricalPersonsForm'}, #{'label':'Store Historical Persons','action':'storeHistoricalPersons'}, ) # TODO: is this used here? 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'} # (is this used?) folders=['MPIWGProject','Folder','ECHO_Navigation'] # language of this instance lang = 'en' # types of objects that show up in navigation nav_meta_types = ['MPIWGTemplate','MPIWGLink','MPIWGFolder'] # # templates # main_template = PageTemplateFile('zpt/www/main_template', globals()) common_template = PageTemplateFile('zpt/www/common_template', globals()) mpiwg_css = ImageFile('css/mpiwg.css', globals()) # make docuviewer_css refreshable for development mpiwg_css.index_html = refreshingImageFileIndexHtml def getLang(self): """returns the default language""" return self.lang def browserCheck(self): """check the browsers request to find out the browser type""" bt = {} ua = self.REQUEST.get_header("HTTP_USER_AGENT") bt['ua'] = ua bt['isIE'] = False bt['isN4'] = False if string.find(ua, 'MSIE') > -1: bt['isIE'] = True else: bt['isN4'] = (string.find(ua, 'Mozilla/4.') > -1) try: nav = ua[string.find(ua, '('):] ie = string.split(nav, "; ")[1] if string.find(ie, "MSIE") > -1: bt['versIE'] = string.split(ie, " ")[1] except: pass bt['isMac'] = string.find(ua, 'Macintosh') > -1 bt['isWin'] = string.find(ua, 'Windows') > -1 bt['isIEWin'] = bt['isIE'] and bt['isWin'] bt['isIEMac'] = bt['isIE'] and bt['isMac'] bt['staticHTML'] = False return bt def createOrUpdateId_raw(self): """create sequence to create ids for bibliography""" debug=None #suche groesste existierende id founds=self.ZSQLQuery("select id from bibliography") if founds: ids=[int(x.id[1:]) for x in founds] maximum=max(ids) id_raw=self.ZSQLQuery("select nextval('id_raw')",debug=debug) if id_raw: self.ZSQLQuery("drop sequence id_raw",debug=debug) self.ZSQLQuery("create sequence id_raw start %i"%(maximum+1),debug=debug) def queryLink(self,link): """append querystring to the link""" return "%s?%s"%(link,self.REQUEST.get('QUERY_STRING','')) def getKategory(self,url): """kategorie""" splitted=url.split("/") return splitted[4] def isNewCapital(self,text=None,reset=None): if text: text=text.upper() if reset: self.REQUEST['capital']="A" return True else: if len(text)>0 and not (text[0]==self.REQUEST['capital']): self.REQUEST['capital']=text[0] return True else: return False def subNavStatic(self,obj): """subnav" von self""" subs=self.ZopeFind(obj,obj_metatypes=['MPIWGTemplate','MPIWGLink']) subret=[] for x in subs: if not(x[1].title==""): subret.append(x) subret.sort(sortWeight) return subret def getSubsections(self, here=None): """return sub-navigation elements i.e. elements below sections""" p = here if p is None: p = self sec = None # descend parents to the root (and remember the last id) while p is not None and p.meta_type != 'MPIWGRoot': sec = p p = p.aq_parent subsecs = sec.objectItems(self.nav_meta_types) subsecs = [s for s in subsecs if s[1].title != ""] subsecs.sort(sortWeight) return subsecs # compatibility subNav = getSubsections def isType(self,object,meta_type): """teste ob ein object vom meta_type ist.""" return (object.meta_type==meta_type) def isActive(self,name): """teste ob subnavigation aktiv""" for part in self.REQUEST['URL'].split("/"): if part==name: return True return False def getSections(self): """returns a list of all sections i.e. top-level MPIWGFolders""" items = self.objectValues(spec='MPIWGFolder')[:] items.sort(key=lambda x:int(x.weight)) return items def getSectionStyle(self, name, style=""): """returns a string with the given style + '-sel' if the current section == name""" if self.getSection() == name: return style + '-sel' else: return style 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 def getFeatures(self, num=None): """returns a list of the last num Features""" dir = getattr(self, 'features', None) if dir is None: return [] items = dir.objectValues(spec='MPIWGFeature')[:] items.sort(key=lambda x:int(x.weight)) if num is not None: # take only the last num elements items = items[-num:] return items def getDepartments(self): """returns a list of the Departments""" dir = getattr(self, 'departments', None) if dir is None: return [] items = dir.objectValues(spec='MPIWGDepartment')[:] items.sort(key=lambda x:int(x.weight)) return items def getDepartment(self, projectNumber=None): """returns a Department object""" dir = getattr(self, 'departments', None) if dir is None: return None if projectNumber is not None: for dep in dir.objectValues(spec='MPIWGDepartment'): if dep.getProjectNumber() == projectNumber: return dep return None def getProjectFolder(self): """returns the MPIWGProjectFolder""" dir = getattr(self, 'projects', None) return dir def getStaffFolder(self): """returns the MPIWGStaffFolder""" dir = getattr(self, 'members_test', None) # TODO: fix the test return dir def getMPIWGRoot(self): """returns the MPIWG root""" return self def MPIWGrootURL(self): """returns the URL to the root""" return self.absolute_url() # TODO: make obsolete def decode(self, s): """unicodify""" return unicodify(s) # TODO: remove def replaceNotEmpty(self,format,field): """replace not empty""" if field and (not field.lstrip()==''): return format%field #return self.decode(format%field) else: return "" def redirectIndex_html(self,request): #return request['URL1']+'/index_html' return urllib.urlopen(request['URL1']+'/index_html').read() def formatBibliography(self,here,found): """format""" return formatBibliography(here,found) def getValue(self,fieldStr): """Inhalt des Feldes""" if type(fieldStr)==StringType: field=fieldStr else: field=fieldStr[0] try: if field[len(field)-1]==";": field=field[0:len(field)-1] except: """nothing""" field=re.sub(r';([^\s])','; \g<1>',field) return field.encode('utf-8') def sortedNames(self,list): """sort names""" def sortLastName(x_c,y_c): try: x=urllib.unquote(x_c).encode('utf-8','ignore') except: x=urllib.unquote(x_c) try: y=urllib.unquote(y_c).encode('utf-8','ignore') except: x=urllib.unquote(y_c) try: last_x=x.split()[len(x.split())-1] last_y=y.split()[len(y.split())-1] except: last_x="" last_y="" if last_x<last_y: return 1 elif last_x>last_y: return -1 else: return 0 list.sort(sortLastName) list.reverse() return list def __init__(self, id, title): """init""" self.id=id self.title=title def urlQuote(self,str): """quote""" return urllib.quote(str) def urlUnQuote(self,str): """quote""" return urllib.unquote(str) def changeMPIWGRootForm(self): """edit""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeMPIWGRootForm')).__of__(self) return pt() def changeMPIWGRoot(self,title,connection_id,coneServiceURL,lang=None,autocommit=None,RESPONSE=None): """change""" self.title=title self.connection_id=connection_id #self.disciplineList=disciplineList #self.themesList=themesList self.coneServiceURL=coneServiceURL if lang is not None: self.lang = lang self.autocommit = (autocommit == "on") if RESPONSE is not None: RESPONSE.redirect('manage_main') def updatePublicationDB(self,personId=None): """updates the publication db, i.e. copy year and type into the main table""" if personId: founds = self.ZSQLInlineSearch(_table="publications",key_main=personId) else: founds = self.ZSQLInlineSearch(_table="publications") for found in founds: if found.id_institutsbibliographie and (not found.id_institutsbibliographie =="") and (not found.id_institutsbibliographie =="0"): entries = self.ZSQLInlineSearch(_table="institutsbiblio",id=found.id_institutsbibliographie) for entry in entries: self.ZSQLChange(_table='publications',_identify='oid=%s' % found.oid,year=entry.year,referencetype=entry.reference_type) if found.id_gen_bib and (not found.id_gen_bib ==""): entries = self.ZSQLInlineSearch(_table="bibliography",id=found.id_gen_bib) for entry in entries: self.ZSQLChange(_table='publications',_identify='oid=%s' % found.oid,year=entry.year,referencetype=entry.reference_type) return True def showNewDBEntries(self): """zeige neue Eintraege in der Datenbank ohne e-mail adressen bzw. fuer die noch kein Object angelegt wurde""" qstr="select * from personal_www where web_object_created='no' and not key=''" res=self.ZSQLQuery(qstr) pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','showNewDBEntries.zpt')).__of__(self) return pt(newEntries=res) def createNewStaffObjects(self,RESPONSE): """create new staff object""" memberFolder=getattr(self,'members') args=self.REQUEST.form arg_k=args.keys() arg_k.remove("submit") ret="" for key in arg_k: k=self.urlUnQuote(key) qstr="select * from personal_www where key=%s"%self.ZSQLQuote(k) res=self.ZSQLQuery(qstr)[0] if args[key]!="": #email-adresse wurde eingetragen #create the object e_mail=args[key] try: newObj=MPIWGStaff.MPIWGStaff(e_mail,res.last_name,res.first_name,k) memberFolder._setObject(e_mail,newObj) obj=getattr(memberFolder,e_mail) obj.reindex_object() ret+="Created %s \n"%e_mail created=True except: msg="Cannot create new user %s (%s %s)"%(e_mail,sys.exc_info()[0],sys.exc_info()[1]) logging.error(msg) ret+=msg+"\n" created=False if created: qstr="update personal_www set web_object_created='yes',e_mail='%s@mpiwg-berlin.mpg.de' where key=%s"%(e_mail,self.ZSQLQuote(k)) self.ZSQLQuery(qstr) return ret def generateNewPersonEntry(self,data): """generate a new person entry for data, neue personen werden zunaechst nur in der datenbank angelegt """ #memberFolder=getattr(self,'members') #create the object # try: # newObj=MPIWGStaff.MPIWGStaff(urllib.quote(data['key']),data['last_name'].encode('utf-8'),data['first_name'].encode('utf-8')) # memberFolder._setObject(urllib.quote(data['key']),newObj) # except: # return False, "Cannot create new user %s (%s %s)"%(data['key'],sys.exc_info()[0],sys.exc_info()[1]) # #create the new entry in the database result,msg=MPIWGStaff.createNewDBEntry(self,data['publish_the_data'],data['key'],data['last_name'], data['first_name'],data['titles_new'],data['status'],"", "",data['date_from'],data['date_to'], data['department'],'',data['funded_by'], data['e_mail2'],data['current_work'],"yes",data['date_stay_at_mpiwg'],data['group'],"no",data['current_work']) return result,msg def updatePersonEntry(self,data,ignoreEntries=None): """update an person entry from data. but ignore all fields in ignore Entries""" if ignoreEntries is None: ignoreEntries = [] #ignoreEntries.append('current_work') # TODO:updatecurrent work logging.debug("updatePersonEntry: data=%s ignoreEntries=%s"%(repr(data),repr(ignoreEntries))) if data['date_to']=="": # wenn date_to leer data['date_to']="date_none" if data['date_from']=="": # wenn date_fromleer data['date_from']="date_none" msg="" #eintragen columns=data.keys() for x in ignoreEntries: logging.debug("updatePersonEntry: ignoring %s"%x) try: #falls in ignore entries felder sind, die nicht in columns sind, fange den fehler ab columns.remove(x) except: pass insert=[] for key in columns: if data[key]=="date_none": # date_none eintrag wird zu null uebersetzt insert.append('%s=null'%key) else: insert.append(""" "%s"=%s"""%(key,self.ZSQLQuote(data[key]))) insertStr=",".join(insert) queryStr="update personal_www SET %s where key='%s'"%(insertStr,data['key']) self.ZSQLQuery("SET DATESTYLE TO 'German'") self.ZSQLQuery(queryStr) #currentwork #if not (txt==""): # queryStr="INSERT INTO current_work (id_main,current,publish) VALUES ('%s','%s','%s')"%(id,txt,txt_p) # # self.ZSQLQuery(queryStr) return True,msg def updatePersonalwww_doIt(self): """do the update""" args=self.REQUEST.form resultSet=self.REQUEST.SESSION['personal_www']['resultSet'] news=self.REQUEST.SESSION['personal_www']['news'] conflicts=self.REQUEST.SESSION['personal_www']['conflicts'] logging.debug("updatePersonalwww_doIt: args=%s\n resultSet=%s\n news=%s\n conflicts=%s"%(args,resultSet,news,conflicts)) ret="<html><body>" # generate the new entry if news and (len(news)>0): ret+="<h2>Hinzugefügt</h2>" ret+="<p>Neueinträge erscheinen erst auf der Homepage, wenn ihnen eine e-mail Adresse zugeordnet wurde.</p>" ret+="<ul>" for new in news: if args.has_key(self.urlQuote(new.encode('utf-8'))): # entry was selected result,msg=self.generateNewPersonEntry(resultSet[new]) if not result: logging.error("Error (generateNewPersonEntry) %s"%msg) ret+="<li>ERROR: %s %s"%(new.encode('utf-8'),msg) else: ret+="<li>OK: %s"%(new.encode('utf-8')) if news and (len(news)>0): ret+="<p>Neueinträge erscheinen erst auf der Homepage, wenn ihnen eine e-mail Adresse zugeordnet wurde.</p>" ret+="</ul>" # update if len(conflicts.keys())>0: ret+="<h2>Änderung des Benutzers übernehmen</h2>" ret+="<p>Wenn nötig in Filemaker-db ändern:</p>" # konflicte for conflict in conflicts.keys(): ignoreEntries=[] displayIgnored=[] for cf in conflicts[conflict]: if args[conflict.encode('utf-8')+'_'+cf[0]]=="stored": #use the stored one ignoreEntries.append(cf[0]) #so ignore field cf[0] displayIgnored.append(cf) if len(displayIgnored)>0: ret+="<h3>%s</h3>"%conflict.encode('utf-8') ret+="<table border='1'>" for iE in displayIgnored: ret+="<tr><td>%s</td><td>%s</td><td>%s</td>"%(iE[0].encode('utf-8'),iE[1].encode('utf-8'),iE[2].encode('utf-8')) ret+="</table>" self.updatePersonEntry(resultSet[conflict],ignoreEntries=ignoreEntries) # rest cl=list(conflicts.keys()) for key in resultSet.keys(): if key not in cl: self.updatePersonEntry(resultSet[key]) return ret+"</body></html>" def updateInstitutsbiliography(self): """update the Institutsbibliogrpahy""" self.upDateSQL('personalwww.xml') return "<html><body>DONE</body></html>" def updatePersonalwww_html(self): """update form for the homepages web form""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','updatePersonalwww.zpt')).__of__(self) return pt() def updatePersonalwww(self,uploadfile): """update personalwww @param uploadfile: file handle auf das file """ dsn=self.getConnectionObj().connection_string #dsn="dbname=personalwww" resultSet=updatePersonalWWW.importFMPXML(uploadfile) news,conflicts=updatePersonalWWW.checkImport(dsn, resultSet) self.REQUEST.SESSION['personal_www']={} self.REQUEST.SESSION['personal_www']['resultSet']=resultSet self.REQUEST.SESSION['personal_www']['news']=news self.REQUEST.SESSION['personal_www']['conflicts']=conflicts pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','updatePersonalwww_check.zpt')).__of__(self) return pt() def getAllMembers(self): #ret=[] def sorter(x,y): return cmp(x[0].lower(),y[0].lower()) results=self.MembersCatalog({'isPublished':True}) ret=[(unicodify(", ".join([proj.lastName, proj.firstName])), proj.getKey) for proj in results] ret.sort(sorter) return ret def printAllMembers(self): """print""" members=self.getAllMembers() ret="" for x in members: ret+="<p>%s</p>"%x return ret def makeList(self,entry): """makes a list out of one entry or repeat a list""" if type(entry) is StringType: return [entry] else: return entry def getTreeRSS(self,dep=None,date=None,onlyActive=1,onlyArchived=0): """generateTree""" rss="""<?xml version="1.0" encoding="utf-8"?> <rss version="2.0"> <channel>""" for obj in self.getTree(dep, date, onlyActive, onlyArchived): linkStr="""<link>http://www.mpiwg-berlin.mpg.de/en/research/projects/%s</link>""" rss+="""<item>""" rss+=linkStr%obj[3].getId() rss+="""</item>""" if hasattr(obj[3],'publicationList'): rss+="""<item>""" rss+=linkStr%(obj[3].getId()+"/publicationList"); rss+="""</item>""" rss+="""</channel> </rss>""" return rss def getRelativeUrlFromPerson(self,list): """get urls to person list""" ret=[] persons=list.split(";") for person in persons: if len(person)>1: #nicht nur Trennzeichen splitted=person.split(",") if len(splitted)==1: splitted=person.split(" ") splittedNew=[re.sub(r'\s(.*)','$1',split) for split in splitted] if splittedNew[0]=='': del splittedNew[0] search=string.join(splittedNew,' AND ') if not search=='': try: proj=self.MembersCatalog({'title':search}) except: proj=None if proj: #ret.append("<a href=%s >%s</a>"%(proj[0].absolute_url,person.encode('utf-8'))) ret.append("<a href=%s >%s</a>"%('members/'+proj[0].id+'/index.html',person)) else: #ret.append("%s"%person.encode('utf-8')) ret.append("%s"%person) return string.join(ret,";") def getMemberIdFromKey(self,key): """gibt die ensprechende id im members Ordner zum key""" if key=="": return "" try: key=utf8ify(key) catalogged=self.MembersCatalog({'getKey':key}) if len(catalogged)==0: return "" else: return catalogged[0].getObject().getId() except: return "" def manage_addMPIWGRootForm(self): """form for adding the root""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGRootForm.zpt')).__of__(self) return pt() def manage_addMPIWGRoot(self,id,title,connection_id="",RESPONSE=None): """add a root folder""" newObj=MPIWGRoot(id,title) self._setObject(id,newObj) ob=getattr(self,id) setattr(ob,'connection_id',connection_id) if RESPONSE is not None: RESPONSE.redirect('manage_main')