Diff for /cdli/cdli_files.py between versions 1.21 and 1.115

version 1.21, 2006/06/13 20:59:56 version 1.115, 2010/03/19 14:01:41
Line 1 Line 1
 """CDLI extensions of the filearchive"""  """CDLI extensions of the filearchive"""
 from Products.versionedFile.versionedFile import *  from Products.versionedFile.extVersionedFile import *
 from Products.ZCatalog.CatalogPathAwareness import CatalogAware  from Products.ZCatalog.CatalogPathAwareness import CatalogAware
 from tempfile import mkstemp,mkdtemp  
 import os.path  import os.path
 import os  import os
 from types import *  
 import urlparse  import urlparse
   import urllib
   import cgi
 from OFS.OrderedFolder import OrderedFolder  from OFS.OrderedFolder import OrderedFolder
 from OFS.SimpleItem import SimpleItem  from OFS.SimpleItem import SimpleItem
 import time  import time
Line 13  from OFS.Folder import manage_addFolder Line 13  from OFS.Folder import manage_addFolder
 import re  import re
 from AccessControl import ClassSecurityInfo  from AccessControl import ClassSecurityInfo
 from Acquisition import Implicit  from Acquisition import Implicit
   from Globals import Persistent
 from threading import Thread  from threading import Thread
 from ZPublisher.HTTPRequest import HTTPRequest  from ZPublisher.HTTPRequest import HTTPRequest
 from ZPublisher.HTTPResponse import HTTPResponse  from ZPublisher.HTTPResponse import HTTPResponse
 from ZPublisher.BaseRequest import RequestContainer  from ZPublisher.BaseRequest import RequestContainer
 import threading  import threading
 global tmpVar  import logging
   import transaction
 class uploadATFfinallyThread(Thread):  import copy
     """class for adding uploaded filed (temporarily stored in the staging area at /tmp"""  import codecs
       import sys
     def __init__(self):  from BTrees.IOBTree import IOBTree 
         """init for uploadATFfinallyThread"""  from BTrees.OOBTree import OOBTree 
         self.continueVar=True  import cdliSplitter
         self.returnValue=None  from sets import Set
         self.end=False  import md5
         Thread.__init__(self)  from DownloadBasket import DownloadBasketFinallyThread
              from types import *
     def set(self,procedure,comment="",basketname='',unlock=None,SESSION=None,username=None,serverport="8080"):  import pickle
         """set start values for the thread"""  import tempfile
         self.procedure=procedure  
         self.comment=comment  
         self.basketname=basketname  
         self.unlock=unlock  
         self.SESSION=SESSION  
         self.username=username  
         self.serverport=serverport  
           
     def __call__(self):  
         """call of the thread (equals run)"""  
         self.run()  
         return True  
       
     def getContext(self, app,serverport="8080"):  
         """get the context within the ZODB"""  
                   
         resp = HTTPResponse(stdout=None)  from cdli_helpers import *
         env = {  
             'SERVER_NAME':'localhost',  
             'SERVER_PORT':serverport,  
             'REQUEST_METHOD':'GET'  
             }  
         req = HTTPRequest(None, env, resp)  
         return app.__of__(RequestContainer(REQUEST = req))  
             
       
     def run(self):  
         """run"""  
           
         self.result=""  
         #find context within ZODB  
         from Zope import DB  
         conn = DB.open()  
         root = conn.root()  
         app  = root['Application']  
         ctx = self.getContext(app,serverport=self.serverport)  
   
         #add the files  
         self.uploadATFfinallyThread(ctx,self.procedure,comment=self.comment,basketname=self.basketname,unlock=self.unlock,SESSION=self.SESSION,username=self.username)  
         #commit the transactions  
         get_transaction().commit()  
         conn.close()  
         #set flag for end of this method  
         self.end=True  
         return True  
           
     def getResult(self):  class CDLIFileObject(CatalogAware,extVersionedFileObject):
         """method for accessing result"""      """CDLI file object"""
                   
         return self.result      meta_type="CDLI File Object"
       default_catalog='CDLIObjectsCatalog'
             
     def uploadATFfinallyThread(self,ctx,procedure,comment="",basketname='',unlock=None,RESPONSE=None,SESSION=None,username=None):      security=ClassSecurityInfo()
         """upload the files"""  
         #TODO: make this configurable, at the moment, rootFolder for cdli has to be cdliRoot  
         ctx2=ctx.cdliRoot  
         
         self.result+="<h2>Start processing</h2>"      security.declareProtected('manage','index_html')
                   
         #shall I only upload the changed files?      security.declarePublic('view')
         if procedure=="uploadchanged":      view = PageTemplateFile('zpt/viewCDLIFile.zpt', globals())
               
             uploadFns=SESSION.get('changed',[])+SESSION.get('newPs',[])      security.declarePublic('editATF')
       editATF = PageTemplateFile('zpt/editATFFile.zpt', globals())
                   
         #or all      def PrincipiaSearchSource(self):
         elif procedure=="uploadAll":             """Return cataloguable key for ourselves."""
             uploadFns=[]             return str(self)
             for x in os.listdir(SESSION['tmpdir']):  
                 if not x in SESSION['errors']:  
                     uploadFns.append(x)  
                                           
         #or maybe nothing      def setAuthor(self, author):
         elif procedure=="noupload":          """change the author"""
                         return True          self.author = author
         else:  
             uploadFns=[]  
               
         #do first the changed files      
         for fn in uploadFns:  
             founds=ctx2.CDLICatalog.search({'title':fn})  
             if len(founds)>0:  
                 SESSION['author']=str(username)  
                 self.result+="<p>Changing : %s"%fn  
                 founds[0].getObject().manage_addCDLIFileObject('',comment,SESSION['author'],file=file(os.path.join(SESSION['tmpdir'],fn)))  
               
           
         #now add the new files          
         newPs=SESSION['newPs']  
         if len(newPs)>0:  
             tmpDir=SESSION['tmpdir']  
             self.result+="<p>Adding files</p>"  
             #TODO: make this configurable, at the moment base folder for the files has to be cdli_main  
             ctx2.cdli_main.importFiles(comment=comment,author=str(username) ,folderName=tmpDir, files=newPs,ext=self)  
                                   
       def makeThisVersionCurrent_html(self):
           """form for mthis version current"""
                   
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','makeThisVersionCurrent.zpt')).__of__(self)
           return pt()                 
                   
         #unlock locked files?      security.declarePublic('makeThisVersionCurrent')
         if unlock:      def makeThisVersionCurrent(self,comment,author,RESPONSE=None):
             self.result+="<p>Unlock files</p>"          """copy this version to current"""
             unlockFns=[]          parent=self.aq_parent
             for x in os.listdir(SESSION['tmpdir']):          parent.manage_addVersionedFileObject(id=None,vC=comment,author=author,file=self.getData(),RESPONSE=RESPONSE)
                     if not x in SESSION['errors']:          #newversion=parent.manage_addCDLIFileObject('',comment,author)
                         unlockFns.append(x)          #newversion.manage_upload(self.getData())
               
             for fn in unlockFns:  
                 founds=ctx2.CDLICatalog.search({'title':fn})  
                 if len(founds)>0:  
                     SESSION['author']=str(username)  
                      
                     founds[0].getObject().lockedBy=""  
                       
         #if a basketname is give, add files to the basket  
         if not (basketname ==''):  
             self.result+="<p>Add basket</p>"  
             basketId=ctx2.basketContainer.getBasketIdfromName(basketname)  
               
             if not basketId: # create new basket  
                 ob=ctx2.basketContainer.addBasket(basketname)  
                 basketId=ob.getId()  
             basket=getattr(ctx2.basketContainer,str(basketId))  
             ids=os.listdir(SESSION['tmpdir'])  
             basket.addObjects(ids,deleteOld=True,username=str(username))      
                                 
         if RESPONSE is not None:          #if RESPONSE is not None:
             RESPONSE.redirect(self.aq_parent.absolute_url())          #    RESPONSE.redirect(self.aq_parent.absolute_url()+'/history')
                   
           return True
   
       def getFormattedData(self):
           """fromat text"""
           data=self.getData()
   #        return re.sub("\s\#lem"," #lem",data) #remove return vor #lem
           return re.sub("#lem","       #lem",data) #remove return vor #lem
                 
         return True  
           
 class uploadATFThread(Thread):      security.declarePublic('getPNumber')
     """class for checking the files befor uploading"""      def getPNumber(self):
           """get the pnumber"""
           try:
                   txt=re.match("&[PpSs](\d*)\s*=([^\r\n]*)",self.getData()[0:])
           except:
                   txt=self.getData()[0:]
           
     def __init__(self):                  return "ERROR"
         """initialise"""          try:
               return "P"+txt.group(1)
           except:
               return "ERROR"
                   
         self.continueVar=True      security.declarePublic('getDesignation')
         self.returnValue=None      def getDesignation(self):
           """get the designation out of the file"""
           try:
                   txt=re.match("&[PpSs](\d*)\s*=([^\r\n]*)",self.getData()[0:])
           except:
                   txt=self.getData()[0:]
                   
         Thread.__init__(self)                  return "ERROR"
           try:
               return txt.group(2)
           except:
               return "ERROR"
                   
                   
     def set(self,upload,basketId,username,serverport="8080"):  manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1')
         """set start values for the thread"""  
         self.result=""  
         self.upload=upload  
         self.basketId=basketId  
         self.username=username  
         self.serverport=serverport  
                   
     def __call__(self):  def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',versionNumber=0,
         """call method """                               precondition='', content_type='',
         self.run()                               from_tmp=False,REQUEST=None):
         return True      """Add a new File object.
       Creates a new File object 'id' with the contents of 'file'"""
           
     def getContext(self, app,serverport="8080"):      id=str(id)
         """get the context within the ZODB"""      title=str(title)
         resp = HTTPResponse(stdout=None)      content_type=str(content_type)
         env = {      precondition=str(precondition)
             'SERVER_NAME':'localhost',  
             'SERVER_PORT':serverport,  
             'REQUEST_METHOD':'GET'  
             }  
         req = HTTPRequest(None, env, resp)  
         return app.__of__(RequestContainer(REQUEST = req))  
           
     def run(self):  
        
         self.result=""  
         #find context within ZODB  
         from Zope import DB  
         conn = DB.open()  
         root = conn.root()  
         app  = root['Application']  
         ctx = self.getContext(app,serverport=self.serverport)  
         self.uploadATFThread(ctx,self.upload,self.basketId)  
                   
         while self.continueVar:      id, title = cookId(id, title, file)
             pass  
         get_transaction().abort()  
         conn.close()  
         print "done"  
                   
     def getResult(self):      self=self.this()
         """method for accessing result"""  
         return self.result  
           
     def uploadATFThread(self,ctx,upload,basketId=0):      # First, we create the file without data:
         """upload an atf file"""      self._setObject(id, CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=vC,time=time.localtime(),author=author))
         #TODO: add comments      fob = self._getOb(id)
         #TODO: finish uploadATF  
         self.result="<html><body><h2>I am loading your file...</h2>"  
         #make sure that id is a string and not an integer  
         basketId=str(basketId)  
                   
         #TODO: make this configurable, at the moment, rootFolder for cdli has to be cdliRoot      # Now we "upload" the data.  By doing this in two steps, we
         ctx2=ctx.cdliRoot      # can use a database trick to make the upload more efficient.
                   
         #get temporary file for staging the downloaded and splitted files      if file and not from_tmp:
         dir=mkdtemp()          fob.manage_upload(file)
       elif file and from_tmp:
           fob.manage_file_upload(file) # manage_upload_from_tmp doesn't exist in ExtFile2
       #    fob.manage_upload_from_tmp(file) # manage_upload_from_tmp doesn't exist in ExtFile2
       if content_type:
           fob.content_type=content_type
                   
       #logging.debug("manage_add: lastversion=%s"%self.getData())
       logging.debug("reindex1: %s in %s"%(repr(self),repr(self.default_catalog)))
       self.reindex_object()
       #logging.debug("manage_add: fob_data=%s"%fob.getData())
       logging.debug("reindex2: %s in %s"%(repr(fob), repr(fob.default_catalog)))
       fob.index_object()
                   
         changed=[] # changed files      self.CDLIRoot.updateOrAddToFileBTree(ob)
         errors=[]  # files with errors      if REQUEST is not None:
         newPs=[]   # new p filed          REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
         psNotInCatalog=[] # files not in the catalog  
                   
         #split the uploadedd atf file  
         basketNameFromFile, numberOfFiles=splitatf(upload,dir)  
                   
         #find basketId if not set  class CDLIFile(extVersionedFile,CatalogAware):
       """CDLI file"""
                   
         #get active abaket      security=ClassSecurityInfo()
         if basketId == '0':      meta_type="CDLI file"
             basketObj=ctx2.basketContainer.getActiveBasket()      content_meta_type = ["CDLI File Object"]
             if basketObj:  
                 basketId=basketObj.getId()  
                                   
         #if there is no active baske and no basketid given, id is empty, else get besketname and length      default_catalog='CDLICatalog'
         if basketId == '0':  
             basketNameFromId=""  
             basketLen=0  
         else:  
             basketNameFromId=getattr(ctx2.basketContainer,basketId).title  
             basketLen=getattr(ctx2.basketContainer,basketId).getLastVersion().numberOfItems()  
                           
       security.declareProtected('manage','index_html')
                   
         self.result+="<html><body><h2>I got the files</h2><p>I am checking now the files</p>"      def getLastVersionData(self):
           """get last version data"""
           return self.getData()
   
       def getLastVersionFormattedData(self):
           """get last version data"""
           return self.getContentObject().getFormattedData()
   
       def getTextId(self):
           """returns P-number of text"""
           # assuming that its the beginning of the title
           return self.title[:7]
                                                                         
         #start to check the files      #security.declarePublic('history')
         for fn in os.listdir(dir):      def history(self):
           """history"""  
                           
             self.result+="<p>check:%s</p>"%fn          ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
           if ext:
               return getattr(self,ext[0][1].getId())()
                           
             # check if file is in the catalog          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','versionHistory')).__of__(self)
             #TODO: checkCatalog is not implemented yet          return pt()
             if ctx2.cdli_main.checkCatalog(fn):  
                 psNotInCatalog.append(fn)  
                                   
             #check if p-file already at the server    
             founds=ctx2.CDLICatalog.search({'title':fn})      
               
             #if not than add filename to the list of newfiles      def getBasketFromId(self,basketid, context=None):
             if len(founds)==0:          """get basket from id"""
                 newPs.append(fn)  
                           
             #if p file alread at the server              if not context:
             for found in founds:              context=self
                 #analyse the differences to the actual file  
                 obj=found.getObject()  
                 
                 if (not obj.lockedBy=='') and (not obj.lockedBy==self.username):          for basket in self.ZopeFind(context,obj_metatypes=["CDLIBasket"]):
                     errors.append(obj)              if basket[0]==basketid:
                   return basket[1]
                 else:                  else:
                     data=file(os.path.join(dir,fn)).read()              None
                     diffs=obj.diff(data)  
                     if diffs[0]>0:  
                         changed.append((obj,diffs))  
                         #hochladen  
           
         #ready, set the returnValues  
         self.result+="<h3>Done</h3></body></html>"  
           
         self.returnValue={}  
         self.returnValue['changed']=changed  
         self.returnValue['errors']=errors  
         self.returnValue['newPs']=newPs  
         self.returnValue['tmpdir']=dir  
         self.returnValue['basketLen']=basketLen  
         self.returnValue['numberOfFiles']=numberOfFiles  
         self.returnValue['basketNameFromId']=basketNameFromId  
         self.returnValue['basketNameFromFile']=basketNameFromFile  
         self.returnValue['basketId']=basketId  
         self.returnValue['dir']=dir  
           
         #ctx2.cdli_main.setTemp('v_uploadATF_returnValue',True)  
       
           
 class Basket_old(Folder):  
     """shopping basket - alte fassung """  
       
     meta_type="Basket"  
     _v_stack={}  
   
     def getObjUrl(self,objId):  
         """getUrl"""  
         founds=self.CDLICatalog.search({'title':objId})  
         if len(founds)>0:  
              return founds[0].getObject().absolute_url()  
            
         else: #assume version number  
             splitted=objId.split("_")  
             founds=self.CDLICatalog.search({'title':splitted[1]})          
             return founds[0].getObject().absolute_url()+'/'+objId  
           
     def storeAllLink(self,results):  
         """erzeuge link zum speicher aller results"""  
         nr=self.REQUEST['_ZopeId']  
                   
         if results:  
             self._v_stack[nr]=[x.getObject().getId() for x in results]  
                   
         return self.absolute_url()+"/storeAll?id="+nr      def isContainedInBaskets(self,context=None):
           """check is this file is part of any basket
           @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog
                           has to exist.
           """
   
           if not context:
               context=self
           
     def storeAll(self,id):          ret=[]
         """store all"""          for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}):
               #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why?
         try:          try:
             results=self._v_stack[id]                  ret.append(x.getObject())
         except:          except:
             #TODO: write expired page                  pass
             return "expired"          return ret
                   #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})]
         return self.storeInBasketForm(results)  
           
     def storeInBasketForm(self,ids):  
         """ store an object form"""  
           
         if type(ids) is not ListType:  
             ids=[ids]  
         self.REQUEST.SESSION['ids']=ids[0:]  
                   
         self.REQUEST.SESSION['BACKLINK']=self.REQUEST['HTTP_REFERER']  
   
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','storeBasketObject.zpt')).__of__(self)      def _newContentObject(self, id, title='', versionNumber=0, versionComment=None, time=None, author=None):
         return pt()          """factory for content objects. to be overridden in derived classes."""
           logging.debug("_newContentObject(CDLI)")
           return CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=versionComment,time=time,author=author)
                   
     def storeInBasket(self,username,ids=None,RESPONSE=None,REQUEST=None):  
         """store it"""  
                   
         if not ids:      def addCDLIFileObjectForm(self):
             ids=REQUEST.SESSION['ids']          """add a new version"""
               
         self.REQUEST.SESSION['basketUser']=username  
                   
         baskets=self.ZopeFind(self,obj_ids=[username])          if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]:
         if len(baskets)>0:              return "please login first"
             basket=baskets[0][1]          if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''):
               out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self)
               return out()
         else:          else:
             manage_addBasketObject(self,username)              return "Sorry file is locked by somebody else"
             basket=self._getOb(username)  
           
           
         basket.addObjects(ids)  
         back=self.REQUEST.SESSION.get('BACKLINK', None)  
   
         if RESPONSE:      def manage_addCDLIFileObject(self,id,vC,author,
             RESPONSE.redirect(back)                                   file='',title='',
                                    precondition='', 
                                    content_type='',
                                    changeName='no',newName='', 
                                    come_from=None,
                                    from_tmp=False,RESPONSE=None):
           """add"""
                           
           try: #TODO: der ganze vC unsinn muss ueberarbeitet werden
               vC=self.REQUEST['vC']
           except:
               pass
   
           ob = self.addContentObject(id, vC, author, file, title, changeName=changeName, newName=newName, from_tmp=from_tmp,
                                      precondition=precondition, content_type=content_type)
           
     def showBasket(self,user=None,set=None,RESPONSE=None):          try:
         """show the basket"""              #FIXME: wozu ist das gut?
               self.REQUEST.SESSION['objID_parent']=self.getId()
           except:
               pass
                   
         if user:          #self.cdliRoot.updateOrAddToFileBTree(self)# now update the object in the cache
             self.REQUEST.SESSION['basketUser']=user  
                   
         if not user and not set:  
             user=self.REQUEST.SESSION.get('basketUser',None)  
                   
         if not user:          if RESPONSE:
             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','orizeBasketUser.zpt')).__of__(self)              if ob.getSize()==0:
                   self.REQUEST.SESSION['objID']=ob.getId()
                   pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)
             return pt()              return pt()
         else:          else:
             baskets=self.ZopeFind(self,obj_ids=[user])                  if come_from and (come_from!=""):
                               RESPONSE.redirect(come_from+"?change="+self.getId())
   
         if len(baskets)>0:  
             RESPONSE.redirect(baskets[0][1].absolute_url())  
             return True   
         else:          else:
             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','emptyBasket.zpt')).__of__(self)                      RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title)
             return pt()          else:
               return ob
                   
   
 def manage_addBasket_oldForm(self):  def manage_addCDLIFileForm(self):
     """add the basket form"""      """interface for adding the OSAS_root"""
     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addBasket.zpt')).__of__(self)      pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self)
     return pt()      return pt()
   
 def manage_addBasket_old(self,id,title,RESPONSE=None):  def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None):
     """add the basket"""      """add the OSAS_root"""
     ob=Basket()      newObj=CDLIFile(id,title,lockedBy,author)
           
     ob.id=str(id)      tryToggle=True
     ob.title=title      tryCount=0
     self._setObject(id, ob)  
     ob=self._getOb(id)      self._setObject(id,newObj)                  
       getattr(self,id).reindex_object()
           
     if RESPONSE is not None:      if RESPONSE is not None:
         RESPONSE.redirect('manage_main')          RESPONSE.redirect('manage_main')
   
           
 class BasketObject_old(Folder):  def checkUTF8(data):
     """Basket Object - alte fassung"""      """check utf 8"""
           try:
     meta_type="basketObject"          data.encode('utf-8')
     def __init__(self):  
                 """init basket object"""  
                 self.contents=[]  
   
     def numberOfItems(self):  
         """return anzahl der elemente im basket"""  
         return len(self.contents)  
       
     def addObjects(self,ids):  
         """addObjects"""  
           
         for id in ids:  
             founds=self.CDLICatalog.search({'title':id})  
             for found in founds:  
                 if found.getObject() not in self.contents:  
                     tm=self.contents[0:]  
                     tm.append(found.getObject())  
                     self.contents=tm[0:]  
       
         return True          return True
       except:
           return False
   
     def index_html(self):  
                 """view the basket"""  
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','basketObject_index_html.zpt')).__of__(self)  
                 return pt()  
   
     def deleteObjects(self,ids,RESPONSE=None):  
         """delete objects"""  
         list = self.contents[0:]  
         for content in list:  
                  
                 if content.getId() in ids:  
                     self.contents.remove(content)  
           
   
         if RESPONSE:  
                     RESPONSE.redirect(self.absolute_url())  
   
   
     def unlockTest(self):  
         """unlock all files of the testuser for debuggin"""  
         for object in self.contents:  
   
                 if str(object.lockedBy)=="test":  
                     object.lockedBy=""  
               
     def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None):  
         """download all selected files in one file"""  
           
         ret=""  
         lockedObjects={}  
           
   
         if lock:  
               
             if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':  
                   
                 return "please login first"  
   
             #check if a locked object exist in the basket.  
             lockedObjects={}  
             for object in self.contents:  
   
                 if not object.lockedBy=="":  
                     lockedObjects[object.title]=repr(object.lockedBy)  
                      
                       
             keys=lockedObjects.keys()  
               
               
             if len(keys)>0 and (not procedure):  
                 self.REQUEST.SESSION['lockedObjects']=lockedObjects  
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)  
                 return pt()  
            
             elif not procedure: #keine fails gesperrt dann alle donwloaden  
                 procedure="downloadAll"   
                   
   def checkFile(filename,data,folder):
       """check the files"""
       # first check the file name
       fn=filename.split(".") # no extension
   
       if not (fn[0][0]=="P" or fn[0][0]=="S"):
           return False,"P/S missing in the filename"
       elif len(fn[0])!=7:
           return False,"P number has not the right length 6"
       elif not checkUTF8(data):
           return False,"not utf-8"
       else:
           return True,""
   
         for object in self.contents:  
                           
                 if (procedure=="downloadAll") or (object.lockedBy=='') or (object.lockedBy==self.REQUEST['AUTHENTICATED_USER']):  def splitatf(fh,dir=None,ext=None):
                     ret+=object.getLastVersion().data      """split it"""
       ret=None
       nf=None
       i=0
                                   
                 if lock and object.lockedBy=='':      #ROC: why split \n first and then \r???
                     object.lockedBy=self.REQUEST['AUTHENTICATED_USER']      if (type(fh) is StringType) or (type(fh) is UnicodeType):
           iter=fh.split("\n")
       else:
           iter=fh.readlines()
           
       for lineTmp in iter:
           lineTmp=lineTmp.replace(codecs.BOM_UTF8,'') # make sure that all BOM are removed..
           for line in lineTmp.split("\r"):
               #logging.info("Deal with: %s"%line)
               if ext:
                   i+=1
                   if (i%100)==0:
                       ext.result+="."
                   if i==10000:
                       i=0
                       ext.result+="<br>"
               #check if basket name is in the first line
               if line.find("#atf basket")>=0: #old convention
                   ret=line.replace('#atf basket ','')
                   ret=ret.split('_')[0]
               elif line.find("#basket:")>=0: #new convention
                   ret=line.replace('#basket: ','')
                   ret=ret.split('_')[0]
   
               else:
                   if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile
                       if nf:
                           nf.close() #close last file
   
         self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="basket_%s.atf" """%self.getId())  
         self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")  
         length=len(ret)  
         self.REQUEST.RESPONSE.setHeader("Content-Length",length)  
         self.REQUEST.RESPONSE.write(ret)      
                   
                       filename=line[1:].split("=")[0].rstrip()+".atf"
                       if dir:
                           filename=os.path.join(dir,filename)
                       nf=file(filename,"w")
                       logging.info("open %s"%filename)
                   if nf:    
                       nf.write(line.replace("\n","")+"\n")
                   
 def manage_addBasket_oldObjectForm(self):      try:        
     """add form"""          nf.close()
       except:
     pass      pass
   
 def manage_addBasket_oldObject(self,id,title='',RESPONSE=None):      if not((type(fh) is StringType) or (type(fh) is UnicodeType)):
     """add"""          fh.close()
           return ret,len(os.listdir(dir))
     ob=BasketObject()  
           
     ob.id=str(id)  
     ob.title=title  
     self._setObject(id, ob)  
     ob=self._getOb(id)  
       
     if RESPONSE is not None:  
         RESPONSE.redirect('manage_main')  
   
   class CDLIFileFolder(extVersionedFileFolder):
       """CDLI File Folder"""
   
 class CDLIBasketContainer(OrderedFolder):      security=ClassSecurityInfo()
     """contains the baskets"""      meta_type="CDLI Folder"
       file_meta_type=['CDLI file']
       folder_meta_type=['CDLI Folder']
           
       file_catalog='CDLICatalog'
   
     security=ClassSecurityInfo()      #downloadCounter=0 # counts how many download for all files currently run, be mehr als 5 wird verweigert.
     meta_type="CDLIBasketContainer"      tmpStore2={}
           
     def deleteBaskets(self,ids=None):      def _newVersionedFile(self, id, title='', lockedBy=None, author=None):
         """delete baskets, i.e. move them into trash folder"""          """factory for versioned files. to be overridden in derived classes."""
           logging.debug("_newVersionedFile(CDLI)")
           return CDLIFile(id, title, lockedBy=lockedBy, author=author)
                   
       def setTemp(self,name,value):
           """set tmp"""
                   
         found=self.ZopeFind(self,obj_ids=['trash'])          setattr(self,name,value)
                   
         if len(found)<1:      deleteFileForm = PageTemplateFile("zpt/doDeleteFile", globals())
             manage_addFolder(self, 'trash')  
             trash=self._getOb('trash')  
         else:  
             trash=found[0][1]  
                   
       def delete(self,ids,REQUEST=None):
           """delete these files"""
         if type(ids) is not ListType:          if type(ids) is not ListType:
             ids=[ids]              ids=[ids]
         cut=self.manage_cutObjects(ids)  
         trash.manage_pasteObjects(cut)  
                   
     def manageBaskets(self,ids,submit,REQUEST=None,RESPONSE=None):          self.manage_delObjects(ids)
         """manage baskets, delete or copy"""  
         if submit=="delete":  
             self.deleteBaskets(ids)  
                   
           if REQUEST is not None:
               return self.index_html()
                 
                           
         if RESPONSE:      def getVersionNumbersFromIds(self,ids):
             RESPONSE.redirect(self.absolute_url())          """get the numbers of the current versions of documents described by their ids"""
     def getBasketIdfromName(self,basketname):  
         """get id from name"""  
   
         for basket in self.ZopeFind(self,obj_metatypes=["CDLIBasket"]):          ret=[]
             if basket[1].title==basketname:          searchStr=" OR ".join(ids)
                 return basket[0]  
         else:  
             None  
           
     security.declareProtected('manage','uploadBasket_html')                  founds=self.CDLICatalog.search({'title':searchStr})
                           
     def uploadBasket_html(self,basketId='0'):          for found in founds:
         """upload an atf file, html form"""              lastVersion=found.getObject().getContentObject()
               ret.append((found.getId,lastVersion))
                   
           return ret
   
         basketId=str(basketId)      def getFile(self,fn):
         if not basketId=='0':          """get the content of the file fn"""
             basketName=getattr(self.basketContainer,basketId).title          logging.debug("getFile: %s"%repr(fn))
           if not self.hasObject(fn):
               # search deeper
               founds=getattr(self, self.file_catalog).search({'textid':fn})
               if founds:
                   obj=founds[0].getObject().getContentObject()
         else:          else:
             basketName=""                  return "" 
                       else:
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasket_html.zpt')).__of__(self)              obj = self[fn].getContentObject()
         return pt(basketId=basketId,basketName=basketName)  
         
           return obj.getData()[0:] 
   
                   
     def index_html(self):      def checkCatalog(self,fn):
         """stanadard ansicht"""          """check if fn is in the catalog"""
           #TODO add checkCatalog
                   
   
       def findObjectsFromListWithVersion(self,list,author=None):
           """find objects from a list with versions
           @param list: list of tuples  (cdliFile,version)
           """
           #self.REQUEST.SESSION['fileIds']=list#store fieldIds in session for further usage
           #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
   
         ext=self.ZopeFind(self,obj_ids=["index.html"])          pt=getattr(self,'filelistVersioned.html')
         if ext:  
             return ext[0][1]()  
                   
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self)          return pt(search=list,author=author)
         return pt()  
           
     def getStorageFolderRoot(self):  
         """root des storage folders"""  
         return self.cdli_main  
           
     def __init__(self,id,title):      def getAllPNumbers(self):
         """ init basket container"""          """get a list of all files (resp their p-numbers) stored"""
         self.id=id  
         self.title=title  
             
           ret=[x.getId for x in  self.CDLICatalog()]
             
     def getBaskets(self,sortField='title'):          return ret
         """get all baskets files"""  
   
         def sortName(x,y):  
             return cmp(x[1].title.lower(),y[1].title.lower())  
   
         def sortDate(x,y):      def expandFile(self,fileId,fileTree):
             return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())          """wildcard in fileID suche alle Treffer"""
           founds=self.CDLICatalog({'title':fileId})
           for found in founds:
               fileTree.add(found.getId)
               logging.debug("ADDD:"+found.getId)
   
       def findObjectsFromList(self,enterList=None,display=False,start=None,upload=None,list=None,basketName=None,numberOfObjects=None,RESPONSE=None,REQUEST=None,returnHash=False,hash=None):
           """findObjectsFromList (, TAB oder LINE separated)"""
                   
         def sortComment(x,y):          logging.debug("start: findObjectsFromList")
           #logging.debug("start: findObjectsFromList"+repr(list))
   
                   
           if upload: # list from file upload
               txt=upload.read()
                           
              try:          if enterList:
                 xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()              txt=enterList
              except:  
                 xc='ZZZZZZZZZZZZZ'.lower()  
              try:  
                 yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()  
              except:  
                 yc='ZZZZZZZZZZZZZ'.lower()  
           
           if upload or enterList:
               txt=txt.replace(",","\n")
               txt=txt.replace("\t","\n")
               txt=txt.replace("\r","\n")
               idsTmp=txt.split("\n")
               ids=[]
               for id in idsTmp: # make sure that no empty lines
                   idTmp=id.lstrip().rstrip()
                   if len(idTmp)>0:
           
              if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):                      ids.append(idTmp)
                                     
                  try:              #self.REQUEST.SESSION['ids']=" OR ".join(ids)
                      xc=x[1].getLastVersion().getComment().lower()  
                  except:  
                      xc='ZZZZZZZZZZZZZ'.lower()  
                                             
              if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):              pt=getattr(self,'filelist.html')
                  try:              self.REQUEST.SESSION['searchList']=ids
                      yc=y[1].getLastVersion().getComment().lower()              return pt(search=ids)
                  except:  
                      yc='ZZZZZZZZZZZZZ'.lower()  
           
           if basketName:
               #TODO: get rid of one of these..
                             
                  return cmp(xc,yc)              pt=getattr(self,'filelist.html')
               return pt(basketName=basketName,numberOfObjects=numberOfObjects)
                   
         def sortAuthor(x,y):  
                           
             return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower())          result =self.CDLICache.retrieve(hash)
           if result:
              logging.debug("give result from storage2")
              return hash,result
                   
         baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])          if list is not None: # got already a list
                   
               logging.debug(" ----List version")
               ret=[]
               fileTree=Set()
                   
         if sortField=='title':              for fileId in list:
             baskets.sort(sortName)  
         elif sortField=='date':  
             baskets.sort(sortDate)  
         elif sortField=='author':  
             baskets.sort(sortAuthor)  
         elif sortField=='comment':  
             baskets.sort(sortComment)  
   
         return baskets                  if fileId.find("*")>-1: #check for wildcards
                           self.expandFile(fileId,fileTree)
   
                   elif len(fileId.split("."))==1:
                           fileId=fileId+".atf"
                           fileTree.add(fileId)
                   #logging.debug("   -----:"+fileId)
                   #ret+=self.CDLICatalog({'title':fileId})
                   #x =self.getFileObject(fileId)
                   #if x is not None:
                   #    ret.append(x)
   
                                                 
     def getNewId(self):  
         """createIds"""  
         last=getattr(self,'last',0)  
         last +=1  
         while len(self.ZopeFind(self,obj_ids=[str(last)]))>0:  
             last+=1  
           
         self.last=last              ids = fileTree & self.v_file_ids
         return last              #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
               l=makelist(fileTree)[0:]
               #logging.debug("l-list:"+repr(l))
               self.REQUEST.SESSION['fileIds']=l#store fieldIds in session for further usage
               self.REQUEST.SESSION['searchList']=l
               #self.REQUEST.SESSION['searchList']=['P000001.atf']
             
               
               hash = md5.new(repr(makelist(fileTree))).hexdigest() # erzeuge hash als identification
               self.REQUEST.SESSION['hash']=hash
               #TODO: do I need garbage collection for v_tmpStore ?
               
               #logging.debug("Hash:"+repr(hash))
   #        
   #            if hasattr(self.cdliRoot,'v_tmpStore') and self.cdliRoot.v_tmpStore.has_key(hash): 
   #               logging.debug("asking for storage")
   #               res=self.cdliRoot.v_tmpStore[hash]
   #               if res:
   #                   if returnHash == True:
   #                       return hash,res
   #                   return res
           
     def setActiveBasket(self,basketId,REQUEST=None):              #TODO: get rid of one of these..
         """store active basketId in a cookie"""              #ids=[x.getObject().getId() for x in ret]
         self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/")              ret=[(self.getFileObject(x),self.getFileObjectLastVersion(x)) for x in ids]
                   
         if REQUEST:              #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
             REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+REQUEST['QUERY_STRING'])              #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
                           
     def getActiveBasket(self):              if display:
         """get active basket from cookie"""                  pt=getattr(self,'filelist.html')
                   
         id= self.REQUEST.cookies.get('CDLIActiveBasket',None)                  return pt(search=ids)
         if id:  
             obj=getattr(self,str(id),None)  
         else:          else:
             obj=None                  #self.REQUEST.SESSION['hash'] = ret # store in session 
         return obj  
       
     def getActualUserName(self):  
         """get name of the actualuser"""  
         return str(self.REQUEST['AUTHENTICATED_USER'])  
       
           
     def addBasket(self,newBasketName):                  #logging.debug("HHHHHHNEU:"+repr(self.makelist(ids)))
         """add a new basket"""                  #logging.debug("HHHHHHNEU:"+repr(hash))
                   self.CDLICache.store(hash,ret)
                   
         ob=manage_addCDLIBasket(self,newBasketName)                  if returnHash == True:
         return ob                      return hash,ret
                       return ret
     def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None):  
         """store it"""  
         if not ids:  
             ids=self.REQUEST.SESSION['fileIds']  
               
         if type(ids) is not ListType:  
             ids=[ids]  
           
         if (submit.lower()=="store in new basket") or (submit.lower()=="new basket"):  
             basketRet=self.addBasket(newBasketName)  
             self.setActiveBasket(basketRet.getId())  
             basket=getattr(self,basketRet.getId())  
         elif (submit.lower()=="store in active basket") or (submit.lower()=="active basket"):  
             basket=self.getActiveBasket()  
           
         added=basket.addObjects(ids)  
         back=self.REQUEST['HTTP_REFERER'].split("?")[0]+"?basketName="+basket.title+"&numberOfObjects="+str(added)  
                   
                   
         if fromFileList:  
   
             return self.cdli_main.findObjectsFromList(list=self.REQUEST.SESSION['fileIds'],basketName=basket.title,numberOfObjects=added)          if start:
               RESPONSE.redirect("filelist.html?start:int="+str(start))
                 
         if RESPONSE:      security.declareProtected('Manage','createAllFilesAsSingleFile')
       def createAllFilesAsSingleFile(self,RESPONSE=None):
           """download all files"""
                           
             RESPONSE.redirect(back)          def sortF(x,y):
               return cmp(x[0],y[0])
                           
         return True          catalog=getattr(self,self.file_catalog)
           #tf,tfilename=mkstemp()
           if not hasattr(self.temp_folder,'downloadCounter'):
               self.temp_folder.downloadCounter=0
           
 def manage_addCDLIBasketContainerForm(self):          if getattr(self.temp_folder,'downloadCounter',0) > 5:
     """add the CDLIBasketContainer form"""              return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self)  
     return pt()  
   
 def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None):          self.temp_folder.downloadCounter+=1
     """add the basket"""          self._p_changed=1
     ob=CDLIBasketContainer(id,title)          transaction.get().commit()
           
     self._setObject(id, ob)          list=[(x.getId,x) for x in catalog()]
           list.sort(sortF)
           
     if RESPONSE is not None:  
         RESPONSE.redirect('manage_main')  
   
 class CDLIBasket(Folder,CatalogAware):  
     """basket"""  
           
     meta_type="CDLIBasket"          RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf")
     default_catalog="CDLIBasketCatalog"          RESPONSE.setHeader("Content-Type","application/octet-stream")
           tmp=""
           for l in list:
               obj=l[1].getObject()
           
     def getFile(self,obj):              if obj.meta_type=="CDLI file":
         return obj[1]  
           
     def getFileLastVersion(self,obj):                  #os.write(tf,obj.getLastVersion().data)
         return obj[0]                  if RESPONSE:
                       RESPONSE.write(obj.getData()[0:])
                       RESPONSE.write("\n")
                   self.temp_folder.downloadCounter-=1 
                   self._p_changed=1
           transaction.get().commit()
           #os.close(tf)
           #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename)
           return True
           
     def getFileNamesInLastVersion(self):      def downloadFile(self,fn):
         """get content of the last version as list"""          """download fn - not used yet"""
           self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId())
           self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
           self.REQUEST.RESPONSE.write(file(fn).read())
                   
         return [x[1].getId() for x in self.getLastVersion().getContent()]  
           
     def isActual(self,obj):  
         """teste ob im basket die aktuelle version ist"""  
         actualNo=obj[1].getLastVersion().getVersionNumber()  
         storedNo=obj[0].getVersionNumber()  
                   
         founds=self.CDLICatalog.search({'title':obj[0].getId()})      def hasParent(self):
         if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash":          """returns true falls subfolder"""
             return False, -1  
                   
         if actualNo==storedNo:          if self.aq_parent.meta_type in self.folder_meta_type:
             return True , 0              return True
         else:          else:
             return False, actualNo              return False
                   
     def history(self):      def getFolders(self):
         """history"""            """get all subfolders"""
           ret=[]
           folders=self.ZopeFind(self,obj_metatypes=self.folder_meta_type)
           for folder in folders:
               ret.append((folder[1],
                           len(self.ZopeFind(folder[1],obj_metatypes=self.folder_meta_type)),
                           len(self.ZopeFind(folder[1],obj_metatypes=self.file_meta_type))
                           ))
           return ret
   
         ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])              
       security.declareProtected('manage','index_html')
       def index_html(self):
           """main"""
           ext=self.ZopeFind(self,obj_ids=["index.html"])
         if ext:          if ext:
             return getattr(self,ext[0][1].getId())()              return ext[0][1]()
                   
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self)          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self)
         return pt()          return pt()
           
     def getStorageFolderRoot(self):  
         """root des storage folders"""  
         return self.aq_parent.cdli_main  
       
     def __init__(self,id,title,shortDescription="",comment=""):  
         """init a CDLIBasket"""  
           
         self.id=id  
         self.title=title  
         self.shortDescription=shortDescription  
         self.comment=comment  
    
      
              
     def getLastVersion(self):  
         """hole letzte version"""  
         ids=[int(x[0]) for x in self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])]  
         ids.sort()  
         if len(ids)==0:  
             return None  
         else:      
             ob=getattr(self,str(ids[-1]))  
             return ob  
      
     def getVersions(self):  
         """get versions"""  
         versions=self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])  
         return versions  
   
      
       
     def addObjects(self,ids,deleteOld=None,username=None):  
         """generate a new version of the basket with objects added"""  
          
         lastVersion=self.getLastVersion()  
           
         if lastVersion is None:  
             oldContent=[]  
         else:  
             oldContent=lastVersion.basketContent[0:]  
   
         if deleteOld:  
             oldContent=[]  
   
         newContent=[]  
         added=0  
         for id in ids:  
             founds=self.CDLICatalog.search({'title':id})  
   
             for found in founds:  
                 if found.getObject() not in oldContent:  
                     #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version  
                     newContent.append((found.getObject().getLastVersion(),found.getObject()))  
                     added+=1  
   
         content=oldContent+newContent  
         if not username:  
             user=self.getActualUserName()  
         else:  
             user = username  
               
         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content)  
       
         return added  
       
     def deleteObjects(self,ids,RESPONSE=None,REQUEST=None):  
         """delete objects"""  
           
         if type(ids) is not ListType:  
             ids=[ids]  
          
         lastVersion=self.getLastVersion()   
         oldContent=lastVersion.basketContent[0:]  
         newContent=[]  
         for obj in oldContent:  
             if obj[1].getId() not in ids:  
                 newContent.append(obj)  
           
                   
         user=self.getActualUserName()  
           
         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)  
           
         if RESPONSE:  
             obj=self._getOb(ob.getId())  
             RESPONSE.redirect(obj.absolute_url())  
           
 def manage_addCDLIBasketForm(self):  
     """add the CDLIBasketContainer form"""  
     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasket.zpt')).__of__(self)  
     return pt()  
   
 def manage_addCDLIBasket(self,title,shortDescription="",comment="",RESPONSE=None):  manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals())
     """add the basket"""  
           
     id=str(self.getNewId())  
           
     ob=CDLIBasket(id,title,shortDescription,comment)  def manage_addCDLIFileFolder(self, id, title='',
                        createPublic=0,
                        createUserF=0,
                        REQUEST=None):
       """Add a new Folder object with id *id*.
           
       If the 'createPublic' and 'createUserF' parameters are set to any true
       value, an 'index_html' and a 'UserFolder' objects are created respectively
       in the new folder.
       """
       ob=CDLIFileFolder()
       ob.id=str(id)
       ob.title=title
     self._setObject(id, ob)      self._setObject(id, ob)
       ob=self._getOb(id)
           
     if RESPONSE is not None:      checkPermission=getSecurityManager().checkPermission
         RESPONSE.redirect('manage_main')  
     else:  
         return ob  
   
 class CDLIBasketVersion(SimpleItem):  
     """version of a basket"""  
       
     meta_type="CDLIBasketVersion"  
       
     def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None):  
         """download all selected files in one file"""  
           
         ret=""  
         lockedObjects={}  
           
   
         if lock:  
                           
             if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':      if createUserF:
           if not checkPermission('Add User Folders', ob):
               raise Unauthorized, (
                     'You are not authorized to add User Folders.'
                     )
           ob.manage_addUserFolder()
                                   
                 return "please login first"  
   
             #check if a locked object exist in the basket.      if REQUEST is not None:
             lockedObjects={}          return self.manage_main(self, REQUEST, update_menu=1)
             for object in self.basketContent:  
   
                 if not object[1].lockedBy=="":  class CDLIRoot(Folder):
                     lockedObjects[object[1].title]=repr(object[1].lockedBy)      """main folder for cdli"""
                                         
       meta_type="CDLIRoot"
       downloadCounterBaskets=0 # counts the current basket downloads if counter > 10 no downloads are possible
                                           
             keys=lockedObjects.keys()      file_catalog = 'CDLICatalog'
                           
       # word splitter for search
       splitter = {'words':cdliSplitter.wordSplitter(),
                   'graphemes':cdliSplitter.graphemeSplitter()}
       
       def redirect(self,RESPONSE,url):
           """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen"""
           
           timeStamp=time.time()
           
           if url.find("?")>-1: #giebt es schon parameter
               addStr="&time=%s"
           else:
               addStr="?time=%s"
               
           RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
           logging.error(email.Utils.formatdate()+' GMT')
           RESPONSE.redirect(url+addStr%timeStamp)
       
       def unicodify(self,txt):
           return unicodify(txt)
       def invalidateOldCacheVersion(self):
           """loescht die alte Version des Cache"""
           del self.v_tmpStore
           return "done"
       
       def viewATF(self,id,RESPONSE):
           """view an Object"""
           ob = self.CDLICatalog({'title':id})
           logging.debug(ob[0].getObject().getLastVersion().absolute_url()+"/view")
           if len(ob)>0:
               RESPONSE.redirect(ob[0].getObject().getLastVersion().absolute_url()+"/view")
           return "not found"
       
       def history(self,id,RESPONSE):
           """view an Object"""
           ob = self.CDLICatalog({'title':id})
           if len(ob)>0:
               RESPONSE.redirect(ob[0].absolute_url+"/history")
           return "not found"
       
   
       def downloadLocked(self,id,RESPONSE):
           """view an Object"""
           ob = self.CDLICatalog({'title':id})
           if len(ob)>0:
               RESPONSE.redirect(ob[0].absolute_url+"/downloadLocked")
           return "not found"
       
       def download(self,id,RESPONSE):
           """view an Object"""
           ob = self.CDLICatalog({'title':id})
           if len(ob)>0:
               logging.info("objekt:"+repr(ob[0]))
               #RESPONSE.redirect(ob[0].getLastVersion().absolute_url())
               RESPONSE.redirect(ob[0].absolute_url+"/download")
           return "not found"
       def addCDLIFileObjectForm(self,id,RESPONSE):
           """view an Object"""
           ob = self.CDLICatalog({'title':id})
           if len(ob)>0:
               RESPONSE.redirect(ob[0].absolute_url+"/addCDLIFileObjectForm")
           return "not found"
       
       def addVersionedFileObjectForm(self,id,RESPONSE):
           """view an Object"""
           ob = self.CDLICatalog({'title':id})
           if len(ob)>0:
               RESPONSE.redirect(ob[0].absolute_url+"/addVersionedFileObjectForm")
           return "not found"
       
       def unlock(self,id,RESPONSE):
           """view an Object"""
           ob = self.CDLICatalog({'title':id})
           if len(ob)>0:
               RESPONSE.redirect(ob[0].absolute_url+"/unlock")
           return "not found"
       
       
       def getFileObject(self,fileId):
           """get an object"""
           logging.debug("getFileObj:"+repr(fileId))
           if isinstance(fileId,CDLIFileObject): # support for old baskets
                     return fileId
           x=self.v_files.get(fileId)
           logging.debug("obj: "+repr(x))
           if x==None:
               folder=fileId[0:3]
               f2=fileId[0:5]
               fObj = getattr(self.cdliRoot.cdli_main,folder);
               f2Obj = getattr(fObj,f2)
               
               o = getattr(f2Obj,fileId)
               logging.debug(o);
               self.updateOrAddToFileBTree(o)
               return o
           return x
       
       def getFileObjectLastVersion(self,fileId):
           """get an object"""
           x=self.v_files_lastVersion.get(fileId)
           logging.debug("lastVersion: "+repr(x))
           if x==None:
               folder=fileId[0:3]
               f2=fileId[0:5]
               fObj = getattr(self.cdliRoot.cdli_main,folder);
               f2Obj = getattr(fObj,f2)
   
               o =getattr(f2Obj,fileId)
               logging.debug(o);
               return o.getLastVersion()
           
   
           return x
       
       def showFileIds(self):
           """showIds"""
           return self.v_file_ids
       
       def generateFileBTree(self):
           """erzeuge einen Btree aus allen Files"""
           self.v_files = OOBTree()
           self.v_files_lastVersion = OOBTree()
           self.v_file_ids = Set()
           
           for x in self.CDLICatalog.searchResults():
               
               self.v_files.update({x.getId:x.getObject()})
               self.v_files_lastVersion.update({x.getId:x.getObject().getLastVersion()})
               self.v_file_ids.add(x.getId)
               logging.debug("add:"+x.getId+"XXX"+repr(x.getObject()))
                           
             if len(keys)>0 and (not procedure):          return True
                 self.REQUEST.SESSION['lockedObjects']=lockedObjects  
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)  
                 return pt()  
                     
             elif not procedure: #keine fails gesperrt dann alle donwloaden  
                 procedure="downloadAll"   
                   
       def updateOrAddToFileBTree(self,obj):
           """update a BTree"""
           self.v_files.update({obj.getId():obj})
           self.v_files_lastVersion.update({obj.getId():obj.getLastVersion()})
   
         for object in self.basketContent:          self.v_file_ids.add(obj.getId())
           #change everthing around to make it persistent...
           tmp = self.v_files
           self.v_files=tmp
                           
                 if (procedure=="downloadAll") or (object[1].lockedBy=='') or (object[1].lockedBy==self.REQUEST['AUTHENTICATED_USER']):          tmp2=self.v_file_ids
                     ret+=object[0].data          self.v_file_ids=tmp2
                                   
                 if lock and object[1].lockedBy=='':          self.CDLICache.cleanCache() #be sure that the cache is clean
                     object[1].lockedBy=self.REQUEST['AUTHENTICATED_USER']          logging.debug("update:"+obj.getId()+"XXX"+repr(obj))
   
         basket_name=self.aq_parent.title+"_V"+self.getId()  
                   
         #write basketname to header of atf file      def deleteFromBTree(self,objId):
         ret="#atf basket %s\n"%basket_name+ret          """delete an obj"""
           self.v_files.pop(objId)
           self.v_files_lastVersion.pop(objId)
           self.v_file_ids.remove(objId)
                   
         self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.atf" """%basket_name)  
         self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")  
         length=len(ret)  
         self.REQUEST.RESPONSE.setHeader("Content-Length",length)  
         self.REQUEST.RESPONSE.write(ret)      
           
    
     def numberOfItems(self):  
         """return anzahl der elemente im basket"""  
         return len(self.basketContent)  
       
     def getTime(self):  
         """getTime"""  
         #return self.bobobase_modification_time().ISO()  
         
         if hasattr(self,'time'):  
             return time.strftime("%Y-%m-%d %H:%M:%S",self.time)  
         elif hasattr(self,'timefixed'):  
             return self.timefixed  
         else:  
             setattr(self,'timefixed',self.bobobase_modification_time().ISO())  
             return self.bobobase_modification_time().ISO()  
       
     def getContent(self):  
         """get Basket Content"""  
         return self.basketContent  
   
       
     def __init__(self,id,user,comment="",basketContent=[]):  
         """ init a basket version"""  
         self.id=id  
         self.coment=comment  
         self.basketContent=basketContent[0:]  
         self.user=user  
         self.time=time.localtime()  
           
     def getUser(self):  
         """get user"""  
         return self.user  
       
     def getComment(self):  
         """get Comment"""  
         return self.comment  
     
     def index_html(self):  
             """view the basket"""  
             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketVersionMain.zpt')).__of__(self)  
             return pt()  
             
     def getObjUrl(self,result):      def deleteFiles(self,ids):
         """getUrl of the version of the object"""          """delete files"""
         objId=result[1].getTitle()          for id in ids:
         founds=self.CDLICatalog.search({'title':objId})              founds=self.CDLICatalog.search({'title':id.split(".")[0]})
         if len(founds)>0:              if founds:
              return founds[0].getObject().getLastVersion().absolute_url()                  logging.debug("deleting %s"%founds)
                   folder=founds[0].getObject().aq_parent #get the parent folder of the object
                   logging.debug("deleting from %s"%folder)
                   cut=folder.delete([founds[0].getId]) #cut it out
                     
         else: #assume version number  
             splitted=objId.split("_")  
             founds=self.CDLICatalog.search({'title':splitted[1]})          
             return founds[0].getObject().getLastVersion().absolute_url()+'/'+objId  
         
 def manage_addCDLIBasketVersion(self,user,comment="",basketContent=[],RESPONSE=None):  
     """add a version"""  
           
     #check for already existing versions      def searchText(self, query, index='graphemes'):
           """searches query in the fulltext index and returns a list of file ids/P-numbers"""
           # see also: http://www.plope.com/Books/2_7Edition/SearchingZCatalog.stx#2-13
           logging.debug("searchtext for '%s' in index %s"%(query,index))
           #import Products.ZCTextIndex.QueryParser
           #qp = QueryParser.QueryParser()
           #logging.debug()
           idxQuery = {index:{'query':query}}
           idx = getattr(self, self.file_catalog)
           # do search
           resultset = idx.search(query_request=idxQuery,sort_index='textid')
           # put only the P-Number in the result 
           results = [res.getId[:7] for res in resultset]
           logging.debug("searchtext: found %d texts"%len(results))
           return results
   
   
       def getFile(self, pnum):
           """get the translit file with the given pnum"""
           f = getattr(self, self.file_catalog).search({'textid':pnum})
           if not f:
               return ""
           
           return f[0].getObject().getData()
            
   
       def showFile(self,fileId,wholePage=False):
           """show a file
           @param fileId: P-Number of the document to be displayed
           """
           f=getattr(self, self.file_catalog).search({'textid':fileId})
           if not f:
               return ""
     
     lastVersion=self.getLastVersion()          if wholePage:
     if lastVersion is None:              logging.debug("show whole page")
         newId=str(1)              return f[0].getObject().getContentObject().view()
     else:      else:
         newId=str(int(lastVersion.getId())+1)              return f[0].getObject().getLastVersionFormattedData()
           
     ob=CDLIBasketVersion(newId,user,comment,basketContent)  
           
     self._setObject(newId, ob)      def showWordInFile(self,fileId,word,indexName='graphemes',regExp=False,):
               """get lines with word from FileId"""
     if RESPONSE is not None:          logging.debug("showwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId)) 
         RESPONSE.redirect('manage_main')  
     else:  
         return ob  
           
 class CDLIFileObject(versionedFileObject):          file = formatAtfFullLineNum(self.getFile(fileId))
     """CDLI file object"""          ret=[]
       
     meta_type="CDLI File Object"  
       
     security=ClassSecurityInfo()  
       
     def view(self):  
         """view file"""  
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','viewCDLIFile.zpt')).__of__(self)  
         return pt()  
       
     security.declarePublic('getDesignation')  
     def getDesignation(self):  
         """get the designation out of the file"""  
         try:  
                 txt=re.match("&[Pp](\d*)\s*=([^\r\n]*)",self.data[0:])  
         except:  
                 txt=self.data[0:]  
                   
                 return "ERROR"  
         try:  
             return txt.group(2)  
         except:  
             return "ERROR"  
                   
 manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1')          # add whitespace before and whitespace and line-end to splitter bounds expressions
           bounds = self.splitter[indexName].bounds
           splitexp = "(%s|\s)(%%s)(%s|\s|\Z)"%(bounds,bounds)
           # clean word expression 
           # TODO: this should use QueryParser itself
           # take out double quotes
           word = word.replace('"','')
           # take out ignorable signs
           ignorable = self.splitter[indexName].ignorex
           word = ignorable.sub('', word)
           # compile into regexp objects and escape parens
           wordlist = [re.compile(splitexp%re.escape(w)) for w in word.split(' ')]
               
           for line in file.splitlines():
               for word in wordlist:
                   #logging.debug("showwordinfile: searching for %s in %s"%(word.pattern,ignoreable.sub('',line)))
                   if word.search(ignorable.sub('',line)):
                       line = formatAtfLineHtml(line)
                       ret.append(line)
                       break
   
 def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',precondition='', content_type='',          return ret
                    REQUEST=None):  
     """Add a new File object.  
   
     Creates a new File object 'id' with the contents of 'file'"""  
   
     id=str(id)      def showWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
     title=str(title)          """
     content_type=str(content_type)          get lines with word from all ids in list FileIds.
     precondition=str(precondition)          returns dict with id:lines pairs.
               """
     id, title = cookId(id, title, file)          logging.debug("showwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds))
   
     self=self.this()          return dict([(id,self.showWordInFile(id, word, indexName, regExp)) for id in fileIds])
   
     # First, we create the file without data:  
     self._setObject(id, CDLIFileObject(id,title,'',content_type, precondition))  
     self._getOb(id).versionComment=str(vC)  
     self._getOb(id).time=time.localtime()  
           
     setattr(self._getOb(id),'author',author)      def tagWordInFile(self,fileId,word,indexName='graphemes',regExp=False):
           """get text with word highlighted from FileId"""
           logging.debug("tagwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId)) 
           
     # Now we "upload" the data.  By doing this in two steps, we          file=self.getFile(fileId)
     # can use a database trick to make the upload more efficient.          tagStart=u'<span class="found">'
     if file:          tagEnd=u'</span>'
         self._getOb(id).manage_upload(file)          tagStr=tagStart + u'%%s' + tagEnd
     if content_type:          ret=[]
         self._getOb(id).content_type=content_type  
   
     if REQUEST is not None:          # add whitespace to splitter bounds expressions and compile into regexp object
         REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')          bounds = self.splitter[indexName].bounds
           wordsplit = re.compile("(%s|\s)"%bounds)
           # clean word expression 
           # TODO: this should use QueryParser itself
           word = word.replace('"','') # take out double quotes
           # take out ignoreable signs
           ignorable = self.splitter[indexName].ignorex
           word = ignorable.sub('', word)
           # split search terms by blanks
           words = word.split(' ')
           # split search terms again (for grapheme search with words)
           splitwords = dict(((w,self.splitter[indexName].process([w])) for w in words))
               
           for line in file.splitlines():
               line = unicodify(line)
               # ignore lemma and other lines
               if line.lstrip().startswith('#lem:'):
                   continue
               # ignore p-num line
               if line.startswith('&P') or line.startswith('&S'):
                   continue
               # ignore version lines
               if line.startswith('#version'):
                   continue
               # ignore atf type lines
               if line.startswith('#atf:'):
                   continue
   
               # first scan
               hitwords = []
               for w in words:
                   if ignorable.sub('',line).find(w) > -1:
                       # word is in line
                       # append split word for grapheme search with words
                       hitwords.extend(splitwords[w])
                       #hitwords.extend(wordsplit.split(w))
                      
               # examine hits closer
               if hitwords:
                   # split line into words
                   parts = wordsplit.split(line)
                   line = ""
                   for p in parts:
                       #logging.debug("tagwordinfile: searching for %s in %s"%(p,hitwords))
                       # reassemble line
                       if ignorable.sub('', p) in hitwords:
                           #logging.debug("tagwordinfile: found %s in %s"%(p,hitwords))
                           # this part was found
                           line += tagStart + formatAtfHtml(p) + tagEnd
                       else:
                           line += formatAtfHtml(p)
                   
               else:
                   # no hits
                   line = formatAtfHtml(line)
           
 class CDLIFile(versionedFile,CatalogAware):              ret.append(line)
     """CDLI file"""  
           
     meta_type="CDLI file"          return u'<br>\n'.join(ret)
     default_catalog='CDLICatalog'  
           
           
     
     def isContainedInBaskets(self,context=None):      def tagWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
         """check is this file is part of any basket  
         @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog  
                         has to exist.  
         """          """
           get texts with highlighted word from all ids in list FileIds.
           returns dict with id:text pairs.
           """
           logging.debug("tagwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds)) 
           return dict([(id,self.tagWordInFile(id, word, indexName, regExp)) for id in fileIds])
   
         if not context:  
             context=self  
                   
       def getFileVersionList(self, pnum):
           """get the version history as a list for the translit file with the given pnum"""
           f = getattr(self, self.file_catalog).search({'textid':pnum})
           if not f:
               return []
           
           return f[0].getObject().getVersionList()
            
   
       def URLquote(self,str):
           """quote url"""
           return urllib.quote(str)
       
       def URLunquote(self,str):
           """unquote url"""
           return urllib.unquote(str)
       
       def URLquote_plus(self,str):
           """quote url"""
           return urllib.quote_plus(str)
       
       def URLunquote_plus(self,str):
           """unquote url"""
           return urllib.unquote_plus(str)
       
       def changeUserForPObjectFromFile(self,user,fname):
           """aendere user fuer alle p in fiele"""
           pns = file(os.path.join(package_home(globals()),'inputs',fname),"r")
           for p in pns.readlines():
               p=p.lstrip().rstrip()
               logging.info(str(p+".atf"))
               pObj=self.getFileObject(p+".atf")
               if pObj is not None:  
                   logging.info(pObj)
                   lv=pObj.getContentObject()
                   logging.info("author:"+lv.author)
                   lv.author=user
                   lv.versionComment="XXXXXXX"
       
       def forceunlock(self,REQUEST=None,user=None,fid=None):
           "break all locks"
           if fid is not None:
               self.getFileObject(fid).forceunlock()
               return fid
         ret=[]          ret=[]
         for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}):  
             #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why?  
             try:  
                 ret.append(x.getObject())  
             except:  
                 pass  
         return ret  
         #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})]  
           
           
     def addCDLIFileObjectForm(self):  
         """add a new version"""  
           
         if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]:  
             return "please login first"  
         if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''):  
             out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self)  
             return out()  
         else:  
             return "Sorry file is locked by somebody else"  
                   
     def manage_addCDLIFileObject(self,id,vC,author,file='',title='',precondition='', content_type='',changeName='no',newName='', RESPONSE=None):          for f in self.ZopeFind(self,obj_metatypes="CDLI file",search_sub=1):
         """add"""             un=f[1].forceunlock(user=user)
         try: #TODO: der ganze vC unsinn muss ueberarbeitet werden             logging.info("check:"+f[0])
             vC=self.REQUEST['vC']             if un and un !="":
         except:                 ret.append((f[0],un))
             pass  
                   
           if REQUEST is not None:
               pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','breakLockResponse.zpt')).__of__(self)
                   
         if changeName=="yes":              return pt(ret=ret)
             filename=file.filename  
             self.title=filename[max(filename.rfind('/'),  
                         filename.rfind('\\'),  
                         filename.rfind(':'),  
                         )+1:]  
   
           return ret
   
         if not newName=='':  
             self.title=newName[0:]  
                   
       def getLockedFiles(self,REQUEST=None,user=None):
           """hole alle gesperrten files"""
           ret={}
       
           for nm,f in self.v_files.items():
               lb = str(f.lockedBy)
               add=False
               if (lb is not None) and (lb!=""):
                  
                   if user is None:
                       add=True
                   else:
                       if str(lb)==user:
                           add=True
                   if add==True:
                       if not ret.has_key(lb):
                           ret[lb]=[]
                       ret[lb].append(nm)
                   
   
           if REQUEST is not None:
               pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','showlockResponse.zpt')).__of__(self)
                   
               return pt(ret=ret)
                   
         positionVersionNum=getattr(self,'positionVersionNum','front')          return ret
                   
         if positionVersionNum=='front':      def getChangesByAuthor(self,author,n=100):
             id="V%i"%self.getVersion()+"_"+self.title          """getChangesByAuthor"""
         else:          zcat=self.CDLIObjectsCatalog
             tmp=os.path.splitext(self.title)          res=zcat({'lastEditor':author,
             if len(tmp)>1:                       'sort_on':'getTime',
                 id=tmp[0]+"_V%i"%self.getVersion()+tmp[1]                       'sort_order':'descending',
             else:                       'sort_limit':n})[:n ]
                 id=tmp[0]+"_V%i"%self.getVersion()                         
           return res
       
       def getChangesByAuthor_html(self,author,n=100):
           """html output for changes by author"""
           tmp={}
           list=[]                         
           for x in self.getChangesByAuthor(author):
              nr=x.getObject().getVersionNumber()
              id=x.getObject().aq_parent.getId()
              #hinzufuegen, wenn Version neuer als die 
              if tmp.get(id,(0,0))[1] < nr:
                   tmp[id]=(x.getObject().aq_parent,nr)
   
        
           return self.cdli_main.findObjectsFromListWithVersion(list=tmp.values(),author=author)           
           
       def getLastChanges(self,n=100):
           """get the last n changes""" 
           n=int(n)                   
           zcat=self.CDLICatalog
           return zcat({'sort_on':'getLastChangeDate',
                        'sort_order':'descending',
                        'sort_limit':n})[:n ]
        
       
       def getLastChanges_html(self,n=100):
           """get the last n changes"""
           list = [x.getId for x in self.getLastChanges(n)]
           return self.cdli_main.findObjectsFromList(list=list,display=True)
                           
       def refreshTxt(self,txt="",threadName=None):
           """txt fuer refresh"""
                   
         manage_addCDLIFileObject(self,id,vC,author,file,id,precondition, content_type)          return """ 2;url=%s?repeat=%s """%(self.absolute_url()+txt,threadName)
         objs=self.ZopeFind(self,obj_ids=[id])[0][1].setVersionNumber(int(self.getVersion()))  
         self.REQUEST.SESSION['objID_parent']=self.getId()  
   
         if RESPONSE:      def refreshTxtBasket(self,txt="",threadName=None):
             obj=self.ZopeFind(self,obj_ids=[id])[0][1]          """txt fuer refresh"""
             if obj.getSize()==0:  
                 self.REQUEST.SESSION['objID']=obj.getId()  
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)  
                 return pt()  
   
             else:          return """ 2;url=%s?repeat=%s """%(txt,threadName)
                 RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title)  
   
         else:  
             return self.ZopeFind(self,obj_ids=[id])[0][1]  
                   
       def getResult(self,threadName=None):
          """result of thread"""
          try:
           return self._v_uploadATF[threadName].getResult()
          except:
           return "One moment, please"
                   
 def manage_addCDLIFileForm(self):  
     """interface for adding the OSAS_root"""  
     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self)  
     return pt()  
   
 def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None):      def checkThreads(self):
     """add the OSAS_root"""          """check threads"""
     newObj=CDLIFile(id,title,lockedBy,author)          ret="<html><body>"
     self._setObject(id,newObj)          for thread in threading.enumerate():
              ret+="<p>%s (%s): %s</p>"%(repr(thread),thread.getName(),thread.isAlive())
         
     if RESPONSE is not None:          return ret
         RESPONSE.redirect('manage_main')  
   
   
       def uploadATFRPC(self,data,username):
           """upload an atffile via xml-rpc"""
           uploader=uploadATFThread()
   
           #generate an random id for the upload object
           from random import randint
           if (not self.REQUEST.SESSION.get('idTmp',None)):
   
 def splitatf(fh,dir=None):              idTmp=str(randint(0,1000000000))
     """split it"""              self.REQUEST.SESSION['idTmp']=idTmp
     ret=None  
     nf=None  
     for line in fh.readlines():  
         #check if basket name is in the first line  
         if line.find("#atf basket")>=0:  
             ret=line.replace('#atf basket ','')  
             ret=ret.split('_')[0]  
         else:          else:
             if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile              idTmp=self.REQUEST.SESSION.get('idTmp',None)
                 if nf:  
                     nf.close() #close last file  
                           
                                   
                 filename=line[1:].split("=")[0].rstrip()+".atf"          uploader.set(data,0,username,idTmp)
                 if dir:  
                     filename=os.path.join(dir,filename)  
                 nf=file(filename,"w")  
             if nf:      
                 nf.write(line)  
                   
     nf.close()          stObj=uploader.run()
     fh.close()  
     return ret,len(os.listdir(dir))  
   
           processor=uploadATFfinallyThread()
   
 class CDLIFileFolder(versionedFileFolder):          basketname=stObj.returnValue['basketNameFromFile']
     """CDLI File Folder"""  
           
     security=ClassSecurityInfo()          processor.set("uploadchanged",basketname=basketname,SESSION=stObj.returnValue,username=username,serverport=self.REQUEST['SERVER_PORT'])
     meta_type="CDLI Folder"  
     filesMetaType=['CDLI file']  
     folderMetaType=['CDLI Folder']  
     default_catalog='CDLICatalog'  
           
     def setTemp(self,name,value):          processor.run()
         """set tmp"""  
   
         setattr(self,name,value)  
                                                                                   
           return generateXMLReturn(stObj.returnValue)
                                                                                 
     def delete(self,ids):      def uploadATF(self,repeat=None,upload=None,basketId=0,RESPONSE=None):
         """delete this file, i.e. move into a trash folder"""          """upload an atf file / basket file"""
           #self._v_uploadATF.returnValue=None
                             
         found=self.ZopeFind(self,obj_ids=['.trash'])          #generate an random id for the upload thread
           from random import randint
           if (not self.REQUEST.SESSION.get('idTmp',None)):
                   
         if len(found)<1:              idTmp=str(randint(0,1000000000))
             manage_addCDLIFileFolder(self, '.trash',title="Trash")              self.REQUEST.SESSION['idTmp']=idTmp
             trash=self._getOb('.trash')  
         else:          else:
             trash=found[0][1]              idTmp=self.REQUEST.SESSION.get('idTmp',None)
                   
         if type(ids) is not ListType:  
             ids=[ids]  
         cut=self.manage_cutObjects(ids)  
         trash.manage_pasteObjects(cut)  
           
     def getVersionNumbersFromIds(self,ids):  
         """get the numbers of the current versions of documents described by their ids"""  
           
         ret=[]  
         searchStr=" OR ".join(ids)  
           
         founds=self.CDLICatalog.search({'title':searchStr})  
           
         for found in founds:  
             lastVersion=found.getObject().getLastVersion()  
             ret.append((found.getId,lastVersion))  
           
         return ret  
       
     def checkCatalog(self,fn):  
         """check if fn is in the catalog"""  
         #TODO add checkCatalog  
            
     def refreshTxt(self,txt=""):  
         """txt fuer refresh"""  
     
         return """ 2;url=%s?repeat=%s """%(self.absolute_url()+txt,self.threadName)  
   
       
     def getResult(self):  
        """result of thread"""  
        try:  
         return self._v_uploadATF.getResult()  
        except:  
         return "One moment, please"  
       
     def uploadATF(self,repeat=None,upload=None,basketId=0,RESPONSE=None):  
         """standard ausgabe"""  
         #self._v_uploadATF.returnValue=None  
   
         threadName=repeat          threadName=repeat
         if not threadName or threadName=="":          if not threadName or threadName=="":
               #new thread not called from the waiting page
             tmpVar=False              tmpVar=False
          
             thread=uploadATFThread()              thread=uploadATFThread()
             self._v_uploadATF=thread              threadName=thread.getName()[0:]                                
               if (not hasattr(self,'_v_uploadATF')):
                      self._v_uploadATF={}
                                          
               self._v_uploadATF[threadName]=thread
             #self._xmltrans.start()              #self._xmltrans.start()
             #thread=Thread(target=self._v_uploadATF)              #thread=Thread(target=self._v_uploadATF)
                           logging.info("set thread. extern")
             self._v_uploadATF.set(upload,basketId,self.REQUEST['AUTHENTICATED_USER'],serverport=self.REQUEST['SERVER_PORT'])              self._v_uploadATF[threadName].set(upload,basketId,self.REQUEST['AUTHENTICATED_USER'],idTmp,serverport=self.REQUEST['SERVER_PORT'])
             #thread.start()              #thread.start()
             self._v_uploadATF.start()              logging.info("start thread. extern")
               self._v_uploadATF[threadName].start()
   
                           
             self.threadName=self._v_uploadATF.getName()[0:]              self.threadName=self._v_uploadATF[threadName].getName()[0:]
             wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])              wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
   
             if wait_template:              if wait_template:
                 return wait_template[0][1]()                  return wait_template[0][1]()
             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)              pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
             return pt(txt='/uploadATF')              return pt(txt='/uploadATF',threadName=threadName)
             #_v_xmltrans.run()              #_v_xmltrans.run()
                           
         else:          else:
             #recover thread, if lost              #recover thread, if lost
             if not hasattr(self,'_v_uploadATF'):              if (not hasattr(self,'_v_uploadATF')):
                  self._v_uploadATF={}
               if not self._v_uploadATF.get(threadName,None):
                  for thread in threading.enumerate():                   for thread in threading.enumerate():
                          if threadName == thread.getName():                           if threadName == thread.getName():
                                        self._v_uploadATF=thread                                         self._v_uploadATF[threadName]=thread
   
             if not self._v_uploadATF.returnValue:              if self._v_uploadATF.get(threadName,None) and (not self._v_uploadATF[threadName].returnValue):
                   
   
                 wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])                  wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
