Annotation of cdli/cdli_basket.py, revision 1.7

1.1       dwinter     1: """CDLI extensions of the filearchive"""    
                      2: from Products.versionedFile.extVersionedFile import *
                      3: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
                      4: import os.path
                      5: import os
                      6: import urlparse
                      7: import urllib
                      8: import cgi
                      9: from OFS.OrderedFolder import OrderedFolder
                     10: from OFS.SimpleItem import SimpleItem
                     11: import time
                     12: from OFS.Folder import manage_addFolder
                     13: import re
                     14: from AccessControl import ClassSecurityInfo
                     15: from Acquisition import Implicit
                     16: from Globals import Persistent
                     17: from threading import Thread
                     18: from ZPublisher.HTTPRequest import HTTPRequest
                     19: from ZPublisher.HTTPResponse import HTTPResponse
                     20: from ZPublisher.BaseRequest import RequestContainer
                     21: import threading
                     22: import logging
                     23: import transaction
                     24: import copy
                     25: import codecs
                     26: import sys
                     27: from BTrees.IOBTree import IOBTree 
                     28: import cdliSplitter
                     29: from sets import Set
                     30: import md5
                     31: from DownloadBasket import DownloadBasketFinallyThread
                     32: from types import *
                     33: import pickle
                     34: import tempfile
1.2       dwinter    35: from cdli_files import CDLIFile              
1.3       dwinter    36: from cdli_files import splitatf,checkFile
1.1       dwinter    37: from cdli_helpers import *
1.3       dwinter    38: 
1.1       dwinter    39: class BasketContent(SimpleItem):
                     40:     """classe fuer den Inhalt eines Baskets"""
                     41:    
                     42:     def getFileAndVersionFromId(self,pnum,versionNr):
                     43:        
                     44:         obj=self.cdliRoot.getFileObject(pnum)
                     45:         logging.debug("obj : %s"%obj)
                     46:         version=obj.getVersionNr(versionNr)
                     47:         logging.debug("-------vs: %s"%version.getFileName())
                     48:         return version,obj
                     49:     
                     50:     def __init__(self,content=[]):
                     51:         """content"""
                     52:         
                     53:         self.setContent(content[0:])
                     54:     
                     55:     def getContent(self,filtered=True):
                     56:         return self.contentList
                     57:     
                     58:     def getContentOld(self,filtered=True):
                     59:         """get content"""
                     60:         logging.debug("content object: content List %s"%self.contentList)
                     61:         ret=[]
                     62:         
                     63:         return [self.getFileAndVersionFromId(x[0],x[1]) for x in self.contentList]
                     64: #            
                     65: #        if filtered:
                     66: #            for x in self.contentList:
                     67: #                    if not((x[0] is None) or (x[1] is None)):
                     68: #                            ret.append(x)
                     69: #            logging.debug("content object: content List -done filtered")
                     70: #            return ret
                     71: #            
                     72: #        else:
                     73: #            logging.debug("content object: content List -done  not filtered")
                     74: #            return self.contentList
                     75: 
                     76:     def allContent(self):
                     77:         """get all content"""
                     78:         return self.getContent(filtered=False)
                     79: 
                     80:     def setContent(self,content):
                     81:         contentList=[]
                     82:         for x in content:
                     83:             if not((x[0] is None) or (x[1] is None)):
                     84:             
1.7     ! dwinter    85:                 try: # old version 
        !            86:                     contentList.append((x[1].getId(),x[0].getVersionNumber()))
        !            87:                 except:
        !            88:                     contentList.append(x)
        !            89:                 
        !            90:                 
1.1       dwinter    91:         logging.debug("cl: %s"%contentList)
                     92:         self.contentList=contentList[0:]
                     93:    
                     94:     def numberOfItems(self):
                     95:         """number"""
                     96:         
                     97:         return len(self.getContent())
                     98:         
                     99:     
                    100: class uploadATFfinallyThread(Thread):
                    101:     """class for adding uploaded filed (temporarily stored in the staging area at /tmp"""
                    102:     
                    103:     def __init__(self):
                    104:         """init for uploadATFfinallyThread"""
                    105:         self.continueVar=True
                    106:         self.returnValue=None
                    107:         self.end=False
                    108:         Thread.__init__(self)
                    109:            
                    110:     def set(self,procedure,comment="",basketname='',unlock=None,SESSION=None,username=None,serverport="8080"):
                    111:         """set start values for the thread"""
                    112:         self.procedure=procedure
                    113:         self.comment=comment
                    114:         self.basketname=basketname
                    115:         self.unlock=unlock
                    116:         self.SESSION=SESSION
                    117:         self.username=username
                    118:         self.serverport=serverport
                    119:        
                    120:         
                    121:     def __call__(self):
                    122:         """call of the thread (equals run)"""
                    123:         self.run()
                    124:         return True
                    125:     
                    126:     def getContext(self, app,serverport="8080"):
                    127:         """get the context within the ZODB"""
                    128:         
                    129:         resp = HTTPResponse(stdout=None)
                    130:         env = {
                    131:             'SERVER_NAME':'localhost',
                    132:             'SERVER_PORT':serverport,
                    133:             'REQUEST_METHOD':'GET'
                    134:             }
                    135:         req = HTTPRequest(None, env, resp)
                    136:         return app.__of__(RequestContainer(REQUEST = req))
                    137:           
                    138:         
                    139:     def run(self):
                    140:         """run"""
                    141:         
                    142:         self.result=""
                    143:         #find context within ZODB
