Mercurial > hg > MPIWGWeb
view MPIWGRoot.py @ 129:741ddaf604b1
Merge with 2e2dd6a5ab262af6ef4e0a1e19192fd8183608e7
author | dwinter |
---|---|
date | Thu, 30 May 2013 22:00:41 +0200 |
parents | 11b7f98c7ed1 2e2dd6a5ab26 |
children | ee79f6ba8d01 |
line wrap: on
line source
from Products.PageTemplates.PageTemplateFile import PageTemplateFile from App.ImageFile import ImageFile from Globals import package_home import string import os import logging from OFS.Folder import Folder import sys from Products.ZSQLExtend.ZSQLExtend import ZSQLExtendFolder from MPIWGHelper import * import updatePersonalWWW import MPIWGStaff from SrvTxtUtils import getInt, getAt, utf8ify, refreshingImageFileIndexHtml, getDateString 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'}, ) # (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 mpiwg_css refreshable for development mpiwg_css.index_html = refreshingImageFileIndexHtml jquery_js = ImageFile('js/jquery.js', globals()) mpiwg_js = ImageFile('js/mpiwg.js', globals()) # make mpiwg_js refreshable for development mpiwg_js.index_html = refreshingImageFileIndexHtml def __init__(self, id, title): """init""" self.id=id self.title=title # 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 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 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 getDateString(self, **args): """Return a formatted date string.""" return getDateString(**args) 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(spec=self.nav_meta_types) subsecs = [s for s in subsecs if s[1].title != ""] subsecs.sort(key=lambda x:getInt(getattr(x[1], 'weight', '0'))) return subsecs # compatibility subNav = getSubsections def getSections(self): """returns a list of all sections i.e. top-level MPIWGFolders""" items = self.objectValues(spec='MPIWGFolder') items.sort(key=lambda x:getInt(getattr(x, 'weight', '0'))) return items 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 getFeatureAuthorMap(self): """Return a map of authors of features. Returns a dict with author names and a list of feature numbers. """ features = self.getFeatures() authors = {} # build dict of unique authors and features fno = 0 for f in features: author = f.getAuthor() fno += 1 if author: for a in author.split(';'): a = a.strip() if a in authors: authors[a].append(fno) else: authors[a] = [fno] return authors 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, id=None, projectNumber=None): """returns a Department object""" dir = getattr(self, 'departments', None) if dir is None: return None if id is not None: return dir.get(id, 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', 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) 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') # TODO: is this used? 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 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 getAllProjectPublications(self): """get all publications""" fw=file("/tmp/allProjectPublications","w") projects =self.projects.getProjectsAsList(None,active=0,archived=0) for project in projects: logging.debug(project) if hasattr(project,'publicationList'): try: x =project.publicationList.bibliolist.data except: logging.error("Can't do: %s"%project.absolute_url()) continue id=project.getId() for l in x.split("\n"): fw.write("%s,%s\n"%(id,l)) fw.flush() fw.close() def getBookLinkFromID(self,ident): """holt die url auf eine buchseite, bekommt identifier MPIWG-Book:XXXX""" splitted = ident.split(":") if len(splitted)!=2: logging.debug("getBookLinkFromID: %s not a valid book id, should be MPIWG-Book:XXXX"%ident) return books = getattr(self,'books',None) if books is None: logging.debug("getBookLinkFromID: cannot find books page folder") return bookobj = getattr(books,splitted[1],None) if bookobj is None: logging.debug("getBookLinkFromID: %s not a valid book id"%ident) return return "books/"+splitted[1] 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')