File:  [Repository] / cdli / cdli_files.py
Revision 1.19: download - view: text, annotated - select for diffs - revision graph
Tue Jun 13 18:34:10 2006 UTC (17 years, 11 months ago) by dwinter
Branches: MAIN
CVS tags: HEAD
threaded file upload

"""CDLI extensions of the filearchive"""
from Products.versionedFile.versionedFile import *
from Products.ZCatalog.CatalogPathAwareness import CatalogAware
from tempfile import mkstemp,mkdtemp
import os.path
import os
from types import *
import urlparse
from OFS.OrderedFolder import OrderedFolder
from OFS.SimpleItem import SimpleItem
import time
from OFS.Folder import manage_addFolder
import re
from AccessControl import ClassSecurityInfo
from Acquisition import Implicit
from threading import Thread
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.BaseRequest import RequestContainer

global tmpVar

class uploadATFfinallyThread(Thread):
 
    def __init__(self):
        self.continueVar=True
        self.returnValue=None
        self.end=False
        Thread.__init__(self)
           
    def set(self,procedure,comment="",basketname='',unlock=None,SESSION=None,username=None,serverport="8080"):
        """set values"""
        self.procedure=procedure
        self.comment=comment
        self.basketname=basketname
        self.unlock=unlock
        self.SESSION=SESSION
        self.username=username
        self.serverport=serverport
        
    def __call__(self):
        """wait"""
        self.run()
        return True
    
    def getContext(self, app,serverport="8080"):
        resp = HTTPResponse(stdout=None)
        env = {
            '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=""
        from Zope import DB
        conn = DB.open()
        root = conn.root()
        app  = root['Application']
        ctx = self.getContext(app,serverport=self.serverport)

        self.uploadATFfinallyThread(ctx,self.procedure,comment=self.comment,basketname=self.basketname,unlock=self.unlock,SESSION=self.SESSION,username=self.username)
        get_transaction().commit()
        conn.close()
        self.end=True
        return True
    
    def getResult(self):
        return self.result
     
    def uploadATFfinallyThread(self,ctx,procedure,comment="",basketname='',unlock=None,RESPONSE=None,SESSION=None,username=None):
        """upload the files"""
        ctx2=ctx.cdliRoot
   
        self.result+="<h2>Start processing</h2>"
        if procedure=="uploadchanged":
      
            uploadFns=SESSION.get('changed',[])+SESSION.get('newPs',[])
        
        elif procedure=="uploadAll":
            uploadFns=[]
            for x in os.listdir(SESSION['tmpdir']):
                if not x in SESSION['errors']:
                    uploadFns.append(x)
        elif procedure=="noupload":
                        return True
        else:
            uploadFns=[]
            
        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)))
            
        
                
        newPs=SESSION['newPs']
        if len(newPs)>0:
            tmpDir=SESSION['tmpdir']
            self.result+="<p>Adding files</p>"
            ctx2.cdli_main.importFiles(comment=comment,author=str(username) ,folderName=tmpDir, files=newPs,ext=self)
                
        
        
        #unlock
        if unlock:
            self.result+="<p>Unlock files</p>"
            unlockFns=[]
            for x in os.listdir(SESSION['tmpdir']):
                    if not x in SESSION['errors']:
                        unlockFns.append(x)
            
            for fn in unlockFns:
                founds=ctx2.CDLICatalog.search({'title':fn})
                if len(founds)>0:
                    SESSION['author']=str(username)
                   
                    founds[0].getObject().lockedBy=""
                    
        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:
            RESPONSE.redirect(self.aq_parent.absolute_url())
        

       
        return True
    