1.4       casties   144:         from Zope2 import DB
1.1       dwinter   145:         conn = DB.open()
                    146:         root = conn.root()
                    147:         app  = root['Application']
                    148:         ctx = self.getContext(app,serverport=self.serverport)
                    149: 
                    150:         #add the files
                    151:         self.uploadATFfinallyThread(ctx,self.procedure,comment=self.comment,basketname=self.basketname,unlock=self.unlock,SESSION=self.SESSION,username=self.username)
                    152:         #commit the transactions
                    153:         transaction.get().commit()
                    154:         conn.close()
                    155:         #set flag for end of this method
                    156:         self.end=True
                    157:         logging.info("ended")
                    158:         return True
                    159:     
                    160:     def __del__(self):
                    161:         """delete"""
                    162:         
                    163:         
                    164:     
                    165:     def getResult(self):
                    166:         """method for accessing result"""
                    167:         
                    168:         return self.result
                    169:      
                    170:     def uploadATFfinallyThread(self,ctx,procedure,comment="",basketname='',unlock=None,RESPONSE=None,SESSION=None,username=None):
                    171:         """upload the files"""
                    172:         #TODO: make this configurable, at the moment, rootFolder for cdli has to be cdliRoot
                    173:         ctx2=ctx.cdliRoot
                    174:    
                    175:         self.result+="<h2>Start processing</h2>"
                    176:         
                    177:         #shall I only upload the changed files?
                    178:         logging.debug("uploadATFfinally procedure: %s"%procedure)
                    179:         if procedure=="uploadchanged":
                    180:             changed=[x[0] for x in SESSION.get('changed',[])]
                    181:             uploadFns=changed+SESSION.get('newPs',[])
                    182:         
                    183:         #or all
                    184:         elif procedure=="uploadAll":
                    185:             uploadFns=[]
                    186:             for x in os.listdir(SESSION['tmpdir']):
                    187:                 if not x in SESSION['lockerrors']:
                    188:                     uploadFns.append(x)
                    189:                     
                    190:         #or maybe nothing
                    191:         elif procedure=="noupload":
                    192:             return True
                    193:         else:
                    194:             uploadFns=[]
                    195:             
                    196:         #do first the changed files    
                    197:         i=0
                    198:         for fn in uploadFns:
                    199:             logging.debug("uploadATFfinally uploadFn=%s"%fn)
                    200:             i+=1
                    201:             founds=ctx2.CDLICatalog.search({'title':fn})
                    202:             if len(founds)>0:
                    203:                 SESSION['author']=str(username)
                    204:                 self.result="<p>Changing : %s"%fn+self.result
                    205:                 logging.debug("uploadatffinallythread changing:%s"%fn+self.result)
                    206:                 founds[0].getObject().manage_addCDLIFileObject('',comment,SESSION['author'],file=os.path.join(SESSION['tmpdir'],fn),from_tmp=True)
                    207:             if i%200==0:
                    208:                 transaction.get().commit()
                    209:                 logging.debug("uploadatffinallythread changing: do commit")
                    210:         
                    211:         transaction.get().commit()
                    212:         logging.debug("uploadatffinallythread changing: last commit")
                    213: 
                    214:         #now add the new files        
                    215:         newPs=SESSION['newPs']
                    216:         if len(newPs)>0:
                    217:             tmpDir=SESSION['tmpdir']
                    218:             logging.debug("uploadatffinallythread adding start")
                    219:             self.result="<p>Adding files</p>"+self.result
                    220:             #TODO: make this configurable, at the moment base folder for the files has to be cdli_main
                    221:             ctx2.importFiles(comment=comment,author=str(username) ,folderName=tmpDir, files=newPs,ext=self)
                    222:             logging.debug("uploadatffinallythread adding finished")
                    223:         
                    224:         #unlock locked files?
                    225:         if unlock:
                    226:             logging.debug("uploadatffinallythread unlocking start")
                    227:             self.result="<p>Unlock files</p>"+self.result
                    228:             unlockFns=[]
                    229:             for x in os.listdir(SESSION['tmpdir']):
                    230:                     if not x in SESSION['errors']:
                    231:                         unlockFns.append(x)
                    232:                         
                    233:             logging.debug("unlocking have now what to unlock")
                    234:                         
                    235:             for fn in unlockFns:
                    236:                 #logging.info("will unlock: %s"%fn)
                    237:                 founds=ctx2.CDLICatalog.search({'title':fn})
                    238:                 #logging.info("found it: %s"%repr(founds))
                    239:                 if len(founds)>0:
                    240:                     #logging.info("unlock: %s"%founds[0].getObject().getId())
                    241:                     SESSION['author']=str(username)
                    242:                     founds[0].getObject().lockedBy=""
                    243: 
                    244:             logging.debug("uploadatffinallythread unlocking done")
                    245:                     
                    246:         #if a basketname is given, add files to the basket
                    247:         if not (basketname ==''):
                    248:             logging.debug("uploadatffinallythread add to basket %s"%basketname)
                    249:             self.result="<p>Add to basket</p>"+self.result
                    250:             basketId=ctx2.basketContainer.getBasketIdfromName(basketname)
                    251:             
                    252:             if not basketId: # create new basket
                    253:                 logging.debug("uploadatffinallythread create basket %s"%basketname)
                    254:                 self.result="<p>Create a new basket</p>"+self.result
                    255:                 ob=ctx2.basketContainer.addBasket(basketname)
                    256:                 basketId=ob.getId()
                    257:             basket=getattr(ctx2.basketContainer,str(basketId))
                    258:             ids=os.listdir(SESSION['tmpdir'])
                    259:             #logging.debug("should add:"+repr(ids))
                    260:             basket.addObjects(ids,deleteOld=True,username=str(username))    
                    261:                
                    262:         logging.debug("uploadatffinallythread uploadfinally done")
                    263: 
                    264:         if RESPONSE is not None:
                    265:             RESPONSE.redirect(self.aq_parent.absolute_url())
                    266:         
                    267:         return True
                    268: 
                    269: class tmpStore(SimpleItem):
                    270:     """simple item"""
                    271:     meta_type="cdli_upload"
                    272:     
                    273:     def __init__(self,id):
                    274:         """init tmp"""
                    275:         self.id=id
                    276:         
                    277: class uploadATFThread(Thread):
                    278:     """class for checking the files befor uploading"""
                    279:     
                    280:     def __init__(self):
                    281:         """initialise"""
                    282:         
                    283:         self.continueVar=True
                    284:         self.returnValue=None
                    285:         
                    286:         Thread.__init__(self)
                    287:         
                    288:         
                    289:     def set(self,upload,basketId,username,idTmp,serverport="8080"):
                    290:         """set start values for the thread"""
                    291:         self.result=""
                    292:         self.upload=upload
                    293:         self.basketId=basketId
                    294:         self.username=username
                    295:         self.serverport=serverport
                    296:         self.idTmp=idTmp
                    297:         
                    298:     def __call__(self):
                    299:         """call method """
                    300:         self.run()
                    301:         return True
                    302:     
                    303:     def getContext(self, app,serverport="8080"):
                    304:         """get the context within the ZODB"""
                    305:         resp = HTTPResponse(stdout=None)
                    306:         env = {
                    307:             'SERVER_NAME':'localhost',
                    308:             'SERVER_PORT':serverport,
                    309:             'REQUEST_METHOD':'GET'
                    310:             }
                    311:         req = HTTPRequest(None, env, resp)
                    312:         return app.__of__(RequestContainer(REQUEST = req))
                    313:         
                    314:     def run(self):
                    315:         idTmp=self.idTmp
                    316:         self.result=""
                    317:         #find context within ZODB
1.4       casties   318:         from Zope2 import DB
1.1       dwinter   319:         conn = DB.open()
                    320:         root = conn.root()
                    321:         app  = root['Application']
                    322:         ctx = self.getContext(app,serverport=self.serverport)
                    323:         logging.info("run intern")
                    324:         try:
                    325:             logging.info("created: %s"%idTmp)
                    326:             ctx.temp_folder._setObject(idTmp,tmpStore(idTmp))
                    327:         except:
                    328:             logging.error("thread upload: %s %s"%sys.exc_info()[0:2])
                    329:             
                    330:         logging.info("call thread intern")
                    331:         self.uploadATFThread(ctx,self.upload,idTmp,self.basketId)
                    332:      
                    333:         #ctx.cdliRoot.cdli_main.tmpStore2[self.getName()[0:]]=self.returnValue
                    334:         
                    335:         
                    336:         transaction.get().commit()
                    337:        
                    338:         conn.close()
                    339:         
                    340:         return getattr(ctx.temp_folder,idTmp)
                    341:         
                    342:     def getResult(self):
                    343:         """method for accessing result"""
                    344:         return self.result
                    345:     
                    346:     def uploadATFThread(self,ctx,upload,idTmp,basketId=0):
                    347:         """upload an atf file"""
                    348:         #TODO: add comments
                    349:         #TODO: finish uploadATF
                    350:         
                    351:         stObj=getattr(ctx.temp_folder,idTmp)
                    352:         logging.info("start, upload thread")
                    353:         self.result="<html><body><h2>I got your file, start now to split it into single atf-files!</h2><p>"
                    354:     
                    355:         #make sure that id is a string and not an integer
                    356:         basketId=str(basketId)
1.3       dwinter   357:         logging.info("basketID:"+basketId)
1.1       dwinter   358:         #TODO: make this configurable, at the moment, rootFolder for cdli has to be cdliRoot
                    359:         ctx2=ctx.cdliRoot
                    360:         
                    361:         #get temporary file for staging the downloaded and splitted files
                    362:         dir=tempfile.mkdtemp()
                    363:         
1.3       dwinter   364:         logging.info("tmpfFile:"+str(dir))
1.1       dwinter   365:         changed=[] # changed files
                    366:         errors=[]  # files with errors
                    367:         lockerrors=[]  # files with errors
                    368: 
                    369:         newPs=[]   # new p filed
                    370:         psNotInCatalog=[] # files not in the catalog
                    371:         
                    372:         #split the uploadedd atf file
