File:  [Repository] / MPIWGWeb / Attic / MPIWGRoot.py
Revision 1.1.2.15: download - view: text, annotated - select for diffs - revision graph
Fri Sep 5 11:33:08 2008 UTC (15 years, 9 months ago) by casties
Branches: r2
add mpiwgfolder to navigation

    1: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
    2: from Products.PageTemplates.PageTemplate import PageTemplate
    3: from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
    4: from Products.ZSQLExtend.ZSQLExtend import ZSQLExtendFolder
    5: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
    6: from OFS.Image import Image
    7: from Globals import package_home
    8: import urllib
    9: import MPIWGStaff
   10: import string
   11: import re
   12: import os
   13: from types import *
   14: import logging
   15: import xmlhelper # Methoden zur Verwaltung der projekt xml
   16: from OFS.SimpleItem import SimpleItem
   17: from OFS.Folder import Folder
   18: from Products.ZSQLMethods.SQL import SQLConnectionIDs
   19: from AccessControl import ClassSecurityInfo
   20: from bibliography import *
   21: import time
   22: import xml.dom.minidom
   23: import sys
   24: from Ft.Xml.XPath import Evaluate
   25: from Ft.Xml.XPath.Context import Context
   26: from Ft.Xml.Domlette import NonvalidatingReader,PrettyPrint, Print
   27: from Ft.Xml import EMPTY_NAMESPACE
   28: import copy
   29: import updatePersonalWWW
   30: import MPIWGStaff
   31: from MPIWGHelper import *
   32: 
   33: 
   34: def sortWeight(x,y):
   35:     x1=int(getattr(x[1],'weight','0'))
   36:     y1=int(getattr(y[1],'weight','0'))
   37:     return cmp(x1,y1)
   38: 
   39: 
   40: class MPIWGRoot(ZSQLExtendFolder):
   41:     """Stammordner fuer den Web-Server"""
   42: 
   43:     meta_type='MPIWGRoot'
   44: 
   45:     fieldLabels={'WEB_title':'WEB_Title',
   46:                  'xdata_01':'Responsible Scientists',
   47:                  'xdata_02':'Department',
   48:                  'xdata_03':'Historical Persons',
   49:                  'xdata_04':'Time period',
   50:                  'xdata_05':'Sorting number',
   51:                  'xdata_06':'Keywords',
   52:                  'xdata_07':'Short title',
   53:                  'xdata_08':'Other involved scholars' ,
   54:                  'xdata_09':'Disciplines',
   55:                  'xdata_10':'Themes',
   56:                  'xdata_11':'Object Digitallibrary',
   57:                  'xdata_12':'Cooperation partners',
   58:                  'xdata_13':'Funding institutions',
   59:                  'WEB_project_header':'WEB_project_header',
   60:                  'WEB_project_description':'WEB_project_description',
   61:                  'WEB_related_pub':'WEB_related_pub'}
   62:     
   63:     folders=['MPIWGProject','Folder','ECHO_Navigation']
   64: 
   65:     # types of objects that show up in navigation
   66:     nav_meta_types = ['MPIWGTemplate','MPIWGLink','MPIWGFolder']
   67: 
   68:     def getGetNeighbourhood(self,obj, wordStr, length=100,tagging=True):
   69:         """finde umgebung um die worte in wordStr, zurueckgegeben wird eine Array mit den Umgebungen von Fundstellen der Worte
   70:         alle Tags werden entfernt, die Fundstellen werden mit <span class="found">XX</span> getaggt, die Umgebungen werden 
   71:         case insensitive gesucht
   72:         @param wordStr: string mit Worten getrennt durch Leerzeichen, Phrasen sind mit " gekennzeichnet
   73:                         "eine phrase", "*"  bezeichnet wildcards und wird ignoriert"
   74:         @param length: optional, default wert 100, 2*length ist die groesse der Umgebung
   75:         @param tagging: optional default wert true, kein span tag wird erzweugt falls tag=false
   76:         """
   77:         
   78:         ret=[] # nimmt das Array auf, dass spaeter zurueckgegeben wird
   79:         ranges=[] #Array mit tupeln x,y wobei x die Position des Anfang und y des Endes der i-ten Umgebung angiebt
   80:         
   81:         def isInRanges(nr,length):
   82:             """test ob eine gegeben Position nr schon irgendwo in einer Umgebung ist, gibt den Index des ersten Wertes aus ranges zurueck, 
   83:             -1, wenn kein Treffer
   84:             
   85:             @param nr: Position die geprueft werden soll
   86:             @param length: Laenge des Wortes das geprueft werden soll
   87:             """
   88:             for x in ranges:
   89:                 if (x[0]<=nr) and (nr < (x[1]-length)):
   90:                     return ranges.index(x)
   91:             return -1
   92:                 
   93:         # deal with phrases, in Phrasen werden die Leerzeichen durch "_" ersetzt.
   94:         def rep_empty(str):
   95:             x= re.sub(" ","_",str.group(0))
   96:             return re.sub("\"","",x)
   97:             
   98:         wordStr=re.sub("\".*?\"", rep_empty,wordStr)#ersetze leerzeichen in " " durch "_" und loesche "
   99:         
  100:         #deal with wildcards, for our purposes it is enough to delete the wildcard 
  101:         wordStr=wordStr.replace("*","")
  102:         
  103:         words=wordStr.split(" ")
  104:         #if not words is ListType:
  105:         #   words=[words]
  106:             
  107:         txt=obj.harvest_page()
  108:         if not txt:
  109:             return ret
  110:         txt=re.sub("<.*?>", "", txt) # loesche alle Tags
  111:         for word in words:
  112:             word=re.sub("_"," ",word) # ersetze zurueck "_" durch " "
  113:             pos=0
  114:             
  115:             n=txt.lower().count(word.lower()) # wie oft tritt das Wort auf
  116: 
  117:             for i in range(n):
  118:                 pos=txt.lower().find(word.lower(),pos)
  119: 
  120:                 if pos > 0:
  121:                     x=max(0,pos-length)
  122:                     y=min(len(txt),pos+length)
  123:                   
  124:                     
  125:                     #is word already in one of the results
  126:                     nr=isInRanges(pos,len(word))
  127:                     if nr >=0:# word ist in einer schon gefunden Umgebung, dann vergroessere diese
  128:                         x=min(ranges[nr][0],x)
  129:                         y=max(ranges[nr][1],y)
  130:               
  131:                     str=txt[x:y]
  132:                 
  133:                     if nr >=0: # word ist in einer schon gefunden Umgebung
  134:                         ranges[nr]=(x,y) # neue Position der Umgebung
  135: 
  136:                         ret[nr]=str # neue Umgebung
  137:                     else: # andernfalls neue Umgebung hinzufuegen
  138:                         ranges.append((x,y))
  139: 
  140:                         ret.append(str)
  141:                     
  142:                     pos=pos+len(word)
  143:                 else:
  144:                     break;
  145:                 
  146:         # now highlight everything        
  147:         if tagging:
  148:             for x in range(len(ret)):
  149:                 for word in words:
  150:                     repl=re.compile(word,re.IGNORECASE)
  151:                     ret[x]=repl.sub(""" <span class="found">%s</span>"""%word.upper(),ret[x])
  152: 
  153:         return ret
  154:     def copyAllImagesToMargin(self):
  155:         """tranformiere alle Bilder in die Margins"""
  156:         projects=self.getTree()
  157:         ret=""
  158:         for project in projects:
  159:             proj=project[3]
  160:             try:
  161:                 persons=proj.copyImageToMargin();
  162:             except:
  163:                 logging.error("Cannnot do: %s"%repr(project))
  164:                 
  165:     def transformProjectsToId(self):
  166:         """trnasformiere zu ID, Hilfsfunktion die die alten Templates analysiert und mit der neuen Liste
  167:         verantwortlicher Personen versieht"""
  168:         projects=self.getTree()
  169:         ret=""
  170:         for project in projects:
  171:             
  172:             proj=project[3]
  173:             persons=proj.identifyNames(proj.getContent('xdata_01'))
  174:             if not hasattr(proj,'responsibleScientistsList'):
  175:                         proj.responsibleScientistsList=[]
  176:                         
  177:             for person in persons.items():
  178:               
  179:                 if len(person[1]) >1: #nicht eindeutig
  180:                     ret+="nicht eindeutig ---  %s:  %s\n"%(proj.getId(),person[0])
  181:                     
  182:                 elif len(person[1]) ==0: #kein eintrage
  183:                     ret+="kein eintrag---  %s:  %s\n"%(proj.getId(),person[0])
  184:                     proj.responsibleScientistsList.append((person[0],""))
  185:                 else:           
  186:                     proj.responsibleScientistsList.append((person[0],person[1][0].getObject().getKey()))
  187:         
  188:         return ret
  189:           
  190:                 
  191:     def harvestProjects(self):
  192:         """harvest"""
  193:         folder="/tmp"
  194:         try:
  195:             os.mkdir("/tmp/harvest_MPIWG")
  196:         except:
  197:             pass
  198:         founds=self.ZopeFind(self.aq_parent.projects,obj_metatypes=['MPIWGProject'],search_sub=1)
  199:         for found in founds:
  200:             txt=found[1].harvest_page()
  201:         
  202:             if txt and (txt != ""):
  203:                 name=found[0].replace("/","_")
  204:                 fh=file("/tmp/harvest_MPIWG/"+name,"w")
  205:                 fh.write(txt)
  206:                 fh.close()
  207:                 
  208:     def decode(self,str):
  209:         """decoder"""
  210: 
  211:         if not str:
  212:             return ""
  213:         if type(str) is StringType:
  214:             try:            
  215:                 return str.decode('utf-8')
  216:             except:
  217:                 return str.decode('latin-1')
  218:         else:
  219:             return str
  220: 
  221: 
  222:     def getat(self,array,idx=0,default=None):
  223:         """return array element idx or default (but no exception)"""
  224:         if len(array) <= idx:
  225:             return default
  226:         else:
  227:             return array[idx]
  228:         
  229: 
  230:     def browserCheck(self):
  231:         """check the browsers request to find out the browser type"""
  232:         bt = {}
  233:         ua = self.REQUEST.get_header("HTTP_USER_AGENT")
  234:         bt['ua'] = ua
  235:         bt['isIE'] = False
  236:         bt['isN4'] = False
  237:         if string.find(ua, 'MSIE') > -1:
  238:             bt['isIE'] = True
  239:         else:
  240:             bt['isN4'] = (string.find(ua, 'Mozilla/4.') > -1)
  241: 
  242:         try:
  243:             nav = ua[string.find(ua, '('):]
  244:             ie = string.split(nav, "; ")[1]
  245:             if string.find(ie, "MSIE") > -1:
  246:                 bt['versIE'] = string.split(ie, " ")[1]
  247:         except: pass
  248: 
  249:         bt['isMac'] = string.find(ua, 'Macintosh') > -1
  250:         bt['isWin'] = string.find(ua, 'Windows') > -1
  251:         bt['isIEWin'] = bt['isIE'] and bt['isWin']
  252:         bt['isIEMac'] = bt['isIE'] and bt['isMac']
  253:         bt['staticHTML'] = False
  254: 
  255:         return bt
  256: 
  257: 
  258:     def versionHeaderEN(self):
  259:         """version header text"""
  260:         
  261:         date= self.REQUEST.get('date',None)
  262:         if date:
  263:             txt="""<h2>This pages shows the project which existed at %s</h2>"""%str(date)
  264:             return txt
  265:         return ""
  266: 
  267:     def versionHeaderDE(self):
  268:         """version header text"""
  269:         date= self.REQUEST.get('date',None)
  270:         if date:
  271:             txt="""<h2>Auf dieser Seite finden Sie die Projekte mit Stand vom %s</h2>"""%str(date)
  272:         return ""
  273:     
  274:         
  275:     def createOrUpdateId_raw(self):
  276:         """create sequence to create ids for bibliography"""
  277:         debug=None
  278:         #suche groesste existierende id
  279:         founds=self.ZSQLQuery("select id from bibliography")
  280:         
  281:         if founds:
  282:             ids=[int(x.id[1:]) for x in founds]
  283:             maximum=max(ids)
  284:             
  285:             id_raw=self.ZSQLQuery("select nextval('id_raw')",debug=debug)
  286:             
  287:             if id_raw:
  288:                 self.ZSQLQuery("drop sequence id_raw",debug=debug)
  289:             
  290:             self.ZSQLQuery("create sequence id_raw start %i"%(maximum+1),debug=debug)
  291:         
  292:     
  293:     def queryLink(self,link):
  294:         """append querystring to the link"""
  295:         return "%s?%s"%(link,self.REQUEST.get('QUERY_STRING',''))
  296: 
  297:     def getKategory(self,url):
  298:         """kategorie"""
  299:         splitted=url.split("/")
  300:         return splitted[4]
  301: 
  302:     def generateUrlProject(self,url,project=None):
  303:         """erzeuge aus absoluter url, relative des Projektes"""
  304:         if project:
  305:             splitted=url.split("/")
  306:             length=len(splitted)
  307:             short=splitted[length-2:length]
  308:             
  309:             base=self.REQUEST['URL3']+"/"+"/".join(short)
  310: 
  311:         else:
  312:             findPart=url.find("/projects/")
  313:             base=self.REQUEST['URL1']+"/"+url[findPart:]
  314: 
  315:                 
  316:         return base
  317:     
  318:     def isNewCapital(self,text=None,reset=None):
  319:         if reset:
  320:             self.REQUEST['capital']="A"
  321:             return True
  322:         else:
  323:             if len(text)>0 and not (text[0]==self.REQUEST['capital']):
  324:                 self.REQUEST['capital']=text[0]
  325:                 return True
  326:             else:
  327:                 return False
  328:     
  329:     def subNavStatic(self,obj):
  330:         """subnav" von self"""
  331:         subs=self.ZopeFind(obj,obj_metatypes=['MPIWGTemplate','MPIWGLink'])
  332:         subret=[]
  333: 
  334:         for x in subs:
  335:             if not(x[1].title==""):
  336:                 subret.append(x)
  337:         subret.sort(sortWeight)
  338:         return subret
  339:     
  340:     def subNav(self,obj):
  341:         """return subnav elemente"""
  342:         #if obj.meta_type in ['MPIWGTemplate','MPIWGLink']:
  343:         #    id=obj.aq_parent.getId()
  344:         #else:
  345: 
  346:         #id=obj.getId()
  347: 
  348:         
  349:         #suche die zweite ebene
  350:         
  351:         if not obj.aq_parent.getId() in ['de','en']:
  352:             obj=obj.aq_parent
  353:         
  354:         while not self.ZopeFind(self,obj_ids=[obj.getId()]):
  355:             obj=obj.aq_parent
  356:         
  357:       
  358:         if hasattr(self,obj.getId()):
  359:             
  360:             subs=self.ZopeFind(getattr(self,obj.getId()),obj_metatypes=self.nav_meta_types)
  361:             subret=[]
  362: 
  363:             for x in subs:
  364:                 if not(x[1].title==""):
  365:                     subret.append(x)
  366:             subret.sort(sortWeight)
  367:             return subret
  368:         else:
  369:             return None
  370: 
  371:     def isType(self,object,meta_type):
  372:         """teste ob ein object vom meta_type ist."""
  373:         return (object.meta_type==meta_type)
  374:     
  375:     def isActive(self,name):
  376:         """teste ob subnavigation aktiv"""
  377:         for part in self.REQUEST['URL'].split("/"):
  378:             if part==name:
  379:                 return True
  380:         return False
  381:         
  382:     
  383:     def getSections(self):
  384:         """returns a list of all sections i.e. top-level MPIWGFolders"""
  385:         secs = self.objectItems(['MPIWGFolder'])
  386:         secs.sort(sortWeight)
  387:         #logging.debug("root: %s secs: %s"%(repr(self.absolute_url()), repr(secs)))
  388:         # return pure list of objects
  389:         return [s[1] for s in secs]
  390: 
  391:     def getSectionStyle(self, name, style=""):
  392:         """returns a string with the given style + '-sel' if the current section == name"""
  393:         if self.getSection() == name:
  394:             return style + '-sel'
  395:         else:
  396:             return style    
  397: 
  398:     def getFeatures(self):
  399:         """returns a list of all Features"""
  400:         dir = getattr(self, 'features')
  401:         features = dir.objectItems(['MPIWGFeature'])
  402:         features.sort(sortWeight)
  403:         # return pure list of objects
  404:         return [f[1] for f in features]
  405: 
  406: 
  407:     def MPIWGrootURL(self):
  408:         """returns the URL to the root"""
  409:         return self.absolute_url()
  410:         
  411:     def upDateSQL(self,fileName):
  412:         """updates SQL databases using fm.jar"""
  413:         fmJarPath=os.path.join(package_home(globals()), 'updateSQL/fm.jar')
  414:         xmlPath=os.path.join(package_home(globals()), "updateSQL/%s"%fileName)
  415:         logger("MPIWG Web",logging.INFO,"java -classpath %s -Djava.awt.headless=true Convert %s"%(fmJarPath,xmlPath))
  416:         ret=os.popen("java -classpath %s -Djava.awt.headless=true Convert %s"%(fmJarPath,xmlPath),"r").read()
  417:         logger("MPIWG Web",logging.INFO,"result convert: %s"%ret)
  418:         return 1
  419:     
  420:     def patchProjects(self,RESPONSE):
  421:         """patch"""
  422:         projects=self.ZopeFind(self.projects,obj_metatypes=['MPIWGProject'])
  423:         for project in projects:
  424:                 tmp=project[1].WEB_project_description[0].replace("/CD/projects/","")[0:]
  425:                 setattr(project[1],'WEB_project_description',[tmp[0:]])
  426:                 RESPONSE.write("<p>%s</p>\n"%project[0])
  427:             
  428:     def replaceNotEmpty(self,format,field):
  429:         """replace not empty"""
  430:         if field and (not field.lstrip()==''):
  431:             return self.decode(format%field)
  432:         else:
  433:             return ""
  434:         
  435: 
  436:     def isActiveMember(self,key):
  437:         """tested ob Mitarbeiter key ist aktiv"""
  438:         key=utf8ify(key)
  439:         ret=self.getat(self.ZSQLInlineSearch(_table='personal_www',
  440:                                             _op_key='eq',key=key,
  441:                                             _op_publish_the_data='eq',
  442:                                             publish_the_data='yes'))
  443:         
  444:         logging.info("ACTIVE_MEMBER  %s"%ret)
  445:         if ret:
  446:             return True
  447:         else:
  448:             return False
  449:         
  450:     def isActual(self,project):
  451:         """checke if project is actual"""
  452:         actualTime=time.localtime()
  453:         
  454:         if hasattr(project,'getObject'): #obj ist aus einer catalogTrefferList
  455:             obj=project.getObject()
  456:         else:
  457:             obj=project
  458:             
  459:         if getattr(obj,'archiveTime',actualTime)< actualTime:
  460:             return False
  461:         else:
  462:             return True
  463:         
  464:     def redirectIndex_html(self,request):
  465:         #return request['URL1']+'/index_html'
  466:         
  467:         return urllib.urlopen(request['URL1']+'/index_html').read()
  468: 
  469:     
  470:     def formatBibliography(self,here,found):
  471:         """format"""
  472:         return formatBibliography(here,found)
  473:     
  474:     def getValue(self,fieldStr):
  475:         """Inhalt des Feldes"""
  476:         
  477:         if type(fieldStr)==StringType:
  478:             field=fieldStr
  479:         else:
  480:             field=fieldStr[0]
  481:         try:
  482:             if field[len(field)-1]==";":
  483:                 field=field[0:len(field)-1]
  484:         except:
  485: 
  486:             """nothing"""
  487:         field=re.sub(r';([^\s])','; \g<1>',field)
  488:         return field.encode('utf-8')
  489: 
  490: 
  491:     
  492:     def sortedNames(self,list):
  493:         """sort names"""
  494: 
  495:         def sortLastName(x_c,y_c):
  496:             try:
  497:                 x=urllib.unquote(x_c).encode('utf-8','ignore')
  498:             except:
  499:                 x=urllib.unquote(x_c)
  500: 
  501:             try:
  502:                 y=urllib.unquote(y_c).encode('utf-8','ignore')
  503:             except:
  504:                 x=urllib.unquote(y_c)
  505:                 
  506: 
  507:             
  508:             try:
  509:                 last_x=x.split()[len(x.split())-1]
  510:                 last_y=y.split()[len(y.split())-1]
  511: 
  512:             except:
  513: 
  514:                 last_x=""
  515:                 last_y=""
  516:             
  517:             
  518:             
  519:             if last_x<last_y:
  520:                 return 1
  521:             elif last_x>last_y:
  522:                 return -1
  523:             else:
  524:                 return 0
  525:             
  526:         list.sort(sortLastName)
  527:         list.reverse()
  528:         
  529:         return list
  530:     
  531:     def __init__(self, id, title):
  532:         """init"""
  533:         self.id=id
  534:         self.title=title
  535: 
  536:     def removeStopWords(self,xo):
  537:         """remove stop words from xo"""
  538:         if not hasattr(self,'_v_stopWords'):
  539:             self._v_stopWords=self.stopwords_en.data.split("\n")
  540:     
  541:         x=str(xo)
  542:     
  543:         strx=x.split(" ")
  544:   
  545:         for tmp in strx:
  546:      
  547:             if tmp.lower() in self._v_stopWords:
  548:                 del strx[strx.index(tmp)]
  549: 
  550:         return " ".join(strx)
  551:     
  552:     def urlQuote(self,str):
  553:         """quote"""
  554:         return urllib.quote(str)
  555: 
  556:     def urlUnQuote(self,str):
  557:         """quote"""
  558:         return urllib.unquote(str)
  559:     
  560:         
  561: 
  562:     def getProjectsByFieldContent(self,fieldName,fieldContentsEntry, date=None):
  563:         """gib alle Projekte aus mit Value von field mit fieldName enthaelt ein Element der Liste fieldContents"""
  564:         def sort(x,y):
  565:                 return cmp(x.WEB_title[0],y.WEB_title[0])
  566: 
  567:         if type(fieldContentsEntry) is StringType:
  568:             fieldContentsTmp=[fieldContentsEntry]
  569:         else:
  570:             fieldContentsTmp=fieldContentsEntry
  571: 
  572:         fieldContents=[]
  573:         for x in fieldContentsTmp:
  574:             fieldContents.append(" AND ".join(x.split()))
  575:         projects=self.ProjectCatalog({fieldName:string.join(fieldContents,' AND')})
  576:         #print projects
  577:         #ret=[x for x in projects]
  578:         ret=[]
  579:         for x in projects:
  580:             obj=x.getObject()
  581:             obj=obj.getActualVersion(date)
  582:             if obj and (not getattr(obj,'invisible',None)):
  583:                 #if not (x in ret):
  584:                     ret.append(x)
  585: 
  586:         ret.sort(sort)
  587:         return ret
  588: 
  589:     def changeMPIWGRootForm(self):
  590:         """edit"""
  591:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeMPIWGRootForm')).__of__(self)
  592:         return pt()
  593: 
  594:     def changeMPIWGRoot(self,title,disciplineList,themesList,connection_id,RESPONSE=None):
  595:         """change"""
  596:         self.title=title
  597:         self.connection_id=connection_id
  598:         self.disciplineList=disciplineList
  599:         self.themesList=themesList
  600: 
  601:         if RESPONSE is not None:
  602:             RESPONSE.redirect('manage_main')
  603: 
  604: 
  605:     def getContexts(self,childs=None,parents=None,depth=None,date=None,onlyActive=True):
  606:         """childs alle childs, alle parents"""
  607:         ret=[]
  608:         
  609:         if parents:
  610:             pnums=parents.split(".")
  611:             while len(pnums) > 1:
  612:                 pnums.pop()
  613:                 parentId=string.join(pnums,".")
  614:         
  615:                 for project in self.getProjectFields('xdata_05',sort='int',date=date):
  616:                     if project[1]==parentId:
  617:                         ret.append(project)
  618:                 
  619:                 if (depth is not None) and (len(ret) >= depth):
  620:                     break
  621: 
  622:         if childs:
  623:             for project in self.getProjectFields('xdata_05',sort='int',date=date):
  624:                 searchStr=childs+"(\..*)"
  625:                
  626:                 if (onlyActive and project[0].isActiveProject()) or (not onlyActive):
  627:                     if re.match(searchStr,project[1]):
  628:                         
  629:                         if depth:
  630:     
  631:                             if int(depth)>=len(project[1].split("."))-len(childs.split(".")):
  632:                         
  633:                                 ret.append(project)
  634:                         else:
  635:                             ret.append(project)
  636:         
  637:         #logging.debug("getContexts: childs=%s parents=%s depth=%s => %s"%(childs,parents,depth,repr(ret)))
  638:         return ret
  639: 
  640:     
  641:     def getProjectFields(self,fieldName,date=None,folder=None,sort=None):
  642:         """getListofFieldNames"""
  643:         ret=[]
  644:     
  645:         objects=self.ZopeFind(self.projects,obj_metatypes=['MPIWGProject'],search_sub=0)
  646: 
  647:                 
  648:         for object in objects:
  649:             obj=object[1]
  650:             obj=obj.getActualVersion(date)
  651:             if obj and (not getattr(obj,'invisible',None)):
  652:                 if fieldName=="WEB_title_or_short":
  653: 
  654:                     if len(obj.getContent('xdata_07'))<3: # hack weil z.Z. manchmal noch ein Trennzeichen ; oder , im Feld statt leer
  655:                         fieldNameTmp="WEB_title"
  656:                     else:
  657:                         fieldNameTmp="xdata_07"
  658:                 else:
  659:                     fieldNameTmp=fieldName
  660: 
  661:                 ret.append((obj,obj.getContent(fieldNameTmp)))
  662: 
  663:         
  664:         if sort=="int":
  665:             ret.sort(sortI)
  666:         elif sort=="stopWords":
  667:  
  668:             ret.sort(sortStopWords(self))
  669:             
  670:         else:
  671:             ret.sort(sortF)
  672:         
  673:         return ret
  674: 
  675:     def showNewProjects(self):
  676:         projects=[]
  677:         for objs in self.getProjectFields('WEB_title_or_short'): # Get all Projets
  678:             if objs[0].xdata_05 and (objs[0].xdata_05[0] == ""):
  679:                 
  680:                 projects.append(objs)
  681:                 
  682:         return projects
  683:     
  684:         
  685:     manage_options = Folder.manage_options+(
  686:         {'label':'Update personal homepages','action':'updatePersonalwww_html'},
  687:         {'label':'Reindex catalogs','action':'reindexCatalogs'},
  688:         {'label':'Main config','action':'changeMPIWGRootForm'},
  689:         {'label':'add e-mails','action':'showNewDBEntries'},
  690:         {'label':'update the institutsbibliography','action':'updateInstitutsbiliography'},
  691:         #{'label':'Edit Historical Persons','action':'editHistoricalPersonsForm'},
  692:         #{'label':'Store Historical Persons','action':'storeHistoricalPersons'},
  693:         )
  694:     
  695: 
  696:     def updatePublicationDB(self,personId=None):
  697:         """updates the publication db, i.e. copy year and type into the main table"""
  698:         
  699:         if personId:
  700:             founds = self.ZSQLInlineSearch(_table="publications",key_main=personId)
  701:         else:
  702:             founds = self.ZSQLInlineSearch(_table="publications")
  703:             
  704:         for found in founds:
  705:                         
  706:             if found.id_institutsbibliographie and (not found.id_institutsbibliographie =="") and (not found.id_institutsbibliographie =="0"):
  707:                 
  708:                 entries = self.ZSQLInlineSearch(_table="institutsbiblio",id=found.id_institutsbibliographie)
  709:                 for entry in entries:
  710:                     self.ZSQLChange(_table='publications',_identify='oid=%s' % found.oid,year=entry.year,referencetype=entry.reference_type)
  711:                     
  712:             if found.id_gen_bib and (not found.id_gen_bib ==""):
  713:                 entries = self.ZSQLInlineSearch(_table="bibliography",id=found.id_gen_bib)
  714:                 for entry in entries:
  715:                     self.ZSQLChange(_table='publications',_identify='oid=%s' % found.oid,year=entry.year,referencetype=entry.reference_type)
  716:                     
  717:         return True        
  718:     
  719:     def showNewDBEntries(self):
  720:         """zeige neue Eintraege in der Datenbank ohne e-mail adressen bzw. fuer die noch kein Object angelegt wurde"""
  721:         
  722:         qstr="select * from personal_www where web_object_created='no' and not key=''"
  723:         res=self.ZSQLQuery(qstr)
  724:         
  725:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','showNewDBEntries.zpt')).__of__(self)
  726:         return pt(newEntries=res)
  727:    
  728:     def createNewStaffObjects(self,RESPONSE):
  729:         """create new staff object"""
  730:         
  731:         memberFolder=getattr(self,'members')
  732:         args=self.REQUEST.form
  733:         arg_k=args.keys()
  734:         arg_k.remove("submit")
  735:         ret=""
  736:         for key in arg_k:
  737:             k=self.urlUnQuote(key)
  738:           
  739:             qstr="select * from personal_www where key=%s"%self.ZSQLQuote(k)
  740:             res=self.ZSQLQuery(qstr)[0]
  741:             if args[key]!="": #email-adresse wurde eingetragen
  742:                 #create the object
  743:                 e_mail=args[key]
  744:                 try:
  745:                     newObj=MPIWGStaff.MPIWGStaff(e_mail,res.last_name,res.first_name,k)
  746:                     memberFolder._setObject(e_mail,newObj)
  747:                     obj=getattr(memberFolder,e_mail)
  748:                     obj.reindex_object()
  749:                     ret+="Created %s \n"%e_mail
  750:                     created=True
  751:                 except:
  752:                     msg="Cannot create new user %s (%s %s)"%(e_mail,sys.exc_info()[0],sys.exc_info()[1])
  753:                     logging.error(msg)
  754:                     ret+=msg+"\n"
  755:                     created=False
  756:                 
  757:                 if created:
  758:                     qstr="update personal_www set web_object_created='yes',e_mail='%s@mpiwg-berlin.mpg.de' where key=%s"%(e_mail,self.ZSQLQuote(k))
  759:                     self.ZSQLQuery(qstr)
  760:         
  761:         return ret
  762:                    
  763:         
  764:     def generateNewPersonEntry(self,data):
  765:         """generate a new person entry for data, neue personen werden zunaechst nur in der datenbank angelegt """
  766:         
  767:         #memberFolder=getattr(self,'members')
  768:         #create the object
  769:         
  770: #        try:
  771: #            newObj=MPIWGStaff.MPIWGStaff(urllib.quote(data['key']),data['last_name'].encode('utf-8'),data['first_name'].encode('utf-8')) 
  772: #            memberFolder._setObject(urllib.quote(data['key']),newObj)
  773: #        except:
  774: #            return False, "Cannot create new user %s (%s %s)"%(data['key'],sys.exc_info()[0],sys.exc_info()[1])
  775: #        
  776:         
  777:         #create the new entry in the database
  778:         
  779:         
  780:         result,msg=MPIWGStaff.createNewDBEntry(self,data['publish_the_data'],data['key'],data['last_name'],
  781:                                   data['first_name'],data['title'],data['status'],"",
  782:                                   "",data['date_from'],data['date_to'],
  783:                                   data['department'],data['home_inst'],data['funded_by'],
  784:                                   data['e_mail2'],data['current_work'],"yes",data['date_stay_at_mpiwg'],data['group'],"no",data['current_work'])
  785:         
  786:         return result,msg
  787:  
  788:     def updatePersonEntry(self,data,ignoreEntries=[]):
  789:         """update an person entry from data. but ignore all fields in ignore Entries"""
  790:         
  791:         ignoreEntries.append('current_work') # TODO:updatecurrent work
  792:         
  793:         if data['date_to']=="": # wenn date_to leer
  794:              data['date_to']="date_none"
  795:         
  796:         if data['date_from']=="": # wenn date_fromleer
  797:              data['date_from']="date_none"
  798:         msg=""
  799:    
  800:         
  801:         #eintragen
  802:          
  803:         columns=data.keys()
  804:         for x in ignoreEntries:
  805:             logging.info("ign rem: %s"%x)
  806:             try: #falls in ignore entries felder sind, die nicht in columns sind, fange den fehler ab
  807:              columns.remove(x)
  808:             except:
  809:                 pass
  810: 
  811:         
  812:         insert=[]
  813:         for key in columns:
  814:             if data[key]=="date_none": # date_none eintrag wird zu null uebersetzt
  815:                 insert.append('%s=null'%key)
  816:             else:
  817:                 insert.append(""" "%s"=%s"""%(key,self.ZSQLQuote(data[key])))
  818:             
  819:         insertStr=",".join(insert)
  820:         queryStr="update personal_www SET %s where key='%s'"%(insertStr,data['key'])
  821:         self.ZSQLQuery("SET DATESTYLE TO 'German'")
  822:         self.ZSQLQuery(queryStr)
  823:        
  824:         #currentwork
  825:         #if not (txt==""):
  826:         #    queryStr="INSERT INTO current_work (id_main,current,publish) VALUES ('%s','%s','%s')"%(id,txt,txt_p)
  827:         #
  828:         #    self.ZSQLQuery(queryStr)
  829:         
  830:         return True,msg
  831: 
  832: 
  833:     def updatePersonalwww_doIt(self):
  834:         """do the update"""
  835:         args=self.REQUEST.form
  836:         resultSet=self.REQUEST.SESSION['personal_www']['resultSet']
  837:         news=self.REQUEST.SESSION['personal_www']['news']
  838:         conflicts=self.REQUEST.SESSION['personal_www']['conflicts']
  839:         ret="<html><body>"
  840:         # generate the new entry
  841:       
  842:         if news and (len(news)>0):
  843:             ret+="<h2>Hinzugef&uuml;gt</h2>"
  844:             ret+="<p>Neueintr&auml;ge erscheinen erst auf der Homepage, wenn ihnen eine e-mail Adresse zugeordnet wurde.</p>"
  845:             ret+="<ul>"
  846:         for new in news:
  847:       
  848:             if args.has_key(self.urlQuote(new.encode('utf-8'))): # entry was selected
  849:                 result,msg=self.generateNewPersonEntry(resultSet[new])
  850:                 if not result:
  851:                     logging.error("Error (generateNewPersonEntry) %s"%msg)
  852:                     ret+="<li>ERROR: %s %s"%(new.encode('utf-8'),msg)
  853:                 else:
  854:                     ret+="<li>OK: %s"%(new.encode('utf-8'))
  855:         if news and (len(news)>0):
  856:             ret+="<p>Neueintr&auml;ge erscheinen erst auf der Homepage, wenn ihnen eine e-mail Adresse zugeordnet wurde.</p>"
  857:             ret+="</ul>"     
  858:         
  859:         # update
  860: 
  861:         if len(conflicts.keys())>0:
  862:             ret+="<h2>&Auml;nderung des Benutzers &uuml;bernehmen</h2>"
  863:             ret+="<p>Wenn n&ouml;tig in Filemaker-db &auml;ndern:</p>"
  864:             
  865:         # konflicte   
  866:         for conflict in conflicts.keys():
  867:             ignoreEntries=[]
  868:             displayIgnored=[]
  869:             for cf in conflicts[conflict]:
  870:                 if args[conflict.encode('utf-8')+'_'+cf[0]]=="stored": #use the stored one
  871:                     ignoreEntries.append(cf[0])  #so ignore field cf[0]       
  872:                     displayIgnored.append(cf)
  873:             if len(displayIgnored)>0:
  874:                 ret+="<h3>%s</h3>"%conflict.encode('utf-8')
  875:                 
  876:                 ret+="<table border='1'>"
  877:                 for iE in displayIgnored:
  878:                     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'))
  879:                 ret+="</tabel>"
  880:                 
  881:             self.updatePersonEntry(resultSet[conflict],ignoreEntries=ignoreEntries)
  882:          
  883:          # rest
  884:         cl=list(conflicts.keys())
  885:         
  886:         for key in resultSet.keys():
  887:              if key not in cl:
  888:                  self.updatePersonEntry(resultSet[key])
  889:         return ret+"</body></html>"
  890:                      
  891: 
  892:     def updateInstitutsbiliography(self):
  893:         """update the Institutsbibliogrpahy"""
  894:         self.upDateSQL('personalwww.xml')
  895:         return "<html><body>DONE</body></html>"
  896: 
  897: 
  898:     
  899: 
  900:     def updatePersonalwww_html(self):
  901:         """update form for the homepages web form"""
  902:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','updatePersonalwww.zpt')).__of__(self)
  903:         return pt()
  904: 
  905:     
  906:     def updatePersonalwww(self,uploadfile):
  907:         """update personalwww
  908:         @param uploadfile: file handle auf das file
  909:         """
  910:         dsn=self.getConnectionObj().connection_string
  911:         #dsn="dbname=personalwww"
  912:         resultSet=updatePersonalWWW.importFMPXML(uploadfile)
  913:         news,conflicts=updatePersonalWWW.checkImport(dsn, resultSet)
  914: 
  915:         self.REQUEST.SESSION['personal_www']={}
  916:         self.REQUEST.SESSION['personal_www']['resultSet']=resultSet
  917:         self.REQUEST.SESSION['personal_www']['news']=news
  918:         self.REQUEST.SESSION['personal_www']['conflicts']=conflicts
  919:         
  920:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','updatePersonalwww_check.zpt')).__of__(self)
  921:         return pt()
  922:     
  923: 
  924:      
  925:     def reindexCatalogs(self,RESPONSE=None):
  926:         """reindex members and project catalog"""
  927:         
  928:         
  929:         try:
  930:             
  931:             self.ProjectCatalog.manage_catalogReindex(self.REQUEST,RESPONSE,self.REQUEST['URL1'])
  932:         except:
  933:             logger("MPIWG Root (updatehomepage)",logging.WARNING," %s %s"%sys.exc_info()[:2])
  934:             
  935:         
  936:     
  937:         
  938:            
  939:         if RESPONSE:
  940:             RESPONSE.redirect('manage_main')
  941: 
  942:         
  943:         
  944: 
  945:     def getAllMembers(self):
  946:         #ret=[]
  947:         
  948:         def sorter(x,y):
  949:             return cmp(x[0],y[0])
  950:                     
  951:         results=self.MembersCatalog({'isPublished':True})
  952:        
  953:         ret=[(", ".join([proj.lastName, proj.firstName]).decode('utf-8'),proj.getKey) for proj in results]
  954:         
  955:         ret.sort(sorter)
  956:         return ret
  957:     
  958:     
  959:     def printAllMembers(self):
  960:         """print"""
  961:         members=self.getAllMembers()
  962:         ret=""
  963:         for x in members:
  964:             ret+="<p>%s</p>"%x
  965:         return ret
  966:     
  967:         
  968:     def makeList(self,entry):
  969:         """makes a list out of one entry or repeat a list"""
  970:         if type(entry) is StringType:
  971:             return [entry]
  972:         else:
  973:             return entry
  974: 
  975:     def getTreeRSS(self,dep=None,date=None,onlyActive=1,onlyArchived=0):
  976:         """generateTree"""
  977:         rss="""<?xml version="1.0" encoding="utf-8"?>
  978:                  <rss version="2.0">
  979:                    <channel>"""
  980:         
  981:         for obj in self.getTree(dep, date, onlyActive, onlyArchived):
  982:             linkStr="""<link>http://wwwneu.mpiwg-berlin.mpg.de/en/research/projects/%s</link>"""
  983:             rss+="""<item>"""
  984:             rss+=linkStr%obj[3].getId()
  985:             rss+="""</item>"""
  986:             if hasattr(obj[3],'publicationList'):
  987: 	        rss+="""<item>"""
  988:                 rss+=linkStr%(obj[3].getId()+"/publicationList");
  989:                 rss+="""</item>"""
  990:         rss+="""</channel>
  991:         </rss>"""
  992: 
  993:         
  994:         return rss
  995: 
  996:     def getTree(self,dep=None,date=None,onlyActive=0,onlyArchived=0):
  997:         """generate Tree from project list
  998:         als Liste, jeder Eintrag ist ein Tupel ,(Tiefe, ProjektNummer,ProjektObject
  999:         onlyActive = 0  : alle Projekte
 1000:         onlyActive = 1 : nur active Projekte
 1001:         onlyActive = 2: nur inactive Projekte
 1002:         
 1003:         onlyArchived=0: alle Projekte
 1004:         onlyArchived= 1 : nur aktuelle Projekte
 1005:         onlyArchived = 2: nur archivierte Projekte
 1006:         """
 1007: 
 1008:         returnListTmp=[]
 1009:         returnList=[]
 1010:         
 1011:         for project in self.getProjectFields('xdata_05',sort="int",date=date): # get Projects sorted by xdata_05
 1012: 
 1013:             for idNr in project[1].split(";"): # more than one number
 1014:                 if not idNr=="":
 1015:                     splittedId=idNr.split(".")
 1016:                     depth=len(splittedId)
 1017:                     nr=idNr
 1018:                     #title=project[0].WEB_title
 1019:                     title=[project[0].getContent('WEB_title')]
 1020:                     #print title
 1021:                     
 1022:                     if idNr[0]=="x": # kompatibilitaet mit alter Konvention, x vor der Nummer macht project inactive
 1023:                         project[0].setActiveFlag(False)
 1024:                    
 1025:                     if (not dep) or (idNr[0]==dep): #falls dep gesetzt ist nur dieses hinzufuegen.
 1026:                         
 1027:                         if (onlyActive==0):
 1028:                             returnListTmp.append((depth,nr,title,project[0]))
 1029:                         elif (onlyActive==1) and project[0].isActiveProject(): #nur active projekte
 1030:                             returnListTmp.append((depth,nr,title,project[0]))
 1031:                         elif (onlyActive==2) and (not project[0].isActiveProject()): #nur active projekte
 1032:                             returnListTmp.append((depth,nr,title,project[0]))
 1033:                    
 1034:                    
 1035:         #filter jetzt die Liste nach Archived oder nicht
 1036:         for entry in returnListTmp:
 1037:                     if (onlyArchived==0):
 1038:                             returnList.append(entry)
 1039:                     elif (onlyArchived==1) and (not entry[3].isArchivedProject()): #nur active projekte
 1040:                             returnList.append(entry)
 1041:                     elif (onlyArchived==2) and (entry[3].isArchivedProject()): #nur active projekte
 1042:                             returnList.append(entry)
 1043:                    
 1044:         
 1045:         return returnList
 1046: 
 1047: 
 1048:         
 1049:     def changePosition(self,treeId,select,RESPONSE=None):
 1050:         """Change Postion Entry"""
 1051:         numbers=[]
 1052: 
 1053:         # Suche hoechste bisherige nummer
 1054:         projects=self.getProjectFields('xdata_05') # get Projects sorted by xdata_05
 1055:         #print "pj",projects
 1056:         for project in projects: #suche alle subtrees der treeId
 1057:             #print treeId
 1058:             
 1059:             founds=re.match(treeId+"\.(.*)",project[1].split(";")[0])
 1060:             if founds:
 1061:                 #print "x",founds.group(0),len(founds.group(0).split("."))
 1062:                 if len(founds.group(0).split("."))==len(treeId.split("."))+1: # nur ein punkt mehr, d.h. untere ebene
 1063:                     try:
 1064:                         numbers.append(int(founds.group(0).split(".")[len(founds.group(0).split("."))-1]))
 1065:                     except:
 1066:                         numbers.append(int(0))
 1067: 
 1068:         try:
 1069:             highest=max(numbers)
 1070:         except:
 1071:             highest=0
 1072:         projects=self.showNewProjects()
 1073:         for i in self.makeList(select):
 1074:             highest+=10
 1075:             projects[int(i)][0].xdata_05=treeId+"."+str(highest)
 1076: 
 1077: 
 1078:         if RESPONSE is not None:
 1079:             RESPONSE.redirect('showTree')
 1080:         
 1081:     def changeTree(self,RESPONSE=None):
 1082:         """change the complete tree"""
 1083:         form=self.REQUEST.form
 1084:         hashList={}
 1085:         onlyArchived=int(form.get("onlyArchived",0))
 1086:         onlyActive=int(form.get("onlyActive",0))
 1087:         
 1088:         
 1089:         fields=self.getTree(onlyArchived=onlyArchived,onlyActive=onlyActive)
 1090:         
 1091:         logging.info("GOT TREE!----------------------------------------------------")
 1092:         for field in form.keys():
 1093:             
 1094:             splitted=field.split('_')
 1095:             if (len(splitted)>1) and (splitted[1]=="runningNumber"): #feld hat die Form Nummer_name und runnignNumber
 1096:             
 1097:                 
 1098:                 nr=int(splitted[0]) # nummer des Datensatzes
 1099:                 currentEntry = fields[nr]
 1100:             
 1101:                 if form.has_key(str(nr)+'_active'): # active flag is set
 1102:                     fields[nr][3].setActiveFlag(True)
 1103:                 else:
 1104:                     fields[nr][3].setActiveFlag(False)
 1105:                     
 1106:                 #nummer hat sich geŠndert
 1107:                 
 1108:                 entryChanged = False;
 1109:                 
 1110:                 
 1111:                 if not (fields[nr][3].xdata_05==form[str(nr)+'_number']):
 1112:                     logging.info("Changed!Number+++++++++++++++++++++++++++++++++")
 1113:                     fields[nr][3].xdata_05=form[str(nr)+'_number']
 1114:                     entryChanged = True
 1115:                     
 1116:                 #completed har sich geaendert
 1117:                             
 1118:                 if not (fields[nr][3].getCompletedAt()==fields[nr][3].transformDate(form[str(nr)+'_completed'])):
 1119:                     fields[nr][3].setCompletedAt(form[str(nr)+'_completed'])
 1120:                     logging.info("Changed!Completed+++++++++++++++++++++++++++++++++")
 1121:                     entryChanged = True
 1122:                 
 1123:                 if not (fields[nr][3].getStartedAt()==fields[nr][3].transformDate(form[str(nr)+'_started'])):
 1124:                     fields[nr][3].setStartedAt(form[str(nr)+'_started'])
 1125:                     logging.info("Changed!Started+++++++++++++++++++++++++++++++++")
 1126:                     entryChanged = True
 1127:                 
 1128:                 
 1129:                 if entryChanged:
 1130:                     logging.info("Changed!+++++++++++++++++++++++++++++++++")
 1131:                     fields[nr][3].copyObjectToArchive()
 1132:                 
 1133:                     
 1134:         if RESPONSE is not None:
 1135:             RESPONSE.redirect('showTree')
 1136: 
 1137:     def getProjectWithId(self,id):
 1138:         fields=self.getProjectFields('xdata_05')
 1139:         for field in fields:
 1140:             if field[1]==id:
 1141:                 return field[0]
 1142: 
 1143:         return None
 1144:             
 1145:         
 1146:             
 1147:         
 1148:     def getRelativeUrlFromPerson(self,list):
 1149:         """get urls to person list"""
 1150:         ret=[]
 1151:         persons=list.split(";")
 1152:         for person in persons:
 1153:             
 1154:             if len(person)>1: #nicht nur Trennzeichen
 1155:                 splitted=person.split(",")
 1156:                 if len(splitted)==1:
 1157:                     splitted=person.split(" ")
 1158:                 splittedNew=[re.sub(r'\s(.*)','$1',split) for split in splitted]
 1159:                 if splittedNew[0]=='':
 1160:                     del splittedNew[0]
 1161:                 search=string.join(splittedNew,' AND ')
 1162:                 
 1163:                 if not search=='':
 1164: 
 1165:                     try:
 1166:                         proj=self.MembersCatalog({'title':search})
 1167:                     except:
 1168:                         proj=None
 1169: 
 1170:                 if proj:
 1171:                     #ret.append("<a href=%s >%s</a>"%(proj[0].absolute_url,person.encode('utf-8')))
 1172:                     ret.append("<a href=%s >%s</a>"%('members/'+proj[0].id+'/index.html',person))
 1173:                 else:
 1174:                     #ret.append("%s"%person.encode('utf-8'))
 1175:                     ret.append("%s"%person)
 1176:         return string.join(ret,";")
 1177:         
 1178:     def getMemberIdFromKey(self,key):
 1179:         """gibt die ensprechende id  im members Ordner zum key"""
 1180:         
 1181:         if key=="":
 1182:             return ""
 1183:         try:
 1184:             key=utf8ify(key)
 1185:             catalogged=self.MembersCatalog({'getKey':key})
 1186:             if len(catalogged)==0:
 1187:                 return ""
 1188:             else:
 1189:                 return catalogged[0].getObject().getId()
 1190:         
 1191:         except:
 1192:             return ""
 1193: 
 1194:             
 1195: 
 1196:     def getProjectsOfMembers(self,date=None):
 1197:         """give tuple member /projects"""
 1198:         ret=[]
 1199:         members=self.getAllMembers()
 1200:         logging.error("X %s"%repr(members))
 1201:         #return str(members)
 1202:         for x in members:
 1203:             logging.error("X %s"%repr(x))
 1204:             projects=self.getProjectsOfMember(key=x[1],date=date)
 1205:             if len(projects)>0:
 1206:                 ret.append((x[0],projects))
 1207:             
 1208:         return ret
 1209: 
 1210:     def getProjectsOfMember(self,key=None,date=None,onlyArchived=1,onlyActive=1):
 1211:         """get projects of a member
 1212:     
 1213:         @param key: (optional) Key zur Idenfikation des Benutzer
 1214:         @param date: (optional) Version die zum Zeitpunkt date gueltig war
 1215:         @param onlyArchived: 
 1216:         onlyArchived=0: alle Projekte
 1217:         onlyArchived= 1 : nur aktuelle Projekte
 1218:         onlyArchived = 2: nur archivierte Projekte
 1219:         """
 1220:         # TODO: Die ganze Loesung
 1221:         def sortP(x,y):
 1222:             """sort by sorting number"""
 1223:             return cmp(x.WEB_title,y.WEB_title)
 1224:         
 1225:         ret=[]  
 1226:         if key:     
 1227:             proj=self.ProjectCatalog({'getPersonKeyList':utf8ify(key)})
 1228:         else:
 1229:             return ret # key muss definiert sein
 1230:         
 1231:      
 1232:         if proj:
 1233:             proj2=[]
 1234:             for x in proj:
 1235:                 #logging.error("proj:%s"%repr(x.getPath()))
 1236:                 if (not getattr(x.getObject(),'invisible',None)) and (getattr(x.getObject(),'archiveTime','')==''):   
 1237:                       proj2.append(x)
 1238: 
 1239:         else:
 1240:             proj2=[]
 1241:             
 1242:        
 1243:        
 1244:         proj2.sort(sortP)
 1245: 
 1246:         projectListe=[]
 1247:         #logging.error("getprojectsofmember proj2: %s"%repr(proj2))
 1248:         for proj in proj2:   
 1249:             obj=proj.getObject()
 1250:             add=False
 1251:             if onlyArchived==1: #nur aktuell projecte
 1252:                 if not obj.isArchivedProject():
 1253:                     add=True
 1254:             elif onlyArchived==2: #nur archivierte
 1255:                 if obj.isArchivedProject():
 1256:                     add=True
 1257:             else: #alle
 1258:                add=True 
 1259:                
 1260:             if onlyActive==1: #nur active projecte
 1261:                 if obj.isActiveProject():
 1262:                     add=add & True
 1263:                 else:
 1264:                     add=add & False
 1265:                 
 1266:             elif onlyArchived==2: #nur nicht aktvive
 1267:                 if not obj.isActiveProject():
 1268:                     add=add & True
 1269:             else: #alle
 1270:                add=add & True
 1271:                     
 1272:             if add:
 1273:                 projectListe.append(obj)
 1274:                 
 1275:         #logging.error("getprojectsofmember projectliste: %s"%repr(projectListe))
 1276:         return projectListe
 1277:      
 1278:     def givePersonList(self,name):
 1279:         """check if person is in personfolder and return list of person objects"""
 1280:         
 1281:         splitted=name.split(",")
 1282:         if len(splitted)==1:
 1283:             splitted=name.lstrip().rstrip().split(" ")
 1284:         splittedNew=[split.lstrip() for split in splitted]
 1285:         
 1286:         if splittedNew[0]=='':
 1287:             del splittedNew[0]
 1288:         search=string.join(splittedNew,' AND ')
 1289:         
 1290:         if not search=='':
 1291:             proj=self.MembersCatalog({'title':search})
 1292: 
 1293:         if proj:
 1294:             return [[x.lastName,x.firstName] for x in proj]
 1295:         else:
 1296:             return []
 1297:             
 1298: ##         splitted=name.split(",") # version nachname, vorname...
 1299: ##         if len(splitted)>1:
 1300: ##             lastName=splitted[0] 
 1301: ##             firstName=splitted[1]
 1302: ##         else: 
 1303: ##             splitted=name.split(" ") #version vorname irgenwas nachnamae
 1304:         
 1305: ##             lastName=splitted[len(splitted)-1]
 1306: ##             firstName=string.join(splitted[0:len(splitted)-1])
 1307: 
 1308: ##         objs=[]
 1309: 
 1310:         #print  self.members 
 1311:       ##   for x in self.members.__dict__:
 1312: ##             obj=getattr(self.members,x)
 1313: ##             if hasattr(obj,'lastName') and hasattr(obj,'firstName'):
 1314:                 
 1315: ##                 if (re.match(".*"+obj.lastName+".*",lastName) or re.match(".*"+lastName+".*",obj.lastName)) and (re.match(".*"+obj.firstName+".*",firstName) or re.match(".*"+firstName+".*",obj.firstName)):
 1316:                     
 1317: ##                     objs.append((obj,lastName+", "+firstName))
 1318: 
 1319:         
 1320: ##        return objs
 1321: 
 1322: 
 1323:     def personCheck(self,names):
 1324:         """all persons for list"""
 1325:         #print "names",names
 1326:         splitted=names.split(";")
 1327:         ret={}
 1328:         for name in splitted:
 1329: 
 1330:             if not (name==""):
 1331:                 try:
 1332:                     ret[name]=self.givePersonList(name)
 1333:                 except:
 1334:                     """NOTHIHN"""
 1335:         #print "RET",ret
 1336:         return ret
 1337: 
 1338:     def giveCheckList(self,person,fieldname):
 1339:         """return checklist"""
 1340:         #print "GCL",fieldname
 1341:         if fieldname=='xdata_01':
 1342:             x=self.personCheck(person.getContent(fieldname))
 1343:             #print "GCLBACKX",x
 1344:             return x
 1345:         
 1346: 
 1347:     def isCheckField(self,fieldname):
 1348:         """return chechfield"""
 1349:         
 1350:         return (fieldname in checkFields)
 1351: 
 1352:     
 1353:     def generateNameIndex(self):
 1354:         """erzeuge einen index verwendeter personen"""
 1355:         import psycopg
 1356:         o = psycopg.connect('dbname=authorities user=dwinter password=3333',serialize=0) 
 1357:         results={}
 1358:         print self.fulltext.historicalNames.items()
 1359:         for nameItem in self.fulltext.historicalNames.items(): #gehe durch alle namen des lexikons
 1360:             
 1361:             c = o.cursor() 
 1362:             name=nameItem[0]
 1363:             print "check",name
 1364:             c.execute("select lastname,firstname from persons where lower(lastname) = '%s'"%quote(name))
 1365:             tmpres=c.fetchall()
 1366:             firstnames=[result[1] for result in tmpres] # find all firstnames
 1367:             if tmpres:
 1368:                 lastname=tmpres[0][0]
 1369:                 
 1370:             for found in self.fulltext({'names':name}):
 1371:                 if found.getObject().isActual():
 1372:                     for nh in found.getObject().getGetNeighbourhood(name, length=50,tagging=False): #hole umgebung
 1373:                         #schaue nun ob der vorname hinter oder vor dem name ist
 1374:                         position=nh.find(lastname)
 1375:                         # vorher
 1376:                         #print "NH",nh
 1377:                         bevorS=nh[0:position].split()
 1378:                         #print "BV",bevorS
 1379:                         if len(bevorS)>1:
 1380:                             try:
 1381:                                 bevor=[bevorS[-1],bevorS[-2]]
 1382:                             except:
 1383:                                 bevor=[bevorS[0]]
 1384:                         else:
 1385:                             bevor=[]
 1386:                         #nachher
 1387:                         behindS= re.split("[,|;| ]",nh[position:]) 
 1388:                         #print "BH",behindS
 1389:                         if len(behindS)>2:
 1390:                             try:
 1391:                                 behind=behindS[1:3]
 1392:                             except:
 1393:                                 behind=[bevorS[1]]
 1394:                         else:
 1395:                             behind=[]
 1396:                         for firstname in firstnames:
 1397:                             if firstname in bevor+behind: #Namen wie mit Adelspraedikaten werden so erstmal nich gefunden
 1398:                                 id="%s,%s"%(lastname,firstname)
 1399:                                 if not results.has_key(id):
 1400:                                     results[id]=[]
 1401:                                 objId=found.getObject().getId()
 1402:                                 if not (objId in results[id]):
 1403:                                     print "d %s for %s"%(id,objId)    
 1404:                                     results[id].append(objId)    
 1405:             self.nameIndex=results
 1406:         return results
 1407:                     
 1408:     def editNameIndexHTML(self):
 1409:         """edit the name index"""
 1410:         if not hasattr(self,'nameIndexEdited'): # falls editierter index noch nicht existiert, kopiere automatisch erstellten
 1411:             self.nameIndexEdited=copy.copy(self.nameIndex)
 1412:             print "huh"
 1413:         #self.nameIndexEdited=copy.copy(self.nameIndex)
 1414:         #print self.nameIndexEdited
 1415:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editHistoricalNames.zpt')).__of__(self)
 1416:         return pt()
 1417:     
 1418:     def getNamesInProject(self,projectId):
 1419:         """get all names ofnameIndexEdited which are references in projec with projectId"""
 1420:         
 1421:         ret=[]
 1422:         for name in self.nameIndexEdited.keys():
 1423:             if projectId in self.nameIndexEdited[name]:
 1424:                 ret.append(name)
 1425:         
 1426:         return ret
 1427:     
 1428:     def editNameIndex(self,RESPONSE=None,name=None,occurrances=None,submit=None):
 1429:         """edit the index"""
 1430:         nI=self.nameIndexEdited # mI introduced to make sure that changes to nameIndexEdited are know to ZODB
 1431:         if submit=="delete":
 1432:            
 1433: 
 1434:             dh=getattr(self,'deletedHistoricalNames',{})
 1435:             
 1436:             if type(dh) is ListType:
 1437:                 dh={}
 1438:             if not dh.has_key(name):
 1439:                 dh[name]=occurrances.split("\n")
 1440:             else:
 1441:                 dh[name]+=occurrances.split("\n")
 1442:             
 1443:             self.deletedHistoricalNames=dh
 1444:             
 1445:             del self.nameIndexEdited[name]
 1446:             
 1447:         
 1448:         elif (submit=="change"):
 1449:             
 1450:             nI[name]=occurrances.split("\n")[0:]
 1451:             
 1452:         elif (submit=="add"):
 1453:             if not nI.has_key(name):
 1454:                 nI[name]=occurrances.split("\n")
 1455:             else:
 1456:                 nI[name]+=occurrances.split("\n")
 1457:     
 1458:         self.nameIndexEdited=nI
 1459:    
 1460:       
 1461:         if RESPONSE is not None:
 1462:             RESPONSE.redirect('editNameIndexHTML')
 1463:         
 1464:     
 1465:     
 1466:     def restoreIndex(self):
 1467:         """restore"""
 1468:         self.nameIndexEdited=self.nameIndex
 1469:         return "done"
 1470:     
 1471: 
 1472:             
 1473: def manage_addMPIWGRootForm(self):
 1474:     """form for adding the root"""
 1475:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGRootForm.zpt')).__of__(self)
 1476:     return pt()
 1477: 
 1478: def manage_addMPIWGRoot(self,id,title,connection_id="",RESPONSE=None):
 1479:     """add a root folder"""
 1480:     newObj=MPIWGRoot(id,title)
 1481:     self._setObject(id,newObj)
 1482:     ob=getattr(self,id)
 1483:     setattr(ob,'connection_id',connection_id)
 1484:     if RESPONSE is not None:
 1485:         RESPONSE.redirect('manage_main')
 1486:         

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>