File:  [Repository] / cdli / cdli_files.py
Revision 1.12: download - view: text, annotated - select for diffs - revision graph
Sun Mar 19 03:27:21 2006 UTC (18 years, 3 months ago) by dwinter
Branches: MAIN
CVS tags: HEAD
bug fixes and some new features

    1: """CDLI extensions of the filearchive"""
    2: from Products.versionedFile.versionedFile import *
    3: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
    4: from tempfile import mkstemp,mkdtemp
    5: import os.path
    6: import os
    7: from types import *
    8: import urlparse
    9: from OFS.OrderedFolder import OrderedFolder
   10: from OFS.SimpleItem import SimpleItem
   11: import time
   12: from OFS.Folder import manage_addFolder
   13: import re
   14: 
   15: class Basket_old(Folder):
   16:     """shopping basket - alte fassung """
   17:     
   18:     meta_type="Basket"
   19:     _v_stack={}
   20: 
   21:     def getObjUrl(self,objId):
   22:         """getUrl"""
   23:         founds=self.CDLICatalog.search({'title':objId})
   24:         if len(founds)>0:
   25:              return founds[0].getObject().absolute_url()
   26:          
   27:         else: #assume version number
   28:             splitted=objId.split("_")
   29:             founds=self.CDLICatalog.search({'title':splitted[1]})        
   30:             return founds[0].getObject().absolute_url()+'/'+objId
   31:         
   32:     def storeAllLink(self,results):
   33:         """erzeuge link zum speicher aller results"""
   34:         nr=self.REQUEST['_ZopeId']
   35:         
   36:         if results:
   37:             self._v_stack[nr]=[x.getObject().getId() for x in results]
   38:         
   39:         return self.absolute_url()+"/storeAll?id="+nr
   40:     
   41:     def storeAll(self,id):
   42:         """store all"""
   43:         try:
   44:             results=self._v_stack[id]
   45:         except:
   46:             #TODO: write expired page
   47:             return "expired"
   48:         
   49:         return self.storeInBasketForm(results)
   50:         
   51:     def storeInBasketForm(self,ids):
   52:         """ store an object form"""
   53:         
   54:         if type(ids) is not ListType:
   55:             ids=[ids]
   56:         self.REQUEST.SESSION['ids']=ids[0:]
   57:         
   58:         self.REQUEST.SESSION['BACKLINK']=self.REQUEST['HTTP_REFERER']
   59: 
   60:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','storeBasketObject.zpt')).__of__(self)
   61:         return pt()
   62:         
   63:     def storeInBasket(self,username,ids=None,RESPONSE=None,REQUEST=None):
   64:         """store it"""
   65:         
   66:         if not ids:
   67:             ids=REQUEST.SESSION['ids']
   68:             
   69:         self.REQUEST.SESSION['basketUser']=username
   70:         
   71:         baskets=self.ZopeFind(self,obj_ids=[username])
   72:         if len(baskets)>0:
   73:             basket=baskets[0][1]
   74:         else:
   75:             manage_addBasketObject(self,username)
   76:             basket=self._getOb(username)
   77:         
   78:         
   79:         basket.addObjects(ids)
   80:         back=self.REQUEST.SESSION.get('BACKLINK', None)
   81: 
   82:         if RESPONSE:
   83:             RESPONSE.redirect(back)
   84:             
   85: 
   86:     
   87:     def showBasket(self,user=None,set=None,RESPONSE=None):
   88:         """show the basket"""
   89:         
   90:         if user:
   91:             self.REQUEST.SESSION['basketUser']=user
   92:         
   93:         if not user and not set:
   94:             user=self.REQUEST.SESSION.get('basketUser',None)
   95:         
   96:         if not user:
   97:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','orizeBasketUser.zpt')).__of__(self)
   98:             return pt()
   99:         else:
  100:             baskets=self.ZopeFind(self,obj_ids=[user])
  101:         
  102: 
  103:         if len(baskets)>0:
  104:             RESPONSE.redirect(baskets[0][1].absolute_url())
  105:             return True 
  106:         else:
  107:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','emptyBasket.zpt')).__of__(self)
  108:             return pt()
  109:         
  110: 
  111: def manage_addBasket_oldForm(self):
  112:     """add the basket form"""
  113:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addBasket.zpt')).__of__(self)
  114:     return pt()
  115: 
  116: def manage_addBasket_old(self,id,title,RESPONSE=None):
  117:     """add the basket"""
  118:     ob=Basket()
  119:     
  120:     ob.id=str(id)
  121:     ob.title=title
  122:     self._setObject(id, ob)
  123:     ob=self._getOb(id)
  124:     
  125:     if RESPONSE is not None:
  126:         RESPONSE.redirect('manage_main')
  127: 
  128:     
  129: class BasketObject_old(Folder):
  130:     """Basket Object - alte fassung"""
  131:     
  132:     meta_type="basketObject"
  133:     def __init__(self):
  134:         	"""init basket object"""
  135:         	self.contents=[]
  136: 
  137:     def numberOfItems(self):
  138:         """return anzahl der elemente im basket"""
  139:         return len(self.contents)
  140:     
  141:     def addObjects(self,ids):
  142:         """addObjects"""
  143:         
  144:         for id in ids:
  145:             founds=self.CDLICatalog.search({'title':id})
  146:             for found in founds:
  147:                 if found.getObject() not in self.contents:
  148:                     tm=self.contents[0:]
  149:                     tm.append(found.getObject())
  150:                     self.contents=tm[0:]
  151:     
  152:         return True
  153: 
  154:     def index_html(self):
  155:         	"""view the basket"""
  156:         	pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','basketObject_index_html.zpt')).__of__(self)
  157:         	return pt()
  158: 
  159:     def deleteObjects(self,ids,RESPONSE=None):
  160:         """delete objects"""
  161:         list = self.contents[0:]
  162:         for content in list:
  163:                
  164:                 if content.getId() in ids:
  165:                     self.contents.remove(content)
  166:         
  167: 
  168:         if RESPONSE:
  169:         	    RESPONSE.redirect(self.absolute_url())
  170: 
  171: 
  172:     def unlockTest(self):
  173:         """unlock all files of the testuser for debuggin"""
  174:         for object in self.contents:
  175: 
  176:                 if str(object.lockedBy)=="test":
  177:                     object.lockedBy=""
  178:             
  179:     def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None):
  180:         """download all selected files in one file"""
  181:         
  182:         ret=""
  183:         lockedObjects={}
  184:         
  185: 
  186:         if lock:
  187:             
  188:             if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
  189:                 
  190:                 return "please login first"
  191: 
  192:             #check if a locked object exist in the basket.
  193:             lockedObjects={}
  194:             for object in self.contents:
  195: 
  196:                 if not object.lockedBy=="":
  197:                     lockedObjects[object.title]=repr(object.lockedBy)
  198:                    
  199:                     
  200:             keys=lockedObjects.keys()
  201:             
  202:             
  203:             if len(keys)>0 and (not procedure):
  204:                 self.REQUEST.SESSION['lockedObjects']=lockedObjects
  205:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)
  206:                 return pt()
  207:          
  208:             elif not procedure: #keine fails gesperrt dann alle donwloaden
  209:                 procedure="downloadAll" 
  210:         
  211:         print procedure    
  212:         for object in self.contents:
  213:             
  214:                 if (procedure=="downloadAll") or (object.lockedBy=='') or (object.lockedBy==self.REQUEST['AUTHENTICATED_USER']):
  215:                     ret+=object.getLastVersion().data
  216:                 
  217:                 if lock and object.lockedBy=='':
  218:                     object.lockedBy=self.REQUEST['AUTHENTICATED_USER']
  219: 
  220: 
  221:         self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="basket_%s.atf" """%self.getId())
  222:         self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
  223:         length=len(ret)
  224:         self.REQUEST.RESPONSE.setHeader("Content-Length",length)
  225:         self.REQUEST.RESPONSE.write(ret)    
  226:         
  227:         
  228: def manage_addBasket_oldObjectForm(self):
  229:     """add form"""
  230:     pass
  231: 
  232: def manage_addBasket_oldObject(self,id,title='',RESPONSE=None):
  233:     """add"""
  234:     
  235:     ob=BasketObject()
  236:     
  237:     ob.id=str(id)
  238:     ob.title=title
  239:     self._setObject(id, ob)
  240:     ob=self._getOb(id)
  241:     
  242:     if RESPONSE is not None:
  243:         RESPONSE.redirect('manage_main')
  244: 
  245: 
  246: class CDLIBasketContainer(OrderedFolder):
  247:     """contains the baskets"""
  248:     
  249: 
  250:     security=ClassSecurityInfo()
  251:     meta_type="CDLIBasketContainer"
  252:     
  253:     def deleteBaskets(self,ids=None):
  254:         """delete baskets, i.e. move them into trash folder"""
  255:         
  256:         
  257:         found=self.ZopeFind(self,obj_ids=['trash'])
  258:         
  259:         if len(found)<1:
  260:             manage_addFolder(self, 'trash')
  261:             trash=self._getOb('trash')
  262:         else:
  263:             trash=found[0][1]
  264:         
  265:         if type(ids) is not ListType:
  266:             ids=[ids]
  267:         cut=self.manage_cutObjects(ids)
  268:         trash.manage_pasteObjects(cut)
  269:         
  270:     def manageBaskets(self,ids,submit,REQUEST=None,RESPONSE=None):
  271:         """manage baskets, delete or copy"""
  272:         if submit=="delete":
  273:             self.deleteBaskets(ids)
  274:         
  275:        
  276:             
  277:         if RESPONSE:
  278:             RESPONSE.redirect(self.absolute_url())
  279:     def getBasketIdfromName(self,basketname):
  280:         """get id from name"""
  281: 
  282:         for basket in self.ZopeFind(self,obj_metatypes=["CDLIBasket"]):
  283:             if basket[1].title==basketname:
  284:                 return basket[0]
  285:         else:
  286:             None
  287:     
  288:     security.declareProtected('manage','uploadBasket_html')        
  289:             
  290:     def uploadBasket_html(self,basketId='0'):
  291:         """upload an atf file, html form"""
  292:         
  293: 
  294:         basketId=str(basketId)
  295:         if not basketId=='0':
  296:             basketName=getattr(self.basketContainer,basketId).title
  297:         else:
  298:             basketName=""
  299:             
  300:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasket_html.zpt')).__of__(self)
  301:         return pt(basketId=basketId,basketName=basketName)
  302:    
  303: 
  304:         
  305:     def index_html(self):
  306:         """stanadard ansicht"""
  307:         
  308: 
  309: 
  310:         ext=self.ZopeFind(self,obj_ids=["index.html"])
  311:         if ext:
  312:             return ext[0][1]()
  313:         
  314:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self)
  315:         return pt()
  316:     
  317:     def getStorageFolderRoot(self):
  318:         """root des storage folders"""
  319:         return self.cdli_main
  320:     
  321:     def __init__(self,id,title):
  322:         """ init basket container"""
  323:         self.id=id
  324:         self.title=title
  325:      
  326:      
  327:     def getBaskets(self,sortField='title'):
  328:         """get all baskets files"""
  329: 
  330:         def sortName(x,y):
  331:             return cmp(x[1].title.lower(),y[1].title.lower())
  332: 
  333:         def sortDate(x,y):
  334:             return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())
  335: 
  336:         
  337:         def sortComment(x,y):
  338: 
  339:         
  340:             
  341:              try:
  342:                 xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()
  343:              except:
  344:                 xc='ZZZZZZZZZZZZZ'.lower()
  345:              try:
  346:                 yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()
  347:              except:
  348:                 yc='ZZZZZZZZZZZZZ'.lower()
  349:     
  350:     
  351:              if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):
  352:                  
  353:                  try:
  354:                      xc=x[1].getLastVersion().getComment().lower()
  355:                  except:
  356:                      xc='ZZZZZZZZZZZZZ'.lower()
  357:                      
  358:              if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):
  359:                  try:
  360:                      yc=y[1].getLastVersion().getComment().lower()
  361:                  except:
  362:                      yc='ZZZZZZZZZZZZZ'.lower()
  363:     
  364:              
  365:                  return cmp(xc,yc)
  366:         
  367:         def sortAuthor(x,y):
  368:             
  369:             return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower())
  370:         
  371:         baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
  372:         
  373:         
  374:         if sortField=='title':
  375:             baskets.sort(sortName)
  376:         elif sortField=='date':
  377:             baskets.sort(sortDate)
  378:         elif sortField=='author':
  379:             baskets.sort(sortAuthor)
  380:         elif sortField=='comment':
  381:             baskets.sort(sortComment)
  382: 
  383:         return baskets
  384: 
  385: 
  386:                        
  387:     def getNewId(self):
  388:         """createIds"""
  389:         last=getattr(self,'last',0)
  390:         last +=1
  391:         while len(self.ZopeFind(self,obj_ids=[str(last)]))>0:
  392:             last+=1
  393:     
  394:         self.last=last
  395:         return last
  396:     
  397:     def setActiveBasket(self,basketId,REQUEST=None):
  398:         """store active basketId in a cookie"""
  399:         self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/")
  400:         
  401:         if REQUEST:
  402:             REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+REQUEST['QUERY_STRING'])
  403:             
  404:     def getActiveBasket(self):
  405:         """get active basket from cookie"""
  406:         
  407:         id= self.REQUEST.cookies.get('CDLIActiveBasket',None)
  408:         if id:
  409:             obj=getattr(self,str(id),None)
  410:         else:
  411:             obj=None
  412:         return obj
  413:     
  414:     def getActualUserName(self):
  415:         """get name of the actualuser"""
  416:         return str(self.REQUEST['AUTHENTICATED_USER'])
  417:     
  418:     
  419:     def addBasket(self,newBasketName):
  420:         """add a new basket"""
  421:         
  422:         ob=manage_addCDLIBasket(self,newBasketName)
  423:         return ob
  424:     
  425:     def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None):
  426:         """store it"""
  427:         if not ids:
  428:             ids=self.REQUEST.SESSION['fileIds']
  429:             
  430:         if type(ids) is not ListType:
  431:             ids=[ids]
  432:         
  433:         if (submit.lower()=="store in new basket") or (submit.lower()=="new basket"):
  434:             basketRet=self.addBasket(newBasketName)
  435:             self.setActiveBasket(basketRet.getId())
  436:             basket=getattr(self,basketRet.getId())
  437:         elif (submit.lower()=="store in active basket") or (submit.lower()=="active basket"):
  438:             basket=self.getActiveBasket()
  439:         
  440:         added=basket.addObjects(ids)
  441:         back=self.REQUEST['HTTP_REFERER'].split("?")[0]+"?basketName="+basket.title+"&numberOfObjects="+str(added)
  442:         
  443:         
  444:         if fromFileList:
  445: 
  446:             return self.cdli_main.findObjectsFromList(list=self.REQUEST.SESSION['fileIds'],basketName=basket.title,numberOfObjects=added)
  447:        
  448:         if RESPONSE:
  449:             
  450:             RESPONSE.redirect(back)
  451:             
  452:         return True
  453:     
  454: def manage_addCDLIBasketContainerForm(self):
  455:     """add the CDLIBasketContainer form"""
  456:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self)
  457:     return pt()
  458: 
  459: def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None):
  460:     """add the basket"""
  461:     ob=CDLIBasketContainer(id,title)
  462:     
  463:     self._setObject(id, ob)
  464:     
  465:     if RESPONSE is not None:
  466:         RESPONSE.redirect('manage_main')
  467: 
  468: class CDLIBasket(Folder,CatalogAware):
  469:     """basket"""
  470:     
  471:     meta_type="CDLIBasket"
  472:     default_catalog="CDLIBasketCatalog"
  473:     
  474:     def getFile(self,obj):
  475:         return obj[1]
  476:     
  477:     def getFileLastVersion(self,obj):
  478:         return obj[0]
  479:     
  480:     def getFileNamesInLastVersion(self):
  481:         """get content of the last version as list"""
  482:         
  483:         return [x[1].getId() for x in self.getLastVersion().getContent()]
  484:     
  485:     def isActual(self,obj):
  486:         """teste ob im basket die aktuelle version ist"""
  487:         actualNo=obj[1].getLastVersion().getVersionNumber()
  488:         storedNo=obj[0].getVersionNumber()
  489:         
  490:         founds=self.CDLICatalog.search({'title':obj[0].getId()})
  491:         if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash":
  492:             return False, -1
  493:         
  494:         if actualNo==storedNo:
  495:             return True , 0
  496:         else:
  497:             return False, actualNo
  498:         
  499:     def history(self):
  500:         """history"""  
  501: 
  502:         ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
  503:         if ext:
  504:             return getattr(self,ext[0][1].getId())()
  505:         
  506:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self)
  507:         return pt()
  508:     
  509:     def getStorageFolderRoot(self):
  510:         """root des storage folders"""
  511:         return self.aq_parent.cdli_main
  512:     
  513:     def __init__(self,id,title,shortDescription="",comment=""):
  514:         """init a CDLIBasket"""
  515:         
  516:         self.id=id
  517:         self.title=title
  518:         self.shortDescription=shortDescription
  519:         self.comment=comment
  520:  
  521:    
  522:            
  523:     def getLastVersion(self):
  524:         """hole letzte version"""
  525:         ids=[int(x[0]) for x in self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])]
  526:         ids.sort()
  527:         if len(ids)==0:
  528:             return None
  529:         else:    
  530:             ob=getattr(self,str(ids[-1]))
  531:             return ob
  532:    
  533:     def getVersions(self):
  534:         """get versions"""
  535:         versions=self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])
  536:         return versions
  537: 
  538:    
  539:     
  540:     def addObjects(self,ids,deleteOld=None):
  541:         """generate a new version of the basket with objects added"""
  542:        
  543:         lastVersion=self.getLastVersion()
  544:         
  545:         if lastVersion is None:
  546:             oldContent=[]
  547:         else:
  548:             oldContent=lastVersion.basketContent[0:]
  549: 
  550:         if deleteOld:
  551:             oldContent=[]
  552: 
  553:         newContent=[]
  554:         added=0
  555:         for id in ids:
  556:             founds=self.CDLICatalog.search({'title':id})
  557: 
  558:             for found in founds:
  559:                 if found.getObject() not in oldContent:
  560:                     #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version
  561:                     newContent.append((found.getObject().getLastVersion(),found.getObject()))
  562:                     added+=1
  563: 
  564:         content=oldContent+newContent
  565:         
  566:         user=self.getActualUserName()
  567:         
  568:         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content)
  569:     
  570:         return added
  571:     
  572:     def deleteObjects(self,ids,RESPONSE=None,REQUEST=None):
  573:         """delete objects"""
  574:         
  575:         if type(ids) is not ListType:
  576:             ids=[ids]
  577:        
  578:         lastVersion=self.getLastVersion() 
  579:         oldContent=lastVersion.basketContent[0:]
  580:         newContent=[]
  581:         for obj in oldContent:
  582:             if obj[1].getId() not in ids:
  583:                 newContent.append(obj)
  584:         
  585:                 
  586:         user=self.getActualUserName()
  587:         
  588:         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
  589:         
  590:         if RESPONSE:
  591:             obj=self._getOb(ob.getId())
  592:             RESPONSE.redirect(obj.absolute_url())
  593:         
  594: def manage_addCDLIBasketForm(self):
  595:     """add the CDLIBasketContainer form"""
  596:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasket.zpt')).__of__(self)
  597:     return pt()
  598: 
  599: def manage_addCDLIBasket(self,title,shortDescription="",comment="",RESPONSE=None):
  600:     """add the basket"""
  601:     
  602:     id=str(self.getNewId())
  603:     
  604:     ob=CDLIBasket(id,title,shortDescription,comment)
  605:     
  606:     self._setObject(id, ob)
  607:     
  608:     if RESPONSE is not None:
  609:         RESPONSE.redirect('manage_main')
  610:     else:
  611:         return ob
  612: 
  613: class CDLIBasketVersion(SimpleItem):
  614:     """version of a basket"""
  615:     
  616:     meta_type="CDLIBasketVersion"
  617:     
  618:     def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None):
  619:         """download all selected files in one file"""
  620:         
  621:         ret=""
  622:         lockedObjects={}
  623:         
  624: 
  625:         if lock:
  626:             
  627:             if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
  628:                 
  629:                 return "please login first"
  630: 
  631:             #check if a locked object exist in the basket.
  632:             lockedObjects={}
  633:             for object in self.basketContent:
  634: 
  635:                 if not object[1].lockedBy=="":
  636:                     lockedObjects[object[1].title]=repr(object[1].lockedBy)
  637:                    
  638:                     
  639:             keys=lockedObjects.keys()
  640:             
  641:             
  642:             if len(keys)>0 and (not procedure):
  643:                 self.REQUEST.SESSION['lockedObjects']=lockedObjects
  644:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)
  645:                 return pt()
  646:          
  647:             elif not procedure: #keine fails gesperrt dann alle donwloaden
  648:                 procedure="downloadAll" 
  649:         
  650: 
  651:         for object in self.basketContent:
  652:             
  653:                 if (procedure=="downloadAll") or (object[1].lockedBy=='') or (object[1].lockedBy==self.REQUEST['AUTHENTICATED_USER']):
  654:                     ret+=object[0].data
  655:                 
  656:                 if lock and object[1].lockedBy=='':
  657:                     object[1].lockedBy=self.REQUEST['AUTHENTICATED_USER']
  658: 
  659:         basket_name=self.aq_parent.title+"_V"+self.getId()
  660:         
  661:         #write basketname to header of atf file
  662:         ret="#atf basket %s\n"%basket_name+ret
  663:         
  664:         self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.atf" """%basket_name)
  665:         self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
  666:         length=len(ret)
  667:         self.REQUEST.RESPONSE.setHeader("Content-Length",length)
  668:         self.REQUEST.RESPONSE.write(ret)    
  669:         
  670:  
  671:     def numberOfItems(self):
  672:         """return anzahl der elemente im basket"""
  673:         return len(self.basketContent)
  674:     
  675:     def getTime(self):
  676:         """getTime"""
  677:         #return self.bobobase_modification_time().ISO()
  678:       
  679:         if hasattr(self,'time'):
  680:             return time.strftime("%Y-%m-%d %H:%M:%S",self.time)
  681:         elif hasattr(self,'timefixed'):
  682:             return self.timefixed
  683:         else:
  684:             setattr(self,'timefixed',self.bobobase_modification_time().ISO())
  685:             return self.bobobase_modification_time().ISO()
  686:     
  687:     def getContent(self):
  688:         """get Basket Content"""
  689:         return self.basketContent
  690: 
  691:     
  692:     def __init__(self,id,user,comment="",basketContent=[]):
  693:         """ init a basket version"""
  694:         self.id=id
  695:         self.coment=comment
  696:         self.basketContent=basketContent[0:]
  697:         self.user=user
  698:         self.time=time.localtime()
  699:         
  700:     def getUser(self):
  701:         """get user"""
  702:         return self.user
  703:     
  704:     def getComment(self):
  705:         """get Comment"""
  706:         return self.comment
  707:  
  708:     def index_html(self):
  709:             """view the basket"""
  710:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketVersionMain.zpt')).__of__(self)
  711:             return pt()
  712:      
  713:     def getObjUrl(self,result):
  714:         """getUrl of the version of the object"""
  715:         objId=result[1].getTitle()
  716:         founds=self.CDLICatalog.search({'title':objId})
  717:         if len(founds)>0:
  718:              return founds[0].getObject().getLastVersion().absolute_url()
  719:          
  720:         else: #assume version number
  721:             splitted=objId.split("_")
  722:             founds=self.CDLICatalog.search({'title':splitted[1]})        
  723:             return founds[0].getObject().getLastVersion().absolute_url()+'/'+objId
  724:    
  725: def manage_addCDLIBasketVersion(self,user,comment="",basketContent=[],RESPONSE=None):
  726:     """add a version"""
  727:     
  728:     #check for already existing versions
  729:  
  730:     lastVersion=self.getLastVersion()
  731:     if lastVersion is None:
  732:         newId=str(1)
  733:     else:
  734:         newId=str(int(lastVersion.getId())+1)
  735:     
  736:     ob=CDLIBasketVersion(newId,user,comment,basketContent)
  737:     
  738:     self._setObject(newId, ob)
  739:     
  740:     if RESPONSE is not None:
  741:         RESPONSE.redirect('manage_main')
  742:     else:
  743:         return ob
  744:     
  745: class CDLIFileObject(versionedFileObject):
  746:     """CDLI file object"""
  747:     
  748:     meta_type="CDLI File Object"
  749:     
  750:     security=ClassSecurityInfo()
  751:     
  752:     def view(self):
  753:         """view file"""
  754:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','viewCDLIFile.zpt')).__of__(self)
  755:         return pt()
  756:     
  757:     security.declarePublic('getDesignation')
  758:     def getDesignation(self):
  759:         """get the designation out of the file"""
  760:         txt=re.search("&[Pp](.*)= (.*)",self.data)
  761:         
  762:         try:
  763:             return txt.group(2)
  764:         except:
  765:             return "ERROR"
  766:         
  767: manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1')
  768: 
  769: def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',precondition='', content_type='',
  770:                    REQUEST=None):
  771:     """Add a new File object.
  772: 
  773:     Creates a new File object 'id' with the contents of 'file'"""
  774: 
  775:     id=str(id)
  776:     title=str(title)
  777:     content_type=str(content_type)
  778:     precondition=str(precondition)
  779:     
  780:     id, title = cookId(id, title, file)
  781: 
  782:     self=self.this()
  783: 
  784:     # First, we create the file without data:
  785:     self._setObject(id, CDLIFileObject(id,title,'',content_type, precondition))
  786:     self._getOb(id).versionComment=str(vC)
  787:     self._getOb(id).time=time.localtime()
  788:     
  789:     setattr(self._getOb(id),'author',author)
  790:     
  791:     # Now we "upload" the data.  By doing this in two steps, we
  792:     # can use a database trick to make the upload more efficient.
  793:     if file:
  794:         self._getOb(id).manage_upload(file)
  795:     if content_type:
  796:         self._getOb(id).content_type=content_type
  797: 
  798:     if REQUEST is not None:
  799:         REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
  800:     
  801: class CDLIFile(versionedFile,CatalogAware):
  802:     """CDLI file"""
  803:     
  804:     meta_type="CDLI file"
  805:     default_catalog='CDLICatalog'
  806:     
  807:     
  808:  
  809:     def isContainedInBaskets(self,context=None):
  810:         """check is this file is part of any basket
  811:         @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog
  812:                         has to exist.
  813:         """
  814: 
  815:         if not context:
  816:             context=self
  817:         
  818:         ret=[]
  819:         for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}):
  820:             #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why?
  821:             try:
  822:                 ret.append(x.getObject())
  823:             except:
  824:                 pass
  825:         return ret
  826:         #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})]
  827:         
  828:         
  829:     def addCDLIFileObjectForm(self):
  830:         """add a new version"""
  831:         
  832:         if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]:
  833:             return "please login first"
  834:         if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''):
  835:             out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self)
  836:             return out()
  837:         else:
  838:             return "Sorry file is locked by somebody else"
  839:         
  840:     def manage_addCDLIFileObject(self,id,vC,author,file='',title='',precondition='', content_type='',changeName='no',newName='', RESPONSE=None):
  841:         """add"""
  842:         try: #TODO: der ganze vC unsinn muss ueberarbeitet werden
  843:             vC=self.REQUEST['vC']
  844:         except:
  845:             pass
  846:         
  847:         
  848:         if changeName=="yes":
  849:             filename=file.filename
  850:             self.title=filename[max(filename.rfind('/'),
  851:                         filename.rfind('\\'),
  852:                         filename.rfind(':'),
  853:                         )+1:]
  854: 
  855: 
  856:         if not newName=='':
  857:             self.title=newName[0:]
  858:         
  859:         
  860: 
  861:         
  862:         
  863:         positionVersionNum=getattr(self,'positionVersionNum','front')
  864:         
  865:         if positionVersionNum=='front':
  866:             id="V%i"%self.getVersion()+"_"+self.title
  867:         else:
  868:             tmp=os.path.splitext(self.title)
  869:             if len(tmp)>1:
  870:                 id=tmp[0]+"_V%i"%self.getVersion()+tmp[1]
  871:             else:
  872:                 id=tmp[0]+"_V%i"%self.getVersion()
  873:             
  874:         
  875:         manage_addCDLIFileObject(self,id,vC,author,file,id,precondition, content_type)
  876:         objs=self.ZopeFind(self,obj_ids=[id])[0][1].setVersionNumber(int(self.getVersion()))
  877:         self.REQUEST.SESSION['objID_parent']=self.getId()
  878: 
  879:         if RESPONSE:
  880:             obj=self.ZopeFind(self,obj_ids=[id])[0][1]
  881:             if obj.getSize()==0:
  882:                 self.REQUEST.SESSION['objID']=obj.getId()
  883:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)
  884:                 return pt()
  885: 
  886:             else:
  887:                 RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title)
  888: 
  889:         else:
  890:             return self.ZopeFind(self,obj_ids=[id])[0][1]
  891:         
  892:         
  893: def manage_addCDLIFileForm(self):
  894:     """interface for adding the OSAS_root"""
  895:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self)
  896:     return pt()
  897: 
  898: def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None):
  899:     """add the OSAS_root"""
  900:     newObj=CDLIFile(id,title,lockedBy,author)
  901:     self._setObject(id,newObj)
  902:    
  903:     if RESPONSE is not None:
  904:         RESPONSE.redirect('manage_main')
  905: 
  906: 
  907: 
  908: 
  909: def splitatf(fh,dir=None):
  910:     """split it"""
  911:     ret=None
  912:     nf=None
  913:     for line in fh.readlines():
  914:         #check if basket name is in the first line
  915:         if line.find("#atf basket")>=0:
  916:             ret=line.replace('#atf basket ','')
  917:             ret=ret.split('_')[0]
  918:         else:
  919:             if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile
  920:                 if nf:
  921:                     nf.close() #close last file
  922:             
  923:                 
  924:                 filename=line[1:].split("=")[0].rstrip()+".atf"
  925:                 if dir:
  926:                     filename=os.path.join(dir,filename)
  927:                 nf=file(filename,"w")
  928:             if nf:    
  929:                 nf.write(line)
  930:         
  931:     nf.close()
  932:     fh.close()
  933:     return ret,len(os.listdir(dir))
  934: 
  935: class CDLIFileFolder(versionedFileFolder):
  936:     """CDLI File Folder"""
  937:     
  938:     meta_type="CDLI Folder"
  939:     filesMetaType=['CDLI file']
  940:     folderMetaType=['CDLI Folder']
  941:     default_catalog='CDLICatalog'
  942:     
  943:     def delete(self,ids):
  944:         """delete this file, i.e. move into a trash folder"""
  945:              
  946:         found=self.ZopeFind(self,obj_ids=['.trash'])
  947:         
  948:         if len(found)<1:
  949:             manage_addCDLIFileFolder(self, '.trash',title="Trash")
  950:             trash=self._getOb('.trash')
  951:         else:
  952:             trash=found[0][1]
  953:         
  954:         if type(ids) is not ListType:
  955:             ids=[ids]
  956:         cut=self.manage_cutObjects(ids)
  957:         trash.manage_pasteObjects(cut)
  958:         
  959:     def getVersionNumbersFromIds(self,ids):
  960:         """get the numbers of the current versions of documents described by their ids"""
  961:         
  962:         ret=[]
  963:         searchStr=" OR ".join(ids)
  964:         
  965:         founds=self.CDLICatalog.search({'title':searchStr})
  966:         
  967:         for found in founds:
  968:             lastVersion=found.getObject().getLastVersion()
  969:             ret.append((found.getId,lastVersion))
  970:         
  971:         return ret
  972:     
  973:  
  974:     def uploadATF(self,upload,basketId=0,RESPONSE=None):
  975:         """upload an atf file"""
  976:         #TODO: add comments
  977:         #TODO: finish uploadATF
  978:         basketId=str(basketId)
  979:         
  980:         
  981:         
  982:         dir=mkdtemp()
  983:         changed=[]
  984:         errors=[]
  985:         newPs=[]
  986:         basketNameFromFile, numberOfFiles=splitatf(upload,dir)
  987:         
  988:         if basketId == '0':
  989:             basketObj=self.basketContainer.getActiveBasket()
  990:             if basketObj:
  991:                 basketId=basketObj.getId()
  992:                 
  993:         if basketId == '0':
  994:             basketNameFromId=""
  995:             basketLen=0
  996:         else:
  997:             basketNameFromId=getattr(self.basketContainer,basketId).title
  998:             basketLen=getattr(self.basketContainer,basketId).getLastVersion().numberOfItems()
  999:             
 1000:             
 1001:         for fn in os.listdir(dir):
 1002:             founds=self.CDLICatalog.search({'title':fn})    
 1003:       
 1004:             if len(founds)==0:
 1005:                 newPs.append(fn)
 1006:                 
 1007:             for found in founds:
 1008:                 obj=found.getObject()
 1009:        
 1010:                 if (not obj.lockedBy=='') and (not obj.lockedBy==self.REQUEST['AUTHENTICATED_USER']):
 1011:                     errors.append(obj)
 1012:                 else:
 1013:                     data=file(os.path.join(dir,fn)).read()
 1014:                     diffs=obj.diff(data)
 1015:                     if diffs[0]>0:
 1016:                         changed.append((obj,diffs))
 1017:                         #hochladen
 1018:         
 1019:         self.REQUEST.SESSION['changed']=[x[0].getId() for x in changed]
 1020:         self.REQUEST.SESSION['errors']=[x.getId() for x in errors]
 1021:         self.REQUEST.SESSION['newPs']=newPs
 1022:         self.REQUEST.SESSION['tmpdir']=dir
 1023:       
 1024:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
 1025:         return pt(changed=changed,errors=errors,dir=dir,newPs=newPs,basketLen=basketLen,numberOfFiles=numberOfFiles,
 1026:                    basketNameFromId=basketNameFromId,basketNameFromFile=basketNameFromFile,basketId=basketId)
 1027:                     
 1028:     def uploadATFfinally(self,procedure,comment="",basketname='',unlock=None,RESPONSE=None):
 1029:         """upload the files"""
 1030:         
 1031:         if procedure=="uploadchanged":
 1032:             uploadFns=self.REQUEST.SESSION['changed']+self.REQUEST.SESSION['newPs']
 1033:         
 1034:         elif procedure=="uploadAll":
 1035:             uploadFns=[]
 1036:             for x in os.listdir(self.REQUEST.SESSION['tmpdir']):
 1037:                 if not x in self.REQUEST.SESSION['errors']:
 1038:                     uploadFns.append(x)
 1039:         else:
 1040:             uploadFns=[]
 1041:             
 1042:         for fn in uploadFns:
 1043:             founds=self.CDLICatalog.search({'title':fn})
 1044:             if len(founds)>0:
 1045:                 self.REQUEST.SESSION['author']=str(self.REQUEST['AUTHENTICATED_USER'])
 1046: 
 1047:                 founds[0].getObject().manage_addCDLIFileObject('',comment,self.REQUEST.SESSION['author'],file=file(os.path.join(self.REQUEST.SESSION['tmpdir'],fn)))
 1048:             
 1049:         
 1050:                 
 1051:         newPs=self.REQUEST.SESSION['newPs']
 1052:         if len(newPs)>0:
 1053:             tmpDir=self.REQUEST.SESSION['tmpdir']
 1054:         
 1055:             self.cdli_main.importFiles(comment=comment,author=str(self.REQUEST['AUTHENTICATED_USER']) ,folderName=tmpDir, files=newPs)
 1056:                 
 1057:         
 1058:         
 1059:         #unlock
 1060:         if unlock:
 1061:             unlockFns=[]
 1062:             for x in os.listdir(self.REQUEST.SESSION['tmpdir']):
 1063:                     if not x in self.REQUEST.SESSION['errors']:
 1064:                         unlockFns.append(x)
 1065:             
 1066:             for fn in unlockFns:
 1067:                 founds=self.CDLICatalog.search({'title':fn})
 1068:                 if len(founds)>0:
 1069:                     self.REQUEST.SESSION['author']=str(self.REQUEST['AUTHENTICATED_USER'])
 1070:                    
 1071:                     founds[0].getObject().lockedBy=""
 1072:                     
 1073:         if not (basketname ==''):
 1074:             basketId=self.basketContainer.getBasketIdfromName(basketname)
 1075:             
 1076:             if not basketId: # create new basket
 1077:                 ob=self.basketContainer.addBasket(basketname)
 1078:                 basketId=ob.getId()
 1079:             basket=getattr(self.basketContainer,str(basketId))
 1080:             ids=os.listdir(self.REQUEST.SESSION['tmpdir'])
 1081:             basket.addObjects(ids,deleteOld=True)    
 1082:                 
 1083:         if RESPONSE is not None:
 1084:             RESPONSE.redirect(self.aq_parent.absolute_url())
 1085:         
 1086: 
 1087:     def findObjectsFromList(self,start=None,upload=None,list=None,basketName=None,numberOfObjects=None,RESPONSE=None):
 1088:         """findObjectsFromList (, TAB oder LINE separated)"""
 1089:         if upload: # list from file upload
 1090:             txt=upload.read()
 1091:             txt=txt.replace(",","\n")
 1092:             txt=txt.replace("\t","\n")
 1093:             txt=txt.replace("\r","\n")
 1094:             idsTmp=txt.split("\n")
 1095:             ids=[]
 1096:             for id in idsTmp: # make sure that no empty lines
 1097:                 idTmp=id.lstrip().rstrip()
 1098:                 if len(idTmp)>0:
 1099:                     
 1100:                     ids.append(idTmp)
 1101:                     
 1102:             #self.REQUEST.SESSION['ids']=" OR ".join(ids)
 1103: 
 1104:             pt=getattr(self,'filelist.html')
 1105:             self.REQUEST.SESSION['searchList']=ids
 1106:             return pt(search=ids)
 1107:         
 1108:         if basketName:
 1109:             #TODO: get rid of one of these..
 1110:             
 1111:             pt=getattr(self,'filelist.html')
 1112:             return pt(basketName=basketName,numberOfObjects=numberOfObjects)
 1113:         
 1114:         if list: # got already a list
 1115:             ret=[]
 1116:             for fileId in list:
 1117:                 if len(fileId.split("."))==1:
 1118:                         fileId=fileId+".atf"
 1119: 
 1120:                 ret+=self.CDLICatalog({'title':fileId})
 1121:             #TODO: get rid of one of these..
 1122:             self.REQUEST.SESSION['fileIds']=[x.getObject().getId() for x in ret]#store fieldIds in session for further usage
 1123:             self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
 1124:             return ret
 1125:         
 1126:         if start:
 1127:             RESPONSE.redirect("filelist.html?start:int="+str(start))
 1128:     
 1129:     def createAllFilesAsSingleFile(self,RESPONSE=None):
 1130:         """download all files"""
 1131:         
 1132:         def sortF(x,y):
 1133:             return cmp(x[0],y[0])
 1134:         
 1135:         catalog=getattr(self,self.default_catalog)
 1136:         #tf,tfilename=mkstemp()
 1137:         
 1138:         
 1139:         list=[(x.getId,x) for x in catalog()]
 1140:         list.sort(sortF)
 1141:         
 1142:         RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf")
 1143:         RESPONSE.setHeader("Content-Type","application/octet-stream")
 1144:        
 1145:         for l in list:
 1146:             obj=l[1].getObject()
 1147:             
 1148:             if obj.meta_type=="CDLI file":
 1149:                 
 1150:                 #os.write(tf,obj.getLastVersion().data)
 1151:                 if RESPONSE:
 1152:                     RESPONSE.write(obj.getLastVersion().data)
 1153:         #os.close(tf)
 1154:         #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename)
 1155:         return True
 1156:     
 1157:     def downloadFile(self,fn):
 1158:         """download fn - not used yet"""
 1159:         self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId())
 1160:         self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
 1161:         self.REQUEST.RESPONSE.write(file(fn).read())
 1162:         
 1163:       
 1164:                 
 1165:     def hasParent(self):
 1166:         """returns true falls subfolder"""
 1167:       
 1168:         if self.aq_parent.meta_type in self.folderMetaType:
 1169:             return True
 1170:         else:
 1171:             return False
 1172:         
 1173:     def getFolders(self):
 1174:         """get all subfolders"""
 1175:         ret=[]
 1176:         folders=self.ZopeFind(self,obj_metatypes=self.folderMetaType)
 1177:         for folder in folders:
 1178:             ret.append((folder[1],
 1179:                         len(self.ZopeFind(folder[1],obj_metatypes=self.folderMetaType)),
 1180:                         len(self.ZopeFind(folder[1],obj_metatypes=self.filesMetaType))
 1181:                         ))
 1182:         return ret
 1183:     
 1184:             
 1185:     def getFolders_OLD(self):
 1186:         """get all subfolders"""
 1187:         ret=[]
 1188:         folders=self.ZopeFind(self,obj_metatypes=self.folderMetaType)
 1189:         for folder in folders:
 1190:             ret.append((folder[1],
 1191:                         len(self.ZopeFind(folder[1],obj_metatypes=self.folderMetaType)),
 1192:                         len(getattr(self,self.default_catalog)({'path':folder[0]}))
 1193:                         ))
 1194:         return ret
 1195:     
 1196:     def index_html(self):
 1197:         """main"""
 1198:         ext=self.ZopeFind(self,obj_ids=["index.html"])
 1199:         if ext:
 1200:             return ext[0][1]()
 1201:         
 1202:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self)
 1203:         return pt()
 1204:     
 1205:     def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/Documents/workspace/cdli/atf", files=None):
 1206:         """import files"""
 1207:         
 1208:         if not files:
 1209:             files=os.listdir(folderName)
 1210:             
 1211:         for f in files:
 1212:             folder=f[0:3]
 1213:             f2=f[0:5]
 1214:             obj=self.ZopeFind(self,obj_ids=[folder])
 1215:             
 1216:             if not obj:
 1217:                 manage_addCDLIFileFolder(self,folder,folder)
 1218:                 fobj=getattr(self,folder)
 1219:         
 1220:             else:
 1221:                 fobj=obj[0][1]
 1222:             
 1223:             obj2=fobj.ZopeFind(fobj,obj_ids=[f2])
 1224:         
 1225:             if not obj2:
 1226:                 manage_addCDLIFileFolder(fobj,f2,f2)
 1227:                 fobj2=getattr(fobj,f2)
 1228:         
 1229:             else:
 1230:                 fobj2=obj2[0][1]
 1231:               
 1232:             file2=file(os.path.join(folderName,f))   
 1233:             id=f
 1234:             manage_addCDLIFile(fobj2,f,'','')
 1235:             id=f
 1236:             ob=fobj2._getOb(f)
 1237:             ob.title=id
 1238:             
 1239:             manage_addCDLIFileObject(ob,id,comment,author,file2,content_type='')
 1240:             self.CDLICatalog.catalog_object(ob)
 1241:             #self.CDLICatalog.manage_catalogFoundItems(obj_ids=[id],search_sub=1)
 1242:             #self.CDLICatalog.manage_catalogObject(self.REQUEST, self.REQUEST.RESPONSE, 'CDLICatalog', urlparse.urlparse(ob.absolute_url())[1])
 1243:             
 1244:         return "ok"
 1245:     
 1246: manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals())
 1247: 
 1248:     
 1249: def manage_addCDLIFileFolder(self, id, title='',
 1250:                      createPublic=0,
 1251:                      createUserF=0,
 1252:                      REQUEST=None):
 1253:     """Add a new Folder object with id *id*.
 1254: 
 1255:     If the 'createPublic' and 'createUserF' parameters are set to any true
 1256:     value, an 'index_html' and a 'UserFolder' objects are created respectively
 1257:     in the new folder.
 1258:     """
 1259:     ob=CDLIFileFolder()
 1260:     ob.id=str(id)
 1261:     ob.title=title
 1262:     self._setObject(id, ob)
 1263:     ob=self._getOb(id)
 1264: 
 1265:     checkPermission=getSecurityManager().checkPermission
 1266: 
 1267:     if createUserF:
 1268:         if not checkPermission('Add User Folders', ob):
 1269:             raise Unauthorized, (
 1270:                   'You are not authorized to add User Folders.'
 1271:                   )
 1272:         ob.manage_addUserFolder()
 1273: 
 1274:   
 1275:     if REQUEST is not None:
 1276:         return self.manage_main(self, REQUEST, update_menu=1)
 1277: 
 1278: 

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