1.3       dwinter   373:         logging.info("start splitting")
1.1       dwinter   374:         basketNameFromFile, numberOfFiles=splitatf(upload,dir,ext=self)
                    375:         
                    376:         #find basketId if not set
                    377:         
                    378:         #get active abaket
                    379:         if basketId == '0':
                    380:             basketObj=ctx2.basketContainer.getActiveBasket()
                    381:             if basketObj:
                    382:                 basketId=basketObj.getId()
                    383:                 
                    384:         #if there is no active basket and no basketid given, id is empty, else get besketname and length
                    385:         if basketId == '0':
                    386:             basketNameFromId=""
                    387:             basketLen=0
                    388:         else:
                    389:             basketNameFromId=getattr(ctx2.basketContainer,basketId).title
                    390:             basketLen=getattr(ctx2.basketContainer,basketId).getLastVersion().numberOfItems()
                    391:             
                    392:         logging.info("got the file, upload thread")
                    393:         self.result+="""<html><body><h2>I got the files</h2><
                    394:                         p>I am computing the differences to the exisiting files</p>"""
                    395:                                    
                    396:         #start to check the files
                    397:         for fn in os.listdir(dir):
                    398:             
                    399:             self.result="<p>process:%s</p>"%fn+self.result
                    400:             
                    401:             # check if file is in the catalog
                    402:             #TODO: checkCatalog is not implemented yet
                    403:             if ctx2.cdli_main.checkCatalog(fn):
                    404:                 psNotInCatalog.append(fn)
                    405:                 
                    406:             #check if p-file already at the server  
                    407:             founds=ctx2.CDLICatalog.search({'title':fn})    
                    408:       
                    409:             #if not than add filename to the list of newfiles
                    410:             
                    411:             data=file(os.path.join(dir,fn)).read()
                    412:             status,msg=checkFile(fn,data,dir)
                    413:             #status=True
                    414:             
                    415:             
                    416:             if not status: # error
                    417:                 errors.append((fn,msg))
                    418:             
                    419:             else:
                    420:                 if len(founds)==0:
                    421:                     newPs.append(fn)
                    422: 
                    423:                 #if p file alread at the server    
                    424:                 for found in founds:
                    425:                     #analyse the differences to the actual file
                    426:                     obj=found.getObject()
                    427: 
                    428:                     if (not (str(obj.lockedBy))=='') and (not (str(obj.lockedBy)==str(self.username))):
                    429:                                 lockerrors.append((fn,str(obj.lockedBy)))
                    430:                     else:
                    431:                 
                    432:                         diffs=obj.diff(data)
                    433:                         if diffs[0]>0:
                    434:                             changed.append((obj,diffs)) #hochladen
                    435: 
                    436:         #ready, set the returnValues
                    437:         self.result+="<h3>Done</h3></body></html>"
                    438:         
                    439:         stObj.returnValue={}
                    440:         
                    441:         stObj.returnValue['errors']=errors
                    442:         
                    443:         stObj.returnValue['newPs']=newPs
                    444:         stObj.returnValue['tmpdir']=dir
                    445:         stObj.returnValue['basketLen']=basketLen
                    446:         stObj.returnValue['numberOfFiles']=numberOfFiles
                    447:         stObj.returnValue['basketNameFromId']=basketNameFromId
                    448:         stObj.returnValue['basketNameFromFile']=basketNameFromFile
                    449:         stObj.returnValue['basketId']=basketId
                    450:         stObj.returnValue['dir']=dir
                    451:         #stObj.returnValue['changed']=copy.copy(changed)
                    452:         stObj.returnValue['changed']=[(x[0].getId(),x[1][0]) for x in changed]
                    453:         #stObj.returnValue['lockerrors']=[x[0].getId() for x in lockerrors]
                    454:         stObj.returnValue['lockerrors']=[x for x in lockerrors]
                    455:         self.returnValue=True
                    456:         #ctx2.cdli_main.setTemp('v_uploadATF_returnValue',True)
                    457:     
                    458: class CDLIBasketContainer(OrderedFolder):
                    459:     """contains the baskets"""
                    460:     
                    461: 
                    462:     security=ClassSecurityInfo()
                    463:     meta_type="CDLIBasketContainer"
                    464:     
                    465:     def getResultHash(self):
                    466:         """get the result hash for debug purposes"""
                    467:         return self.resultHash.keys()
                    468:     
                    469:     def getPNumbersOfBasket(self,basketName):
                    470:         """get all pnumbers of a basket as a list, returns an empty list if basket not found
                    471:         @param basketName: name of the basket
                    472:         """
                    473:         ret=[]
                    474:         basketId=self.getBasketIdfromName(basketName)
                    475:         if not basketId:
                    476:             return []
                    477:         
                    478:         ob=getattr(self,basketId).getContent() #get the content of a basket
                    479:         
                    480:         ret=[x[0].split(".")[0] for x in ob]
                    481:         
                    482:         return ret
                    483:     
                    484:     security.declareProtected('manage','getBasketAsOneFile')       
                    485:     def getBasketAsOneFile(self,basketName,current="no"):
                    486:         """returns all files of the basket combined in one file
                    487:         @param basketName: Name of the basket
                    488:         @param current: (optional) if current is set to "yes" then the most current version of 
                    489:                         all files are downloaded and not the versions of the files as stored in the basket
                    490:         """
                    491:         ret=""
                    492:         basketId=self.getBasketIdfromName(basketName)
                    493:         if not basketId:
                    494:             return ""
                    495:         
                    496:         ob=getattr(self,basketId).getLastVersion()
                    497:         for pnum,versionNr in ob.getContent():
                    498:             obj=self.cdliRoot.getFileObject(pnum)
                    499:        # logging.debug("obj : %s"%obj)
                    500:        # version=obj.getVersionNr(versionNr)
                    501:       
                    502:             if current=="no": #version as they are in the basket
                    503:                             cur= obj.getVersionNr(versionNr)
                    504:                             ret+=str(cur.getData())+"\n"
                    505:             elif current=="yes":
                    506:                             #search current object
                    507:                             #logging.debug("current: %s"%object[1].getId().split(".")[0])
                    508:                             obj.getData()
                    509:         return ret
                    510:     
                    511:     security.declareProtected('manage','upDateBaskets') 
                    512:     def upDateBaskets(self):
                    513:         """update content in to objects"""
                    514:         
                    515:         founds=self.ZopeFind(self,obj_metatypes=['CDLIBasketVersion'],search_sub=1)
                    516: 
                    517:         for found in founds:
                    518:             found[1].updateBasket()
                    519:         
                    520:     security.declareProtected('manage','deleteBaskets')        
                    521:     def deleteBaskets(self,ids=None):
                    522:         """delete baskets, i.e. move them into trash folder"""
                    523:         
                    524:         if ids is None:
                    525:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
                    526:             txt="Sorry, no basket selected!"
                    527:             return pt(txt=txt)
                    528:         
                    529:         found=self.ZopeFind(self,obj_ids=['trash'])
                    530:         
                    531:         if len(found)<1:
                    532:             manage_addFolder(self, 'trash')
                    533:             trash=self._getOb('trash')
                    534:         else:
                    535:             trash=found[0][1]
                    536:         
                    537:         if type(ids) is not ListType:
                    538:             ids=[ids]
                    539:         logging.error("XERXON:"+repr(ids))
                    540:         if len(ids)==0:
                    541:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
                    542:             txt="Sorry, no basket selected!"
                    543:             return pt(txt=txt)
                    544:    
                    545:         cut=self.manage_cutObjects(ids)
                    546:         trash.manage_pasteObjects(cut)
                    547:         return None
                    548:     security.declareProtected('manage','manageBaskets')       
                    549:     def manageBaskets(self,submit,ids=None,basket1="",basket2="",joinBasket="",subtractBasket="",REQUEST=None,RESPONSE=None):
                    550:         """manage baskets, delete or copy"""
                    551:         if submit=="delete":
                    552:             ret= self.deleteBaskets(ids)
                    553:             if ret:
                    554:                 return ret
                    555:         elif submit=="join":
                    556:             flag,msg=self.joinBasket(joinBasket, ids)
                    557:             logging.info("joining %s %s"%(flag,msg))
                    558:             if not flag:
                    559:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
                    560:                 
                    561:                 return pt(txt=msg)
                    562:        
                    563:         elif submit=="subtract":
                    564:             logging.info("BBBb %s %s"%(basket1,basket2))
                    565:             flag,msg=self.subtractBasket(subtractBasket, basket1,basket2)
                    566:             logging.info("subtract %s %s"%(flag,msg))
                    567:             
                    568:         if RESPONSE:
                    569:             RESPONSE.redirect(self.absolute_url())
                    570:     
                    571:     security.declareProtected('View','getBasketIdfromName')       
                    572:     def getBasketIdfromName(self,basketname):
                    573:         """get id from name"""
                    574: 
                    575:         for basket in self.ZopeFind(self,obj_metatypes=["CDLIBasket"]):
                    576:             if basket[1].title==basketname:
                    577:                 return basket[0]
                    578:         else:
                    579:             None
                    580:     
                    581:     security.declareProtected('manage','uploadBasket_html')        