Line 1340  class CDLIFileFolder(versionedFileFolder Line 1295  class CDLIFileFolder(versionedFileFolder
                                   
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)                  pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
   
                 return pt(txt='/uploadATF')                  return pt(txt='/uploadATF',threadName=threadName)
                                   
             else:              else:
                   tmp=getattr(self.temp_folder,idTmp).returnValue
   
                 tmp=self._v_uploadATF.returnValue                  pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
                 self._v_uploadATF.continueVar=False  
                                   
                 self.REQUEST.SESSION['changed']=[x[0].getId() for x in tmp['changed']]                  return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'],
                 self.REQUEST.SESSION['errors']=[x.getId() for x in tmp['errors']]                    basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
                 self.REQUEST.SESSION['newPs']=tmp['newPs']  
                 self.REQUEST.SESSION['tmpdir']=tmp['dir']  
               
       def redoUpload(self,threadName):
          """redo the upload"""
          tmp=self.cdli_main.tmpStore2[threadName]
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)                  pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
                 return pt(changed=tmp['changed'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'],         return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'],
                   basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])                    basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
                                                                                 
     def uploadATFfinally(self,procedure='',comment="",basketname='',unlock=None,repeat=None,RESPONSE=None):      def uploadATFfinally(self,procedure='',comment="",basketname='',unlock=None,repeat=None,RESPONSE=None):
         """nowupload the files"""          """nowupload the files"""
          
          
          
         threadName=repeat          threadName=repeat
         if not threadName or threadName=="":          if not threadName or threadName=="":
               thread=uploadATFfinallyThread()
               threadName=thread.getName()[0:]
   
               if (not hasattr(self,'_v_uploadATF')):
                                   self._v_uploadATF={}
                           
                         
             self._v_uploadATF=uploadATFfinallyThread()              self._v_uploadATF[threadName]=thread
   
               idTmp=self.REQUEST.SESSION['idTmp']
               stObj=getattr(self.temp_folder,idTmp)
               self._v_uploadATF[threadName].set(procedure,comment=comment,basketname=basketname,unlock=unlock,SESSION=stObj.returnValue,username=self.REQUEST['AUTHENTICATED_USER'],serverport=self.REQUEST['SERVER_PORT'])
                   
             self._v_uploadATF.set(procedure,comment=comment,basketname=basketname,unlock=unlock,SESSION=self.REQUEST.SESSION,username=self.REQUEST['AUTHENTICATED_USER'],serverport=self.REQUEST['SERVER_PORT'])              self._v_uploadATF[threadName].start()
   
             self._v_uploadATF.start()  
   
                           
             self.threadName=self._v_uploadATF.getName()[0:]  
             wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])              wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
   
             if wait_template:              if wait_template:
                 return wait_template[0][1]()                  return wait_template[0][1]()
             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)              pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
   
             return pt(txt='/uploadATFfinally')              return pt(txt='/uploadATFfinally',threadName=threadName)
             #_v_xmltrans.run()              #_v_xmltrans.run()
                   
         else:          else:
             #recover thread, if lost              #recover thread, if lost
             if not hasattr(self,'_v_uploadATF'):              if not hasattr(self,'_v_uploadATF'):
                  self._v_uploadATF={}
               if not self._v_uploadATF.get(threadName,None):
                  for thread in threading.enumerate():                   for thread in threading.enumerate():
                          if threadName == thread.getName():                           if threadName == thread.getName():
                                        self._v_uploadATF=thread                                         self._v_uploadATF[threadName]=thread
                                                                                 
             if hasattr(self,'_v_uploadATF') and (self._v_uploadATF is not None) and (not self._v_uploadATF.end) :              if self._v_uploadATF.get(threadName,None) and (self._v_uploadATF[threadName] is not None) and (not self._v_uploadATF[threadName].end) :
   
                 wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])                  wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
                 if wait_template:                  if wait_template:
                         return wait_template[0][1]()                          return wait_template[0][1]()
                                   
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)                  pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
                 return pt(txt='/uploadATFfinally')                  return pt(txt='/uploadATFfinally',threadName=threadName)
             else:              else:
   
               if RESPONSE is not None:  
                   RESPONSE.redirect(self.aq_parent.absolute_url())  
                   
                                      
   
                 idTmp=self.REQUEST.SESSION['idTmp']
                 stObj=getattr(self.temp_folder,idTmp) 
                 self.REQUEST.SESSION['idTmp']=None
   
     def findObjectsFromList(self,start=None,upload=None,list=None,basketName=None,numberOfObjects=None,RESPONSE=None):                #update changed
         """findObjectsFromList (, TAB oder LINE separated)"""                logging.debug("dir:"+repr(stObj.returnValue['changed']))
                                                        for x in stObj.returnValue['changed']:
                               ob=self.CDLICatalog.search({'title':x[0]})
         if upload: # list from file upload                      try:
             txt=upload.read()                          self.cdliRoot.updateOrAddToFileBTree(ob[0].getObject())
             txt=txt.replace(",","\n")                      except:
             txt=txt.replace("\t","\n")  
             txt=txt.replace("\r","\n")  
             idsTmp=txt.split("\n")  
             ids=[]  
             for id in idsTmp: # make sure that no empty lines  
                 idTmp=id.lstrip().rstrip()  
                 if len(idTmp)>0:  
                       
                     ids.append(idTmp)  
                       
             #self.REQUEST.SESSION['ids']=" OR ".join(ids)  
   
             pt=getattr(self,'filelist.html')  
             self.REQUEST.SESSION['searchList']=ids  
             return pt(search=ids)  
           
         if basketName:  
             #TODO: get rid of one of these..  
               
             pt=getattr(self,'filelist.html')  
             return pt(basketName=basketName,numberOfObjects=numberOfObjects)  
           
         if list is not None: # got already a list  
             ret=[]  
             for fileId in list:  
                 if len(fileId.split("."))==1:  
                         fileId=fileId+".atf"  
   
                 ret+=self.CDLICatalog({'title':fileId})  
             #TODO: get rid of one of these..  
             self.REQUEST.SESSION['fileIds']=[x.getObject().getId() for x in ret]#store fieldIds in session for further usage  
             self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']  
             return ret  
           
         if start:  
             RESPONSE.redirect("filelist.html?start:int="+str(start))  
                                          
   
   
     security.declareProtected('Manage','createAllFilesAsSingleFile')  
     def createAllFilesAsSingleFile(self,RESPONSE=None):  
         """download all files"""  
           
         def sortF(x,y):  
             return cmp(x[0],y[0])  
           
         catalog=getattr(self,self.default_catalog)  
         #tf,tfilename=mkstemp()  
           
           
         list=[(x.getId,x) for x in catalog()]  
         list.sort(sortF)  
           
         RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf")  
         RESPONSE.setHeader("Content-Type","application/octet-stream")  
          
         for l in list:  
             obj=l[1].getObject()  
               
             if obj.meta_type=="CDLI file":  
                   
                 #os.write(tf,obj.getLastVersion().data)  
                 if RESPONSE:  
                     RESPONSE.write(obj.getLastVersion().data[0:])  
         #os.close(tf)  
         #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename)  
         return True  
       
     def downloadFile(self,fn):  
         """download fn - not used yet"""  
         self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId())  
         self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")  
         self.REQUEST.RESPONSE.write(file(fn).read())  
           
         
                   
     def hasParent(self):  
         """returns true falls subfolder"""  
         
         if self.aq_parent.meta_type in self.folderMetaType:  
             return True  
         else:  
             return False  
           
     def getFolders(self):  
         """get all subfolders"""  
         ret=[]  
         folders=self.ZopeFind(self,obj_metatypes=self.folderMetaType)  
         for folder in folders:  
             ret.append((folder[1],  
                         len(self.ZopeFind(folder[1],obj_metatypes=self.folderMetaType)),  
                         len(self.ZopeFind(folder[1],obj_metatypes=self.filesMetaType))  
                         ))  
         return ret  
       
               
     def getFolders_OLD(self):  
         """get all subfolders"""  
         ret=[]  
         folders=self.ZopeFind(self,obj_metatypes=self.folderMetaType)  
         for folder in folders:  
             ret.append((folder[1],  
                         len(self.ZopeFind(folder[1],obj_metatypes=self.folderMetaType)),  
                         len(getattr(self,self.default_catalog)({'path':folder[0]}))  
                         ))  
         return ret  
       
     def index_html(self):  
         """main"""  
         ext=self.ZopeFind(self,obj_ids=["index.html"])  
         if ext:  
             return ext[0][1]()  
                   
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self)                          logging.error("uploadATFfinally - cannot update Object %s Error: %s %s"%(ob[1],sys.exc_info()[0],sys.exc_info()[1]))
         return pt()                for x in stObj.returnValue['newPs']:
                     obj=self.getFileObject(x) #updates the object in the cache
                     logging.debug("Got:"+repr(obj))
                 if RESPONSE is not None:
                     RESPONSE.redirect(self.absolute_url())
           
     def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/Documents/workspace/cdli/atf", files=None,ext=None):      def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/atf", files=None,ext=None):
         """import files"""          """import files"""
                   logging.debug("importFiles folderName=%s files=%s ext=%s"%(folderName,files,ext))
           root=self.cdli_main
           count=0
         if not files:          if not files:
             files=os.listdir(folderName)              files=os.listdir(folderName)
                           
         for f in files:          for f in files:
             folder=f[0:3]              folder=f[0:3]
             f2=f[0:5]              f2=f[0:5]
             obj=self.ZopeFind(self,obj_ids=[folder])              
               #check if main folder PXX already exists
               obj=self.ZopeFind(root,obj_ids=[folder])
               logging.debug("importFiles: folder=%s f2=%s obj=%s"%(folder,f2,obj)) 
             if ext:              if ext:
                   ext.result="<p>adding: %s </p>"%f+ext.result
   
       
                 ext.result+="<p>Adding: %s </p>"%f              if not obj: # if not create it
             if not obj:                  manage_addCDLIFileFolder(root,folder,folder)
                 manage_addCDLIFileFolder(self,folder,folder)                  fobj=getattr(root,folder)
                 fobj=getattr(self,folder)                  #transaction.get().commit()                           
                   
             else:              else:
                 fobj=obj[0][1]                  fobj=obj[0][1]
                           
               #check IF PYYYYY already exist
             obj2=fobj.ZopeFind(fobj,obj_ids=[f2])              obj2=fobj.ZopeFind(fobj,obj_ids=[f2])
               logging.debug("importFiles: fobj=%s obj2=%s"%(fobj,obj2)) 
                   
             if not obj2:              if not obj2:# if not create it
                 manage_addCDLIFileFolder(fobj,f2,f2)                  manage_addCDLIFileFolder(fobj,f2,f2)
                 fobj2=getattr(fobj,f2)                  fobj2=getattr(fobj,f2)
                   
             else:              else:
                 fobj2=obj2[0][1]                  fobj2=obj2[0][1]
                               
             file2=file(os.path.join(folderName,f))                 # not add the file
               file2=os.path.join(folderName,f)  
             id=f              id=f
             manage_addCDLIFile(fobj2,f,'','')              logging.debug("importFiles: addCDLIFile fobj2=%s, f=%s file2=%s"%(fobj2,repr(f),repr(file2)))
             id=f              fobj2.addFile(vC='',file=file(file2),author=author,newName=f)
             ob=fobj2._getOb(f)              logging.debug("importfiles: fobj2.add")
             ob.title=id              count+=1
                           
             manage_addCDLIFileObject(ob,id,comment,author,file2,content_type='')              #now add the file to the storage
             self.CDLICatalog.catalog_object(ob)              ob = getattr(fobj2,f)
             #self.CDLICatalog.manage_catalogFoundItems(obj_ids=[id],search_sub=1)              logging.debug("importfiles: btree_start")
             #self.CDLICatalog.manage_catalogObject(self.REQUEST, self.REQUEST.RESPONSE, 'CDLICatalog', urlparse.urlparse(ob.absolute_url())[1])              #self.cdliRoot.updateOrAddToFileBTree(ob)
                           logging.debug("importfiles: btree_end")
               if count%100==0:
                   logging.debug("importfiles: committing")
                   transaction.get().commit()
   
           logging.debug("importfiles: committing")
           transaction.get().commit()
           logging.debug("importfiles: committing done")
         return "ok"          return "ok"
           
 manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals())  
   
   manage_addCDLIRootForm=DTMLFile('dtml/rootAdd', globals())
           
 def manage_addCDLIFileFolder(self, id, title='',      
   def manage_addCDLIRoot(self, id, title='',
                      createPublic=0,                       createPublic=0,
                      createUserF=0,                       createUserF=0,
                      REQUEST=None):                       REQUEST=None):