class uploadATFThread(Thread):
    
    def __init__(self):
        self.continueVar=True
        self.returnValue=None
        
        Thread.__init__(self)
        
        
    def set(self,upload,basketId,username,serverport="8080"):
        self.result=""
        self.upload=upload
        self.basketId=basketId
        self.username=username
        self.serverport=serverport
        
    def __call__(self):
        """wait"""
        self.run()
        return True
    
    def getContext(self, app,serverport="8080"):
        resp = HTTPResponse(stdout=None)
        env = {
            '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=""
        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:
            pass
        get_transaction().abort()
        conn.close()

        
    def getResult(self):
        return self.result
    
    def uploadATFThread(self,ctx,upload,basketId=0):
        """upload an atf file"""
        #TODO: add comments
        #TODO: finish uploadATF
        self.result="<html><body><h2>I am loading your file...</h2>"
        basketId=str(basketId)
        
        
        ctx2=ctx.cdliRoot
        dir=mkdtemp()
        changed=[]
        errors=[]
        newPs=[]
        psNotInCatalog=[]
        basketNameFromFile, numberOfFiles=splitatf(upload,dir)
        
        if basketId == '0':
            basketObj=ctx2.basketContainer.getActiveBasket()
            if basketObj:
                basketId=basketObj.getId()
                
        if basketId == '0':
            basketNameFromId=""
            basketLen=0
        else:
            basketNameFromId=getattr(ctx2.basketContainer,basketId).title
            basketLen=getattr(ctx2.basketContainer,basketId).getLastVersion().numberOfItems()
            
        
        self.result+="<html><body><h2>I got the files</h2><p>I am checking now the files</p>"
                                       
        for fn in os.listdir(dir):
            
            self.result+="<p>check:%s</p>"%fn
            
            if ctx2.cdli_main.checkCatalog(fn):
                psNotInCatalog.append(fn)
                
                
            founds=ctx2.CDLICatalog.search({'title':fn})    
      
            if len(founds)==0:
                newPs.append(fn)
                
            for found in founds:
                obj=found.getObject()
       
                if (not obj.lockedBy=='') and (not obj.lockedBy==self.username):
                    errors.append(obj)
                else:
                    data=file(os.path.join(dir,fn)).read()
                    diffs=obj.diff(data)
                    if diffs[0]>0:
                        changed.append((obj,diffs))
                        #hochladen
        
      
        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 storeAll(self,id):
        """store all"""
        try:
            results=self._v_stack[id]
        except:
            #TODO: write expired page
            return "expired"
        
        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)
        return pt()
        
    def storeInBasket(self,username,ids=None,RESPONSE=None,REQUEST=None):
        """store it"""
        
        if not ids:
            ids=REQUEST.SESSION['ids']
            
        self.REQUEST.SESSION['basketUser']=username
        
        baskets=self.ZopeFind(self,obj_ids=[username])
        if len(baskets)>0:
            basket=baskets[0][1]
        else:
            manage_addBasketObject(self,username)
            basket=self._getOb(username)
        
        
        basket.addObjects(ids)
        back=self.REQUEST.SESSION.get('BACKLINK', None)

        if RESPONSE:
            RESPONSE.redirect(back)
            

    
    def showBasket(self,user=None,set=None,RESPONSE=None):
        """show the basket"""
        
        if user:
            self.REQUEST.SESSION['basketUser']=user
        
        if not user and not set:
            user=self.REQUEST.SESSION.get('basketUser',None)
        
        if not user:
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','orizeBasketUser.zpt')).__of__(self)
            return pt()
        else:
            baskets=self.ZopeFind(self,obj_ids=[user])
        

        if len(baskets)>0:
            RESPONSE.redirect(baskets[0][1].absolute_url())
            return True 
        else:
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','emptyBasket.zpt')).__of__(self)
            return pt()
        

def manage_addBasket_oldForm(self):
    """add the basket form"""
    pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addBasket.zpt')).__of__(self)
    return pt()

def manage_addBasket_old(self,id,title,RESPONSE=None):
    """add the basket"""
    ob=Basket()
    
    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 BasketObject_old(Folder):
    """Basket Object - alte fassung"""
    
    meta_type="basketObject"
    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

    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" 
        

        for object in self.contents:
            
                if (procedure=="downloadAll") or (object.lockedBy=='') or (object.lockedBy==self.REQUEST['AUTHENTICATED_USER']):
                    ret+=object.getLastVersion().data
                
                if lock and object.lockedBy=='':
                    object.lockedBy=self.REQUEST['AUTHENTICATED_USER']


        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)    
        
        
def manage_addBasket_oldObjectForm(self):
    """add form"""
    pass