1.5       dwinter   582:    
                    583:     def uploadBasketAsync_html(self,basketId='0'):
                    584:         """upload an atf file, html form, jetzt aufruf der nicht asyncronen version mit ticktes"""
                    585:         
                    586: 
                    587:         basketId=str(basketId)
                    588:         if not basketId=='0':
                    589:             basketName=getattr(self.basketContainer,basketId).title
                    590:         else:
                    591:             basketName=""
                    592:             
                    593:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasketAsync_html.zpt')).__of__(self)
                    594:         return pt(basketId=basketId,basketName=basketName)
                    595:    
                    596: 
1.1       dwinter   597:             
                    598:     def uploadBasket_html(self,basketId='0'):
                    599:         """upload an atf file, html form"""
                    600:         
                    601: 
                    602:         basketId=str(basketId)
                    603:         if not basketId=='0':
                    604:             basketName=getattr(self.basketContainer,basketId).title
                    605:         else:
                    606:             basketName=""
                    607:             
                    608:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasket_html.zpt')).__of__(self)
                    609:         return pt(basketId=basketId,basketName=basketName)
                    610:    
                    611: 
                    612:     security.declareProtected('manage','index_html')    
                    613:     def index_html(self):
                    614:         """stanadard ansicht"""
                    615:         
                    616: 
                    617: 
                    618:         ext=self.ZopeFind(self,obj_ids=["index.html"])
                    619:         if ext:
                    620:             return ext[0][1]()
                    621:         
                    622:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self)
                    623:         return pt()
                    624:     
                    625:     def getStorageFolderRoot(self):
                    626:         """root des storage folders"""
                    627:         return self.cdli_main
                    628:     
                    629:     def __init__(self,id,title):
                    630:         """ init basket container"""
                    631:         self.id=id
                    632:         self.title=title
                    633:      
                    634:  
                    635:     def getBasketsId(self):
                    636:         """get all baskets als klartext"""
                    637:         
                    638:         ret=""
                    639:         baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
                    640:         for basket in baskets:
                    641:             com,user,time,values = basket[1].getContentIds()
                    642:             ret+= "BASKET:"+com+"\t"+user+"\t"+time+"\n"
                    643:             for x in values:
                    644:                 ret+= x[0]+"\t"+x[1]+"\n"
                    645:                 return ret
                    646: 
                    647:     def getBaskets(self,sortField='title'):
                    648:         """get all baskets files"""
                    649: 
                    650:         def sortName(x,y):
                    651:             return cmp(x[1].title.lower(),y[1].title.lower())
                    652: 
                    653:         def sortDate(x,y):
                    654:             return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())
                    655: 
                    656:         
                    657:         def sortComment(x,y):
                    658: 
                    659:         
                    660:             
                    661:              try:
                    662:                 xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()
                    663:              except:
                    664:                 xc='ZZZZZZZZZZZZZ'.lower()
                    665:              try:
                    666:                 yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()
                    667:              except:
                    668:                 yc='ZZZZZZZZZZZZZ'.lower()
                    669:     
                    670:     
                    671:              if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):
                    672:                  
                    673:                  try:
                    674:                      xc=x[1].getLastVersion().getComment().lower()
                    675:                  except:
                    676:                      xc='ZZZZZZZZZZZZZ'.lower()
                    677:                      
                    678:              if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):
                    679:                  try:
                    680:                      yc=y[1].getLastVersion().getComment().lower()
                    681:                  except:
                    682:                      yc='ZZZZZZZZZZZZZ'.lower()
                    683:     
                    684:              
                    685:                  return cmp(xc,yc)
                    686:         
                    687:         def sortAuthor(x,y):
                    688:             
                    689:             return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower())
                    690:         
                    691:         baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
                    692:         
                    693:         
                    694:         if sortField=='title':
                    695:             baskets.sort(sortName)
                    696:         elif sortField=='date':
                    697:             baskets.sort(sortDate)
                    698:         elif sortField=='author':
                    699:             baskets.sort(sortAuthor)
                    700:         elif sortField=='comment':
                    701:             baskets.sort(sortComment)
                    702: 
                    703:         return baskets
                    704:     
                    705:         
                    706:     def subtractBasket(self,newBasket,basket1,basket2):
                    707:         """subtract basket2 from basket1 
                    708:         (i.e. newbasket will contain alle elements of basket1 which are not in basket2), 
                    709:         if basket2 contains files which are not in basket1, then theses files fill be ignored
                    710:                
                    711:         @param newbasket: name of the new basket
                    712:         @param basket1: basket where basket2 will be subtracted from
                    713:         @param basket2: see above
                    714:       
                    715:         """
                    716:         
                    717:         logging.info("CCCCC %s %s"%(basket1,basket2))
                    718:    
                    719:         try:
                    720:             newB=self.addBasket(newBasket)
                    721:         except:
                    722:             return False, "cannot create the new basket"
                    723:         
                    724:         
                    725: 
                    726:        
                    727:      
                    728:         bas2= getattr(self,basket2)            
                    729:         bas2content=bas2.getContent()
                    730:         bas2ids=[x[0] for x in bas2content]
                    731:         
                    732:        
                    733:             
                    734:         bas1= getattr(self,basket1)   
                    735:         bas1content=bas1.getContent()
                    736:         
                    737:         
                    738:         newBasketContent={}
                    739:         
                    740:         for id,version in bas1content:
                    741:             if not (id in bas2ids):
                    742:                 newBasketContent[id]=version
                    743:         
                    744:         username=self.getActualUserName()
                    745:         
                    746:         logging.info("sbc %s"%newBasketContent)
                    747:         newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
                    748:         
                    749:         return True, ""
                    750:     
                    751:             
                    752:     def joinBasket(self,newBasket,oldBaskets):
                    753:         """join two baskets
                    754:         @param newbasket: name of the new basket
                    755:         @param oldbaskets: list of baskets to be joined
                    756:         """
                    757:         if oldBaskets is None:
                    758:             return False, "No Baskets selected!"
                    759:         
                    760:         try:
                    761:             newB=self.addBasket(newBasket)
                    762:         except:
                    763:             return False, "cannot create the new basket"
                    764:         
                    765:         newBasketContent={}
                    766:      
                    767:         for ob in oldBaskets:
                    768:             x= getattr(self,ob,None)
                    769:             if x is None:
                    770:                 return False, "cannot find basket: %s"%ob
                    771:             
                    772:             ids=x.getContent() # hole den Inhalt
                    773:             
                    774:             for id,version in ids:
                    775:                 if newBasketContent.has_key(id): # p number gibt's schon
                    776:                     newBasketContent[id]=max(newBasketContent[id],version) # speichere die groessere Versionsnumber
                    777:                 else:
                    778:                     newBasketContent[id]=version
                    779:         username=self.getActualUserName()
                    780:         
                    781:         logging.info("nbc %s"%newBasketContent)
                    782:         newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
                    783:         
                    784:         return True, ""
                    785:     
                    786:     def getNewId(self):
                    787:         """createIds"""
                    788:         last=getattr(self,'last',0)
                    789:         last +=1
                    790:         while len(self.ZopeFind(self,obj_ids=[str(last)]))>0:
                    791:             last+=1
                    792:     
                    793:         self.last=last
                    794:         return last
                    795:     
                    796:     def setActiveBasket(self,basketId,REQUEST=None):
                    797:         """store active basketId in a cookie"""
                    798:         self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/")
                    799:         try:
                    800:             qs=cgi.parse_qs(REQUEST['QUERY_STRING'])
                    801:             del(qs['basketId'])
                    802:         except:
                    803:             qs={}
                    804:         if REQUEST:
                    805:             REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+urllib.urlencode(qs))
                    806:             
                    807:     def getActiveBasket(self):
                    808:         """get active basket from cookie"""
                    809:         
                    810:         id= self.REQUEST.cookies.get('CDLIActiveBasket',None)
                    811:         if id:
                    812:             obj=getattr(self,str(id),None)
                    813:         else:
                    814:             obj=None
                    815:         return obj
                    816:     
                    817:     def getActualUserName(self):
                    818:         """get name of the actualuser"""
                    819:         return str(self.REQUEST['AUTHENTICATED_USER'])
                    820:     
                    821:     security.declareProtected('manage','addBasket') 
                    822:     def addBasket(self,newBasketName):
                    823:         """add a new basket"""
                    824:         
                    825:         ob=manage_addCDLIBasket(self,newBasketName)
                    826:         return ob
                    827: 
                    828:     def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None):
                    829:         """store it"""
                    830:         if not ids:
                    831:             ids=self.REQUEST.SESSION['fileIds']
                    832:            
                    833:         if (type(ids) is not ListType) and (not isinstance(ids,Set)):
                    834:             ids=[ids]
                    835:         
                    836:         if isinstance(ids,Set):
                    837:             ids=list(ids)
                    838:             
                    839:         if (submit.lower()=="store in new basket") or (submit.lower()=="new basket"):
                    840:             basketRet=self.addBasket(newBasketName)
                    841:             self.setActiveBasket(basketRet.getId())
                    842:             basket=getattr(self,basketRet.getId())
                    843:         elif (submit.lower()=="store in active basket") or (submit.lower()=="active basket"):
                    844:             basket=self.getActiveBasket()
                    845:         
                    846:         added=basket.addObjects(ids)
                    847:         back=self.REQUEST['HTTP_REFERER'].split("?")[0]+"?basketName="+basket.title+"&numberOfObjects="+str(added)
                    848:         
                    849:         
                    850:         if fromFileList:
                    851: 
                    852:             return self.cdli_main.findObjectsFromList(list=ids,basketName=basket.title,numberOfObjects=added)
                    853:        
                    854:         if RESPONSE:
                    855:             
                    856:             RESPONSE.redirect(back)
                    857:             
                    858:         return True
                    859:     
                    860: def manage_addCDLIBasketContainerForm(self):
                    861:     """add the CDLIBasketContainer form"""
                    862:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self)
                    863:     return pt()
                    864: 
                    865: def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None):
                    866:     """add the basket"""
                    867:     ob=CDLIBasketContainer(id,title)
                    868:     
                    869:     self._setObject(id, ob)
                    870:     
                    871:     if RESPONSE is not None:
                    872:         RESPONSE.redirect('manage_main')
                    873: 
                    874: class CDLIBasket(Folder,CatalogAware):
                    875:     """basket"""
                    876:     
                    877:     meta_type="CDLIBasket"
                    878:     default_catalog="CDLIBasketCatalog"
                    879:     
                    880:     def searchInBasket(self,indexName,searchStr,regExp=False):
                    881:         """searchInBasket"""
                    882: 
                    883:         lst=self.searchInLineIndexDocs(indexName,searchStr,uniq=True,regExp=regExp) #TODO: fix this
                    884:         ret={}
                    885:         
                    886:         lv=self.getLastVersion()
                    887: 
                    888: 
                    889:         for obj in lv.content.getContent():
                    890:             id=obj[1].getId().split(".")[0]
                    891:             if id in lst:
                    892:         
                    893:                 ret[id]=self.showWordInFile(id,searchStr,lineList=self.getLinesFromIndex(indexName,searchStr,id,regExp=regExp),regExp=regExp,indexName=indexName)
                    894:         
                    895:         
                    896:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','searchResultsInBasket')).__of__(self)
                    897:         return pt(result=ret,indexName=indexName,regExp=regExp,word=searchStr)
                    898:         
                    899:          
                    900:  
                    901:         
                    902:     def searchInBasket_v1(self,searchStr):
                    903:         """search occurences of searchStr in files im basket"""
                    904:         ret=[]
                    905:         lv=self.getLastVersion()
                    906:         logging.info("searching")
                    907:         for obj in lv.content.getContent():
                    908:             txt=obj[0].getData()
                    909:             for x in txt.split("\n"):
                    910:                 logging.info("search %s"%x)
                    911:                 if re.match(searchStr,x):
                    912:                     ret.append(x)
                    913:         
                    914:         return "\n".join(ret)
                    915:                 
                    916:             
                    917:     def getFile(self,obj):
                    918:         return obj[1]
                    919:     
                    920:     def getFileLastVersion(self,obj):
                    921:         return obj[0]
                    922:     
                    923:     def getFileNamesInLastVersion(self):
                    924:         """get content of the last version as list"""
                    925:         
                    926:         return [x[1].getId() for x in self.getLastVersion().getContent()]
                    927:     
                    928: 
                    929:     def isActual(self,obj,nummer):
                    930:         """teste ob im basket die aktuelle version ist, obj kann entweder ein CDLIFile sein oder eine 
                    931:         eine pnummer, die auf ein CDLIFile verweist"""
                    932:         try:
                    933:             #logging.debug("isActual:"+repr(obj))
                    934:             if isinstance(obj, CDLIFile):
                    935:                 actualNo=obj.getLastVersion().getVersionNumber()
                    936:             else:
                    937:                 actualNo=self.cdliRoot.getFileObjectLastVersion(obj).getVersionNumber()
                    938:             
                    939:             if actualNo==nummer:
                    940:                 return True , 0
                    941:             else:
                    942:                 return False, actualNo
                    943:         except:
                    944:             logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
                    945:             logging.error("""         PARAMS: %s %s"""%(obj,nummer))
                    946:             return False, -1
                    947:     def isActualOld(self,obj):
                    948:         """teste ob im basket die aktuelle version ist"""
                    949:         try:
                    950:             #logging.debug("isActual:"+repr(obj))
                    951:             actualNo=obj[1].getLastVersion().getVersionNumber()
                    952:             storedNo=obj[0].getVersionNumber()
                    953:             
                    954:            
                    955:             #actualNo=self.getFileObjectLastVersion(obj.getId()).getVersionNumber()
                    956:                 
                    957:             #if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash":
                    958:             #    return False, -1
                    959:             
                    960:             if actualNo==storedNo:
                    961:                 return True , 0
                    962:             else:
                    963:                 return False, actualNo
                    964:         except:
                    965:             logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
                    966:     
                    967:             return False, -1
                    968:             
                    969:     def history(self):
                    970:         """history"""  
                    971: 
                    972:         ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
                    973:         if ext:
                    974:             return getattr(self,ext[0][1].getId())()
                    975:         
                    976:         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self)
                    977:         return pt()
                    978:     
                    979:     def getStorageFolderRoot(self):
                    980:         """root des storage folders"""
                    981:         return self.aq_parent.cdli_main
                    982:     
                    983:     def __init__(self,id,title,shortDescription="",comment=""):
                    984:         """init a CDLIBasket"""
                    985:         
                    986:         self.id=id
                    987:         self.title=title
                    988:         self.shortDescription=shortDescription
                    989:         self.comment=comment
                    990:  
                    991:     def getActualUserName(self):
                    992:         """get name of the actualuser"""
                    993:        
                    994:         return str(self.REQUEST['AUTHENTICATED_USER'])
                    995:   
                    996:            
                    997:     def getLastVersion(self):
                    998:         """hole letzte version"""
                    999: 
                   1000:         ids=[]
                   1001:         idsTmp= self.objectIds()
                   1002:         for x in idsTmp:
                   1003:             try:
                   1004:                 ids.append(int(x))
                   1005:             except:
                   1006:                 pass
                   1007:         ids.sort()
                   1008:       
                   1009:         if len(ids)==0:
                   1010:             return None
                   1011:         else:    
                   1012:             ob=getattr(self,str(ids[-1]))
                   1013: 
                   1014:             
                   1015:             return ob
                   1016:    
                   1017:     def getVersions(self):
                   1018:         """get versions"""
                   1019:         versions=self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])
                   1020:         return versions
                   1021: 
                   1022:    
