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