def manage_addBasket_oldObject(self,id,title='',RESPONSE=None):
    """add"""
    
    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 CDLIBasketContainer(OrderedFolder):
    """contains the baskets"""
    

    security=ClassSecurityInfo()
    meta_type="CDLIBasketContainer"
    
    def deleteBaskets(self,ids=None):
        """delete baskets, i.e. move them into trash folder"""
        
        
        found=self.ZopeFind(self,obj_ids=['trash'])
        
        if len(found)<1:
            manage_addFolder(self, 'trash')
            trash=self._getOb('trash')
        else:
            trash=found[0][1]
        
        if type(ids) is not ListType:
            ids=[ids]
        cut=self.manage_cutObjects(ids)
        trash.manage_pasteObjects(cut)
        
    def manageBaskets(self,ids,submit,REQUEST=None,RESPONSE=None):
        """manage baskets, delete or copy"""
        if submit=="delete":
            self.deleteBaskets(ids)
        
       
            
        if RESPONSE:
            RESPONSE.redirect(self.absolute_url())
    def getBasketIdfromName(self,basketname):
        """get id from name"""

        for basket in self.ZopeFind(self,obj_metatypes=["CDLIBasket"]):
            if basket[1].title==basketname:
                return basket[0]
        else:
            None
    
    security.declareProtected('manage','uploadBasket_html')        
            
    def uploadBasket_html(self,basketId='0'):
        """upload an atf file, html form"""
        

        basketId=str(basketId)
        if not basketId=='0':
            basketName=getattr(self.basketContainer,basketId).title
        else:
            basketName=""
            
        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasket_html.zpt')).__of__(self)
        return pt(basketId=basketId,basketName=basketName)
   

        
    def index_html(self):
        """stanadard ansicht"""
        


        ext=self.ZopeFind(self,obj_ids=["index.html"])
        if ext:
            return ext[0][1]()
        
        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self)
        return pt()
    
    def getStorageFolderRoot(self):
        """root des storage folders"""
        return self.cdli_main
    
    def __init__(self,id,title):
        """ init basket container"""
        self.id=id
        self.title=title
     
     
    def getBaskets(self,sortField='title'):
        """get all baskets files"""

        def sortName(x,y):
            return cmp(x[1].title.lower(),y[1].title.lower())

        def sortDate(x,y):
            return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())

        
        def sortComment(x,y):

        
            
             try:
                xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()
             except:
                xc='ZZZZZZZZZZZZZ'.lower()
             try:
                yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()
             except:
                yc='ZZZZZZZZZZZZZ'.lower()
    
    
             if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):
                 
                 try:
                     xc=x[1].getLastVersion().getComment().lower()
                 except:
                     xc='ZZZZZZZZZZZZZ'.lower()
                     
             if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):
                 try:
                     yc=y[1].getLastVersion().getComment().lower()
                 except:
                     yc='ZZZZZZZZZZZZZ'.lower()
    
             
                 return cmp(xc,yc)
        
        def sortAuthor(x,y):
            
            return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower())
        
        baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
        
        
        if sortField=='title':
            baskets.sort(sortName)
        elif sortField=='date':
            baskets.sort(sortDate)
        elif sortField=='author':
            baskets.sort(sortAuthor)
        elif sortField=='comment':
            baskets.sort(sortComment)

        return baskets


                       
    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
        return last
    
    def setActiveBasket(self,basketId,REQUEST=None):
        """store active basketId in a cookie"""
        self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/")
        
        if REQUEST:
            REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+REQUEST['QUERY_STRING'])
            
    def getActiveBasket(self):
        """get active basket from cookie"""
        
        id= self.REQUEST.cookies.get('CDLIActiveBasket',None)
        if id:
            obj=getattr(self,str(id),None)
        else:
            obj=None
        return obj
    
    def getActualUserName(self):
        """get name of the actualuser"""
        return str(self.REQUEST['AUTHENTICATED_USER'])
    
    
    def addBasket(self,newBasketName):
        """add a new basket"""
        
        ob=manage_addCDLIBasket(self,newBasketName)
        return ob
    
    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 RESPONSE:
            
            RESPONSE.redirect(back)
            
        return True
    
def manage_addCDLIBasketContainerForm(self):
    """add the CDLIBasketContainer form"""
    pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self)
    return pt()

def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None):
    """add the basket"""
    ob=CDLIBasketContainer(id,title)
    
    self._setObject(id, ob)
    
    if RESPONSE is not None:
        RESPONSE.redirect('manage_main')