1.7     ! dwinter  1023:     def updateObjects(self,ids=[],RESPONSE=None,REQUEST=None):
        !          1024:         """update ids, ids not in the basket then add"""
        !          1025:         logging.debug("update")
        !          1026:         logging.debug(repr(ids))
1.1       dwinter  1027:         if type(ids) is not ListType:
                   1028:             ids=[ids]
                   1029:        
                   1030:         lastVersion=self.getLastVersion() 
                   1031:         oldContent=lastVersion.content.getContent()
                   1032:         newContent=[]
                   1033:         
1.7     ! dwinter  1034:         #keine ids dann alle update
        !          1035:         if len(ids)==0:
        !          1036:             ids=[x[0] for x in oldContent]
        !          1037:             
        !          1038:         #first copy the id not to be updated
1.1       dwinter  1039:         for obj in oldContent:
1.7     ! dwinter  1040:             logging.debug("obj:"+repr(obj))
        !          1041:             try: # old format of the basket 
        !          1042:                 if obj[1].getId() not in ids:
        !          1043:                     newContent.append(obj)
        !          1044:             except:
        !          1045:                 if obj[0] not in ids:
        !          1046:                     newContent.append(obj)
1.1       dwinter  1047:         #now add the new
                   1048:                
                   1049:         for id in ids:
                   1050:             founds=self.CDLICatalog.search({'title':id})
                   1051: 
                   1052:             for found in founds:
                   1053:                 if found.getObject() not in oldContent:
                   1054:                     #TODO: was passiert wenn, man eine Object dazufuegt, das schon da ist aber eine neuere version
