Annotation of cdli/cdli_files.py, revision 1.104
1.22 dwinter 1: """CDLI extensions of the filearchive"""
1.47 dwinter 2: from Products.versionedFile.extVersionedFile import *
1.1 dwinter 3: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
4: import os.path
5: import os
1.3 dwinter 6: import urlparse
1.49 dwinter 7: import urllib
8: import cgi
1.4 dwinter 9: from OFS.OrderedFolder import OrderedFolder
10: from OFS.SimpleItem import SimpleItem
11: import time
1.12 dwinter 12: from OFS.Folder import manage_addFolder
13: import re
1.19 dwinter 14: from AccessControl import ClassSecurityInfo
15: from Acquisition import Implicit
1.39 dwinter 16: from Globals import Persistent
1.19 dwinter 17: from threading import Thread
18: from ZPublisher.HTTPRequest import HTTPRequest
19: from ZPublisher.HTTPResponse import HTTPResponse
20: from ZPublisher.BaseRequest import RequestContainer
1.20 dwinter 21: import threading
1.57 dwinter 22: import logging
1.58 dwinter 23: import transaction
1.61 dwinter 24: import copy
1.66 dwinter 25: import codecs
1.76 dwinter 26: import sys
1.83 dwinter 27: from BTrees.IOBTree import IOBTree
1.81 casties 28: import cdliSplitter
1.83 dwinter 29: from sets import Set
30: import md5
1.87 dwinter 31: from DownloadBasket import DownloadBasketFinallyThread
1.102 dwinter 32: from types import *
1.103 dwinter 33: import pickle
1.104 ! dwinter 34: import tempfile
! 35:
1.85 dwinter 36: def makelist(mySet):
37: x = list(mySet)
38: x.sort()
39: return x
40:
1.79 casties 41: def unicodify(s):
42: """decode str (utf-8 or latin-1 representation) into unicode object"""
43: if not s:
44: return u""
45: if isinstance(s, str):
46: try:
47: return s.decode('utf-8')
48: except:
49: return s.decode('latin-1')
50: else:
51: return s
52:
53: def utf8ify(s):
54: """encode unicode object or string into byte string in utf-8 representation.
55: assumes string objects to be utf-8"""
56: if not s:
57: return ""
58: if isinstance(s, str):
59: return s
60: else:
61: return s.encode('utf-8')
62:
1.81 casties 63: def formatAtfHtml(l):
64: """escape special ATF characters for HTML"""
65: if not l:
66: return ""
67:
68: # replace &
69: l = l.replace('&','&')
70: # replace angular brackets
71: l = l.replace('<','<')
72: l = l.replace('>','>')
73: return l
74:
75: def formatAtfLineHtml(l, nolemma=True):
76: """format ATF line for HTML"""
77: if not l:
78: return ""
79:
80: if nolemma:
81: # ignore lemma lines
82: if l.lstrip().startswith('#lem:'):
83: return ""
84:
85: return formatAtfHtml(l)
86:
1.79 casties 87:
1.81 casties 88:
89: def formatAtfFullLineNum(txt, nolemma=True):
90: """format full line numbers in ATF text"""
91: # surface codes
92: surfaces = {'@obverse':'obv',
93: '@reverse':'rev',
94: '@surface':'surface',
95: '@edge':'edge',
96: '@left':'left',
97: '@right':'right',
98: '@top':'top',
99: '@bottom':'bottom',
100: '@face':'face',
101: '@seal':'seal'}
102:
103: if not txt:
104: return ""
105:
106: ret = []
107: surf = ""
108: col = ""
109: for line in txt.splitlines():
110: line = unicodify(line)
111: if line and line[0] == '@':
112: # surface or column
113: words = line.split(' ')
114: if words[0] in surfaces:
115: surf = line.replace(words[0],surfaces[words[0]]).strip()
116:
117: elif words[0] == '@column':
118: col = ' '.join(words[1:])
119:
120: elif line and line[0] in '123456789':
121: # ordinary line -> add line number
122: line = "%s:%s:%s"%(surf,col,line)
123:
124: ret.append(line)
125:
126: return '\n'.join(ret)
127:
128:
1.73 dwinter 129: def generateXMLReturn(hash):
130: """erzeugt das xml file als returnwert fuer uploadATFRPC"""
131:
132: ret="<return>"
133:
134: ret+="<errors>"
135: for error in hash['errors']:
136: ret+="""<error atf="%s">%s</error>"""%error
137:
138: ret+="</errors>"
139:
140: ret+="<changes>"
141: for changed in hash['changed']:
142: ret+="""<change atf="%s">%s</change>"""%changed
143: ret+="</changes>"
144:
145: ret+="<newPs>"
146: for new in hash['newPs']:
147: ret+="""<new atf="%s"/>"""%new
148: ret+="</newPs>"
149:
150: ret+="</return>"
151: return ret
152:
153:
1.55 dwinter 154: def unique(s):
155: """Return a list of the elements in s, but without duplicates.
156:
157: For example, unique([1,2,3,1,2,3]) is some permutation of [1,2,3],
158: unique("abcabc") some permutation of ["a", "b", "c"], and
159: unique(([1, 2], [2, 3], [1, 2])) some permutation of
160: [[2, 3], [1, 2]].
161:
162: For best speed, all sequence elements should be hashable. Then
163: unique() will usually work in linear time.
164:
165: If not possible, the sequence elements should enjoy a total
166: ordering, and if list(s).sort() doesn't raise TypeError it's
167: assumed that they do enjoy a total ordering. Then unique() will
168: usually work in O(N*log2(N)) time.
169:
170: If that's not possible either, the sequence elements must support
171: equality-testing. Then unique() will usually work in quadratic
172: time.
173: (from the python cookbook)
174: """
175:
176: n = len(s)
177: if n == 0:
178: return []
179:
180: # Try using a dict first, as that's the fastest and will usually
181: # work. If it doesn't work, it will usually fail quickly, so it
182: # usually doesn't cost much to *try* it. It requires that all the
183: # sequence elements be hashable, and support equality comparison.
184: u = {}
185: try:
186: for x in s:
187: u[x] = 1
188: except TypeError:
189: del u # move on to the next method
190: else:
191: return u.keys()
192:
193: # We can't hash all the elements. Second fastest is to sort,
194: # which brings the equal elements together; then duplicates are
195: # easy to weed out in a single pass.
196: # NOTE: Python's list.sort() was designed to be efficient in the
197: # presence of many duplicate elements. This isn't true of all
198: # sort functions in all languages or libraries, so this approach
199: # is more effective in Python than it may be elsewhere.
200: try:
201: t = list(s)
202: t.sort()
203: except TypeError:
204: del t # move on to the next method
205: else:
206: assert n > 0
207: last = t[0]
208: lasti = i = 1
209: while i < n:
210: if t[i] != last:
211: t[lasti] = last = t[i]
212: lasti += 1
213: i += 1
214: return t[:lasti]
215:
216: # Brute force is all that's left.
217: u = []
218: for x in s:
219: if x not in u:
220: u.append(x)
221: return u
222:
223:
1.39 dwinter 224: class BasketContent(SimpleItem):
225: """classe fuer den Inhalt eines Baskets"""
1.77 dwinter 226:
1.102 dwinter 227: def getFileAndVersionFromId(self,pnum,versionNr):
228:
229: obj=self.cdliRoot.getFileObject(pnum)
230: logging.debug("obj : %s"%obj)
231: version=obj.getVersionNr(versionNr)
232: logging.debug("-------vs: %s"%version.getFileName())
233: return version,obj
234:
1.39 dwinter 235: def __init__(self,content=[]):
236: """content"""
1.102 dwinter 237:
238: self.setContent(content[0:])
1.39 dwinter 239:
1.99 dwinter 240: def getContent(self,filtered=True):
1.102 dwinter 241: return self.contentList
242:
243: def getContentOld(self,filtered=True):
1.39 dwinter 244: """get content"""
1.102 dwinter 245: logging.debug("content object: content List %s"%self.contentList)
1.99 dwinter 246: ret=[]
1.102 dwinter 247:
248: return [self.getFileAndVersionFromId(x[0],x[1]) for x in self.contentList]
249: #
250: # if filtered:
251: # for x in self.contentList:
252: # if not((x[0] is None) or (x[1] is None)):
253: # ret.append(x)
254: # logging.debug("content object: content List -done filtered")
255: # return ret
256: #
257: # else:
258: # logging.debug("content object: content List -done not filtered")
259: # return self.contentList
1.99 dwinter 260:
261: def allContent(self):
262: """get all content"""
263: return self.getContent(filtered=False)
264:
1.39 dwinter 265: def setContent(self,content):
1.102 dwinter 266: contentList=[]
267: for x in content:
268: if not((x[0] is None) or (x[1] is None)):
269:
270: contentList.append((x[1].getId(),x[0].getVersionNumber()))
271: logging.debug("cl: %s"%contentList)
272: self.contentList=contentList[0:]
273:
1.39 dwinter 274: def numberOfItems(self):
275: """number"""
276:
277: return len(self.getContent())
278:
279:
1.19 dwinter 280: class uploadATFfinallyThread(Thread):
1.20 dwinter 281: """class for adding uploaded filed (temporarily stored in the staging area at /tmp"""
282:
1.19 dwinter 283: def __init__(self):
1.20 dwinter 284: """init for uploadATFfinallyThread"""
1.19 dwinter 285: self.continueVar=True
286: self.returnValue=None
287: self.end=False
288: Thread.__init__(self)
289:
290: def set(self,procedure,comment="",basketname='',unlock=None,SESSION=None,username=None,serverport="8080"):
1.20 dwinter 291: """set start values for the thread"""
1.19 dwinter 292: self.procedure=procedure
293: self.comment=comment
294: self.basketname=basketname
295: self.unlock=unlock
296: self.SESSION=SESSION
297: self.username=username
298: self.serverport=serverport
1.60 dwinter 299:
1.19 dwinter 300:
301: def __call__(self):
1.20 dwinter 302: """call of the thread (equals run)"""
1.19 dwinter 303: self.run()
304: return True
305:
306: def getContext(self, app,serverport="8080"):
1.20 dwinter 307: """get the context within the ZODB"""
308:
1.19 dwinter 309: resp = HTTPResponse(stdout=None)
310: env = {
311: 'SERVER_NAME':'localhost',
312: 'SERVER_PORT':serverport,
313: 'REQUEST_METHOD':'GET'
314: }
315: req = HTTPRequest(None, env, resp)
316: return app.__of__(RequestContainer(REQUEST = req))
317:
1.26 dwinter 318:
1.19 dwinter 319: def run(self):
1.20 dwinter 320: """run"""
321:
1.19 dwinter 322: self.result=""
1.20 dwinter 323: #find context within ZODB
1.19 dwinter 324: from Zope import DB
325: conn = DB.open()
326: root = conn.root()
327: app = root['Application']
328: ctx = self.getContext(app,serverport=self.serverport)
329:
1.20 dwinter 330: #add the files
1.19 dwinter 331: self.uploadATFfinallyThread(ctx,self.procedure,comment=self.comment,basketname=self.basketname,unlock=self.unlock,SESSION=self.SESSION,username=self.username)
1.20 dwinter 332: #commit the transactions
1.58 dwinter 333: transaction.get().commit()
1.19 dwinter 334: conn.close()
1.20 dwinter 335: #set flag for end of this method
1.19 dwinter 336: self.end=True
1.66 dwinter 337: logging.info("ended")
338: return True
1.19 dwinter 339:
1.22 dwinter 340: def __del__(self):
341: """delete"""
342:
343:
344:
1.19 dwinter 345: def getResult(self):
1.20 dwinter 346: """method for accessing result"""
347:
1.19 dwinter 348: return self.result
349:
350: def uploadATFfinallyThread(self,ctx,procedure,comment="",basketname='',unlock=None,RESPONSE=None,SESSION=None,username=None):
351: """upload the files"""
1.20 dwinter 352: #TODO: make this configurable, at the moment, rootFolder for cdli has to be cdliRoot
1.19 dwinter 353: ctx2=ctx.cdliRoot
354:
355: self.result+="<h2>Start processing</h2>"
1.20 dwinter 356:
357: #shall I only upload the changed files?
1.81 casties 358: logging.debug("uploadATFfinally procedure: %s"%procedure)
1.19 dwinter 359: if procedure=="uploadchanged":
1.66 dwinter 360: changed=[x[0] for x in SESSION.get('changed',[])]
1.61 dwinter 361: uploadFns=changed+SESSION.get('newPs',[])
1.19 dwinter 362:
1.20 dwinter 363: #or all
1.19 dwinter 364: elif procedure=="uploadAll":
365: uploadFns=[]
366: for x in os.listdir(SESSION['tmpdir']):
1.45 dwinter 367: if not x in SESSION['lockerrors']:
1.19 dwinter 368: uploadFns.append(x)
1.20 dwinter 369:
370: #or maybe nothing
1.19 dwinter 371: elif procedure=="noupload":
1.81 casties 372: return True
1.19 dwinter 373: else:
374: uploadFns=[]
375:
1.20 dwinter 376: #do first the changed files
1.65 dwinter 377: i=0
1.19 dwinter 378: for fn in uploadFns:
1.81 casties 379: logging.debug("uploadATFfinally uploadFn=%s"%fn)
1.66 dwinter 380: i+=1
1.19 dwinter 381: founds=ctx2.CDLICatalog.search({'title':fn})
382: if len(founds)>0:
383: SESSION['author']=str(username)
1.63 dwinter 384: self.result="<p>Changing : %s"%fn+self.result
1.81 casties 385: logging.debug("uploadatffinallythread changing:%s"%fn+self.result)
1.49 dwinter 386: founds[0].getObject().manage_addCDLIFileObject('',comment,SESSION['author'],file=os.path.join(SESSION['tmpdir'],fn),from_tmp=True)
1.81 casties 387: if i%200==0:
388: transaction.get().commit()
389: logging.debug("uploadatffinallythread changing: do commit")
1.65 dwinter 390:
391: transaction.get().commit()
1.81 casties 392: logging.debug("uploadatffinallythread changing: last commit")
1.62 dwinter 393:
1.20 dwinter 394: #now add the new files
1.19 dwinter 395: newPs=SESSION['newPs']
396: if len(newPs)>0:
397: tmpDir=SESSION['tmpdir']
1.81 casties 398: logging.debug("uploadatffinallythread adding start")
1.63 dwinter 399: self.result="<p>Adding files</p>"+self.result
1.20 dwinter 400: #TODO: make this configurable, at the moment base folder for the files has to be cdli_main
1.22 dwinter 401: ctx2.importFiles(comment=comment,author=str(username) ,folderName=tmpDir, files=newPs,ext=self)
1.81 casties 402: logging.debug("uploadatffinallythread adding finished")
1.19 dwinter 403:
1.20 dwinter 404: #unlock locked files?
1.19 dwinter 405: if unlock:
1.81 casties 406: logging.debug("uploadatffinallythread unlocking start")
1.63 dwinter 407: self.result="<p>Unlock files</p>"+self.result
1.19 dwinter 408: unlockFns=[]
409: for x in os.listdir(SESSION['tmpdir']):
410: if not x in SESSION['errors']:
411: unlockFns.append(x)
1.81 casties 412:
413: logging.debug("unlocking have now what to unlock")
1.65 dwinter 414:
1.19 dwinter 415: for fn in unlockFns:
1.65 dwinter 416: #logging.info("will unlock: %s"%fn)
1.19 dwinter 417: founds=ctx2.CDLICatalog.search({'title':fn})
1.65 dwinter 418: #logging.info("found it: %s"%repr(founds))
1.19 dwinter 419: if len(founds)>0:
1.65 dwinter 420: #logging.info("unlock: %s"%founds[0].getObject().getId())
1.19 dwinter 421: SESSION['author']=str(username)
422: founds[0].getObject().lockedBy=""
1.81 casties 423:
424: logging.debug("uploadatffinallythread unlocking done")
1.19 dwinter 425:
1.65 dwinter 426: #if a basketname is given, add files to the basket
1.19 dwinter 427: if not (basketname ==''):
1.81 casties 428: logging.debug("uploadatffinallythread add to basket %s"%basketname)
1.65 dwinter 429: self.result="<p>Add to basket</p>"+self.result
1.41 dwinter 430: basketId=ctx2.basketContainer.getBasketIdfromName(basketname)
1.19 dwinter 431:
432: if not basketId: # create new basket
1.81 casties 433: logging.debug("uploadatffinallythread create basket %s"%basketname)
1.65 dwinter 434: self.result="<p>Create a new basket</p>"+self.result
1.19 dwinter 435: ob=ctx2.basketContainer.addBasket(basketname)
436: basketId=ob.getId()
437: basket=getattr(ctx2.basketContainer,str(basketId))
438: ids=os.listdir(SESSION['tmpdir'])
1.93 dwinter 439: #logging.debug("should add:"+repr(ids))
1.19 dwinter 440: basket.addObjects(ids,deleteOld=True,username=str(username))
441:
1.81 casties 442: logging.debug("uploadatffinallythread uploadfinally done")
443:
1.19 dwinter 444: if RESPONSE is not None:
445: RESPONSE.redirect(self.aq_parent.absolute_url())
446:
447: return True
1.60 dwinter 448:
449: class tmpStore(SimpleItem):
450: """simple item"""
451: meta_type="cdli_upload"
1.19 dwinter 452:
1.60 dwinter 453: def __init__(self,id):
454: """init tmp"""
455: self.id=id
456:
1.19 dwinter 457: class uploadATFThread(Thread):
1.20 dwinter 458: """class for checking the files befor uploading"""
1.19 dwinter 459:
460: def __init__(self):
1.20 dwinter 461: """initialise"""
462:
1.19 dwinter 463: self.continueVar=True
464: self.returnValue=None
465:
466: Thread.__init__(self)
467:
468:
1.60 dwinter 469: def set(self,upload,basketId,username,idTmp,serverport="8080"):
1.20 dwinter 470: """set start values for the thread"""
1.19 dwinter 471: self.result=""
472: self.upload=upload
473: self.basketId=basketId
474: self.username=username
475: self.serverport=serverport
1.60 dwinter 476: self.idTmp=idTmp
1.19 dwinter 477:
478: def __call__(self):
1.20 dwinter 479: """call method """
1.19 dwinter 480: self.run()
481: return True
482:
483: def getContext(self, app,serverport="8080"):
1.20 dwinter 484: """get the context within the ZODB"""
1.19 dwinter 485: resp = HTTPResponse(stdout=None)
486: env = {
487: 'SERVER_NAME':'localhost',
488: 'SERVER_PORT':serverport,
489: 'REQUEST_METHOD':'GET'
490: }
491: req = HTTPRequest(None, env, resp)
492: return app.__of__(RequestContainer(REQUEST = req))
493:
494: def run(self):
1.60 dwinter 495: idTmp=self.idTmp
1.19 dwinter 496: self.result=""
1.20 dwinter 497: #find context within ZODB
1.19 dwinter 498: from Zope import DB
499: conn = DB.open()
500: root = conn.root()
501: app = root['Application']
502: ctx = self.getContext(app,serverport=self.serverport)
1.60 dwinter 503: logging.info("run intern")
1.63 dwinter 504: try:
1.73 dwinter 505: logging.info("created: %s"%idTmp)
1.63 dwinter 506: ctx.temp_folder._setObject(idTmp,tmpStore(idTmp))
507: except:
508: logging.error("thread upload: %s %s"%sys.exc_info()[0:2])
509:
1.60 dwinter 510: logging.info("call thread intern")
511: self.uploadATFThread(ctx,self.upload,idTmp,self.basketId)
1.24 dwinter 512:
1.30 dwinter 513: #ctx.cdliRoot.cdli_main.tmpStore2[self.getName()[0:]]=self.returnValue
1.58 dwinter 514:
1.66 dwinter 515:
1.58 dwinter 516: transaction.get().commit()
1.49 dwinter 517:
1.19 dwinter 518: conn.close()
1.22 dwinter 519:
1.73 dwinter 520: return getattr(ctx.temp_folder,idTmp)
1.19 dwinter 521:
522: def getResult(self):
1.20 dwinter 523: """method for accessing result"""
1.19 dwinter 524: return self.result
525:
1.60 dwinter 526: def uploadATFThread(self,ctx,upload,idTmp,basketId=0):
1.19 dwinter 527: """upload an atf file"""
528: #TODO: add comments
529: #TODO: finish uploadATF
1.60 dwinter 530:
531: stObj=getattr(ctx.temp_folder,idTmp)
532: logging.info("start, upload thread")
1.25 dwinter 533: self.result="<html><body><h2>I got your file, start now to split it into single atf-files!</h2><p>"
534:
1.20 dwinter 535: #make sure that id is a string and not an integer
1.19 dwinter 536: basketId=str(basketId)
537:
1.20 dwinter 538: #TODO: make this configurable, at the moment, rootFolder for cdli has to be cdliRoot
539: ctx2=ctx.cdliRoot
1.19 dwinter 540:
1.20 dwinter 541: #get temporary file for staging the downloaded and splitted files
1.104 ! dwinter 542: dir=tempfile.mkdtemp()
1.20 dwinter 543:
544:
545: changed=[] # changed files
546: errors=[] # files with errors
1.45 dwinter 547: lockerrors=[] # files with errors
548:
1.20 dwinter 549: newPs=[] # new p filed
550: psNotInCatalog=[] # files not in the catalog
551:
552: #split the uploadedd atf file
1.25 dwinter 553: basketNameFromFile, numberOfFiles=splitatf(upload,dir,ext=self)
1.19 dwinter 554:
1.20 dwinter 555: #find basketId if not set
556:
557: #get active abaket
1.19 dwinter 558: if basketId == '0':
559: basketObj=ctx2.basketContainer.getActiveBasket()
560: if basketObj:
561: basketId=basketObj.getId()
562:
1.45 dwinter 563: #if there is no active basket and no basketid given, id is empty, else get besketname and length
1.19 dwinter 564: if basketId == '0':
565: basketNameFromId=""
566: basketLen=0
567: else:
568: basketNameFromId=getattr(ctx2.basketContainer,basketId).title
569: basketLen=getattr(ctx2.basketContainer,basketId).getLastVersion().numberOfItems()
570:
1.60 dwinter 571: logging.info("got the file, upload thread")
1.25 dwinter 572: self.result+="""<html><body><h2>I got the files</h2><
573: p>I am computing the differences to the exisiting files</p>"""
1.20 dwinter 574:
575: #start to check the files
1.19 dwinter 576: for fn in os.listdir(dir):
577:
1.63 dwinter 578: self.result="<p>process:%s</p>"%fn+self.result
1.19 dwinter 579:
1.20 dwinter 580: # check if file is in the catalog
581: #TODO: checkCatalog is not implemented yet
1.19 dwinter 582: if ctx2.cdli_main.checkCatalog(fn):
583: psNotInCatalog.append(fn)
584:
1.20 dwinter 585: #check if p-file already at the server
1.19 dwinter 586: founds=ctx2.CDLICatalog.search({'title':fn})
587:
1.20 dwinter 588: #if not than add filename to the list of newfiles
1.46 dwinter 589:
590: data=file(os.path.join(dir,fn)).read()
1.69 dwinter 591: status,msg=checkFile(fn,data,dir)
592: #status=True
593:
594:
1.46 dwinter 595: if not status: # error
596: errors.append((fn,msg))
1.69 dwinter 597:
1.46 dwinter 598: else:
599: if len(founds)==0:
600: newPs.append(fn)
601:
602: #if p file alread at the server
603: for found in founds:
604: #analyse the differences to the actual file
605: obj=found.getObject()
606:
607: if (not (str(obj.lockedBy))=='') and (not (str(obj.lockedBy)==str(self.username))):
1.63 dwinter 608: lockerrors.append((fn,str(obj.lockedBy)))
1.46 dwinter 609: else:
610:
611: diffs=obj.diff(data)
612: if diffs[0]>0:
613: changed.append((obj,diffs)) #hochladen
1.31 dwinter 614:
1.20 dwinter 615: #ready, set the returnValues
1.19 dwinter 616: self.result+="<h3>Done</h3></body></html>"
617:
1.60 dwinter 618: stObj.returnValue={}
1.19 dwinter 619:
1.60 dwinter 620: stObj.returnValue['errors']=errors
1.69 dwinter 621:
1.60 dwinter 622: stObj.returnValue['newPs']=newPs
623: stObj.returnValue['tmpdir']=dir
624: stObj.returnValue['basketLen']=basketLen
625: stObj.returnValue['numberOfFiles']=numberOfFiles
626: stObj.returnValue['basketNameFromId']=basketNameFromId
627: stObj.returnValue['basketNameFromFile']=basketNameFromFile
628: stObj.returnValue['basketId']=basketId
629: stObj.returnValue['dir']=dir
1.61 dwinter 630: #stObj.returnValue['changed']=copy.copy(changed)
631: stObj.returnValue['changed']=[(x[0].getId(),x[1][0]) for x in changed]
632: #stObj.returnValue['lockerrors']=[x[0].getId() for x in lockerrors]
1.63 dwinter 633: stObj.returnValue['lockerrors']=[x for x in lockerrors]
1.60 dwinter 634: self.returnValue=True
1.19 dwinter 635: #ctx2.cdli_main.setTemp('v_uploadATF_returnValue',True)
636:
1.63 dwinter 637:
1.4 dwinter 638: class CDLIBasketContainer(OrderedFolder):
639: """contains the baskets"""
640:
641:
1.9 dwinter 642: security=ClassSecurityInfo()
1.4 dwinter 643: meta_type="CDLIBasketContainer"
644:
1.103 dwinter 645: def getResultHash(self):
646: """get the result hash for debug purposes"""
647: return self.resultHash.keys()
648:
1.73 dwinter 649: def getPNumbersOfBasket(self,basketName):
650: """get all pnumbers of a basket as a list, returns an empty list if basket not found
651: @param basketName: name of the basket
652: """
653: ret=[]
654: basketId=self.getBasketIdfromName(basketName)
655: if not basketId:
656: return []
657:
1.102 dwinter 658: ob=getattr(self,basketId).getContent() #get the content of a basket
1.73 dwinter 659:
660: ret=[x[0].split(".")[0] for x in ob]
661:
662: return ret
663:
1.77 dwinter 664: security.declareProtected('manage','getBasketAsOneFile')
1.73 dwinter 665: def getBasketAsOneFile(self,basketName,current="no"):
666: """returns all files of the basket combined in one file
667: @param basketName: Name of the basket
668: @param current: (optional) if current is set to "yes" then the most current version of
669: all files are downloaded and not the versions of the files as stored in the basket
670: """
671: ret=""
672: basketId=self.getBasketIdfromName(basketName)
673: if not basketId:
674: return ""
675:
676: ob=getattr(self,basketId).getLastVersion()
1.102 dwinter 677: for pnum,versionNr in ob.getContent():
678: obj=self.cdliRoot.getFileObject(pnum)
679: # logging.debug("obj : %s"%obj)
680: # version=obj.getVersionNr(versionNr)
681:
1.73 dwinter 682: if current=="no": #version as they are in the basket
1.102 dwinter 683: cur= obj.getVersionNr(versionNr)
684: ret+=str(cur.getData())+"\n"
1.73 dwinter 685: elif current=="yes":
686: #search current object
1.93 dwinter 687: #logging.debug("current: %s"%object[1].getId().split(".")[0])
1.102 dwinter 688: obj.getData()
1.73 dwinter 689: return ret
690:
1.77 dwinter 691: security.declareProtected('manage','upDateBaskets')
1.39 dwinter 692: def upDateBaskets(self):
693: """update content in to objects"""
694:
695: founds=self.ZopeFind(self,obj_metatypes=['CDLIBasketVersion'],search_sub=1)
696:
697: for found in founds:
698: found[1].updateBasket()
699:
1.32 dwinter 700: security.declareProtected('manage','deleteBaskets')
1.12 dwinter 701: def deleteBaskets(self,ids=None):
702: """delete baskets, i.e. move them into trash folder"""
703:
1.98 dwinter 704: if ids is None:
705: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
706: txt="Sorry, no basket selected!"
707: return pt(txt=txt)
1.12 dwinter 708:
709: found=self.ZopeFind(self,obj_ids=['trash'])
710:
711: if len(found)<1:
712: manage_addFolder(self, 'trash')
713: trash=self._getOb('trash')
714: else:
715: trash=found[0][1]
716:
717: if type(ids) is not ListType:
718: ids=[ids]
1.98 dwinter 719: logging.error("XERXON:"+repr(ids))
720: if len(ids)==0:
721: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
722: txt="Sorry, no basket selected!"
723: return pt(txt=txt)
724:
1.12 dwinter 725: cut=self.manage_cutObjects(ids)
726: trash.manage_pasteObjects(cut)
1.98 dwinter 727: return None
1.32 dwinter 728: security.declareProtected('manage','manageBaskets')
1.73 dwinter 729: def manageBaskets(self,submit,ids=None,basket1="",basket2="",joinBasket="",subtractBasket="",REQUEST=None,RESPONSE=None):
1.12 dwinter 730: """manage baskets, delete or copy"""
731: if submit=="delete":
1.98 dwinter 732: ret= self.deleteBaskets(ids)
733: if ret:
734: return ret
1.72 dwinter 735: elif submit=="join":
1.73 dwinter 736: flag,msg=self.joinBasket(joinBasket, ids)
1.72 dwinter 737: logging.info("joining %s %s"%(flag,msg))
1.98 dwinter 738: if not flag:
739: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
740:
741: return pt(txt=msg)
742:
1.72 dwinter 743: elif submit=="subtract":
744: logging.info("BBBb %s %s"%(basket1,basket2))
1.73 dwinter 745: flag,msg=self.subtractBasket(subtractBasket, basket1,basket2)
1.72 dwinter 746: logging.info("subtract %s %s"%(flag,msg))
1.12 dwinter 747:
748: if RESPONSE:
749: RESPONSE.redirect(self.absolute_url())
1.32 dwinter 750:
1.33 dwinter 751: security.declareProtected('View','getBasketIdfromName')
1.5 dwinter 752: def getBasketIdfromName(self,basketname):
753: """get id from name"""
754:
755: for basket in self.ZopeFind(self,obj_metatypes=["CDLIBasket"]):
756: if basket[1].title==basketname:
757: return basket[0]
758: else:
759: None
1.9 dwinter 760:
761: security.declareProtected('manage','uploadBasket_html')
762:
1.4 dwinter 763: def uploadBasket_html(self,basketId='0'):
764: """upload an atf file, html form"""
1.9 dwinter 765:
766:
1.4 dwinter 767: basketId=str(basketId)
768: if not basketId=='0':
769: basketName=getattr(self.basketContainer,basketId).title
770: else:
771: basketName=""
772:
773: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasket_html.zpt')).__of__(self)
774: return pt(basketId=basketId,basketName=basketName)
775:
776:
1.77 dwinter 777: security.declareProtected('manage','index_html')
1.4 dwinter 778: def index_html(self):
779: """stanadard ansicht"""
1.9 dwinter 780:
781:
782:
1.4 dwinter 783: ext=self.ZopeFind(self,obj_ids=["index.html"])
784: if ext:
785: return ext[0][1]()
786:
787: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self)
788: return pt()
789:
790: def getStorageFolderRoot(self):
791: """root des storage folders"""
792: return self.cdli_main
793:
794: def __init__(self,id,title):
795: """ init basket container"""
796: self.id=id
797: self.title=title
798:
1.51 dwinter 799:
1.49 dwinter 800: def getBasketsId(self):
801: """get all baskets als klartext"""
1.51 dwinter 802:
803: ret=""
1.49 dwinter 804: baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
805: for basket in baskets:
806: com,user,time,values = basket[1].getContentIds()
807: ret+= "BASKET:"+com+"\t"+user+"\t"+time+"\n"
808: for x in values:
809: ret+= x[0]+"\t"+x[1]+"\n"
1.66 dwinter 810: return ret
1.49 dwinter 811:
1.4 dwinter 812: def getBaskets(self,sortField='title'):
813: """get all baskets files"""
814:
815: def sortName(x,y):
816: return cmp(x[1].title.lower(),y[1].title.lower())
817:
818: def sortDate(x,y):
819: return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())
820:
821:
822: def sortComment(x,y):
823:
824:
825:
826: try:
827: xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()
828: except:
829: xc='ZZZZZZZZZZZZZ'.lower()
830: try:
831: yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()
832: except:
833: yc='ZZZZZZZZZZZZZ'.lower()
834:
835:
836: if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):
837:
838: try:
839: xc=x[1].getLastVersion().getComment().lower()
840: except:
841: xc='ZZZZZZZZZZZZZ'.lower()
842:
843: if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):
844: try:
845: yc=y[1].getLastVersion().getComment().lower()
846: except:
847: yc='ZZZZZZZZZZZZZ'.lower()
848:
849:
850: return cmp(xc,yc)
851:
852: def sortAuthor(x,y):
853:
854: return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower())
855:
856: baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
857:
858:
859: if sortField=='title':
860: baskets.sort(sortName)
861: elif sortField=='date':
862: baskets.sort(sortDate)
863: elif sortField=='author':
864: baskets.sort(sortAuthor)
865: elif sortField=='comment':
866: baskets.sort(sortComment)
1.39 dwinter 867:
1.4 dwinter 868: return baskets
1.72 dwinter 869:
870:
871: def subtractBasket(self,newBasket,basket1,basket2):
872: """subtract basket2 from basket1
873: (i.e. newbasket will contain alle elements of basket1 which are not in basket2),
874: if basket2 contains files which are not in basket1, then theses files fill be ignored
875:
876: @param newbasket: name of the new basket
877: @param basket1: basket where basket2 will be subtracted from
878: @param basket2: see above
879:
880: """
1.98 dwinter 881:
1.72 dwinter 882: logging.info("CCCCC %s %s"%(basket1,basket2))
883:
884: try:
885: newB=self.addBasket(newBasket)
886: except:
887: return False, "cannot create the new basket"
888:
889:
1.4 dwinter 890:
1.72 dwinter 891:
892:
893: bas2= getattr(self,basket2)
894: bas2content=bas2.getContent()
895: bas2ids=[x[0] for x in bas2content]
896:
897:
898:
899: bas1= getattr(self,basket1)
900: bas1content=bas1.getContent()
901:
902:
903: newBasketContent={}
904:
905: for id,version in bas1content:
906: if not (id in bas2ids):
907: newBasketContent[id]=version
908:
909: username=self.getActualUserName()
910:
911: logging.info("sbc %s"%newBasketContent)
912: newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
913:
914: return True, ""
915:
916:
917: def joinBasket(self,newBasket,oldBaskets):
1.71 dwinter 918: """join two baskets
919: @param newbasket: name of the new basket
920: @param oldbaskets: list of baskets to be joined
921: """
1.98 dwinter 922: if oldBaskets is None:
923: return False, "No Baskets selected!"
924:
1.72 dwinter 925: try:
926: newB=self.addBasket(newBasket)
927: except:
928: return False, "cannot create the new basket"
929:
930: newBasketContent={}
1.98 dwinter 931:
1.72 dwinter 932: for ob in oldBaskets:
933: x= getattr(self,ob,None)
934: if x is None:
935: return False, "cannot find basket: %s"%ob
936:
937: ids=x.getContent() # hole den Inhalt
938:
939: for id,version in ids:
940: if newBasketContent.has_key(id): # p number gibt's schon
941: newBasketContent[id]=max(newBasketContent[id],version) # speichere die groessere Versionsnumber
942: else:
943: newBasketContent[id]=version
944: username=self.getActualUserName()
945:
946: logging.info("nbc %s"%newBasketContent)
947: newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
948:
949: return True, ""
950:
1.4 dwinter 951: def getNewId(self):
952: """createIds"""
953: last=getattr(self,'last',0)
954: last +=1
955: while len(self.ZopeFind(self,obj_ids=[str(last)]))>0:
956: last+=1
957:
958: self.last=last
959: return last
960:
1.6 dwinter 961: def setActiveBasket(self,basketId,REQUEST=None):
1.4 dwinter 962: """store active basketId in a cookie"""
963: self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/")
1.66 dwinter 964: try:
965: qs=cgi.parse_qs(REQUEST['QUERY_STRING'])
966: del(qs['basketId'])
967: except:
968: qs={}
1.6 dwinter 969: if REQUEST:
1.49 dwinter 970: REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+urllib.urlencode(qs))
1.6 dwinter 971:
1.4 dwinter 972: def getActiveBasket(self):
973: """get active basket from cookie"""
974:
975: id= self.REQUEST.cookies.get('CDLIActiveBasket',None)
1.6 dwinter 976: if id:
977: obj=getattr(self,str(id),None)
978: else:
979: obj=None
1.4 dwinter 980: return obj
1.6 dwinter 981:
1.4 dwinter 982: def getActualUserName(self):
983: """get name of the actualuser"""
984: return str(self.REQUEST['AUTHENTICATED_USER'])
985:
1.77 dwinter 986: security.declareProtected('manage','addBasket')
1.4 dwinter 987: def addBasket(self,newBasketName):
988: """add a new basket"""
989:
990: ob=manage_addCDLIBasket(self,newBasketName)
991: return ob
1.72 dwinter 992:
1.6 dwinter 993: def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None):
1.4 dwinter 994: """store it"""
1.6 dwinter 995: if not ids:
996: ids=self.REQUEST.SESSION['fileIds']
1.83 dwinter 997:
998: if (type(ids) is not ListType) and (not isinstance(ids,Set)):
1.4 dwinter 999: ids=[ids]
1000:
1.83 dwinter 1001: if isinstance(ids,Set):
1002: ids=list(ids)
1003:
1.6 dwinter 1004: if (submit.lower()=="store in new basket") or (submit.lower()=="new basket"):
1.4 dwinter 1005: basketRet=self.addBasket(newBasketName)
1006: self.setActiveBasket(basketRet.getId())
1007: basket=getattr(self,basketRet.getId())
1.6 dwinter 1008: elif (submit.lower()=="store in active basket") or (submit.lower()=="active basket"):
1.4 dwinter 1009: basket=self.getActiveBasket()
1.6 dwinter 1010:
1011: added=basket.addObjects(ids)
1012: back=self.REQUEST['HTTP_REFERER'].split("?")[0]+"?basketName="+basket.title+"&numberOfObjects="+str(added)
1013:
1014:
1015: if fromFileList:
1.7 dwinter 1016:
1.83 dwinter 1017: return self.cdli_main.findObjectsFromList(list=ids,basketName=basket.title,numberOfObjects=added)
1.6 dwinter 1018:
1.4 dwinter 1019: if RESPONSE:
1.6 dwinter 1020:
1.4 dwinter 1021: RESPONSE.redirect(back)
1022:
1.6 dwinter 1023: return True
1024:
1.4 dwinter 1025: def manage_addCDLIBasketContainerForm(self):
1026: """add the CDLIBasketContainer form"""
1027: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self)
1028: return pt()
1029:
1030: def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None):
1031: """add the basket"""
1032: ob=CDLIBasketContainer(id,title)
1033:
1034: self._setObject(id, ob)
1035:
1036: if RESPONSE is not None:
1037: RESPONSE.redirect('manage_main')
1038:
1.5 dwinter 1039: class CDLIBasket(Folder,CatalogAware):
1.4 dwinter 1040: """basket"""
1041:
1042: meta_type="CDLIBasket"
1.5 dwinter 1043: default_catalog="CDLIBasketCatalog"
1.4 dwinter 1044:
1.75 dwinter 1045: def searchInBasket(self,indexName,searchStr,regExp=False):
1046: """searchInBasket"""
1047:
1.81 casties 1048: lst=self.searchInLineIndexDocs(indexName,searchStr,uniq=True,regExp=regExp) #TODO: fix this
1.75 dwinter 1049: ret={}
1050:
1051: lv=self.getLastVersion()
1.76 dwinter 1052:
1053:
1.75 dwinter 1054: for obj in lv.content.getContent():
1055: id=obj[1].getId().split(".")[0]
1056: if id in lst:
1057:
1058: ret[id]=self.showWordInFile(id,searchStr,lineList=self.getLinesFromIndex(indexName,searchStr,id,regExp=regExp),regExp=regExp,indexName=indexName)
1059:
1060:
1061: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','searchResultsInBasket')).__of__(self)
1062: return pt(result=ret,indexName=indexName,regExp=regExp,word=searchStr)
1063:
1064:
1065:
1066:
1067: def searchInBasket_v1(self,searchStr):
1.74 dwinter 1068: """search occurences of searchStr in files im basket"""
1069: ret=[]
1070: lv=self.getLastVersion()
1071: logging.info("searching")
1072: for obj in lv.content.getContent():
1073: txt=obj[0].getData()
1074: for x in txt.split("\n"):
1075: logging.info("search %s"%x)
1076: if re.match(searchStr,x):
1077: ret.append(x)
1078:
1079: return "\n".join(ret)
1080:
1081:
1.4 dwinter 1082: def getFile(self,obj):
1083: return obj[1]
1084:
1085: def getFileLastVersion(self,obj):
1086: return obj[0]
1087:
1.5 dwinter 1088: def getFileNamesInLastVersion(self):
1089: """get content of the last version as list"""
1090:
1091: return [x[1].getId() for x in self.getLastVersion().getContent()]
1092:
1.37 dwinter 1093:
1.102 dwinter 1094: def isActual(self,obj,nummer):
1095: """teste ob im basket die aktuelle version ist, obj kann entweder ein CDLIFile sein oder eine
1096: eine pnummer, die auf ein CDLIFile verweist"""
1097: try:
1098: #logging.debug("isActual:"+repr(obj))
1099: if isinstance(obj, CDLIFile):
1100: actualNo=obj.getLastVersion().getVersionNumber()
1101: else:
1102: actualNo=self.cdliRoot.getFileObjectLastVersion(obj).getVersionNumber()
1103:
1104: if actualNo==nummer:
1105: return True , 0
1106: else:
1107: return False, actualNo
1108: except:
1109: logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
1110: logging.error(""" PARAMS: %s %s"""%(obj,nummer))
1111: return False, -1
1112: def isActualOld(self,obj):
1.4 dwinter 1113: """teste ob im basket die aktuelle version ist"""
1.85 dwinter 1114: try:
1.93 dwinter 1115: #logging.debug("isActual:"+repr(obj))
1.85 dwinter 1116: actualNo=obj[1].getLastVersion().getVersionNumber()
1117: storedNo=obj[0].getVersionNumber()
1118:
1.87 dwinter 1119:
1.93 dwinter 1120: #actualNo=self.getFileObjectLastVersion(obj.getId()).getVersionNumber()
1.85 dwinter 1121:
1.87 dwinter 1122: #if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash":
1123: # return False, -1
1.37 dwinter 1124:
1.85 dwinter 1125: if actualNo==storedNo:
1126: return True , 0
1127: else:
1128: return False, actualNo
1129: except:
1.93 dwinter 1130: logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
1131:
1.12 dwinter 1132: return False, -1
1.85 dwinter 1133:
1.4 dwinter 1134: def history(self):
1135: """history"""
1136:
1137: ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
1138: if ext:
1139: return getattr(self,ext[0][1].getId())()
1140:
1141: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self)
1142: return pt()
1143:
1144: def getStorageFolderRoot(self):
1145: """root des storage folders"""
1146: return self.aq_parent.cdli_main
1147:
1148: def __init__(self,id,title,shortDescription="",comment=""):
1149: """init a CDLIBasket"""
1150:
1151: self.id=id
1152: self.title=title
1153: self.shortDescription=shortDescription
1154: self.comment=comment
1155:
1.72 dwinter 1156: def getActualUserName(self):
1157: """get name of the actualuser"""
1158:
1159: return str(self.REQUEST['AUTHENTICATED_USER'])
1160:
1.4 dwinter 1161:
1162: def getLastVersion(self):
1163: """hole letzte version"""
1.39 dwinter 1164:
1165: ids=[]
1166: idsTmp= self.objectIds()
1167: for x in idsTmp:
1168: try:
1169: ids.append(int(x))
1170: except:
1171: pass
1.4 dwinter 1172: ids.sort()
1.39 dwinter 1173:
1.4 dwinter 1174: if len(ids)==0:
1175: return None
1176: else:
1177: ob=getattr(self,str(ids[-1]))
1.39 dwinter 1178:
1179:
1.4 dwinter 1180: return ob
1181:
1182: def getVersions(self):
1183: """get versions"""
1184: versions=self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])
1185: return versions
1186:
1187:
1.37 dwinter 1188: def updateObjects(self,ids,RESPONSE=None,REQUEST=None):
1189: """update ids, ids not in the basket the add"""
1190: if type(ids) is not ListType:
1191: ids=[ids]
1192:
1193: lastVersion=self.getLastVersion()
1.39 dwinter 1194: oldContent=lastVersion.content.getContent()
1.37 dwinter 1195: newContent=[]
1196:
1197: #first copy the old
1198: for obj in oldContent:
1199: if obj[1].getId() not in ids:
1200: newContent.append(obj)
1201: #now add the new
1202:
1203: for id in ids:
1204: founds=self.CDLICatalog.search({'title':id})
1205:
1206: for found in founds:
1207: if found.getObject() not in oldContent:
1208: #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version
1209: newContent.append((found.getObject().getLastVersion(),found.getObject()))
1210:
1211:
1212: content=newContent
1213: user=self.getActualUserName()
1214:
1215: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
1216:
1.38 dwinter 1217: obj=self._getOb(ob.getId())
1.37 dwinter 1218: if RESPONSE:
1.38 dwinter 1219:
1.37 dwinter 1220: RESPONSE.redirect(obj.absolute_url())
1.38 dwinter 1221:
1222: return obj
1223:
1.72 dwinter 1224: def addObjectsWithVersion(self,ids,deleteOld=None,username=None,catalog=None):
1225: """generate a new version of the basket with objects added,
1226: hier wird jedoch nicht die letzte Version jedes Files hinzugefuegt, s
1227: ondern ids is ein Tupel mit der Id (d.h. der p-number) und der Versionsnummer.
1228: """
1229: logging.info("add to basket (%s)"%(self.getId()))
1230: lastVersion=self.getLastVersion()
1231:
1232: if not catalog:
1233: catalog=self.CDLICatalog
1234:
1235: if lastVersion is None:
1236: oldContent=[]
1237: else:
1238: oldContent=lastVersion.content.getContent()
1239:
1240: if deleteOld:
1241: oldContent=[]
1242:
1243: newContent=[]
1244: added=0
1245:
1246: for id,version in ids.iteritems():
1247: logging.info("adding %s %s"%(id,version))
1248: id=id.split(".")[0] # title nur die pnumber ohne atf
1249:
1250: try:
1251: founds=catalog.search({'title':id})
1252: except:
1253: founds=[]
1254: logging.info(" found %s "%(founds))
1255: for found in founds:
1256: if found.getObject() not in oldContent:
1257:
1258: #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version
1259: newContent.append((found.getObject().getVersions()[version-1][1],found.getObject()))
1260: added+=1
1261:
1262: content=oldContent+newContent
1263: if not username:
1264: logging.error("XXXXXXXXXXX %s"%repr(self))
1265: user=self.getActualUserName()
1266: else:
1267: user = username
1268:
1269: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content)
1270: logging.info("add to basket (%s) done"%(self.getId()))
1271: return added
1272:
1273:
1.19 dwinter 1274: def addObjects(self,ids,deleteOld=None,username=None):
1.4 dwinter 1275: """generate a new version of the basket with objects added"""
1.83 dwinter 1276:
1277: def swap(x):
1278: return (x[1],x[0])
1279:
1.100 dwinter 1280: logging.info("add to basket (%s)"%(repr(ids)))
1.65 dwinter 1281: logging.info("add to basket (%s)"%(self.getId()))
1.4 dwinter 1282: lastVersion=self.getLastVersion()
1283:
1284: if lastVersion is None:
1285: oldContent=[]
1286: else:
1.39 dwinter 1287: oldContent=lastVersion.content.getContent()
1.4 dwinter 1288:
1289: if deleteOld:
1290: oldContent=[]
1291:
1.6 dwinter 1292: added=0
1.83 dwinter 1293: # for id in ids:
1294: # logging.debug("adding:"+id)
1295: # try:
1296: # founds=self.CDLICatalog.search({'title':id})
1297: # except:
1298: # founds=[]
1299: #
1300: # for found in founds:
1301: # if found.getObject() not in oldContent:
1302: # #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version
1303: # newContent.append((found.getObject().getLastVersion(),found.getObject()))
1304: # added+=1
1305:
1.85 dwinter 1306: hash = md5.new(repr(makelist(ids))).hexdigest() # erzeuge hash als identification
1.83 dwinter 1307: #logging.debug("JJJJJJJ:"+repr(self.makelist(ids)))
1.93 dwinter 1308:
1.102 dwinter 1309: retrieved = self.CDLICache.retrieve(hash)
1310: if retrieved:
1311: newContent=Set(map(swap,retrieved))
1.83 dwinter 1312: else:
1.102 dwinter 1313: newContent=Set([(self.getFileObjectLastVersion(x),self.getFileObject(x)) for x in ids])
1314:
1315:
1.83 dwinter 1316:
1.100 dwinter 1317: #remove all Elements which are not stored
1318: if (None,None) in newContent:
1319: newContent.remove((None,None))
1.83 dwinter 1320: content=Set(oldContent).union(newContent)
1321: added = len(content)-len(oldContent)
1.19 dwinter 1322: if not username:
1323: user=self.getActualUserName()
1324: else:
1325: user = username
1.83 dwinter 1326:
1327: #logging.debug("content:"+repr(list(content)))
1328: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=list(content))
1.65 dwinter 1329: logging.info("add to basket (%s) done"%(self.getId()))
1.6 dwinter 1330: return added
1.4 dwinter 1331:
1.51 dwinter 1332:
1333:
1.72 dwinter 1334: def getContent(self):
1335: """print content"""
1336: ret=[]
1337:
1338: lv=self.getLastVersion()
1.102 dwinter 1339: #for obj in lv.content.getContent():
1.93 dwinter 1340: #logging.info("XXXXXXXXXX %s"%repr(obj))
1.102 dwinter 1341: # ret.append((obj[1].getId(),obj[0].versionNumber))
1.72 dwinter 1342:
1.102 dwinter 1343: return lv
1.72 dwinter 1344:
1.49 dwinter 1345: def getContentIds(self):
1346: """print basket content"""
1347: ret=[]
1348: lv=self.getLastVersion()
1.51 dwinter 1349: for obj in lv.content.getContent():
1.49 dwinter 1350: ret.append((obj[0].getId(),obj[1].getId()))
1351:
1352:
1353: return lv.getComment(),lv.getUser(),lv.getTime(),ret
1354:
1.37 dwinter 1355: def changeBasket(self,ids,submit,RESPONSE=None,REQUEST=None):
1356: """change a basket"""
1357: if submit=="update":
1358: return self.updateObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1359: elif submit=="delete":
1360: return self.deleteObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1361:
1.12 dwinter 1362: def deleteObjects(self,ids,RESPONSE=None,REQUEST=None):
1.4 dwinter 1363: """delete objects"""
1.12 dwinter 1364:
1365: if type(ids) is not ListType:
1366: ids=[ids]
1367:
1368: lastVersion=self.getLastVersion()
1.39 dwinter 1369: oldContent=lastVersion.content.getContent()
1.12 dwinter 1370: newContent=[]
1371: for obj in oldContent:
1372: if obj[1].getId() not in ids:
1373: newContent.append(obj)
1374:
1375:
1376: user=self.getActualUserName()
1377:
1378: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
1379:
1380: if RESPONSE:
1381: obj=self._getOb(ob.getId())
1382: RESPONSE.redirect(obj.absolute_url())
1.4 dwinter 1383:
1384: def manage_addCDLIBasketForm(self):
1385: """add the CDLIBasketContainer form"""
1386: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasket.zpt')).__of__(self)
1387: return pt()
1388:
1389: def manage_addCDLIBasket(self,title,shortDescription="",comment="",RESPONSE=None):
1390: """add the basket"""
1391:
1392: id=str(self.getNewId())
1393:
1394: ob=CDLIBasket(id,title,shortDescription,comment)
1395:
1396: self._setObject(id, ob)
1397:
1398: if RESPONSE is not None:
1399: RESPONSE.redirect('manage_main')
1400: else:
1401: return ob
1402:
1.39 dwinter 1403: class CDLIBasketVersion(Implicit,Persistent,Folder):
1.4 dwinter 1404: """version of a basket"""
1405:
1406: meta_type="CDLIBasketVersion"
1.32 dwinter 1407: security=ClassSecurityInfo()
1.4 dwinter 1408:
1.39 dwinter 1409: def updateBasket(self):
1410: """update"""
1411: try:
1412: self._setObject('content',BasketContent(self.basketContent))
1413: except:
1414: try:
1415: if len(self.basketContent)>0:
1416: self.content.setContent(self.basketContent)
1417: except:
1418: print "error",self.getId(),self.aq_parent.getId()
1419: self.basketContent=[]
1420:
1421:
1.37 dwinter 1422: def containsNonActualFiles(self):
1423: """returns True if basket contains one or more non current files"""
1424:
1425: objs=self.getContent()
1426: for obj in objs:
1.102 dwinter 1427: if not self.isActual(obj[0],obj[1])[0]:
1.37 dwinter 1428: return True
1429: return False
1430:
1.72 dwinter 1431: def downloadListOfPnumbers(self):
1432: """download pnumbers of the basket as list"""
1433:
1434: basket_name=self.aq_parent.title
1435:
1436: ids=self.getContent() # get the list of objects
1437: logging.error(ids)
1438: ret="\n".join([x[1].getId().split(".")[0] for x in ids])
1439:
1440: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.txt" """%basket_name)
1441: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
1442: length=len(ret)
1443: self.REQUEST.RESPONSE.setHeader("Content-Length",length)
1444: self.REQUEST.RESPONSE.write(ret)
1445:
1.77 dwinter 1446: security.declareProtected('manage','downloadObjectsAsOneFile')
1.37 dwinter 1447: def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None,check="yes",current="no"):
1.4 dwinter 1448: """download all selected files in one file"""
1.93 dwinter 1449:
1.46 dwinter 1450: if self.temp_folder.downloadCounterBaskets > 10000:
1451: return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
1.45 dwinter 1452:
1453:
1.103 dwinter 1454: #if (check=="yes") and self.containsNonActualFiles():
1455: # pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadObjectAsOneFile_check.zpt')).__of__(self)
1456: #
1457: # return pt(lock=lock)
1458:
1459: # neue Version aus Performancegruenden, es wird nicht mehr getestet, ob es nicht aktuelle Objekte gibt
1460: # sondern lediglich gefragt.
1461: if (check=="yes"):
1462: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadObjectAsOneFile_ask.zpt')).__of__(self)
1463:
1.37 dwinter 1464: return pt(lock=lock)
1465:
1.46 dwinter 1466: else:
1467:
1468: return self.downloadObjectsAsOneFileFinally(lock=lock,procedure=procedure,REQUEST=REQUEST,current="no")
1469:
1.87 dwinter 1470: def downloadObjectsAsOneFileFinally(self,lock=None,procedure=None,REQUEST=None,current="no",repeat=None):
1.46 dwinter 1471: """print do the download"""
1.87 dwinter 1472:
1.93 dwinter 1473:
1.46 dwinter 1474: ret=""
1.4 dwinter 1475: lockedObjects={}
1476:
1.87 dwinter 1477:
1.93 dwinter 1478:
1.4 dwinter 1479: if lock:
1.87 dwinter 1480: logging.debug("------lock:"+repr(lock))
1.4 dwinter 1481: if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
1.87 dwinter 1482:
1.4 dwinter 1483: return "please login first"
1484:
1485: #check if a locked object exist in the basket.
1486: lockedObjects={}
1.39 dwinter 1487: for object in self.content.getContent():
1.102 dwinter 1488: obj=self.getFileObject(object[0])
1489: if (not str(obj.lockedBy)=="") and (not (str(obj.lockedBy)==str(self.REQUEST['AUTHENTICATED_USER']))):
1490: lockedObjects[obj.title]=repr(obj.lockedBy)
1.4 dwinter 1491:
1492:
1493: keys=lockedObjects.keys()
1494:
1495:
1496: if len(keys)>0 and (not procedure):
1497: self.REQUEST.SESSION['lockedObjects']=lockedObjects
1498: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)
1.45 dwinter 1499:
1.87 dwinter 1500:
1.46 dwinter 1501: return pt()
1.4 dwinter 1502:
1503: elif not procedure: #keine fails gesperrt dann alle donwloaden
1504: procedure="downloadAll"
1505:
1.46 dwinter 1506:
1.87 dwinter 1507:
1508:
1509: threadName=repeat
1510: if not threadName or threadName=="":
1511: thread=DownloadBasketFinallyThread()
1512: threadName=thread.getName()[0:]
1513:
1514: if (not hasattr(self,'_v_downloadBasket')):
1515: self._v_downloadBasket={}
1516:
1517:
1518: self._v_downloadBasket[threadName]=thread
1519: logging.debug("dwonloadfinally:"+repr(self))
1.97 dwinter 1520:
1.96 dwinter 1521: if isinstance(self,CDLIBasketVersion):
1522: obj=self
1523: else:
1524: obj=self.aq_parent
1.95 dwinter 1525: logging.debug("dwonloadfinally2:"+repr(obj))
1526: logging.debug("dwonloadfinally2:"+repr(obj.aq_parent))
1527:
1.96 dwinter 1528: obj2=obj.aq_parent
1529: if not isinstance(obj2,CDLIBasket):
1.95 dwinter 1530: obj2=obj2.aq_parent
1531:
1532: basketID=obj2.getId()
1533: versionNumber=obj.getId()
1534: logging.debug("dwonloadfinally2:"+repr(basketID))
1535: logging.debug("dwonloadfinally2:"+repr(versionNumber))
1536:
1.97 dwinter 1537:
1.88 dwinter 1538: if lock:
1539: logging.debug("-----start locking")
1540: for object in self.content.getContent():
1.102 dwinter 1541: obj=self.ctx.getFileObject(object[0])
1542: if obj.lockedBy =='':
1543: obj.lockedBy=self.REQUEST['AUTHENTICATED_USER']
1.88 dwinter 1544: logging.debug("-----finished locking")
1545:
1546: #obj.lockedBy=user
1547: self._v_downloadBasket[threadName].set(lock,procedure,self.REQUEST['AUTHENTICATED_USER'],current,basketID,versionNumber)
1.45 dwinter 1548:
1.87 dwinter 1549: self._v_downloadBasket[threadName].start()
1.4 dwinter 1550:
1.87 dwinter 1551:
1552:
1553: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1554:
1555: if wait_template:
1556: return wait_template[0][1]()
1557: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
1558:
1.88 dwinter 1559: return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
1560: counter=self._v_downloadBasket[threadName].getCounter(),
1561: number=self._v_downloadBasket[threadName].getNumberOfFiles())
1.87 dwinter 1562: #_v_xmltrans.run()
1563:
1564: else:
1565: #recover thread, if lost
1566: if not hasattr(self,'_v_downloadBasket'):
1567: self._v_downloadBasket={}
1568: if not self._v_downloadBasket.get(threadName,None):
1569: for thread in threading.enumerate():
1570: if threadName == thread.getName():
1571: self._v_downloadBasket[threadName]=thread
1572:
1573: if self._v_downloadBasket.get(threadName,None) and (self._v_downloadBasket[threadName] is not None) and (not self._v_downloadBasket[threadName].end) :
1574:
1575: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1576: if wait_template:
1577: return wait_template[0][1]()
1.83 dwinter 1578:
1.87 dwinter 1579: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
1.88 dwinter 1580: return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
1581: counter=self._v_downloadBasket[threadName].getCounter(),
1582: number=self._v_downloadBasket[threadName].getNumberOfFiles())
1.87 dwinter 1583: else:
1584:
1585:
1586: logging.debug("FINISHED")
1587: if not self._v_downloadBasket.get(threadName,None):
1588: for thread in threading.enumerate():
1589: if threadName == thread.getName():
1590: self._v_downloadBasket[threadName]=thread
1591:
1592: #files = self._v_downloadBasket[threadName].result
1.103 dwinter 1593: # lade die files und die locked files, bei grossen Baskets muss u.U. gewartet werden
1594: # bis das Commit aus dem Thread alles geschrieben hat, in dem Falle existiert resultHash[threadName]
1595: # noch nicht.
1596: o1 = file("/tmp/"+threadName,'r')
1597: files=pickle.load(o1)
1598: os.remove("/tmp/"+threadName)
1599: o2 = file("/tmp/"+threadName+'_lockedFiles','r')
1600:
1601: lockedFiles=pickle.load(o2)
1602: os.remove("/tmp/"+threadName+'_lockedFiles')
1603: # try:
1604: # files=self.basketContainer.resultHash[threadName]
1605: # except:
1606: # i=0
1607: # while (not self.basketContainer.resultHash.has_key(threadName)) and (i<100):
1608: # logging.debug(" downloadFinally: I am waiting for thread %s to write the resultHashfile: %s"%(threadName,i))
1609: # time.sleep(5)
1610: # i+=1
1611: # files=self.basketContainer.resultHash[threadName]
1612: #
1613: # try:
1614: # lockedFiles=self.basketContainer.resultLockedHash[threadName]
1615: # except:
1616: # i=0
1617: # while (not self.basketContainer.resultLockedHash.has_key(threadName)) and (i<100):
1618: # logging.debug(" downloadFinally: I am waiting for thread %s to write the LockedHashfile: %s"%(threadName,i))
1619: # time.sleep(5)
1620: # i+=1
1621: # lockedFiles=self.basketContainer.resultLockedHash[threadName]
1.92 dwinter 1622:
1.87 dwinter 1623: # fh=file("/var/tmp/test")
1624: #ret =fh.read()
1625:
1626: if (not isinstance(self.aq_parent,CDLIBasket)):
1627: basket_name=self.aq_parent.aq_parent.title+"_V"+self.getId()
1628: else:
1629: basket_name=self.aq_parent.title+"_V"+self.getId()
1.86 dwinter 1630:
1631:
1632:
1.87 dwinter 1633: #write basketname to header of atf file
1634:
1.45 dwinter 1635:
1.87 dwinter 1636: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.atf" """%basket_name)
1637: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
1638: #length=len(ret)
1639: #self.REQUEST.RESPONSE.setHeader("Content-Length",length)
1.90 dwinter 1640:
1.87 dwinter 1641: ret="#basket: %s\n"%basket_name
1.90 dwinter 1642: self.REQUEST.RESPONSE.write(ret)
1643:
1.87 dwinter 1644: for fileName in files:
1.102 dwinter 1645: logging.debug("download: %s"%fileName)
1.91 dwinter 1646: try:
1.87 dwinter 1647: self.REQUEST.RESPONSE.write(file(fileName).read())
1.91 dwinter 1648: except:
1649: logging.error("downloadasonefile: cannot read %s"%fileName)
1.90 dwinter 1650:
1651:
1652: self.REQUEST.RESPONSE.write("\n# locked files\n")
1653: for fileName in lockedFiles:
1.92 dwinter 1654: self.REQUEST.RESPONSE.write("# %s by %s\n"%fileName)
1.90 dwinter 1655:
1656: self.REQUEST.RESPONSE.write("# locked files end\n")
1657:
1.104 ! dwinter 1658: #del self.basketContainer.resultHash[threadName]
! 1659: #del self.basketContainer.resultLockedHash[threadName]
1.87 dwinter 1660:
1.4 dwinter 1661: def numberOfItems(self):
1662: """return anzahl der elemente im basket"""
1.39 dwinter 1663: return self.content.numberOfItems()
1.4 dwinter 1664:
1665: def getTime(self):
1666: """getTime"""
1667: #return self.bobobase_modification_time().ISO()
1668:
1669: if hasattr(self,'time'):
1670: return time.strftime("%Y-%m-%d %H:%M:%S",self.time)
1671: elif hasattr(self,'timefixed'):
1672: return self.timefixed
1673: else:
1674: setattr(self,'timefixed',self.bobobase_modification_time().ISO())
1675: return self.bobobase_modification_time().ISO()
1676:
1677: def getContent(self):
1678: """get Basket Content"""
1.102 dwinter 1679: logging.debug("retrieving content A")
1680: cnt = self.content
1681: logging.debug("retrieving content: obj %s"%cnt)
1682: tmp = self.content.getContent()
1683: logging.debug("got content")
1684: return tmp
1.4 dwinter 1685:
1686:
1687: def __init__(self,id,user,comment="",basketContent=[]):
1688: """ init a basket version"""
1689: self.id=id
1.74 dwinter 1690: self.comment=comment
1.39 dwinter 1691: self._setObject('content',BasketContent(basketContent))
1692: #self.basketContent=basketContent[0:]a
1.4 dwinter 1693: self.user=user
1694: self.time=time.localtime()
1695:
1696: def getUser(self):
1697: """get user"""
1698: return self.user
1699:
1700: def getComment(self):
1701: """get Comment"""
1702: return self.comment
1703:
1.77 dwinter 1704: security.declareProtected('manage','index_html')
1.4 dwinter 1705: def index_html(self):
1706: """view the basket"""
1.102 dwinter 1707: logging.debug("start index_html - Basket version")
1.37 dwinter 1708: if self.REQUEST.get('change',False):
1.38 dwinter 1709: ob=self.aq_parent.updateObjects(self.REQUEST['change'])
1710:
1711: self.REQUEST.RESPONSE.redirect(ob.absolute_url())#go to new basket, because changing generates a new basket
1.102 dwinter 1712: logging.debug("start index_html - Basket version:template")
1.4 dwinter 1713: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketVersionMain.zpt')).__of__(self)
1714: return pt()
1715:
1716: def getObjUrl(self,result):
1717: """getUrl of the version of the object"""
1.102 dwinter 1718:
1719: founds=self.CDLICatalog.search({'title':result})
1.4 dwinter 1720: if len(founds)>0:
1.12 dwinter 1721: return founds[0].getObject().getLastVersion().absolute_url()
1.4 dwinter 1722:
1723: else: #assume version number
1.102 dwinter 1724: splitted=result.split("_")
1.9 dwinter 1725: founds=self.CDLICatalog.search({'title':splitted[1]})
1.102 dwinter 1726: return founds[0].getObject().getLastVersion().absolute_url()+'/'+result
1.4 dwinter 1727:
1728: def manage_addCDLIBasketVersion(self,user,comment="",basketContent=[],RESPONSE=None):
1729: """add a version"""
1730:
1731: #check for already existing versions
1732:
1733: lastVersion=self.getLastVersion()
1734: if lastVersion is None:
1735: newId=str(1)
1736: else:
1737: newId=str(int(lastVersion.getId())+1)
1738:
1739: ob=CDLIBasketVersion(newId,user,comment,basketContent)
1740:
1741: self._setObject(newId, ob)
1742:
1743: if RESPONSE is not None:
1744: RESPONSE.redirect('manage_main')
1745: else:
1746: return ob
1747:
1.46 dwinter 1748: class CDLIFileObject(CatalogAware,extVersionedFileObject):
1.1 dwinter 1749: """CDLI file object"""
1750:
1751: meta_type="CDLI File Object"
1.25 dwinter 1752: default_catalog='CDLIObjectsCatalog'
1.1 dwinter 1753:
1.12 dwinter 1754: security=ClassSecurityInfo()
1755:
1.78 dwinter 1756: security.declareProtected('manage','index_html')
1.81 casties 1757:
1758: security.declarePublic('view')
1759: view = PageTemplateFile('zpt/viewCDLIFile.zpt', globals())
1760:
1761: security.declarePublic('editATF')
1762: editATF = PageTemplateFile('zpt/editATFFile.zpt', globals())
1763:
1.28 dwinter 1764: def PrincipiaSearchSource(self):
1765: """Return cataloguable key for ourselves."""
1766: return str(self)
1767:
1.89 dwinter 1768: def setAuthor(self, author):
1769: """change the author"""
1770: self.author = author
1771:
1.26 dwinter 1772: def makeThisVersionCurrent_html(self):
1.85 dwinter 1773: """form for mthis version current"""
1.26 dwinter 1774:
1775: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','makeThisVersionCurrent.zpt')).__of__(self)
1776: return pt()
1.81 casties 1777:
1778: security.declarePublic('makeThisVersionCurrent')
1.27 dwinter 1779: def makeThisVersionCurrent(self,comment,author,RESPONSE=None):
1.26 dwinter 1780: """copy this version to current"""
1781: parent=self.aq_parent
1.81 casties 1782: parent.manage_addVersionedFileObject(id=None,vC=comment,author=author,file=self.getData(),RESPONSE=RESPONSE)
1783: #newversion=parent.manage_addCDLIFileObject('',comment,author)
1784: #newversion.manage_upload(self.getData())
1.27 dwinter 1785:
1.81 casties 1786: #if RESPONSE is not None:
1787: # RESPONSE.redirect(self.aq_parent.absolute_url()+'/history')
1.27 dwinter 1788:
1.26 dwinter 1789: return True
1790:
1.52 dwinter 1791: def getFormattedData(self):
1792: """fromat text"""
1793: data=self.getData()
1.70 dwinter 1794: # return re.sub("\s\#lem"," #lem",data) #remove return vor #lem
1795: return re.sub("#lem"," #lem",data) #remove return vor #lem
1.52 dwinter 1796:
1.1 dwinter 1797:
1.40 dwinter 1798: security.declarePublic('getPNumber')
1799: def getPNumber(self):
1.46 dwinter 1800: """get the pnumber"""
1801: try:
1.49 dwinter 1802: txt=re.match("&[Pp](\d*)\s*=([^\r\n]*)",self.getData()[0:])
1.40 dwinter 1803: except:
1.49 dwinter 1804: txt=self.getData()[0:]
1.40 dwinter 1805:
1806: return "ERROR"
1807: try:
1808: return "P"+txt.group(1)
1809: except:
1810: return "ERROR"
1811:
1.12 dwinter 1812: security.declarePublic('getDesignation')
1813: def getDesignation(self):
1814: """get the designation out of the file"""
1.16 dwinter 1815: try:
1.46 dwinter 1816: txt=re.match("&[Pp](\d*)\s*=([^\r\n]*)",self.getData()[0:])
1.13 dwinter 1817: except:
1.46 dwinter 1818: txt=self.getData()[0:]
1.16 dwinter 1819:
1820: return "ERROR"
1.12 dwinter 1821: try:
1822: return txt.group(2)
1823: except:
1824: return "ERROR"
1.81 casties 1825:
1.12 dwinter 1826:
1.1 dwinter 1827: manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1')
1828:
1.81 casties 1829: def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',versionNumber=0,
1830: precondition='', content_type='',
1.48 dwinter 1831: from_tmp=False,REQUEST=None):
1.1 dwinter 1832: """Add a new File object.
1833: Creates a new File object 'id' with the contents of 'file'"""
1.48 dwinter 1834:
1.1 dwinter 1835: id=str(id)
1836: title=str(title)
1837: content_type=str(content_type)
1838: precondition=str(precondition)
1839:
1840: id, title = cookId(id, title, file)
1841:
1842: self=self.this()
1843:
1844: # First, we create the file without data:
1.81 casties 1845: self._setObject(id, CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=vC,time=time.localtime(),author=author))
1.80 casties 1846: fob = self._getOb(id)
1.45 dwinter 1847:
1.1 dwinter 1848: # Now we "upload" the data. By doing this in two steps, we
1849: # can use a database trick to make the upload more efficient.
1.48 dwinter 1850:
1851: if file and not from_tmp:
1.80 casties 1852: fob.manage_upload(file)
1.48 dwinter 1853: elif file and from_tmp:
1.81 casties 1854: fob.manage_file_upload(file) # manage_upload_from_tmp doesn't exist in ExtFile2
1855: # fob.manage_upload_from_tmp(file) # manage_upload_from_tmp doesn't exist in ExtFile2
1.1 dwinter 1856: if content_type:
1.80 casties 1857: fob.content_type=content_type
1.1 dwinter 1858:
1.81 casties 1859: #logging.debug("manage_add: lastversion=%s"%self.getData())
1860: logging.debug("reindex1: %s in %s"%(repr(self),repr(self.default_catalog)))
1.45 dwinter 1861: self.reindex_object()
1.81 casties 1862: #logging.debug("manage_add: fob_data=%s"%fob.getData())
1.80 casties 1863: logging.debug("reindex2: %s in %s"%(repr(fob), repr(fob.default_catalog)))
1.81 casties 1864: fob.index_object()
1.49 dwinter 1865:
1.85 dwinter 1866: self.CDLIRoot.updateOrAddToFileBTree(ob)
1.1 dwinter 1867: if REQUEST is not None:
1868: REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
1.3 dwinter 1869:
1.80 casties 1870:
1.46 dwinter 1871: class CDLIFile(extVersionedFile,CatalogAware):
1.3 dwinter 1872: """CDLI file"""
1873:
1.77 dwinter 1874: security=ClassSecurityInfo()
1.3 dwinter 1875: meta_type="CDLI file"
1.81 casties 1876: content_meta_type = ["CDLI File Object"]
1877:
1.3 dwinter 1878: default_catalog='CDLICatalog'
1.81 casties 1879:
1.78 dwinter 1880: security.declareProtected('manage','index_html')
1.81 casties 1881:
1.51 dwinter 1882: def getLastVersionData(self):
1883: """get last version data"""
1.81 casties 1884: return self.getData()
1.51 dwinter 1885:
1.52 dwinter 1886: def getLastVersionFormattedData(self):
1887: """get last version data"""
1.81 casties 1888: return self.getContentObject().getFormattedData()
1889:
1890: def getTextId(self):
1891: """returns P-number of text"""
1892: # assuming that its the beginning of the title
1893: return self.title[:7]
1.52 dwinter 1894:
1.51 dwinter 1895: #security.declarePublic('history')
1.26 dwinter 1896: def history(self):
1897: """history"""
1898:
1899: ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
1900: if ext:
1901: return getattr(self,ext[0][1].getId())()
1902:
1903: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','versionHistory')).__of__(self)
1904: return pt()
1905:
1906:
1.44 dwinter 1907: def getBasketFromId(self,basketid, context=None):
1908: """get basket from id"""
1909:
1910: if not context:
1911: context=self
1912:
1913: for basket in self.ZopeFind(context,obj_metatypes=["CDLIBasket"]):
1914: if basket[0]==basketid:
1915: return basket[1]
1916: else:
1917: None
1918:
1.12 dwinter 1919:
1.8 dwinter 1920: def isContainedInBaskets(self,context=None):
1921: """check is this file is part of any basket
1922: @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog
1923: has to exist.
1924: """
1925:
1926: if not context:
1927: context=self
1.12 dwinter 1928:
1929: ret=[]
1930: for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}):
1931: #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why?
1932: try:
1933: ret.append(x.getObject())
1934: except:
1935: pass
1936: return ret
1937: #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})]
1.5 dwinter 1938:
1939:
1.81 casties 1940: def _newContentObject(self, id, title='', versionNumber=0, versionComment=None, time=None, author=None):
1941: """factory for content objects. to be overridden in derived classes."""
1942: logging.debug("_newContentObject(CDLI)")
1943: return CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=versionComment,time=time,author=author)
1944:
1945:
1.5 dwinter 1946: def addCDLIFileObjectForm(self):
1947: """add a new version"""
1948:
1949: if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]:
1950: return "please login first"
1951: if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''):
1952: out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self)
1953: return out()
1954: else:
1955: return "Sorry file is locked by somebody else"
1956:
1.37 dwinter 1957: def manage_addCDLIFileObject(self,id,vC,author,
1958: file='',title='',
1959: precondition='',
1960: content_type='',
1961: changeName='no',newName='',
1.48 dwinter 1962: come_from=None,
1963: from_tmp=False,RESPONSE=None):
1.3 dwinter 1964: """add"""
1.48 dwinter 1965:
1.3 dwinter 1966: try: #TODO: der ganze vC unsinn muss ueberarbeitet werden
1967: vC=self.REQUEST['vC']
1968: except:
1969: pass
1970:
1.81 casties 1971: ob = self.addContentObject(id, vC, author, file, title, changeName=changeName, newName=newName, from_tmp=from_tmp,
1972: precondition=precondition, content_type=content_type)
1.3 dwinter 1973:
1.22 dwinter 1974: try:
1.81 casties 1975: #FIXME: wozu ist das gut?
1976: self.REQUEST.SESSION['objID_parent']=self.getId()
1.22 dwinter 1977: except:
1.81 casties 1978: pass
1.37 dwinter 1979:
1.85 dwinter 1980: #self.cdliRoot.updateOrAddToFileBTree(self)# now update the object in the cache
1981:
1982:
1.3 dwinter 1983: if RESPONSE:
1.81 casties 1984: if ob.getSize()==0:
1985: self.REQUEST.SESSION['objID']=ob.getId()
1.3 dwinter 1986: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)
1987: return pt()
1988: else:
1.37 dwinter 1989: if come_from and (come_from!=""):
1.81 casties 1990: RESPONSE.redirect(come_from+"?change="+self.getId())
1.37 dwinter 1991: else:
1992: RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title)
1.3 dwinter 1993: else:
1.81 casties 1994: return ob
1.3 dwinter 1995:
1996:
1997: def manage_addCDLIFileForm(self):
1998: """interface for adding the OSAS_root"""
1999: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self)
2000: return pt()
2001:
2002: def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None):
2003: """add the OSAS_root"""
2004: newObj=CDLIFile(id,title,lockedBy,author)
1.22 dwinter 2005:
2006: tryToggle=True
2007: tryCount=0
2008:
2009: self._setObject(id,newObj)
1.45 dwinter 2010: getattr(self,id).reindex_object()
1.22 dwinter 2011:
1.3 dwinter 2012: if RESPONSE is not None:
2013: RESPONSE.redirect('manage_main')
2014:
1.81 casties 2015:
1.69 dwinter 2016: def checkUTF8(data):
2017: """check utf 8"""
2018: try:
2019: data.encode('utf-8')
2020: return True
2021: except:
2022: return False
2023:
1.1 dwinter 2024:
1.45 dwinter 2025: def checkFile(filename,data,folder):
2026: """check the files"""
2027: # first check the file name
2028: fn=filename.split(".") # no extension
1.48 dwinter 2029:
1.45 dwinter 2030: if not fn[0][0]=="P":
1.46 dwinter 2031: return False,"P missing in the filename"
1.45 dwinter 2032: elif len(fn[0])!=7:
1.46 dwinter 2033: return False,"P number has not the right length 6"
1.69 dwinter 2034: elif not checkUTF8(data):
2035: return False,"not utf-8"
1.45 dwinter 2036: else:
1.69 dwinter 2037: return True,""
2038:
1.45 dwinter 2039:
1.25 dwinter 2040: def splitatf(fh,dir=None,ext=None):
1.2 dwinter 2041: """split it"""
1.4 dwinter 2042: ret=None
1.2 dwinter 2043: nf=None
1.25 dwinter 2044: i=0
1.49 dwinter 2045:
1.81 casties 2046: #ROC: why split \n first and then \r???
1.73 dwinter 2047: if (type(fh) is StringType) or (type(fh) is UnicodeType):
2048: iter=fh.split("\n")
2049: else:
2050: iter=fh.readlines()
2051:
2052: for lineTmp in iter:
1.66 dwinter 2053: lineTmp=lineTmp.replace(codecs.BOM_UTF8,'') # make sure that all BOM are removed..
2054: for line in lineTmp.split("\r"):
2055: #logging.log("Deal with: %s"%line)
2056: if ext:
2057: i+=1
2058: if (i%100)==0:
2059: ext.result+="."
2060: if i==10000:
2061: i=0
2062: ext.result+="<br>"
2063: #check if basket name is in the first line
2064: if line.find("#atf basket")>=0: #old convention
2065: ret=line.replace('#atf basket ','')
2066: ret=ret.split('_')[0]
2067: elif line.find("#basket:")>=0: #new convention
2068: ret=line.replace('#basket: ','')
2069: ret=ret.split('_')[0]
2070:
2071: else:
2072: if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile
2073: if nf:
2074: nf.close() #close last file
2075:
1.49 dwinter 2076:
1.66 dwinter 2077: filename=line[1:].split("=")[0].rstrip()+".atf"
2078: if dir:
2079: filename=os.path.join(dir,filename)
2080: nf=file(filename,"w")
2081: logging.info("open %s"%filename)
2082: if nf:
2083: nf.write(line.replace("\n","")+"\n")
2084:
2085: try:
2086: nf.close()
1.61 dwinter 2087: except:
1.66 dwinter 2088: pass
1.73 dwinter 2089:
2090: if not((type(fh) is StringType) or (type(fh) is UnicodeType)):
2091: fh.close()
1.5 dwinter 2092: return ret,len(os.listdir(dir))
1.4 dwinter 2093:
1.19 dwinter 2094:
1.46 dwinter 2095: class CDLIFileFolder(extVersionedFileFolder):
1.4 dwinter 2096: """CDLI File Folder"""
1.1 dwinter 2097:
1.19 dwinter 2098: security=ClassSecurityInfo()
1.1 dwinter 2099: meta_type="CDLI Folder"
1.81 casties 2100: file_meta_type=['CDLI file']
2101: folder_meta_type=['CDLI Folder']
2102:
2103: file_catalog='CDLICatalog'
2104:
1.45 dwinter 2105: #downloadCounter=0 # counts how many download for all files currently run, be mehr als 5 wird verweigert.
1.24 dwinter 2106: tmpStore2={}
1.81 casties 2107:
2108: def _newVersionedFile(self, id, title='', lockedBy=None, author=None):
2109: """factory for versioned files. to be overridden in derived classes."""
2110: logging.debug("_newVersionedFile(CDLI)")
2111: return CDLIFile(id, title, lockedBy=lockedBy, author=author)
2112:
1.19 dwinter 2113: def setTemp(self,name,value):
2114: """set tmp"""
2115:
2116: setattr(self,name,value)
2117:
1.81 casties 2118: deleteFileForm = PageTemplateFile("zpt/doDeleteFile", globals())
1.19 dwinter 2119:
1.81 casties 2120: def delete(self,ids,REQUEST=None):
2121: """delete these files"""
1.12 dwinter 2122: if type(ids) is not ListType:
2123: ids=[ids]
1.81 casties 2124:
2125: self.manage_delObjects(ids)
1.12 dwinter 2126:
1.81 casties 2127: if REQUEST is not None:
2128: return self.index_html()
2129:
2130:
1.4 dwinter 2131: def getVersionNumbersFromIds(self,ids):
2132: """get the numbers of the current versions of documents described by their ids"""
2133:
2134: ret=[]
2135: searchStr=" OR ".join(ids)
2136:
1.9 dwinter 2137: founds=self.CDLICatalog.search({'title':searchStr})
1.4 dwinter 2138:
2139: for found in founds:
1.81 casties 2140: lastVersion=found.getObject().getContentObject()
1.4 dwinter 2141: ret.append((found.getId,lastVersion))
2142:
2143: return ret
2144:
1.67 dwinter 2145: def getFile(self,fn):
2146: """get the content of the file fn"""
1.81 casties 2147: logging.debug("getFile: %s"%repr(fn))
2148: if not self.hasObject(fn):
2149: # search deeper
2150: founds=getattr(self, self.file_catalog).search({'textid':fn})
2151: if founds:
2152: obj=founds[0].getObject().getContentObject()
2153: else:
2154: return ""
1.67 dwinter 2155: else:
1.81 casties 2156: obj = self[fn].getContentObject()
1.68 dwinter 2157:
1.81 casties 2158: return obj.getData()[0:]
2159:
1.67 dwinter 2160:
1.14 dwinter 2161: def checkCatalog(self,fn):
2162: """check if fn is in the catalog"""
1.19 dwinter 2163: #TODO add checkCatalog
1.14 dwinter 2164:
1.19 dwinter 2165:
1.45 dwinter 2166: def findObjectsFromListWithVersion(self,list,author=None):
1.26 dwinter 2167: """find objects from a list with versions
2168: @param list: list of tuples (cdliFile,version)
2169: """
2170: #self.REQUEST.SESSION['fileIds']=list#store fieldIds in session for further usage
2171: #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
2172:
2173: pt=getattr(self,'filelistVersioned.html')
2174:
1.45 dwinter 2175: return pt(search=list,author=author)
1.26 dwinter 2176:
2177:
1.67 dwinter 2178: def getAllPNumbers(self):
2179: """get a list of all files (resp their p-numbers) stored"""
2180:
2181: ret=[x.getId for x in self.CDLICatalog()]
2182:
2183: return ret
2184:
1.83 dwinter 2185: def expandFile(self,fileId,fileTree):
2186: """wildcard in fileID suche alle Treffer"""
2187: founds=self.CDLICatalog({'title':fileId})
2188: for found in founds:
2189: fileTree.add(found.getId)
2190: logging.debug("ADDD:"+found.getId)
2191:
1.85 dwinter 2192: def findObjectsFromList(self,enterList=None,display=False,start=None,upload=None,list=None,basketName=None,numberOfObjects=None,RESPONSE=None,REQUEST=None,returnHash=False,hash=None):
1.1 dwinter 2193: """findObjectsFromList (, TAB oder LINE separated)"""
1.15 dwinter 2194:
1.83 dwinter 2195: logging.debug("start: findObjectsFromList")
1.85 dwinter 2196: #logging.debug("start: findObjectsFromList"+repr(list))
2197:
2198:
1.6 dwinter 2199: if upload: # list from file upload
2200: txt=upload.read()
1.35 dwinter 2201:
2202: if enterList:
2203: txt=enterList
2204:
2205: if upload or enterList:
1.6 dwinter 2206: txt=txt.replace(",","\n")
2207: txt=txt.replace("\t","\n")
1.12 dwinter 2208: txt=txt.replace("\r","\n")
1.6 dwinter 2209: idsTmp=txt.split("\n")
2210: ids=[]
2211: for id in idsTmp: # make sure that no empty lines
2212: idTmp=id.lstrip().rstrip()
2213: if len(idTmp)>0:
2214:
2215: ids.append(idTmp)
2216:
2217: #self.REQUEST.SESSION['ids']=" OR ".join(ids)
1.12 dwinter 2218:
1.6 dwinter 2219: pt=getattr(self,'filelist.html')
1.7 dwinter 2220: self.REQUEST.SESSION['searchList']=ids
1.6 dwinter 2221: return pt(search=ids)
1.7 dwinter 2222:
1.6 dwinter 2223: if basketName:
1.7 dwinter 2224: #TODO: get rid of one of these..
2225:
1.6 dwinter 2226: pt=getattr(self,'filelist.html')
1.7 dwinter 2227: return pt(basketName=basketName,numberOfObjects=numberOfObjects)
1.6 dwinter 2228:
1.102 dwinter 2229:
2230: result =self.CDLICache.retrieve(hash)
2231: if result:
2232: logging.debug("give result from storage2")
2233: return hash,result
2234:
1.15 dwinter 2235: if list is not None: # got already a list
1.83 dwinter 2236:
2237: logging.debug(" ----List version")
1.6 dwinter 2238: ret=[]
1.83 dwinter 2239: fileTree=Set()
2240:
1.6 dwinter 2241: for fileId in list:
1.83 dwinter 2242:
2243: if fileId.find("*")>-1: #check for wildcards
2244: self.expandFile(fileId,fileTree)
2245:
1.35 dwinter 2246: elif len(fileId.split("."))==1:
1.6 dwinter 2247: fileId=fileId+".atf"
1.83 dwinter 2248: fileTree.add(fileId)
2249: #logging.debug(" -----:"+fileId)
2250: #ret+=self.CDLICatalog({'title':fileId})
2251: #x =self.getFileObject(fileId)
2252: #if x is not None:
2253: # ret.append(x)
1.35 dwinter 2254:
1.83 dwinter 2255:
2256:
2257: ids = fileTree & self.v_file_ids
1.85 dwinter 2258: #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
2259: l=makelist(fileTree)[0:]
1.93 dwinter 2260: #logging.debug("l-list:"+repr(l))
1.85 dwinter 2261: self.REQUEST.SESSION['fileIds']=l#store fieldIds in session for further usage
2262: self.REQUEST.SESSION['searchList']=l
2263: #self.REQUEST.SESSION['searchList']=['P000001.atf']
2264:
1.83 dwinter 2265:
1.85 dwinter 2266: hash = md5.new(repr(makelist(fileTree))).hexdigest() # erzeuge hash als identification
2267: self.REQUEST.SESSION['hash']=hash
2268: #TODO: do I need garbage collection for v_tmpStore ?
1.83 dwinter 2269:
1.84 dwinter 2270: #logging.debug("Hash:"+repr(hash))
1.85 dwinter 2271: #
2272: # if hasattr(self.cdliRoot,'v_tmpStore') and self.cdliRoot.v_tmpStore.has_key(hash):
2273: # logging.debug("asking for storage")
2274: # res=self.cdliRoot.v_tmpStore[hash]
2275: # if res:
2276: # if returnHash == True:
2277: # return hash,res
2278: # return res
1.83 dwinter 2279:
1.7 dwinter 2280: #TODO: get rid of one of these..
1.83 dwinter 2281: #ids=[x.getObject().getId() for x in ret]
2282: ret=[(self.getFileObject(x),self.getFileObjectLastVersion(x)) for x in ids]
1.84 dwinter 2283:
2284: #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
2285: #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
1.85 dwinter 2286:
1.25 dwinter 2287: if display:
2288: pt=getattr(self,'filelist.html')
2289:
2290: return pt(search=ids)
1.83 dwinter 2291: else:
2292: #self.REQUEST.SESSION['hash'] = ret # store in session
1.102 dwinter 2293:
1.83 dwinter 2294: #logging.debug("HHHHHHNEU:"+repr(self.makelist(ids)))
1.84 dwinter 2295: #logging.debug("HHHHHHNEU:"+repr(hash))
1.102 dwinter 2296: self.CDLICache.store(hash,ret)
2297:
1.85 dwinter 2298: if returnHash == True:
2299: return hash,ret
1.25 dwinter 2300: return ret
2301:
2302:
1.1 dwinter 2303:
1.7 dwinter 2304: if start:
2305: RESPONSE.redirect("filelist.html?start:int="+str(start))
1.85 dwinter 2306:
1.19 dwinter 2307: security.declareProtected('Manage','createAllFilesAsSingleFile')
1.1 dwinter 2308: def createAllFilesAsSingleFile(self,RESPONSE=None):
2309: """download all files"""
2310:
2311: def sortF(x,y):
2312: return cmp(x[0],y[0])
2313:
1.81 casties 2314: catalog=getattr(self,self.file_catalog)
1.1 dwinter 2315: #tf,tfilename=mkstemp()
1.66 dwinter 2316: if not hasattr(self.temp_folder,'downloadCounter'):
2317: self.temp_folder.downloadCounter=0
1.49 dwinter 2318:
2319: if getattr(self.temp_folder,'downloadCounter',0) > 5:
1.46 dwinter 2320: return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
1.45 dwinter 2321:
1.46 dwinter 2322: self.temp_folder.downloadCounter+=1
2323: self._p_changed=1
1.58 dwinter 2324: transaction.get().commit()
1.45 dwinter 2325:
1.1 dwinter 2326: list=[(x.getId,x) for x in catalog()]
2327: list.sort(sortF)
1.46 dwinter 2328:
1.45 dwinter 2329:
1.1 dwinter 2330:
2331: RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf")
2332: RESPONSE.setHeader("Content-Type","application/octet-stream")
1.46 dwinter 2333: tmp=""
1.1 dwinter 2334: for l in list:
2335: obj=l[1].getObject()
2336:
2337: if obj.meta_type=="CDLI file":
2338:
2339: #os.write(tf,obj.getLastVersion().data)
2340: if RESPONSE:
1.81 casties 2341: RESPONSE.write(obj.getData()[0:])
1.71 dwinter 2342: RESPONSE.write("\n")
1.46 dwinter 2343: self.temp_folder.downloadCounter-=1
2344: self._p_changed=1
1.58 dwinter 2345: transaction.get().commit()
1.1 dwinter 2346: #os.close(tf)
2347: #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename)
2348: return True
2349:
2350: def downloadFile(self,fn):
2351: """download fn - not used yet"""
2352: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId())
2353: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
2354: self.REQUEST.RESPONSE.write(file(fn).read())
2355:
2356:
2357:
2358: def hasParent(self):
2359: """returns true falls subfolder"""
2360:
1.81 casties 2361: if self.aq_parent.meta_type in self.folder_meta_type:
1.1 dwinter 2362: return True
2363: else:
2364: return False
2365:
2366: def getFolders(self):
2367: """get all subfolders"""
2368: ret=[]
1.81 casties 2369: folders=self.ZopeFind(self,obj_metatypes=self.folder_meta_type)
1.1 dwinter 2370: for folder in folders:
2371: ret.append((folder[1],
1.81 casties 2372: len(self.ZopeFind(folder[1],obj_metatypes=self.folder_meta_type)),
2373: len(self.ZopeFind(folder[1],obj_metatypes=self.file_meta_type))
1.1 dwinter 2374: ))
2375: return ret
2376:
2377:
1.77 dwinter 2378: security.declareProtected('manage','index_html')
1.1 dwinter 2379: def index_html(self):
2380: """main"""
2381: ext=self.ZopeFind(self,obj_ids=["index.html"])
2382: if ext:
2383: return ext[0][1]()
2384:
2385: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self)
2386: return pt()
2387:
1.22 dwinter 2388:
2389: manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals())
2390:
2391:
2392: def manage_addCDLIFileFolder(self, id, title='',
2393: createPublic=0,
2394: createUserF=0,
2395: REQUEST=None):
2396: """Add a new Folder object with id *id*.
2397:
2398: If the 'createPublic' and 'createUserF' parameters are set to any true
2399: value, an 'index_html' and a 'UserFolder' objects are created respectively
2400: in the new folder.
2401: """
2402: ob=CDLIFileFolder()
2403: ob.id=str(id)
2404: ob.title=title
2405: self._setObject(id, ob)
2406: ob=self._getOb(id)
2407:
2408: checkPermission=getSecurityManager().checkPermission
2409:
2410: if createUserF:
2411: if not checkPermission('Add User Folders', ob):
2412: raise Unauthorized, (
2413: 'You are not authorized to add User Folders.'
2414: )
2415: ob.manage_addUserFolder()
2416:
2417:
2418: if REQUEST is not None:
2419: return self.manage_main(self, REQUEST, update_menu=1)
2420:
2421: class CDLIRoot(Folder):
2422: """main folder for cdli"""
2423:
2424: meta_type="CDLIRoot"
1.81 casties 2425: downloadCounterBaskets=0 # counts the current basket downloads if counter > 10 no downloads are possible
2426:
2427: file_catalog = 'CDLICatalog'
2428:
2429: # word splitter for search
2430: splitter = {'words':cdliSplitter.wordSplitter(),
2431: 'graphemes':cdliSplitter.graphemeSplitter()}
2432:
1.51 dwinter 2433:
1.102 dwinter 2434: def unicodify(self,txt):
2435: return unicodify(txt)
2436: def invalidateOldCacheVersion(self):
2437: """loescht die alte Version des Cache"""
2438: del self.v_tmpStore
2439: return "done"
2440:
1.86 dwinter 2441: def viewATF(self,id,RESPONSE):
2442: """view an Object"""
2443: ob = self.CDLICatalog({'title':id})
2444: logging.debug(ob[0].getObject().getLastVersion().absolute_url()+"/view")
2445: if len(ob)>0:
2446: RESPONSE.redirect(ob[0].getObject().getLastVersion().absolute_url()+"/view")
2447: return "not found"
2448:
2449: def history(self,id,RESPONSE):
2450: """view an Object"""
2451: ob = self.CDLICatalog({'title':id})
2452: if len(ob)>0:
2453: RESPONSE.redirect(ob[0].absolute_url+"/history")
2454: return "not found"
2455:
2456:
2457: def downloadLocked(self,id,RESPONSE):
2458: """view an Object"""
2459: ob = self.CDLICatalog({'title':id})
2460: if len(ob)>0:
2461: RESPONSE.redirect(ob[0].absolute_url+"/downloadLocked")
2462: return "not found"
2463:
2464: def download(self,id,RESPONSE):
2465: """view an Object"""
2466: ob = self.CDLICatalog({'title':id})
2467: if len(ob)>0:
2468: RESPONSE.redirect(ob[0].getLastVersion().absolute_url())
2469: return "not found"
2470: def addCDLIFileObjectForm(self,id,RESPONSE):
2471: """view an Object"""
2472: ob = self.CDLICatalog({'title':id})
2473: if len(ob)>0:
2474: RESPONSE.redirect(ob[0].absolute_url+"/addCDLIFileObjectForm")
2475: return "not found"
2476:
2477: def addVersionedFileObjectForm(self,id,RESPONSE):
2478: """view an Object"""
2479: ob = self.CDLICatalog({'title':id})
2480: if len(ob)>0:
2481: RESPONSE.redirect(ob[0].absolute_url+"/addVersionedFileObjectForm")
2482: return "not found"
2483:
2484: def unlock(self,id,RESPONSE):
2485: """view an Object"""
2486: ob = self.CDLICatalog({'title':id})
2487: if len(ob)>0:
2488: RESPONSE.redirect(ob[0].absolute_url+"/unlock")
2489: return "not found"
2490:
1.83 dwinter 2491: def getFileObject(self,fileId):
1.85 dwinter 2492: """get an object"""
1.83 dwinter 2493: x=self.v_files.get(fileId)
2494: #logging.debug(x)
2495: return x
2496:
2497: def getFileObjectLastVersion(self,fileId):
1.85 dwinter 2498: """get an object"""
1.83 dwinter 2499: x=self.v_files_lastVersion.get(fileId)
1.95 dwinter 2500: #logging.debug("lastVersion: "+repr(x))
1.83 dwinter 2501: return x
2502:
1.85 dwinter 2503: def showFileIds(self):
2504: """showIds"""
2505: return self.v_file_ids
2506:
1.83 dwinter 2507: def generateFileBTree(self):
2508: """erzeuge einen Btree aus allen Files"""
2509: self.v_files = OOBTree()
2510: self.v_files_lastVersion = OOBTree()
2511: self.v_file_ids = Set()
2512:
2513: for x in self.CDLICatalog.searchResults():
2514:
2515: self.v_files.update({x.getId:x.getObject()})
2516: self.v_files_lastVersion.update({x.getId:x.getObject().getLastVersion()})
2517: self.v_file_ids.add(x.getId)
2518: logging.debug("add:"+x.getId+"XXX"+repr(x.getObject()))
2519:
1.85 dwinter 2520: return True
2521:
2522:
2523: def updateOrAddToFileBTree(self,obj):
2524: """update a BTree"""
2525: self.v_files.update({obj.getId():obj})
2526: self.v_files_lastVersion.update({obj.getId():obj.getLastVersion()})
2527:
2528: self.v_file_ids.add(obj.getId())
2529: logging.debug("update:"+obj.getId()+"XXX"+repr(obj))
2530:
2531: def deleteFromBTree(self,objId):
2532: """delete an obj"""
2533: self.v_files.pop(objId)
2534: self.v_files_lastVersion.pop(objId)
2535: self.v_file_ids.remove(objId)
2536:
2537:
2538:
1.73 dwinter 2539: def deleteFiles(self,ids):
1.81 casties 2540: """delete files"""
1.73 dwinter 2541: for id in ids:
2542: founds=self.CDLICatalog.search({'title':id.split(".")[0]})
2543: if founds:
1.81 casties 2544: logging.debug("deleting %s"%founds)
1.73 dwinter 2545: folder=founds[0].getObject().aq_parent #get the parent folder of the object
1.81 casties 2546: logging.debug("deleting from %s"%folder)
2547: cut=folder.delete([founds[0].getId]) #cut it out
2548:
1.73 dwinter 2549:
2550:
1.81 casties 2551: def searchText(self, query, index='graphemes'):
2552: """searches query in the fulltext index and returns a list of file ids/P-numbers"""
2553: # see also: http://www.plope.com/Books/2_7Edition/SearchingZCatalog.stx#2-13
2554: logging.debug("searchtext for '%s' in index %s"%(query,index))
2555: #import Products.ZCTextIndex.QueryParser
2556: #qp = QueryParser.QueryParser()
2557: #logging.debug()
2558: idxQuery = {index:{'query':query}}
2559: idx = getattr(self, self.file_catalog)
2560: # do search
2561: resultset = idx.search(query_request=idxQuery,sort_index='textid')
2562: # put only the P-Number in the result
2563: results = [res.getId[:7] for res in resultset]
2564: logging.debug("searchtext: found %d texts"%len(results))
2565: return results
2566:
2567:
2568: def getFile(self, pnum):
2569: """get the translit file with the given pnum"""
2570: f = getattr(self, self.file_catalog).search({'textid':pnum})
2571: if not f:
2572: return ""
1.71 dwinter 2573:
1.81 casties 2574: return f[0].getObject().getData()
2575:
1.57 dwinter 2576:
1.74 dwinter 2577: def showFile(self,fileId,wholePage=False):
1.71 dwinter 2578: """show a file
2579: @param fileId: P-Number of the document to be displayed
2580: """
1.81 casties 2581: f=getattr(self, self.file_catalog).search({'textid':fileId})
1.51 dwinter 2582: if not f:
2583: return ""
2584:
1.74 dwinter 2585: if wholePage:
1.81 casties 2586: logging.debug("show whole page")
2587: return f[0].getObject().getContentObject().view()
1.74 dwinter 2588: else:
2589: return f[0].getObject().getLastVersionFormattedData()
1.55 dwinter 2590:
1.56 dwinter 2591:
1.81 casties 2592: def showWordInFile(self,fileId,word,indexName='graphemes',regExp=False,):
2593: """get lines with word from FileId"""
2594: logging.debug("showwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId))
1.56 dwinter 2595:
1.81 casties 2596: file = formatAtfFullLineNum(self.getFile(fileId))
1.66 dwinter 2597: ret=[]
1.71 dwinter 2598:
1.81 casties 2599: # add whitespace before and whitespace and line-end to splitter bounds expressions
2600: bounds = self.splitter[indexName].bounds
2601: splitexp = "(%s|\s)(%%s)(%s|\s|\Z)"%(bounds,bounds)
2602: # clean word expression
2603: # TODO: this should use QueryParser itself
2604: # take out double quotes
2605: word = word.replace('"','')
2606: # take out ignorable signs
2607: ignorable = self.splitter[indexName].ignorex
2608: word = ignorable.sub('', word)
2609: # compile into regexp objects and escape parens
2610: wordlist = [re.compile(splitexp%re.escape(w)) for w in word.split(' ')]
2611:
2612: for line in file.splitlines():
1.71 dwinter 2613: for word in wordlist:
1.81 casties 2614: #logging.debug("showwordinfile: searching for %s in %s"%(word.pattern,ignoreable.sub('',line)))
2615: if word.search(ignorable.sub('',line)):
2616: line = formatAtfLineHtml(line)
2617: ret.append(line)
2618: break
2619:
1.66 dwinter 2620: return ret
1.56 dwinter 2621:
1.81 casties 2622:
2623: def showWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
2624: """
2625: get lines with word from all ids in list FileIds.
2626: returns dict with id:lines pairs.
2627: """
2628: logging.debug("showwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds))
1.51 dwinter 2629:
1.81 casties 2630: return dict([(id,self.showWordInFile(id, word, indexName, regExp)) for id in fileIds])
2631:
2632:
2633: def tagWordInFile(self,fileId,word,indexName='graphemes',regExp=False):
2634: """get text with word highlighted from FileId"""
2635: logging.debug("tagwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId))
2636:
2637: file=self.getFile(fileId)
2638: tagStart=u'<span class="found">'
2639: tagEnd=u'</span>'
2640: tagStr=tagStart + u'%%s' + tagEnd
1.66 dwinter 2641: ret=[]
1.71 dwinter 2642:
1.81 casties 2643: # add whitespace to splitter bounds expressions and compile into regexp object
2644: bounds = self.splitter[indexName].bounds
2645: wordsplit = re.compile("(%s|\s)"%bounds)
2646: # clean word expression
2647: # TODO: this should use QueryParser itself
2648: word = word.replace('"','') # take out double quotes
2649: # take out ignoreable signs
2650: ignorable = self.splitter[indexName].ignorex
2651: word = ignorable.sub('', word)
2652: # split search terms by blanks
2653: words = word.split(' ')
2654: # split search terms again (for grapheme search with words)
2655: splitwords = dict(((w,self.splitter[indexName].process([w])) for w in words))
1.71 dwinter 2656:
1.81 casties 2657: for line in file.splitlines():
1.79 casties 2658: line = unicodify(line)
1.81 casties 2659: # ignore lemma and other lines
2660: if line.lstrip().startswith('#lem:'):
2661: continue
2662: # ignore p-num line
2663: if line.startswith('&P'):
2664: continue
2665: # ignore version lines
2666: if line.startswith('#version'):
2667: continue
2668: # ignore atf type lines
2669: if line.startswith('#atf:'):
2670: continue
2671:
2672: # first scan
2673: hitwords = []
2674: for w in words:
2675: if ignorable.sub('',line).find(w) > -1:
2676: # word is in line
2677: # append split word for grapheme search with words
2678: hitwords.extend(splitwords[w])
2679: #hitwords.extend(wordsplit.split(w))
2680:
2681: # examine hits closer
2682: if hitwords:
2683: # split line into words
2684: parts = wordsplit.split(line)
2685: line = ""
2686: for p in parts:
2687: #logging.debug("tagwordinfile: searching for %s in %s"%(p,hitwords))
2688: # reassemble line
2689: if ignorable.sub('', p) in hitwords:
2690: #logging.debug("tagwordinfile: found %s in %s"%(p,hitwords))
2691: # this part was found
2692: line += tagStart + formatAtfHtml(p) + tagEnd
2693: else:
2694: line += formatAtfHtml(p)
2695:
2696: else:
2697: # no hits
2698: line = formatAtfHtml(line)
2699:
2700: ret.append(line)
2701:
2702: return u'<br>\n'.join(ret)
2703:
1.66 dwinter 2704:
2705:
1.81 casties 2706: def tagWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
2707: """
2708: get texts with highlighted word from all ids in list FileIds.
2709: returns dict with id:text pairs.
2710: """
2711: logging.debug("tagwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds))
2712: return dict([(id,self.tagWordInFile(id, word, indexName, regExp)) for id in fileIds])
2713:
1.56 dwinter 2714:
1.82 casties 2715: def getFileVersionList(self, pnum):
2716: """get the version history as a list for the translit file with the given pnum"""
2717: f = getattr(self, self.file_catalog).search({'textid':pnum})
2718: if not f:
2719: return []
2720:
2721: return f[0].getObject().getVersionList()
2722:
2723:
1.37 dwinter 2724: def URLquote(self,str):
2725: """quote url"""
2726: return urllib.quote(str)
2727:
2728: def URLunquote(self,str):
2729: """unquote url"""
2730: return urllib.unquote(str)
2731:
1.58 dwinter 2732: def URLquote_plus(self,str):
2733: """quote url"""
2734: return urllib.quote_plus(str)
2735:
2736: def URLunquote_plus(self,str):
2737: """unquote url"""
2738: return urllib.unquote_plus(str)
2739:
1.37 dwinter 2740:
1.26 dwinter 2741: def forceunlock(self):
2742: "break all locks"
2743: ret=[]
2744: for f in self.ZopeFind(self,obj_metatypes="CDLI file",search_sub=1):
2745: un=f[1].forceunlock()
1.39 dwinter 2746:
1.26 dwinter 2747: if un and un !="":
2748: ret.append((f[0],un))
1.46 dwinter 2749:
1.61 dwinter 2750: return ret
1.71 dwinter 2751:
1.61 dwinter 2752:
1.26 dwinter 2753: def getChangesByAuthor(self,author,n=100):
1.25 dwinter 2754: """getChangesByAuthor"""
1.26 dwinter 2755: zcat=self.CDLIObjectsCatalog
2756: res=zcat({'lastEditor':author,
1.25 dwinter 2757: 'sort_on':'getTime',
2758: 'sort_order':'descending',
2759: 'sort_limit':n})[:n ]
1.26 dwinter 2760:
2761: return res
2762:
2763: def getChangesByAuthor_html(self,author,n=100):
2764: """html output for changes by author"""
2765: tmp={}
2766: list=[]
2767: for x in self.getChangesByAuthor(author):
2768: nr=x.getObject().getVersionNumber()
2769: id=x.getObject().aq_parent.getId()
2770: #hinzufuegen, wenn Version neuer als die
2771: if tmp.get(id,(0,0))[1] < nr:
2772: tmp[id]=(x.getObject().aq_parent,nr)
2773:
2774:
1.45 dwinter 2775: return self.cdli_main.findObjectsFromListWithVersion(list=tmp.values(),author=author)
1.26 dwinter 2776:
1.25 dwinter 2777: def getLastChanges(self,n=100):
2778: """get the last n changes"""
2779: n=int(n)
2780: zcat=self.CDLICatalog
2781: return zcat({'sort_on':'getLastChangeDate',
2782: 'sort_order':'descending',
2783: 'sort_limit':n})[:n ]
2784:
2785:
2786: def getLastChanges_html(self,n=100):
2787: """get the last n changes"""
2788: list = [x.getId for x in self.getLastChanges(n)]
2789: return self.cdli_main.findObjectsFromList(list=list,display=True)
2790:
1.24 dwinter 2791: def refreshTxt(self,txt="",threadName=None):
1.22 dwinter 2792: """txt fuer refresh"""
2793:
1.24 dwinter 2794: return """ 2;url=%s?repeat=%s """%(self.absolute_url()+txt,threadName)
1.22 dwinter 2795:
1.87 dwinter 2796: def refreshTxtBasket(self,txt="",threadName=None):
2797: """txt fuer refresh"""
2798:
2799: return """ 2;url=%s?repeat=%s """%(txt,threadName)
2800:
1.22 dwinter 2801:
1.24 dwinter 2802: def getResult(self,threadName=None):
1.22 dwinter 2803: """result of thread"""
2804: try:
1.24 dwinter 2805: return self._v_uploadATF[threadName].getResult()
1.22 dwinter 2806: except:
2807: return "One moment, please"
2808:
1.24 dwinter 2809:
2810: def checkThreads(self):
2811: """check threads"""
1.42 dwinter 2812: ret="<html><body>"
2813: for thread in threading.enumerate():
1.45 dwinter 2814: ret+="<p>%s (%s): %s</p>"%(repr(thread),thread.getName(),thread.isAlive())
1.42 dwinter 2815:
2816: return ret
2817:
2818:
1.73 dwinter 2819: def uploadATFRPC(self,data,username):
2820: """upload an atffile via xml-rpc"""
2821: uploader=uploadATFThread()
2822:
2823: #generate an random id for the upload object
2824: from random import randint
2825: if (not self.REQUEST.SESSION.get('idTmp',None)):
2826:
2827: idTmp=str(randint(0,1000000000))
2828: self.REQUEST.SESSION['idTmp']=idTmp
2829: else:
2830: idTmp=self.REQUEST.SESSION.get('idTmp',None)
2831:
2832:
2833: uploader.set(data,0,username,idTmp)
2834:
2835: stObj=uploader.run()
2836:
2837: processor=uploadATFfinallyThread()
2838:
2839: basketname=stObj.returnValue['basketNameFromFile']
2840:
2841: processor.set("uploadchanged",basketname=basketname,SESSION=stObj.returnValue,username=username,serverport=self.REQUEST['SERVER_PORT'])
2842:
2843: processor.run()
2844:
2845:
2846: return generateXMLReturn(stObj.returnValue)
2847:
1.22 dwinter 2848: def uploadATF(self,repeat=None,upload=None,basketId=0,RESPONSE=None):
1.69 dwinter 2849: """upload an atf file / basket file"""
1.22 dwinter 2850: #self._v_uploadATF.returnValue=None
1.71 dwinter 2851:
2852: #generate an random id for the upload thread
1.60 dwinter 2853: from random import randint
1.61 dwinter 2854: if (not self.REQUEST.SESSION.get('idTmp',None)):
1.22 dwinter 2855:
1.60 dwinter 2856: idTmp=str(randint(0,1000000000))
2857: self.REQUEST.SESSION['idTmp']=idTmp
2858: else:
2859: idTmp=self.REQUEST.SESSION.get('idTmp',None)
2860:
1.71 dwinter 2861:
1.22 dwinter 2862: threadName=repeat
2863: if not threadName or threadName=="":
1.71 dwinter 2864: #new thread not called from the waiting page
1.22 dwinter 2865: tmpVar=False
1.24 dwinter 2866:
1.22 dwinter 2867: thread=uploadATFThread()
1.24 dwinter 2868: threadName=thread.getName()[0:]
1.36 dwinter 2869: if (not hasattr(self,'_v_uploadATF')):
1.24 dwinter 2870: self._v_uploadATF={}
2871:
2872: self._v_uploadATF[threadName]=thread
1.22 dwinter 2873: #self._xmltrans.start()
2874: #thread=Thread(target=self._v_uploadATF)
1.60 dwinter 2875: logging.info("set thread. extern")
2876: self._v_uploadATF[threadName].set(upload,basketId,self.REQUEST['AUTHENTICATED_USER'],idTmp,serverport=self.REQUEST['SERVER_PORT'])
1.22 dwinter 2877: #thread.start()
1.60 dwinter 2878: logging.info("start thread. extern")
1.24 dwinter 2879: self._v_uploadATF[threadName].start()
1.22 dwinter 2880:
2881:
1.24 dwinter 2882: self.threadName=self._v_uploadATF[threadName].getName()[0:]
1.22 dwinter 2883: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2884:
2885: if wait_template:
2886: return wait_template[0][1]()
2887: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1.24 dwinter 2888: return pt(txt='/uploadATF',threadName=threadName)
1.22 dwinter 2889: #_v_xmltrans.run()
2890:
2891: else:
2892: #recover thread, if lost
1.36 dwinter 2893: if (not hasattr(self,'_v_uploadATF')):
1.24 dwinter 2894: self._v_uploadATF={}
2895: if not self._v_uploadATF.get(threadName,None):
1.22 dwinter 2896: for thread in threading.enumerate():
2897: if threadName == thread.getName():
1.24 dwinter 2898: self._v_uploadATF[threadName]=thread
2899:
1.60 dwinter 2900: if self._v_uploadATF.get(threadName,None) and (not self._v_uploadATF[threadName].returnValue):
1.22 dwinter 2901:
2902:
2903: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2904: if wait_template:
2905: return wait_template[0][1]()
2906:
2907: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
2908:
1.24 dwinter 2909: return pt(txt='/uploadATF',threadName=threadName)
1.22 dwinter 2910:
2911: else:
1.60 dwinter 2912: tmp=getattr(self.temp_folder,idTmp).returnValue
1.71 dwinter 2913:
1.22 dwinter 2914: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
1.39 dwinter 2915:
1.47 dwinter 2916: return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'],
1.22 dwinter 2917: basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
1.30 dwinter 2918:
2919: def redoUpload(self,threadName):
2920: """redo the upload"""
2921: tmp=self.cdli_main.tmpStore2[threadName]
2922: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
1.45 dwinter 2923: return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'],
1.30 dwinter 2924: basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
2925:
1.22 dwinter 2926: def uploadATFfinally(self,procedure='',comment="",basketname='',unlock=None,repeat=None,RESPONSE=None):
2927: """nowupload the files"""
2928:
2929:
2930:
2931: threadName=repeat
2932: if not threadName or threadName=="":
1.24 dwinter 2933: thread=uploadATFfinallyThread()
2934: threadName=thread.getName()[0:]
1.36 dwinter 2935:
1.35 dwinter 2936: if (not hasattr(self,'_v_uploadATF')):
1.46 dwinter 2937: self._v_uploadATF={}
1.36 dwinter 2938:
1.43 dwinter 2939:
1.24 dwinter 2940: self._v_uploadATF[threadName]=thread
1.22 dwinter 2941:
1.60 dwinter 2942: idTmp=self.REQUEST.SESSION['idTmp']
2943: stObj=getattr(self.temp_folder,idTmp)
2944: self._v_uploadATF[threadName].set(procedure,comment=comment,basketname=basketname,unlock=unlock,SESSION=stObj.returnValue,username=self.REQUEST['AUTHENTICATED_USER'],serverport=self.REQUEST['SERVER_PORT'])
1.22 dwinter 2945:
1.24 dwinter 2946: self._v_uploadATF[threadName].start()
1.22 dwinter 2947:
2948:
1.24 dwinter 2949:
1.22 dwinter 2950: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2951:
2952: if wait_template:
2953: return wait_template[0][1]()
2954: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
2955:
1.24 dwinter 2956: return pt(txt='/uploadATFfinally',threadName=threadName)
1.22 dwinter 2957: #_v_xmltrans.run()
2958:
2959: else:
2960: #recover thread, if lost
2961: if not hasattr(self,'_v_uploadATF'):
1.24 dwinter 2962: self._v_uploadATF={}
2963: if not self._v_uploadATF.get(threadName,None):
1.22 dwinter 2964: for thread in threading.enumerate():
2965: if threadName == thread.getName():
1.24 dwinter 2966: self._v_uploadATF[threadName]=thread
1.22 dwinter 2967:
1.24 dwinter 2968: if self._v_uploadATF.get(threadName,None) and (self._v_uploadATF[threadName] is not None) and (not self._v_uploadATF[threadName].end) :
1.22 dwinter 2969:
2970: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2971: if wait_template:
2972: return wait_template[0][1]()
2973:
2974: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1.24 dwinter 2975: return pt(txt='/uploadATFfinally',threadName=threadName)
1.22 dwinter 2976: else:
1.85 dwinter 2977:
2978:
2979: idTmp=self.REQUEST.SESSION['idTmp']
2980: stObj=getattr(self.temp_folder,idTmp)
1.60 dwinter 2981: self.REQUEST.SESSION['idTmp']=None
1.85 dwinter 2982:
2983: #update changed
2984: logging.debug("dir:"+repr(stObj.returnValue['changed']))
2985: for x in stObj.returnValue['changed']:
2986: ob=self.CDLICatalog.search({'title':x[0]})
1.104 ! dwinter 2987: try:
! 2988: self.cdliRoot.updateOrAddToFileBTree(ob[0].getObject())
! 2989: except:
! 2990: logging.error("uploadATFfinally - cannot update Object %s Error: %s %s"%(ob[1],sys.exc_info()[0],sys.exc_info()[1]))
1.22 dwinter 2991: if RESPONSE is not None:
2992: RESPONSE.redirect(self.absolute_url())
2993:
1.49 dwinter 2994: def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/atf", files=None,ext=None):
1.1 dwinter 2995: """import files"""
1.81 casties 2996: logging.debug("importFiles folderName=%s files=%s ext=%s"%(folderName,files,ext))
1.22 dwinter 2997: root=self.cdli_main
1.49 dwinter 2998: count=0
1.3 dwinter 2999: if not files:
3000: files=os.listdir(folderName)
3001:
1.1 dwinter 3002: for f in files:
3003: folder=f[0:3]
3004: f2=f[0:5]
1.85 dwinter 3005:
3006: #check if main folder PXX already exists
1.22 dwinter 3007: obj=self.ZopeFind(root,obj_ids=[folder])
1.81 casties 3008: logging.debug("importFiles: folder=%s f2=%s obj=%s"%(folder,f2,obj))
1.19 dwinter 3009: if ext:
1.65 dwinter 3010: ext.result="<p>adding: %s </p>"%f+ext.result
1.81 casties 3011:
1.85 dwinter 3012:
3013: if not obj: # if not create it
1.22 dwinter 3014: manage_addCDLIFileFolder(root,folder,folder)
3015: fobj=getattr(root,folder)
1.58 dwinter 3016: #transaction.get().commit()
1.81 casties 3017:
1.1 dwinter 3018: else:
3019: fobj=obj[0][1]
3020:
1.85 dwinter 3021: #check IF PYYYYY already exist
1.1 dwinter 3022: obj2=fobj.ZopeFind(fobj,obj_ids=[f2])
1.81 casties 3023: logging.debug("importFiles: fobj=%s obj2=%s"%(fobj,obj2))
1.1 dwinter 3024:
1.85 dwinter 3025: if not obj2:# if not create it
1.1 dwinter 3026: manage_addCDLIFileFolder(fobj,f2,f2)
3027: fobj2=getattr(fobj,f2)
3028:
3029: else:
3030: fobj2=obj2[0][1]
3031:
1.85 dwinter 3032: # not add the file
1.48 dwinter 3033: file2=os.path.join(folderName,f)
1.1 dwinter 3034: id=f
1.81 casties 3035: logging.debug("importFiles: addCDLIFile fobj2=%s, f=%s file2=%s"%(fobj2,repr(f),repr(file2)))
3036: fobj2.addFile(vC='',file=file(file2),author=author,newName=f)
1.66 dwinter 3037: count+=1
1.85 dwinter 3038:
3039: #now add the file to the storage
3040: ob = getattr(fobj2,f)
3041: self.cdliRoot.updateOrAddToFileBTree(ob)
3042:
1.81 casties 3043: if count%100==0:
3044: logging.debug("importfiles: committing")
1.66 dwinter 3045: transaction.get().commit()
1.81 casties 3046:
3047: transaction.get().commit()
1.3 dwinter 3048: return "ok"
1.22 dwinter 3049:
3050:
3051: manage_addCDLIRootForm=DTMLFile('dtml/rootAdd', globals())
1.1 dwinter 3052:
3053:
1.22 dwinter 3054: def manage_addCDLIRoot(self, id, title='',
1.1 dwinter 3055: createPublic=0,
3056: createUserF=0,
3057: REQUEST=None):
3058: """Add a new Folder object with id *id*.
3059:
3060: If the 'createPublic' and 'createUserF' parameters are set to any true
3061: value, an 'index_html' and a 'UserFolder' objects are created respectively
3062: in the new folder.
3063: """
1.22 dwinter 3064: ob=CDLIRoot()
1.1 dwinter 3065: ob.id=str(id)
3066: ob.title=title
1.61 dwinter 3067: try:
1.66 dwinter 3068: self._setObject(id, ob)
1.61 dwinter 3069: except:
1.66 dwinter 3070: pass
1.1 dwinter 3071: ob=self._getOb(id)
3072:
3073: checkPermission=getSecurityManager().checkPermission
3074:
3075: if createUserF:
3076: if not checkPermission('Add User Folders', ob):
3077: raise Unauthorized, (
3078: 'You are not authorized to add User Folders.'
3079: )
3080: ob.manage_addUserFolder()
3081:
3082:
3083: if REQUEST is not None:
1.22 dwinter 3084: return self.manage_main(self, REQUEST, update_menu=1)
3085:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>