class CDLIBasket(Folder,CatalogAware):
    """basket"""
    
    meta_type="CDLIBasket"
    default_catalog="CDLIBasketCatalog"
    
    def getFile(self,obj):
        return obj[1]
    
    def getFileLastVersion(self,obj):
        return obj[0]
    
    def getFileNamesInLastVersion(self):
        """get content of the last version as list"""
        
        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()})
        if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash":
            return False, -1
        
        if actualNo==storedNo:
            return True , 0
        else:
            return False, actualNo
        
    def history(self):
        """history"""  

        ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
        if ext:
            return getattr(self,ext[0][1].getId())()
        
        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self)
        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):
    """add the basket"""
    
    id=str(self.getNewId())
    
    ob=CDLIBasket(id,title,shortDescription,comment)
    
    self._setObject(id, ob)
    
    if RESPONSE is not None:
        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':
                
                return "please login first"

            #check if a locked object exist in the basket.
            lockedObjects={}
            for object in self.basketContent:

                if not object[1].lockedBy=="":
                    lockedObjects[object[1].title]=repr(object[1].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" 
        

        for object in self.basketContent:
            
                if (procedure=="downloadAll") or (object[1].lockedBy=='') or (object[1].lockedBy==self.REQUEST['AUTHENTICATED_USER']):
                    ret+=object[0].data
                
                if lock and object[1].lockedBy=='':
                    object[1].lockedBy=self.REQUEST['AUTHENTICATED_USER']

        basket_name=self.aq_parent.title+"_V"+self.getId()
        
        #write basketname to header of atf file
        ret="#atf basket %s\n"%basket_name+ret
        
        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):
        """getUrl of the version of the object"""
        objId=result[1].getTitle()
        founds=self.CDLICatalog.search({'title':objId})
        if len(founds)>0:
             return founds[0].getObject().getLastVersion().absolute_url()
         
        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
 
    lastVersion=self.getLastVersion()
    if lastVersion is None:
        newId=str(1)
    else:
        newId=str(int(lastVersion.getId())+1)
    
    ob=CDLIBasketVersion(newId,user,comment,basketContent)
    
    self._setObject(newId, ob)
    
    if RESPONSE is not None:
        RESPONSE.redirect('manage_main')
    else:
        return ob
    
class CDLIFileObject(versionedFileObject):
    """CDLI file object"""
    
    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')

def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',precondition='', content_type='',
                   REQUEST=None):
    """Add a new File object.

    Creates a new File object 'id' with the contents of 'file'"""

    id=str(id)
    title=str(title)
    content_type=str(content_type)
    precondition=str(precondition)
    
    id, title = cookId(id, title, file)

    self=self.this()

    # 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)
    
    # Now we "upload" the data.  By doing this in two steps, we
    # can use a database trick to make the upload more efficient.
    if file:
        self._getOb(id).manage_upload(file)
    if content_type:
        self._getOb(id).content_type=content_type

    if REQUEST is not None:
        REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
    
class CDLIFile(versionedFile,CatalogAware):
    """CDLI file"""
    
    meta_type="CDLI file"
    default_catalog='CDLICatalog'
    
    
 
    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
        
        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):
        """add"""
        try: #TODO: der ganze vC unsinn muss ueberarbeitet werden
            vC=self.REQUEST['vC']
        except:
            pass
        
        
        if changeName=="yes":
            filename=file.filename
            self.title=filename[max(filename.rfind('/'),
                        filename.rfind('\\'),
                        filename.rfind(':'),
                        )+1:]


        if not newName=='':
            self.title=newName[0:]
        
        

        
        
        positionVersionNum=getattr(self,'positionVersionNum','front')
        
        if positionVersionNum=='front':
            id="V%i"%self.getVersion()+"_"+self.title
        else:
            tmp=os.path.splitext(self.title)
            if len(tmp)>1:
                id=tmp[0]+"_V%i"%self.getVersion()+tmp[1]
            else:
                id=tmp[0]+"_V%i"%self.getVersion()
            
        
        manage_addCDLIFileObject(self,id,vC,author,file,id,precondition, content_type)
        objs=self.ZopeFind(self,obj_ids=[id])[0][1].setVersionNumber(int(self.getVersion()))
        self.REQUEST.SESSION['objID_parent']=self.getId()

        if RESPONSE:
            obj=self.ZopeFind(self,obj_ids=[id])[0][1]
            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:
                RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title)

        else:
            return self.ZopeFind(self,obj_ids=[id])[0][1]
        
        
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):
    """add the OSAS_root"""
    newObj=CDLIFile(id,title,lockedBy,author)
    self._setObject(id,newObj)
   
    if RESPONSE is not None:
        RESPONSE.redirect('manage_main')




def splitatf(fh,dir=None):
    """split it"""
    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:
            if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile
                if nf:
                    nf.close() #close last file
            
                
                filename=line[1:].split("=")[0].rstrip()+".atf"
                if dir:
                    filename=os.path.join(dir,filename)
                nf=file(filename,"w")
            if nf:    
                nf.write(line)
        
    nf.close()
    fh.close()
    return ret,len(os.listdir(dir))