1.7     ! dwinter  1055:                     newContent.append((id,found.getObject().getLastVersion().getVersionNumber()))
1.1       dwinter  1056:         
                   1057: 
                   1058:         content=newContent 
                   1059:         user=self.getActualUserName()
1.7     ! dwinter  1060:         logging.debug(newContent)
1.1       dwinter  1061:         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
                   1062:         
                   1063:         obj=self._getOb(ob.getId())
1.7     ! dwinter  1064:         logging.debug(repr(obj))
        !          1065:         logging.debug("done")
        !          1066:         logging.debug(obj.absolute_url())
1.1       dwinter  1067:         if RESPONSE:
1.7     ! dwinter  1068:             logging.debug("redirect")
1.1       dwinter  1069:             RESPONSE.redirect(obj.absolute_url())
                   1070:         
                   1071:         return obj
                   1072:     
                   1073:     def addObjectsWithVersion(self,ids,deleteOld=None,username=None,catalog=None):
                   1074:         """generate a new version of the basket with objects added, 
                   1075:         hier wird jedoch nicht die letzte Version jedes Files hinzugefuegt, s
                   1076:         ondern ids is ein Tupel mit der Id (d.h. der p-number) und der Versionsnummer.
                   1077:         """
                   1078:         logging.info("add to basket (%s)"%(self.getId()))
                   1079:         lastVersion=self.getLastVersion()
                   1080:         
                   1081:         if not catalog:
                   1082:             catalog=self.CDLICatalog
                   1083:             
                   1084:         if lastVersion is None:
                   1085:             oldContent=[]
                   1086:         else:
                   1087:             oldContent=lastVersion.content.getContent()
                   1088: 
                   1089:         if deleteOld:
                   1090:             oldContent=[]
                   1091: 
                   1092:         newContent=[]
                   1093:         added=0
                   1094:        
                   1095:         for id,version in ids.iteritems():
                   1096:             logging.info("adding %s %s"%(id,version))
                   1097:             id=id.split(".")[0] # title nur die pnumber ohne atf
                   1098:            
                   1099:             try:
                   1100:                 founds=catalog.search({'title':id})
                   1101:             except:
                   1102:                 founds=[]
                   1103:             logging.info(" found %s "%(founds))
                   1104:             for found in founds:
                   1105:                 if found.getObject() not in oldContent:
                   1106:                  
                   1107:                     #TODO: was passiert wenn, man eine Object dazufuegt, das schon da ist aber eine neuere version
                   1108:                     newContent.append((found.getObject().getVersions()[version-1][1],found.getObject()))
                   1109:                     added+=1
                   1110: 
                   1111:         content=oldContent+newContent
                   1112:         if not username:
                   1113:             logging.error("XXXXXXXXXXX %s"%repr(self))
                   1114:             user=self.getActualUserName()
                   1115:         else:
                   1116:             user = username
                   1117:             
                   1118:         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content)
                   1119:         logging.info("add to basket (%s) done"%(self.getId()))
                   1120:         return added
                   1121:     
                   1122:     
                   1123:     def addObjects(self,ids,deleteOld=None,username=None):
                   1124:         """generate a new version of the basket with objects added"""
                   1125:         
                   1126:         def swap(x):
                   1127:             return (x[1],x[0])
                   1128:             
                   1129:         logging.info("add to basket (%s)"%(repr(ids)))
                   1130:         logging.info("add to basket (%s)"%(self.getId()))
                   1131:         lastVersion=self.getLastVersion()
                   1132:         
                   1133:         if lastVersion is None:
                   1134:             oldContent=[]
                   1135:         else:
                   1136:             oldContent=lastVersion.content.getContent()
                   1137: 
                   1138:         if deleteOld:
                   1139:             oldContent=[]
                   1140: 
                   1141:         added=0
                   1142: #        for id in ids:
                   1143: #            logging.debug("adding:"+id)
                   1144: #            try:
                   1145: #                founds=self.CDLICatalog.search({'title':id})
                   1146: #            except:
                   1147: #                founds=[]
                   1148: #           
                   1149: #            for found in founds:
                   1150: #                if found.getObject() not in oldContent:
                   1151: #                    #TODO: was passiert wenn, man eine Object dazufugt, das schon da ist aber eine neuere version
                   1152: #                    newContent.append((found.getObject().getLastVersion(),found.getObject()))
                   1153: #                    added+=1
                   1154: 
                   1155:         hash = md5.new(repr(makelist(ids))).hexdigest() # erzeuge hash als identification
                   1156:         #logging.debug("JJJJJJJ:"+repr(self.makelist(ids)))
                   1157:        
                   1158:         retrieved = self.CDLICache.retrieve(hash)
                   1159:         if retrieved:
1.6       dwinter  1160:             logging.debug("add Objects: retrieved")
1.1       dwinter  1161:             newContent=Set(map(swap,retrieved))
                   1162:         else:
1.6       dwinter  1163:             logging.debug("add Objects: new")
1.1       dwinter  1164:             newContent=Set([(self.getFileObjectLastVersion(x),self.getFileObject(x)) for x in ids])             
                   1165:        
                   1166:      
                   1167:         
                   1168:         #remove all Elements which are not stored
                   1169:         if (None,None) in newContent:   
                   1170:             newContent.remove((None,None))
                   1171:         content=Set(oldContent).union(newContent)
                   1172:         added = len(content)-len(oldContent)
                   1173:         if not username:
                   1174:             user=self.getActualUserName()
                   1175:         else:
                   1176:             user = username
                   1177:         
                   1178:         #logging.debug("content:"+repr(list(content)))
                   1179:         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=list(content))
                   1180:         logging.info("add to basket (%s) done"%(self.getId()))
                   1181:         return added
                   1182:     
                   1183:     
                   1184:                 
                   1185:     def getContent(self):
                   1186:         """print content"""
                   1187:         ret=[]
                   1188:         
                   1189:         lv=self.getLastVersion()
                   1190:         #for obj in lv.content.getContent():
                   1191:             #logging.info("XXXXXXXXXX %s"%repr(obj))
                   1192:         #    ret.append((obj[1].getId(),obj[0].versionNumber))
                   1193:             
                   1194:         return lv
                   1195:         
                   1196:     def getContentIds(self):
                   1197:         """print basket content"""
                   1198:         ret=[]
                   1199:         lv=self.getLastVersion()
                   1200:         for obj in lv.content.getContent():
                   1201:             ret.append((obj[0].getId(),obj[1].getId()))
                   1202:         
                   1203:         
                   1204:         return lv.getComment(),lv.getUser(),lv.getTime(),ret
                   1205: 
1.7     ! dwinter  1206:     def changeBasket(self,submit,ids=[],RESPONSE=None,REQUEST=None):
1.1       dwinter  1207:         """change a basket"""
                   1208:         if submit=="update":
