Annotation of cdli/cdli_basket.py, revision 1.3
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
139: from Zope import DB
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
313: from Zope import DB
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')
577:
578: def uploadBasket_html(self,basketId='0'):
579: """upload an atf file, html form"""
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','uploadBasket_html.zpt')).__of__(self)
589: return pt(basketId=basketId,basketName=basketName)
590:
591:
592: security.declareProtected('manage','index_html')
593: def index_html(self):
594: """stanadard ansicht"""
595:
596:
597:
598: ext=self.ZopeFind(self,obj_ids=["index.html"])
599: if ext:
600: return ext[0][1]()
601:
602: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self)
603: return pt()
604:
605: def getStorageFolderRoot(self):
606: """root des storage folders"""
607: return self.cdli_main
608:
609: def __init__(self,id,title):
610: """ init basket container"""
611: self.id=id
612: self.title=title
613:
614:
615: def getBasketsId(self):
616: """get all baskets als klartext"""
617:
618: ret=""
619: baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
620: for basket in baskets:
621: com,user,time,values = basket[1].getContentIds()
622: ret+= "BASKET:"+com+"\t"+user+"\t"+time+"\n"
623: for x in values:
624: ret+= x[0]+"\t"+x[1]+"\n"
625: return ret
626:
627: def getBaskets(self,sortField='title'):
628: """get all baskets files"""
629:
630: def sortName(x,y):
631: return cmp(x[1].title.lower(),y[1].title.lower())
632:
633: def sortDate(x,y):
634: return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())
635:
636:
637: def sortComment(x,y):
638:
639:
640:
641: try:
642: xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()
643: except:
644: xc='ZZZZZZZZZZZZZ'.lower()
645: try:
646: yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()
647: except:
648: yc='ZZZZZZZZZZZZZ'.lower()
649:
650:
651: if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):
652:
653: try:
654: xc=x[1].getLastVersion().getComment().lower()
655: except:
656: xc='ZZZZZZZZZZZZZ'.lower()
657:
658: if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):
659: try:
660: yc=y[1].getLastVersion().getComment().lower()
661: except:
662: yc='ZZZZZZZZZZZZZ'.lower()
663:
664:
665: return cmp(xc,yc)
666:
667: def sortAuthor(x,y):
668:
669: return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower())
670:
671: baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
672:
673:
674: if sortField=='title':
675: baskets.sort(sortName)
676: elif sortField=='date':
677: baskets.sort(sortDate)
678: elif sortField=='author':
679: baskets.sort(sortAuthor)
680: elif sortField=='comment':
681: baskets.sort(sortComment)
682:
683: return baskets
684:
685:
686: def subtractBasket(self,newBasket,basket1,basket2):
687: """subtract basket2 from basket1
688: (i.e. newbasket will contain alle elements of basket1 which are not in basket2),
689: if basket2 contains files which are not in basket1, then theses files fill be ignored
690:
691: @param newbasket: name of the new basket
692: @param basket1: basket where basket2 will be subtracted from
693: @param basket2: see above
694:
695: """
696:
697: logging.info("CCCCC %s %s"%(basket1,basket2))
698:
699: try:
700: newB=self.addBasket(newBasket)
701: except:
702: return False, "cannot create the new basket"
703:
704:
705:
706:
707:
708: bas2= getattr(self,basket2)
709: bas2content=bas2.getContent()
710: bas2ids=[x[0] for x in bas2content]
711:
712:
713:
714: bas1= getattr(self,basket1)
715: bas1content=bas1.getContent()
716:
717:
718: newBasketContent={}
719:
720: for id,version in bas1content:
721: if not (id in bas2ids):
722: newBasketContent[id]=version
723:
724: username=self.getActualUserName()
725:
726: logging.info("sbc %s"%newBasketContent)
727: newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
728:
729: return True, ""
730:
731:
732: def joinBasket(self,newBasket,oldBaskets):
733: """join two baskets
734: @param newbasket: name of the new basket
735: @param oldbaskets: list of baskets to be joined
736: """
737: if oldBaskets is None:
738: return False, "No Baskets selected!"
739:
740: try:
741: newB=self.addBasket(newBasket)
742: except:
743: return False, "cannot create the new basket"
744:
745: newBasketContent={}
746:
747: for ob in oldBaskets:
748: x= getattr(self,ob,None)
749: if x is None:
750: return False, "cannot find basket: %s"%ob
751:
752: ids=x.getContent() # hole den Inhalt
753:
754: for id,version in ids:
755: if newBasketContent.has_key(id): # p number gibt's schon
756: newBasketContent[id]=max(newBasketContent[id],version) # speichere die groessere Versionsnumber
757: else:
758: newBasketContent[id]=version
759: username=self.getActualUserName()
760:
761: logging.info("nbc %s"%newBasketContent)
762: newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
763:
764: return True, ""
765:
766: def getNewId(self):
767: """createIds"""
768: last=getattr(self,'last',0)
769: last +=1
770: while len(self.ZopeFind(self,obj_ids=[str(last)]))>0:
771: last+=1
772:
773: self.last=last
774: return last
775:
776: def setActiveBasket(self,basketId,REQUEST=None):
777: """store active basketId in a cookie"""
778: self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/")
779: try:
780: qs=cgi.parse_qs(REQUEST['QUERY_STRING'])
781: del(qs['basketId'])
782: except:
783: qs={}
784: if REQUEST:
785: REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+urllib.urlencode(qs))
786:
787: def getActiveBasket(self):
788: """get active basket from cookie"""
789:
790: id= self.REQUEST.cookies.get('CDLIActiveBasket',None)
791: if id:
792: obj=getattr(self,str(id),None)
793: else:
794: obj=None
795: return obj
796:
797: def getActualUserName(self):
798: """get name of the actualuser"""
799: return str(self.REQUEST['AUTHENTICATED_USER'])
800:
801: security.declareProtected('manage','addBasket')
802: def addBasket(self,newBasketName):
803: """add a new basket"""
804:
805: ob=manage_addCDLIBasket(self,newBasketName)
806: return ob
807:
808: def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None):
809: """store it"""
810: if not ids:
811: ids=self.REQUEST.SESSION['fileIds']
812:
813: if (type(ids) is not ListType) and (not isinstance(ids,Set)):
814: ids=[ids]
815:
816: if isinstance(ids,Set):
817: ids=list(ids)
818:
819: if (submit.lower()=="store in new basket") or (submit.lower()=="new basket"):
820: basketRet=self.addBasket(newBasketName)
821: self.setActiveBasket(basketRet.getId())
822: basket=getattr(self,basketRet.getId())
823: elif (submit.lower()=="store in active basket") or (submit.lower()=="active basket"):
824: basket=self.getActiveBasket()
825:
826: added=basket.addObjects(ids)
827: back=self.REQUEST['HTTP_REFERER'].split("?")[0]+"?basketName="+basket.title+"&numberOfObjects="+str(added)
828:
829:
830: if fromFileList:
831:
832: return self.cdli_main.findObjectsFromList(list=ids,basketName=basket.title,numberOfObjects=added)
833:
834: if RESPONSE:
835:
836: RESPONSE.redirect(back)
837:
838: return True
839:
840: def manage_addCDLIBasketContainerForm(self):
841: """add the CDLIBasketContainer form"""
842: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self)
843: return pt()
844:
845: def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None):
846: """add the basket"""
847: ob=CDLIBasketContainer(id,title)
848:
849: self._setObject(id, ob)
850:
851: if RESPONSE is not None:
852: RESPONSE.redirect('manage_main')
853:
854: class CDLIBasket(Folder,CatalogAware):
855: """basket"""
856:
857: meta_type="CDLIBasket"
858: default_catalog="CDLIBasketCatalog"
859:
860: def searchInBasket(self,indexName,searchStr,regExp=False):
861: """searchInBasket"""
862:
863: lst=self.searchInLineIndexDocs(indexName,searchStr,uniq=True,regExp=regExp) #TODO: fix this
864: ret={}
865:
866: lv=self.getLastVersion()
867:
868:
869: for obj in lv.content.getContent():
870: id=obj[1].getId().split(".")[0]
871: if id in lst:
872:
873: ret[id]=self.showWordInFile(id,searchStr,lineList=self.getLinesFromIndex(indexName,searchStr,id,regExp=regExp),regExp=regExp,indexName=indexName)
874:
875:
876: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','searchResultsInBasket')).__of__(self)
877: return pt(result=ret,indexName=indexName,regExp=regExp,word=searchStr)
878:
879:
880:
881:
882: def searchInBasket_v1(self,searchStr):
883: """search occurences of searchStr in files im basket"""
884: ret=[]
885: lv=self.getLastVersion()
886: logging.info("searching")
887: for obj in lv.content.getContent():
888: txt=obj[0].getData()
889: for x in txt.split("\n"):
890: logging.info("search %s"%x)
891: if re.match(searchStr,x):
892: ret.append(x)
893:
894: return "\n".join(ret)
895:
896:
897: def getFile(self,obj):
898: return obj[1]
899:
900: def getFileLastVersion(self,obj):
901: return obj[0]
902:
903: def getFileNamesInLastVersion(self):
904: """get content of the last version as list"""
905:
906: return [x[1].getId() for x in self.getLastVersion().getContent()]
907:
908:
909: def isActual(self,obj,nummer):
910: """teste ob im basket die aktuelle version ist, obj kann entweder ein CDLIFile sein oder eine
911: eine pnummer, die auf ein CDLIFile verweist"""
912: try:
913: #logging.debug("isActual:"+repr(obj))
914: if isinstance(obj, CDLIFile):
915: actualNo=obj.getLastVersion().getVersionNumber()
916: else:
917: actualNo=self.cdliRoot.getFileObjectLastVersion(obj).getVersionNumber()
918:
919: if actualNo==nummer:
920: return True , 0
921: else:
922: return False, actualNo
923: except:
924: logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
925: logging.error(""" PARAMS: %s %s"""%(obj,nummer))
926: return False, -1
927: def isActualOld(self,obj):
928: """teste ob im basket die aktuelle version ist"""
929: try:
930: #logging.debug("isActual:"+repr(obj))
931: actualNo=obj[1].getLastVersion().getVersionNumber()
932: storedNo=obj[0].getVersionNumber()
933:
934:
935: #actualNo=self.getFileObjectLastVersion(obj.getId()).getVersionNumber()
936:
937: #if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash":
938: # return False, -1
939:
940: if actualNo==storedNo:
941: return True , 0
942: else:
943: return False, actualNo
944: except:
945: logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
946:
947: return False, -1
948:
949: def history(self):
950: """history"""
951:
952: ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
953: if ext:
954: return getattr(self,ext[0][1].getId())()
955:
956: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self)
957: return pt()
958:
959: def getStorageFolderRoot(self):
960: """root des storage folders"""
961: return self.aq_parent.cdli_main
962:
963: def __init__(self,id,title,shortDescription="",comment=""):
964: """init a CDLIBasket"""
965:
966: self.id=id
967: self.title=title
968: self.shortDescription=shortDescription
969: self.comment=comment
970:
971: def getActualUserName(self):
972: """get name of the actualuser"""
973:
974: return str(self.REQUEST['AUTHENTICATED_USER'])
975:
976:
977: def getLastVersion(self):
978: """hole letzte version"""
979:
980: ids=[]
981: idsTmp= self.objectIds()
982: for x in idsTmp:
983: try:
984: ids.append(int(x))
985: except:
986: pass
987: ids.sort()
988:
989: if len(ids)==0:
990: return None
991: else:
992: ob=getattr(self,str(ids[-1]))
993:
994:
995: return ob
996:
997: def getVersions(self):
998: """get versions"""
999: versions=self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])
1000: return versions
1001:
1002:
1003: def updateObjects(self,ids,RESPONSE=None,REQUEST=None):
1004: """update ids, ids not in the basket the add"""
1005: if type(ids) is not ListType:
1006: ids=[ids]
1007:
1008: lastVersion=self.getLastVersion()
1009: oldContent=lastVersion.content.getContent()
1010: newContent=[]
1011:
1012: #first copy the old
1013: for obj in oldContent:
1014: if obj[1].getId() not in ids:
1015: newContent.append(obj)
1016: #now add the new
1017:
1018: for id in ids:
1019: founds=self.CDLICatalog.search({'title':id})
1020:
1021: for found in founds:
1022: if found.getObject() not in oldContent:
1023: #TODO: was passiert wenn, man eine Object dazufuegt, das schon da ist aber eine neuere version
1024: newContent.append((found.getObject().getLastVersion(),found.getObject()))
1025:
1026:
1027: content=newContent
1028: user=self.getActualUserName()
1029:
1030: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
1031:
1032: obj=self._getOb(ob.getId())
1033: if RESPONSE:
1034:
1035: RESPONSE.redirect(obj.absolute_url())
1036:
1037: return obj
1038:
1039: def addObjectsWithVersion(self,ids,deleteOld=None,username=None,catalog=None):
1040: """generate a new version of the basket with objects added,
1041: hier wird jedoch nicht die letzte Version jedes Files hinzugefuegt, s
1042: ondern ids is ein Tupel mit der Id (d.h. der p-number) und der Versionsnummer.
1043: """
1044: logging.info("add to basket (%s)"%(self.getId()))
1045: lastVersion=self.getLastVersion()
1046:
1047: if not catalog:
1048: catalog=self.CDLICatalog
1049:
1050: if lastVersion is None:
1051: oldContent=[]
1052: else:
1053: oldContent=lastVersion.content.getContent()
1054:
1055: if deleteOld:
1056: oldContent=[]
1057:
1058: newContent=[]
1059: added=0
1060:
1061: for id,version in ids.iteritems():
1062: logging.info("adding %s %s"%(id,version))
1063: id=id.split(".")[0] # title nur die pnumber ohne atf
1064:
1065: try:
1066: founds=catalog.search({'title':id})
1067: except:
1068: founds=[]
1069: logging.info(" found %s "%(founds))
1070: for found in founds:
1071: if found.getObject() not in oldContent:
1072:
1073: #TODO: was passiert wenn, man eine Object dazufuegt, das schon da ist aber eine neuere version
1074: newContent.append((found.getObject().getVersions()[version-1][1],found.getObject()))
1075: added+=1
1076:
1077: content=oldContent+newContent
1078: if not username:
1079: logging.error("XXXXXXXXXXX %s"%repr(self))
1080: user=self.getActualUserName()
1081: else:
1082: user = username
1083:
1084: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content)
1085: logging.info("add to basket (%s) done"%(self.getId()))
1086: return added
1087:
1088:
1089: def addObjects(self,ids,deleteOld=None,username=None):
1090: """generate a new version of the basket with objects added"""
1091:
1092: def swap(x):
1093: return (x[1],x[0])
1094:
1095: logging.info("add to basket (%s)"%(repr(ids)))
1096: logging.info("add to basket (%s)"%(self.getId()))
1097: lastVersion=self.getLastVersion()
1098:
1099: if lastVersion is None:
1100: oldContent=[]
1101: else:
1102: oldContent=lastVersion.content.getContent()
1103:
1104: if deleteOld:
1105: oldContent=[]
1106:
1107: added=0
1108: # for id in ids:
1109: # logging.debug("adding:"+id)
1110: # try:
1111: # founds=self.CDLICatalog.search({'title':id})
1112: # except:
1113: # founds=[]
1114: #
1115: # for found in founds:
1116: # if found.getObject() not in oldContent:
1117: # #TODO: was passiert wenn, man eine Object dazufugt, das schon da ist aber eine neuere version
1118: # newContent.append((found.getObject().getLastVersion(),found.getObject()))
1119: # added+=1
1120:
1121: hash = md5.new(repr(makelist(ids))).hexdigest() # erzeuge hash als identification
1122: #logging.debug("JJJJJJJ:"+repr(self.makelist(ids)))
1123:
1124: retrieved = self.CDLICache.retrieve(hash)
1125: if retrieved:
1126: newContent=Set(map(swap,retrieved))
1127: else:
1128: newContent=Set([(self.getFileObjectLastVersion(x),self.getFileObject(x)) for x in ids])
1129:
1130:
1131:
1132: #remove all Elements which are not stored
1133: if (None,None) in newContent:
1134: newContent.remove((None,None))
1135: content=Set(oldContent).union(newContent)
1136: added = len(content)-len(oldContent)
1137: if not username:
1138: user=self.getActualUserName()
1139: else:
1140: user = username
1141:
1142: #logging.debug("content:"+repr(list(content)))
1143: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=list(content))
1144: logging.info("add to basket (%s) done"%(self.getId()))
1145: return added
1146:
1147:
1148:
1149: def getContent(self):
1150: """print content"""
1151: ret=[]
1152:
1153: lv=self.getLastVersion()
1154: #for obj in lv.content.getContent():
1155: #logging.info("XXXXXXXXXX %s"%repr(obj))
1156: # ret.append((obj[1].getId(),obj[0].versionNumber))
1157:
1158: return lv
1159:
1160: def getContentIds(self):
1161: """print basket content"""
1162: ret=[]
1163: lv=self.getLastVersion()
1164: for obj in lv.content.getContent():
1165: ret.append((obj[0].getId(),obj[1].getId()))
1166:
1167:
1168: return lv.getComment(),lv.getUser(),lv.getTime(),ret
1169:
1170: def changeBasket(self,ids,submit,RESPONSE=None,REQUEST=None):
1171: """change a basket"""
1172: if submit=="update":
1173: return self.updateObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1174: elif submit=="delete":
1175: return self.deleteObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1176:
1177: def deleteObjects(self,ids,RESPONSE=None,REQUEST=None):
1178: """delete objects"""
1179:
1180: if type(ids) is not ListType:
1181: ids=[ids]
1182:
1183: lastVersion=self.getLastVersion()
1184: oldContent=lastVersion.content.getContent()
1185: newContent=[]
1186: for obj in oldContent:
1187: if obj[1].getId() not in ids:
1188: newContent.append(obj)
1189:
1190:
1191: user=self.getActualUserName()
1192:
1193: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
1194:
1195: if RESPONSE:
1196: obj=self._getOb(ob.getId())
1197: RESPONSE.redirect(obj.absolute_url())
1198:
1199: def manage_addCDLIBasketForm(self):
1200: """add the CDLIBasketContainer form"""
1201: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasket.zpt')).__of__(self)
1202: return pt()
1203:
1204: def manage_addCDLIBasket(self,title,shortDescription="",comment="",RESPONSE=None):
1205: """add the basket"""
1206:
1207: id=str(self.getNewId())
1208:
1209: ob=CDLIBasket(id,title,shortDescription,comment)
1210:
1211: self._setObject(id, ob)
1212:
1213: if RESPONSE is not None:
1214: RESPONSE.redirect('manage_main')
1215: else:
1216: return ob
1217:
1218:
1219:
1220: class CDLIBasketVersion(Implicit,Persistent,Folder):
1221: """version of a basket"""
1222:
1223: meta_type="CDLIBasketVersion"
1224: security=ClassSecurityInfo()
1225:
1226: def updateBasket(self):
1227: """update"""
1228: try:
1229: self._setObject('content',BasketContent(self.basketContent))
1230: except:
1231: try:
1232: if len(self.basketContent)>0:
1233: self.content.setContent(self.basketContent)
1234: except:
1235: print "error",self.getId(),self.aq_parent.getId()
1236: self.basketContent=[]
1237:
1238:
1239: def containsNonActualFiles(self):
1240: """returns True if basket contains one or more non current files"""
1241:
1242: objs=self.getContent()
1243: for obj in objs:
1244: if not self.isActual(obj[0],obj[1])[0]:
1245: return True
1246: return False
1247:
1248: def downloadListOfPnumbers(self):
1249: """download pnumbers of the basket as list"""
1250:
1251: basket_name=self.aq_parent.title
1252:
1253: ids=self.getContent() # get the list of objects
1254: logging.error(ids)
1255: ret="\n".join([x[1].getId().split(".")[0] for x in ids])
1256:
1257: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.txt" """%basket_name)
1258: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
1259: length=len(ret)
1260: self.REQUEST.RESPONSE.setHeader("Content-Length",length)
1261: self.REQUEST.RESPONSE.write(ret)
1262:
1263: security.declareProtected('manage','downloadObjectsAsOneFile')
1264: def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None,check="yes",current="no"):
1265: """download all selected files in one file"""
1266:
1267: if self.temp_folder.downloadCounterBaskets > 10000:
1268: return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
1269:
1270:
1271: #if (check=="yes") and self.containsNonActualFiles():
1272: # pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadObjectAsOneFile_check.zpt')).__of__(self)
1273: #
1274: # return pt(lock=lock)
1275:
1276: # neue Version aus Performancegruenden, es wird nicht mehr getestet, ob es nicht aktuelle Objekte gibt
1277: # sondern lediglich gefragt.
1278: if (check=="yes"):
1279: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadObjectAsOneFile_ask.zpt')).__of__(self)
1280:
1281: return pt(lock=lock)
1282:
1283: else:
1284:
1285: return self.downloadObjectsAsOneFileFinally(lock=lock,procedure=procedure,REQUEST=REQUEST,current="no")
1286:
1287: def downloadObjectsAsOneFileFinally(self,lock=None,procedure=None,REQUEST=None,current="no",repeat=None):
1288: """print do the download"""
1289:
1290:
1291: ret=""
1292: lockedObjects={}
1293:
1294:
1295:
1296: if lock:
1297: logging.debug("------lock:"+repr(lock))
1298: if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
1299:
1300: return "please login first"
1301:
1302: #check if a locked object exist in the basket.
1303: lockedObjects={}
1304: for object in self.content.getContent():
1305: obj=self.getFileObject(object[0])
1306: if (not str(obj.lockedBy)=="") and (not (str(obj.lockedBy)==str(self.REQUEST['AUTHENTICATED_USER']))):
1307: lockedObjects[obj.title]=repr(obj.lockedBy)
1308:
1309:
1310: keys=lockedObjects.keys()
1311:
1312:
1313: if len(keys)>0 and (not procedure):
1314: self.REQUEST.SESSION['lockedObjects']=lockedObjects
1315: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)
1316:
1317:
1318: return pt()
1319:
1320: elif not procedure: #keine fails gesperrt dann alle donwloaden
1321: procedure="downloadAll"
1322:
1323:
1324:
1325:
1326: threadName=repeat
1327: if not threadName or threadName=="":
1328: thread=DownloadBasketFinallyThread()
1329: threadName=thread.getName()[0:]
1330:
1331: if (not hasattr(self,'_v_downloadBasket')):
1332: self._v_downloadBasket={}
1333:
1334:
1335: self._v_downloadBasket[threadName]=thread
1336: logging.debug("dwonloadfinally:"+repr(self))
1337:
1338: if isinstance(self,CDLIBasketVersion):
1339: obj=self
1340: else:
1341: obj=self.aq_parent
1342: logging.debug("dwonloadfinally2:"+repr(obj))
1343: logging.debug("dwonloadfinally2:"+repr(obj.aq_parent))
1344:
1345: obj2=obj.aq_parent
1346: if not isinstance(obj2,CDLIBasket):
1347: obj2=obj2.aq_parent
1348:
1349: basketID=obj2.getId()
1350: versionNumber=obj.getId()
1351: logging.debug("dwonloadfinally2:"+repr(basketID))
1352: logging.debug("dwonloadfinally2:"+repr(versionNumber))
1353:
1354:
1355: if lock:
1356: logging.debug("-----start locking")
1357: for object in self.content.getContent():
1358: obj=self.getFileObject(object[0])
1359: if obj.lockedBy =='':
1360: obj.lockedBy=self.REQUEST['AUTHENTICATED_USER']
1361: logging.debug("-----finished locking")
1362:
1363: #obj.lockedBy=user
1364: self._v_downloadBasket[threadName].set(lock,procedure,self.REQUEST['AUTHENTICATED_USER'],current,basketID,versionNumber)
1365:
1366: self._v_downloadBasket[threadName].start()
1367:
1368:
1369:
1370: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1371:
1372: if wait_template:
1373: return wait_template[0][1]()
1374: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
1375:
1376: return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
1377: counter=self._v_downloadBasket[threadName].getCounter(),
1378: number=self._v_downloadBasket[threadName].getNumberOfFiles())
1379: #_v_xmltrans.run()
1380:
1381: else:
1382: #recover thread, if lost
1383: if not hasattr(self,'_v_downloadBasket'):
1384: self._v_downloadBasket={}
1385: if not self._v_downloadBasket.get(threadName,None):
1386: for thread in threading.enumerate():
1387: if threadName == thread.getName():
1388: self._v_downloadBasket[threadName]=thread
1389:
1390: if self._v_downloadBasket.get(threadName,None) and (self._v_downloadBasket[threadName] is not None) and (not self._v_downloadBasket[threadName].end) :
1391:
1392: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1393: if wait_template:
1394: return wait_template[0][1]()
1395:
1396: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
1397: return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
1398: counter=self._v_downloadBasket[threadName].getCounter(),
1399: number=self._v_downloadBasket[threadName].getNumberOfFiles())
1400: else:
1401:
1402:
1403: logging.debug("FINISHED")
1404: if not self._v_downloadBasket.get(threadName,None):
1405: for thread in threading.enumerate():
1406: if threadName == thread.getName():
1407: self._v_downloadBasket[threadName]=thread
1408:
1409: #files = self._v_downloadBasket[threadName].result
1410: # lade die files und die locked files, bei grossen Baskets muss u.U. gewartet werden
1411: # bis das Commit aus dem Thread alles geschrieben hat, in dem Falle existiert resultHash[threadName]
1412: # noch nicht.
1413: o1 = file("/tmp/"+threadName,'r')
1414: files=pickle.load(o1)
1415: os.remove("/tmp/"+threadName)
1416: o2 = file("/tmp/"+threadName+'_lockedFiles','r')
1417:
1418: lockedFiles=pickle.load(o2)
1419: os.remove("/tmp/"+threadName+'_lockedFiles')
1420: # try:
1421: # files=self.basketContainer.resultHash[threadName]
1422: # except:
1423: # i=0
1424: # while (not self.basketContainer.resultHash.has_key(threadName)) and (i<100):
1425: # logging.debug(" downloadFinally: I am waiting for thread %s to write the resultHashfile: %s"%(threadName,i))
1426: # time.sleep(5)
1427: # i+=1
1428: # files=self.basketContainer.resultHash[threadName]
1429: #
1430: # try:
1431: # lockedFiles=self.basketContainer.resultLockedHash[threadName]
1432: # except:
1433: # i=0
1434: # while (not self.basketContainer.resultLockedHash.has_key(threadName)) and (i<100):
1435: # logging.debug(" downloadFinally: I am waiting for thread %s to write the LockedHashfile: %s"%(threadName,i))
1436: # time.sleep(5)
1437: # i+=1
1438: # lockedFiles=self.basketContainer.resultLockedHash[threadName]
1439:
1440: # fh=file("/var/tmp/test")
1441: #ret =fh.read()
1442:
1443: if (not isinstance(self.aq_parent,CDLIBasket)):
1444: basket_name=self.aq_parent.aq_parent.title+"_V"+self.getId()
1445: else:
1446: basket_name=self.aq_parent.title+"_V"+self.getId()
1447:
1448:
1449:
1450: #write basketname to header of atf file
1451:
1452:
1453: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.atf" """%basket_name)
1454: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
1455: #length=len(ret)
1456: #self.REQUEST.RESPONSE.setHeader("Content-Length",length)
1457:
1458: ret="#basket: %s\n"%basket_name
1459: self.REQUEST.RESPONSE.write(ret)
1460:
1461: for fileName in files:
1462: logging.debug("download: %s"%fileName)
1463: try:
1464: self.REQUEST.RESPONSE.write(file(fileName).read())
1465: except:
1466: logging.error("downloadasonefile: cannot read %s"%fileName)
1467:
1468:
1469: self.REQUEST.RESPONSE.write("\n# locked files\n")
1470: for fileName in lockedFiles:
1471: self.REQUEST.RESPONSE.write("# %s by %s\n"%fileName)
1472:
1473: self.REQUEST.RESPONSE.write("# locked files end\n")
1474:
1475: #del self.basketContainer.resultHash[threadName]
1476: #del self.basketContainer.resultLockedHash[threadName]
1477:
1478: def numberOfItems(self):
1479: """return anzahl der elemente im basket"""
1480: return self.content.numberOfItems()
1481:
1482: def getTime(self):
1483: """getTime"""
1484: #return self.bobobase_modification_time().ISO()
1485:
1486: if hasattr(self,'time'):
1487: return time.strftime("%Y-%m-%d %H:%M:%S",self.time)
1488: elif hasattr(self,'timefixed'):
1489: return self.timefixed
1490: else:
1491: setattr(self,'timefixed',self.bobobase_modification_time().ISO())
1492: return self.bobobase_modification_time().ISO()
1493:
1494: def getContent(self):
1495: """get Basket Content"""
1496: logging.debug("retrieving content A")
1497: cnt = self.content
1498: logging.debug("retrieving content: obj %s"%cnt)
1499: tmp = self.content.getContent()
1500: logging.debug("got content")
1501: return tmp
1502:
1503:
1504: def __init__(self,id,user,comment="",basketContent=[]):
1505: """ init a basket version"""
1506: self.id=id
1507: self.comment=comment
1508: self._setObject('content',BasketContent(basketContent))
1509: #self.basketContent=basketContent[0:]a
1510: self.user=user
1511: self.time=time.localtime()
1512:
1513: def getUser(self):
1514: """get user"""
1515: return self.user
1516:
1517: def getComment(self):
1518: """get Comment"""
1519: return self.comment
1520:
1521: security.declareProtected('manage','index_html')
1522: def index_html(self):
1523: """view the basket"""
1524: logging.debug("start index_html - Basket version")
1525: if self.REQUEST.get('change',False):
1526: ob=self.aq_parent.updateObjects(self.REQUEST['change'])
1527:
1528: self.REQUEST.RESPONSE.redirect(ob.absolute_url())#go to new basket, because changing generates a new basket
1529: logging.debug("start index_html - Basket version:template")
1530: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketVersionMain.zpt')).__of__(self)
1531: return pt()
1532:
1533: def getObjUrl(self,result):
1534: """getUrl of the version of the object"""
1535:
1536: founds=self.CDLICatalog.search({'title':result})
1537: if len(founds)>0:
1538: return founds[0].getObject().getLastVersion().absolute_url()
1539:
1540: else: #assume version number
1541: splitted=result.split("_")
1542: founds=self.CDLICatalog.search({'title':splitted[1]})
1543: return founds[0].getObject().getLastVersion().absolute_url()+'/'+result
1544:
1545: def manage_addCDLIBasketVersion(self,user,comment="",basketContent=[],RESPONSE=None):
1546: """add a version"""
1547:
1548: #check for already existing versions
1549:
1550: lastVersion=self.getLastVersion()
1551: if lastVersion is None:
1552: newId=str(1)
1553: else:
1554: newId=str(int(lastVersion.getId())+1)
1555:
1556: ob=CDLIBasketVersion(newId,user,comment,basketContent)
1557:
1558: self._setObject(newId, ob)
1559:
1560: if RESPONSE is not None:
1561: RESPONSE.redirect('manage_main')
1562: else:
1563: return ob
1564:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>