class CDLIFileFolder(versionedFileFolder):
    """CDLI File Folder"""
    
    security=ClassSecurityInfo()
    meta_type="CDLI Folder"
    filesMetaType=['CDLI file']
    folderMetaType=['CDLI Folder']
    default_catalog='CDLICatalog'
    
    def setTemp(self,name,value):
        """set tmp"""

        setattr(self,name,value)
                                        
                                       
    def delete(self,ids):
        """delete this file, i.e. move into a trash folder"""
             
        found=self.ZopeFind(self,obj_ids=['.trash'])
        
        if len(found)<1:
            manage_addCDLIFileFolder(self, '.trash',title="Trash")
            trash=self._getOb('.trash')
        else:
            trash=found[0][1]
        
        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
        if not threadName or threadName=="":
            tmpVar=False

            self._v_uploadATF=uploadATFThread()
           
            #self._xmltrans.start()
            #thread=Thread(target=self._v_uploadATF)
            
            self._v_uploadATF.set(upload,basketId,self.REQUEST['AUTHENTICATED_USER'],serverport=self.REQUEST['SERVER_PORT'])
            #thread.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'])

            if wait_template:
                return wait_template[0][1]()
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
            return pt(txt='/uploadATF')
            #_v_xmltrans.run()
            
        else:

            if not self._v_uploadATF.returnValue:
        

                wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
                if wait_template:
                        return wait_template[0][1]()
                
                pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)

                return pt(txt='/uploadATF')
                
            else:

                tmp=self._v_uploadATF.returnValue
                self._v_uploadATF.continueVar=False
                
                self.REQUEST.SESSION['changed']=[x[0].getId() for x in tmp['changed']]
                self.REQUEST.SESSION['errors']=[x.getId() for x in tmp['errors']]
                self.REQUEST.SESSION['newPs']=tmp['newPs']
                self.REQUEST.SESSION['tmpdir']=tmp['dir']
      
                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'],
                  basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
                                       
    def uploadATFfinally(self,procedure='',comment="",basketname='',unlock=None,repeat=None,RESPONSE=None):
        """nowupload the files"""
       
       
       
        threadName=repeat
        if not threadName or threadName=="":
            
           
            self._v_uploadATF=uploadATFfinallyThread()

        
            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.start()

            
            self.threadName=self._v_uploadATF.getName()[0:]
            wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])

            if wait_template:
                return wait_template[0][1]()
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)

            return pt(txt='/uploadATFfinally')
            #_v_xmltrans.run()
        
        else:
            
            if hasattr(self,'_v_uploadATF') and (self._v_uploadATF is not None) and (not self._v_uploadATF.end) :

                wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
                if wait_template:
                        return wait_template[0][1]()
                
                pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
                return pt(txt='/uploadATFfinally')
            else:

              if RESPONSE is not None:
                  RESPONSE.redirect(self.aq_parent.absolute_url())
                
                                   


    def findObjectsFromList(self,start=None,upload=None,list=None,basketName=None,numberOfObjects=None,RESPONSE=None):
        """findObjectsFromList (, TAB oder LINE separated)"""
                                       
        
        if upload: # list from file upload
            txt=upload.read()
            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:
                    
                    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)
        return pt()
    
    def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/Documents/workspace/cdli/atf", files=None,ext=None):
        """import files"""
        
        if not files:
            files=os.listdir(folderName)
            
        for f in files:
            folder=f[0:3]
            f2=f[0:5]
            obj=self.ZopeFind(self,obj_ids=[folder])
            if ext:
  
                ext.result+="<p>Adding: %s </p>"%f
            if not obj:
                manage_addCDLIFileFolder(self,folder,folder)
                fobj=getattr(self,folder)
        
            else:
                fobj=obj[0][1]
            
            obj2=fobj.ZopeFind(fobj,obj_ids=[f2])
        
            if not obj2:
                manage_addCDLIFileFolder(fobj,f2,f2)
                fobj2=getattr(fobj,f2)
        
            else:
                fobj2=obj2[0][1]
              
            file2=file(os.path.join(folderName,f))   
            id=f
            manage_addCDLIFile(fobj2,f,'','')
            id=f
            ob=fobj2._getOb(f)
            ob.title=id
            
            manage_addCDLIFileObject(ob,id,comment,author,file2,content_type='')
            self.CDLICatalog.catalog_object(ob)
            #self.CDLICatalog.manage_catalogFoundItems(obj_ids=[id],search_sub=1)
            #self.CDLICatalog.manage_catalogObject(self.REQUEST, self.REQUEST.RESPONSE, 'CDLICatalog', urlparse.urlparse(ob.absolute_url())[1])
            
        return "ok"
    
manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals())

    
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)
    ob=self._getOb(id)

    checkPermission=getSecurityManager().checkPermission

    if createUserF:
        if not checkPermission('Add User Folders', ob):
            raise Unauthorized, (
                  'You are not authorized to add User Folders.'
                  )
        ob.manage_addUserFolder()

  
    if REQUEST is not None:
        return self.manage_main(self, REQUEST, update_menu=1)


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