1.6       dwinter  1209:             self.updateObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1.1       dwinter  1210:         elif submit=="delete":
1.6       dwinter  1211:             self.deleteObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1.1       dwinter  1212:             
                   1213:     def deleteObjects(self,ids,RESPONSE=None,REQUEST=None):
                   1214:         """delete objects"""
                   1215:         
                   1216:         if type(ids) is not ListType:
                   1217:             ids=[ids]
                   1218:        
                   1219:         lastVersion=self.getLastVersion() 
                   1220:         oldContent=lastVersion.content.getContent()
                   1221:         newContent=[]
                   1222:         for obj in oldContent:
                   1223:             if obj[1].getId() not in ids:
                   1224:                 newContent.append(obj)
                   1225:         
                   1226:                 
                   1227:         user=self.getActualUserName()
                   1228:         
                   1229:         ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
                   1230:         
                   1231:         if RESPONSE:
                   1232:             obj=self._getOb(ob.getId())
                   1233:             RESPONSE.redirect(obj.absolute_url())
                   1234:         
                   1235: def manage_addCDLIBasketForm(self):
                   1236:     """add the CDLIBasketContainer form"""
                   1237:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasket.zpt')).__of__(self)
                   1238:     return pt()
                   1239: 
                   1240: def manage_addCDLIBasket(self,title,shortDescription="",comment="",RESPONSE=None):
                   1241:     """add the basket"""
                   1242:     
                   1243:     id=str(self.getNewId())
                   1244:     
                   1245:     ob=CDLIBasket(id,title,shortDescription,comment)
                   1246:     
                   1247:     self._setObject(id, ob)
                   1248:     
                   1249:     if RESPONSE is not None:
                   1250:         RESPONSE.redirect('manage_main')
                   1251:     else:
                   1252:         return ob
                   1253: 
                   1254: 
                   1255:  
                   1256: class CDLIBasketVersion(Implicit,Persistent,Folder):
                   1257:     """version of a basket"""
                   1258:     
                   1259:     meta_type="CDLIBasketVersion"
                   1260:     security=ClassSecurityInfo()
                   1261:     
                   1262:     def updateBasket(self):
                   1263:         """update"""
                   1264:         try:
                   1265:             self._setObject('content',BasketContent(self.basketContent))
                   1266:         except:
                   1267:             try:
                   1268:                 if len(self.basketContent)>0:
                   1269:                     self.content.setContent(self.basketContent)
                   1270:             except:
                   1271:                 print "error",self.getId(),self.aq_parent.getId()
                   1272:         self.basketContent=[]
                   1273: 
                   1274:         
                   1275:     def containsNonActualFiles(self):
                   1276:         """returns True if basket contains one or more non current files"""
                   1277:         
                   1278:         objs=self.getContent()
                   1279:         for obj in objs:
                   1280:             if not self.isActual(obj[0],obj[1])[0]:
                   1281:                 return True
                   1282:         return False
                   1283:     
                   1284:     def downloadListOfPnumbers(self):
                   1285:         """download pnumbers of the basket as list"""
                   1286:         
                   1287:         basket_name=self.aq_parent.title
                   1288:         
                   1289:         ids=self.getContent() # get the list of objects
                   1290:         logging.error(ids)
                   1291:         ret="\n".join([x[1].getId().split(".")[0] for x in ids])
                   1292:         
                   1293:         self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.txt" """%basket_name)
                   1294:         self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
                   1295:         length=len(ret)
                   1296:         self.REQUEST.RESPONSE.setHeader("Content-Length",length)
                   1297:         self.REQUEST.RESPONSE.write(ret)    
                   1298:         
                   1299:     security.declareProtected('manage','downloadObjectsAsOneFile')
                   1300:     def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None,check="yes",current="no"):
                   1301:         """download all selected files in one file"""
                   1302:         
                   1303:         if self.temp_folder.downloadCounterBaskets > 10000:
                   1304:             return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
                   1305: 
                   1306: 
                   1307:         #if (check=="yes") and self.containsNonActualFiles():
                   1308:         #    pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadObjectAsOneFile_check.zpt')).__of__(self)
                   1309:         #    
                   1310:         #    return pt(lock=lock)
                   1311:         
                   1312:         # neue Version aus Performancegruenden, es wird nicht mehr getestet, ob es nicht aktuelle Objekte gibt
                   1313:         # sondern lediglich gefragt.
                   1314:         if (check=="yes"):
                   1315:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadObjectAsOneFile_ask.zpt')).__of__(self)
                   1316:            
                   1317:             return pt(lock=lock)
                   1318:             
                   1319:         else:
                   1320:             
                   1321:             return self.downloadObjectsAsOneFileFinally(lock=lock,procedure=procedure,REQUEST=REQUEST,current="no")
                   1322:         
                   1323:     def downloadObjectsAsOneFileFinally(self,lock=None,procedure=None,REQUEST=None,current="no",repeat=None):
                   1324:         """print do the download"""
                   1325:  
                   1326:         
                   1327:         ret=""
                   1328:         lockedObjects={}
                   1329: 
                   1330:            
                   1331:     
                   1332:         if lock:
                   1333:             logging.debug("------lock:"+repr(lock))
                   1334:             if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
                   1335:                 
                   1336:                 return "please login first"
                   1337: 
                   1338:             #check if a locked object exist in the basket.
                   1339:             lockedObjects={}
                   1340:             for object in self.content.getContent():
                   1341:                 obj=self.getFileObject(object[0])
                   1342:                 if (not str(obj.lockedBy)=="") and (not (str(obj.lockedBy)==str(self.REQUEST['AUTHENTICATED_USER']))):
                   1343:                     lockedObjects[obj.title]=repr(obj.lockedBy)
                   1344:                    
                   1345:                     
                   1346:             keys=lockedObjects.keys()
                   1347:             
                   1348:             
                   1349:             if len(keys)>0 and (not procedure):
                   1350:                 self.REQUEST.SESSION['lockedObjects']=lockedObjects
                   1351:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)
                   1352:                 
                   1353:                
                   1354:                 return pt()
                   1355:          
                   1356:             elif not procedure: #keine fails gesperrt dann alle donwloaden
                   1357:                 procedure="downloadAll" 
                   1358:         
                   1359:         
                   1360:        
                   1361:        
                   1362:         threadName=repeat
                   1363:         if not threadName or threadName=="":
                   1364:             thread=DownloadBasketFinallyThread()
                   1365:             threadName=thread.getName()[0:]
                   1366: 
                   1367:             if (not hasattr(self,'_v_downloadBasket')):
                   1368:                                 self._v_downloadBasket={}
                   1369: 
                   1370: 
                   1371:             self._v_downloadBasket[threadName]=thread
                   1372:             logging.debug("dwonloadfinally:"+repr(self))
                   1373: 
                   1374:             if isinstance(self,CDLIBasketVersion):
                   1375:                 obj=self
                   1376:             else:
                   1377:                 obj=self.aq_parent
                   1378:             logging.debug("dwonloadfinally2:"+repr(obj))
                   1379:             logging.debug("dwonloadfinally2:"+repr(obj.aq_parent))
                   1380: 
                   1381:             obj2=obj.aq_parent
                   1382:             if not isinstance(obj2,CDLIBasket):
                   1383:                 obj2=obj2.aq_parent
                   1384: 
                   1385:             basketID=obj2.getId()
                   1386:             versionNumber=obj.getId()
                   1387:             logging.debug("dwonloadfinally2:"+repr(basketID))
                   1388:             logging.debug("dwonloadfinally2:"+repr(versionNumber))
                   1389: 
                   1390: 
                   1391:             if lock:
                   1392:                 logging.debug("-----start locking")
                   1393:                 for object in self.content.getContent():
                   1394:                          obj=self.getFileObject(object[0])
                   1395:                          if obj.lockedBy =='':
                   1396:                              obj.lockedBy=self.REQUEST['AUTHENTICATED_USER']
                   1397:                 logging.debug("-----finished locking")
                   1398:                 
                   1399:                     #obj.lockedBy=user
                   1400:             self._v_downloadBasket[threadName].set(lock,procedure,self.REQUEST['AUTHENTICATED_USER'],current,basketID,versionNumber)
                   1401: 
                   1402:             self._v_downloadBasket[threadName].start()
                   1403: 
                   1404:             
                   1405:             
                   1406:             wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
                   1407: 
                   1408:             if wait_template:
                   1409:                 return wait_template[0][1]()
                   1410:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
                   1411: 
                   1412:             return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
                   1413:                                 counter=self._v_downloadBasket[threadName].getCounter(),
                   1414:                                 number=self._v_downloadBasket[threadName].getNumberOfFiles())
                   1415:             #_v_xmltrans.run()
                   1416:         
                   1417:         else:
                   1418:             #recover thread, if lost
                   1419:             if not hasattr(self,'_v_downloadBasket'):
                   1420:                self._v_downloadBasket={}
                   1421:             if not self._v_downloadBasket.get(threadName,None):
                   1422:                  for thread in threading.enumerate():
                   1423:                          if threadName == thread.getName():
                   1424:                                        self._v_downloadBasket[threadName]=thread
                   1425:                                        
                   1426:             if self._v_downloadBasket.get(threadName,None) and (self._v_downloadBasket[threadName] is not None) and (not self._v_downloadBasket[threadName].end) :
                   1427: 
                   1428:                 wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
                   1429:                 if wait_template:
                   1430:                         return wait_template[0][1]()
                   1431:                 
                   1432:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
                   1433:                 return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
                   1434:                           counter=self._v_downloadBasket[threadName].getCounter(),
                   1435:                           number=self._v_downloadBasket[threadName].getNumberOfFiles())
                   1436:             else:
                   1437:               
                   1438:              
                   1439:               logging.debug("FINISHED")
                   1440:               if not self._v_downloadBasket.get(threadName,None):
                   1441:                  for thread in threading.enumerate():
                   1442:                          if threadName == thread.getName():
                   1443:                                        self._v_downloadBasket[threadName]=thread
                   1444:                                        
                   1445:               #files = self._v_downloadBasket[threadName].result
                   1446:               # lade die files und die locked files, bei grossen Baskets muss u.U. gewartet werden
                   1447:               # bis das Commit aus dem Thread alles geschrieben hat, in dem Falle existiert resultHash[threadName]
                   1448:               # noch nicht.
                   1449:               o1 = file("/tmp/"+threadName,'r')
                   1450:               files=pickle.load(o1)
                   1451:               os.remove("/tmp/"+threadName)
                   1452:               o2 = file("/tmp/"+threadName+'_lockedFiles','r')
                   1453:               
                   1454:               lockedFiles=pickle.load(o2)
                   1455:               os.remove("/tmp/"+threadName+'_lockedFiles')
                   1456: #              try:
                   1457: #                  files=self.basketContainer.resultHash[threadName]
                   1458: #              except:
                   1459: #                  i=0
                   1460: #                  while (not self.basketContainer.resultHash.has_key(threadName)) and (i<100):
                   1461: #                      logging.debug(" downloadFinally: I am waiting for thread %s to write the resultHashfile: %s"%(threadName,i))
                   1462: #                      time.sleep(5)
                   1463: #                      i+=1
                   1464: #                  files=self.basketContainer.resultHash[threadName]  
                   1465: #              
                   1466: #              try:
                   1467: #                  lockedFiles=self.basketContainer.resultLockedHash[threadName]
                   1468: #              except:
                   1469: #                  i=0
                   1470: #                  while (not self.basketContainer.resultLockedHash.has_key(threadName)) and (i<100):
                   1471: #                      logging.debug(" downloadFinally: I am waiting for thread %s to write the LockedHashfile: %s"%(threadName,i))
                   1472: #                      time.sleep(5)
                   1473: #                      i+=1
                   1474: #                  lockedFiles=self.basketContainer.resultLockedHash[threadName]
                   1475:      
                   1476:              # fh=file("/var/tmp/test")
                   1477:               #ret =fh.read()
                   1478:          
                   1479:               if (not isinstance(self.aq_parent,CDLIBasket)):
                   1480:                   basket_name=self.aq_parent.aq_parent.title+"_V"+self.getId()
                   1481:               else:
                   1482:                   basket_name=self.aq_parent.title+"_V"+self.getId()
                   1483:         
                   1484:         
                   1485:     
                   1486:                   #write basketname to header of atf file
                   1487:               
                   1488: 
                   1489:               self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.atf" """%basket_name)
                   1490:               self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
                   1491:               #length=len(ret)
                   1492:               #self.REQUEST.RESPONSE.setHeader("Content-Length",length)
                   1493:         
                   1494:               ret="#basket: %s\n"%basket_name
                   1495:               self.REQUEST.RESPONSE.write(ret) 
                   1496:                  
                   1497:               for fileName in files:
                   1498:                 logging.debug("download: %s"%fileName)
                   1499:                 try:
                   1500:                   self.REQUEST.RESPONSE.write(file(fileName).read())
                   1501:                 except:
                   1502:                   logging.error("downloadasonefile: cannot read %s"%fileName)
                   1503:                   
                   1504:             
                   1505:               self.REQUEST.RESPONSE.write("\n# locked files\n")
                   1506:               for fileName in lockedFiles:
                   1507:                   self.REQUEST.RESPONSE.write("#  %s by %s\n"%fileName)
                   1508:               
                   1509:               self.REQUEST.RESPONSE.write("# locked files end\n")
                   1510:               
                   1511:               #del self.basketContainer.resultHash[threadName]
                   1512:               #del self.basketContainer.resultLockedHash[threadName]
                   1513:              
                   1514:     def numberOfItems(self):
                   1515:         """return anzahl der elemente im basket"""
                   1516:         return self.content.numberOfItems()
                   1517:     
                   1518:     def getTime(self):
                   1519:         """getTime"""
                   1520:         #return self.bobobase_modification_time().ISO()
                   1521:       
                   1522:         if hasattr(self,'time'):
                   1523:             return time.strftime("%Y-%m-%d %H:%M:%S",self.time)
                   1524:         elif hasattr(self,'timefixed'):
                   1525:             return self.timefixed
                   1526:         else:
                   1527:             setattr(self,'timefixed',self.bobobase_modification_time().ISO())
                   1528:             return self.bobobase_modification_time().ISO()
                   1529:     
                   1530:     def getContent(self):
                   1531:         """get Basket Content"""
                   1532:         logging.debug("retrieving content A")
                   1533:         cnt = self.content
                   1534:         logging.debug("retrieving content: obj %s"%cnt)
                   1535:         tmp = self.content.getContent()
                   1536:         logging.debug("got content")
                   1537:         return tmp
                   1538: 
                   1539:     
                   1540:     def __init__(self,id,user,comment="",basketContent=[]):
                   1541:         """ init a basket version"""
                   1542:         self.id=id
                   1543:         self.comment=comment
                   1544:         self._setObject('content',BasketContent(basketContent))
                   1545:         #self.basketContent=basketContent[0:]a
                   1546:         self.user=user
                   1547:         self.time=time.localtime()
                   1548:         
                   1549:     def getUser(self):
                   1550:         """get user"""
                   1551:         return self.user
                   1552:     
                   1553:     def getComment(self):
                   1554:         """get Comment"""
                   1555:         return self.comment
                   1556:  
                   1557:     security.declareProtected('manage','index_html')
                   1558:     def index_html(self):
                   1559:             """view the basket"""
                   1560:             logging.debug("start index_html - Basket version")    
                   1561:             if self.REQUEST.get('change',False):
                   1562:                     ob=self.aq_parent.updateObjects(self.REQUEST['change'])
                   1563:                    
                   1564:                     self.REQUEST.RESPONSE.redirect(ob.absolute_url())#go to new basket, because changing generates a new basket
                   1565:             logging.debug("start index_html - Basket version:template")    
                   1566:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketVersionMain.zpt')).__of__(self)
                   1567:             return pt()
                   1568:      
                   1569:     def getObjUrl(self,result):
                   1570:         """getUrl of the version of the object"""
