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