Line 1585  def manage_addCDLIFileFolder(self, id, t Line 1455  def manage_addCDLIFileFolder(self, id, t
     value, an 'index_html' and a 'UserFolder' objects are created respectively      value, an 'index_html' and a 'UserFolder' objects are created respectively
     in the new folder.      in the new folder.
     """      """
     ob=CDLIFileFolder()      ob=CDLIRoot()
     ob.id=str(id)      ob.id=str(id)
     ob.title=title      ob.title=title
       try:
     self._setObject(id, ob)      self._setObject(id, ob)
       except:
           pass
     ob=self._getOb(id)      ob=self._getOb(id)
   
     checkPermission=getSecurityManager().checkPermission      checkPermission=getSecurityManager().checkPermission
Line 1604  def manage_addCDLIFileFolder(self, id, t Line 1477  def manage_addCDLIFileFolder(self, id, t
     if REQUEST is not None:      if REQUEST is not None:
         return self.manage_main(self, REQUEST, update_menu=1)          return self.manage_main(self, REQUEST, update_menu=1)
   
    
   import cdli_basket
   
   
   # Die folgenden Klassen sollte nicht mehr aus diesem Paket benutzt werden, sondern direkt aus
   # cdli_basket importiert werden.
   class uploadATFfinallyThread(cdli_basket.uploadATFfinallyThread):
       """depricates"""
       pass
   
   class tmpStore(cdli_basket.tmpStore):
       """depricated"""
       pass
   
   class uploadATFThread(cdli_basket.uploadATFThread):
       """depricated"""
       pass
   
   class CDLIBasketContainer(cdli_basket.CDLIBasketContainer):
       """depricated"""
       pass
   
   class CDLIBasket(cdli_basket.CDLIBasket):
       """depricated"""
       pass
   
   class CDLIBasketVersion(cdli_basket.CDLIBasketVersion):
       """depricated"""
       pass
   
   class BasketContent(cdli_basket.BasketContent):
       """depricated"""
       pass
       

Removed from v.1.21  
changed lines
  Added in v.1.115


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