1.7     ! dwinter  1571:         logging.debug("getObjUrl:"+result)
1.1       dwinter  1572:         founds=self.CDLICatalog.search({'title':result})
                   1573:         if len(founds)>0:
1.7     ! dwinter  1574:              logging.debug("getObjUrl: founds 1")
        !          1575:              logging.debug("getObjUrl:"+repr(founds[0].getObject()))
        !          1576:              #return founds[0].getObject().getLastVersion().absolute_url()
        !          1577:              return founds[0].getObject().absolute_url()
1.1       dwinter  1578:          
                   1579:         else: #assume version number
1.7     ! dwinter  1580:             logging.debug("getObjUrl: founds 2")
1.1       dwinter  1581:             splitted=result.split("_")
                   1582:             founds=self.CDLICatalog.search({'title':splitted[1]})        
                   1583:             return founds[0].getObject().getLastVersion().absolute_url()+'/'+result
                   1584:    
                   1585: def manage_addCDLIBasketVersion(self,user,comment="",basketContent=[],RESPONSE=None):
                   1586:     """add a version"""
                   1587:     
                   1588:     #check for already existing versions
                   1589:  
                   1590:     lastVersion=self.getLastVersion()
                   1591:     if lastVersion is None:
                   1592:         newId=str(1)
                   1593:     else:
                   1594:         newId=str(int(lastVersion.getId())+1)
                   1595:     
                   1596:     ob=CDLIBasketVersion(newId,user,comment,basketContent)
                   1597:     
                   1598:     self._setObject(newId, ob)
                   1599:     
                   1600:     if RESPONSE is not None:
                   1601:         RESPONSE.redirect('manage_main')
                   1602:     else:
                   1603:         return ob
                   1604:    

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