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