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>