Annotation of cdli/cdli_files.py, revision 1.102
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.83 dwinter 22: from BTrees.OOBTree import OOBTree, OOTreeSet
1.57 dwinter 23: import logging
1.58 dwinter 24: import transaction
1.61 dwinter 25: import copy
1.66 dwinter 26: import codecs
1.76 dwinter 27: import sys
1.83 dwinter 28: from BTrees.IOBTree import IOBTree
1.81 casties 29: import cdliSplitter
1.83 dwinter 30: from sets import Set
31: import md5
1.87 dwinter 32: from DownloadBasket import DownloadBasketFinallyThread
1.102 ! dwinter 33: from types import *
1.85 dwinter 34:
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.73 dwinter 644: def getPNumbersOfBasket(self,basketName):
645: """get all pnumbers of a basket as a list, returns an empty list if basket not found
646: @param basketName: name of the basket
647: """
648: ret=[]
649: basketId=self.getBasketIdfromName(basketName)
650: if not basketId:
651: return []
652:
1.102 ! dwinter 653: ob=getattr(self,basketId).getContent() #get the content of a basket
1.73 dwinter 654:
655: ret=[x[0].split(".")[0] for x in ob]
656:
657: return ret
658:
1.77 dwinter 659: security.declareProtected('manage','getBasketAsOneFile')
1.73 dwinter 660: def getBasketAsOneFile(self,basketName,current="no"):
661: """returns all files of the basket combined in one file
662: @param basketName: Name of the basket
663: @param current: (optional) if current is set to "yes" then the most current version of
664: all files are downloaded and not the versions of the files as stored in the basket
665: """
666: ret=""
667: basketId=self.getBasketIdfromName(basketName)
668: if not basketId:
669: return ""
670:
671: ob=getattr(self,basketId).getLastVersion()
1.102 ! dwinter 672: for pnum,versionNr in ob.getContent():
! 673: obj=self.cdliRoot.getFileObject(pnum)
! 674: # logging.debug("obj : %s"%obj)
! 675: # version=obj.getVersionNr(versionNr)
! 676:
1.73 dwinter 677: if current=="no": #version as they are in the basket
1.102 ! dwinter 678: cur= obj.getVersionNr(versionNr)
! 679: ret+=str(cur.getData())+"\n"
1.73 dwinter 680: elif current=="yes":
681: #search current object
1.93 dwinter 682: #logging.debug("current: %s"%object[1].getId().split(".")[0])
1.102 ! dwinter 683: obj.getData()
1.73 dwinter 684: return ret
685:
1.77 dwinter 686: security.declareProtected('manage','upDateBaskets')
1.39 dwinter 687: def upDateBaskets(self):
688: """update content in to objects"""
689:
690: founds=self.ZopeFind(self,obj_metatypes=['CDLIBasketVersion'],search_sub=1)
691:
692: for found in founds:
693: found[1].updateBasket()
694:
1.32 dwinter 695: security.declareProtected('manage','deleteBaskets')
1.12 dwinter 696: def deleteBaskets(self,ids=None):
697: """delete baskets, i.e. move them into trash folder"""
698:
1.98 dwinter 699: if ids is None:
700: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
701: txt="Sorry, no basket selected!"
702: return pt(txt=txt)
1.12 dwinter 703:
704: found=self.ZopeFind(self,obj_ids=['trash'])
705:
706: if len(found)<1:
707: manage_addFolder(self, 'trash')
708: trash=self._getOb('trash')
709: else:
710: trash=found[0][1]
711:
712: if type(ids) is not ListType:
713: ids=[ids]
1.98 dwinter 714: logging.error("XERXON:"+repr(ids))
715: if len(ids)==0:
716: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
717: txt="Sorry, no basket selected!"
718: return pt(txt=txt)
719:
1.12 dwinter 720: cut=self.manage_cutObjects(ids)
721: trash.manage_pasteObjects(cut)
1.98 dwinter 722: return None
1.32 dwinter 723: security.declareProtected('manage','manageBaskets')
1.73 dwinter 724: def manageBaskets(self,submit,ids=None,basket1="",basket2="",joinBasket="",subtractBasket="",REQUEST=None,RESPONSE=None):
1.12 dwinter 725: """manage baskets, delete or copy"""
726: if submit=="delete":
1.98 dwinter 727: ret= self.deleteBaskets(ids)
728: if ret:
729: return ret
1.72 dwinter 730: elif submit=="join":
1.73 dwinter 731: flag,msg=self.joinBasket(joinBasket, ids)
1.72 dwinter 732: logging.info("joining %s %s"%(flag,msg))
1.98 dwinter 733: if not flag:
734: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','cdliError_html.zpt')).__of__(self)
735:
736: return pt(txt=msg)
737:
1.72 dwinter 738: elif submit=="subtract":
739: logging.info("BBBb %s %s"%(basket1,basket2))
1.73 dwinter 740: flag,msg=self.subtractBasket(subtractBasket, basket1,basket2)
1.72 dwinter 741: logging.info("subtract %s %s"%(flag,msg))
1.12 dwinter 742:
743: if RESPONSE:
744: RESPONSE.redirect(self.absolute_url())
1.32 dwinter 745:
1.33 dwinter 746: security.declareProtected('View','getBasketIdfromName')
1.5 dwinter 747: def getBasketIdfromName(self,basketname):
748: """get id from name"""
749:
750: for basket in self.ZopeFind(self,obj_metatypes=["CDLIBasket"]):
751: if basket[1].title==basketname:
752: return basket[0]
753: else:
754: None
1.9 dwinter 755:
756: security.declareProtected('manage','uploadBasket_html')
757:
1.4 dwinter 758: def uploadBasket_html(self,basketId='0'):
759: """upload an atf file, html form"""
1.9 dwinter 760:
761:
1.4 dwinter 762: basketId=str(basketId)
763: if not basketId=='0':
764: basketName=getattr(self.basketContainer,basketId).title
765: else:
766: basketName=""
767:
768: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasket_html.zpt')).__of__(self)
769: return pt(basketId=basketId,basketName=basketName)
770:
771:
1.77 dwinter 772: security.declareProtected('manage','index_html')
1.4 dwinter 773: def index_html(self):
774: """stanadard ansicht"""
1.9 dwinter 775:
776:
777:
1.4 dwinter 778: ext=self.ZopeFind(self,obj_ids=["index.html"])
779: if ext:
780: return ext[0][1]()
781:
782: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self)
783: return pt()
784:
785: def getStorageFolderRoot(self):
786: """root des storage folders"""
787: return self.cdli_main
788:
789: def __init__(self,id,title):
790: """ init basket container"""
791: self.id=id
792: self.title=title
793:
1.51 dwinter 794:
1.49 dwinter 795: def getBasketsId(self):
796: """get all baskets als klartext"""
1.51 dwinter 797:
798: ret=""
1.49 dwinter 799: baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
800: for basket in baskets:
801: com,user,time,values = basket[1].getContentIds()
802: ret+= "BASKET:"+com+"\t"+user+"\t"+time+"\n"
803: for x in values:
804: ret+= x[0]+"\t"+x[1]+"\n"
1.66 dwinter 805: return ret
1.49 dwinter 806:
1.4 dwinter 807: def getBaskets(self,sortField='title'):
808: """get all baskets files"""
809:
810: def sortName(x,y):
811: return cmp(x[1].title.lower(),y[1].title.lower())
812:
813: def sortDate(x,y):
814: return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime())
815:
816:
817: def sortComment(x,y):
818:
819:
820:
821: try:
822: xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower()
823: except:
824: xc='ZZZZZZZZZZZZZ'.lower()
825: try:
826: yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower()
827: except:
828: yc='ZZZZZZZZZZZZZ'.lower()
829:
830:
831: if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()):
832:
833: try:
834: xc=x[1].getLastVersion().getComment().lower()
835: except:
836: xc='ZZZZZZZZZZZZZ'.lower()
837:
838: if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()):
839: try:
840: yc=y[1].getLastVersion().getComment().lower()
841: except:
842: yc='ZZZZZZZZZZZZZ'.lower()
843:
844:
845: return cmp(xc,yc)
846:
847: def sortAuthor(x,y):
848:
849: return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower())
850:
851: baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket'])
852:
853:
854: if sortField=='title':
855: baskets.sort(sortName)
856: elif sortField=='date':
857: baskets.sort(sortDate)
858: elif sortField=='author':
859: baskets.sort(sortAuthor)
860: elif sortField=='comment':
861: baskets.sort(sortComment)
1.39 dwinter 862:
1.4 dwinter 863: return baskets
1.72 dwinter 864:
865:
866: def subtractBasket(self,newBasket,basket1,basket2):
867: """subtract basket2 from basket1
868: (i.e. newbasket will contain alle elements of basket1 which are not in basket2),
869: if basket2 contains files which are not in basket1, then theses files fill be ignored
870:
871: @param newbasket: name of the new basket
872: @param basket1: basket where basket2 will be subtracted from
873: @param basket2: see above
874:
875: """
1.98 dwinter 876:
1.72 dwinter 877: logging.info("CCCCC %s %s"%(basket1,basket2))
878:
879: try:
880: newB=self.addBasket(newBasket)
881: except:
882: return False, "cannot create the new basket"
883:
884:
1.4 dwinter 885:
1.72 dwinter 886:
887:
888: bas2= getattr(self,basket2)
889: bas2content=bas2.getContent()
890: bas2ids=[x[0] for x in bas2content]
891:
892:
893:
894: bas1= getattr(self,basket1)
895: bas1content=bas1.getContent()
896:
897:
898: newBasketContent={}
899:
900: for id,version in bas1content:
901: if not (id in bas2ids):
902: newBasketContent[id]=version
903:
904: username=self.getActualUserName()
905:
906: logging.info("sbc %s"%newBasketContent)
907: newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
908:
909: return True, ""
910:
911:
912: def joinBasket(self,newBasket,oldBaskets):
1.71 dwinter 913: """join two baskets
914: @param newbasket: name of the new basket
915: @param oldbaskets: list of baskets to be joined
916: """
1.98 dwinter 917: if oldBaskets is None:
918: return False, "No Baskets selected!"
919:
1.72 dwinter 920: try:
921: newB=self.addBasket(newBasket)
922: except:
923: return False, "cannot create the new basket"
924:
925: newBasketContent={}
1.98 dwinter 926:
1.72 dwinter 927: for ob in oldBaskets:
928: x= getattr(self,ob,None)
929: if x is None:
930: return False, "cannot find basket: %s"%ob
931:
932: ids=x.getContent() # hole den Inhalt
933:
934: for id,version in ids:
935: if newBasketContent.has_key(id): # p number gibt's schon
936: newBasketContent[id]=max(newBasketContent[id],version) # speichere die groessere Versionsnumber
937: else:
938: newBasketContent[id]=version
939: username=self.getActualUserName()
940:
941: logging.info("nbc %s"%newBasketContent)
942: newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog)
943:
944: return True, ""
945:
1.4 dwinter 946: def getNewId(self):
947: """createIds"""
948: last=getattr(self,'last',0)
949: last +=1
950: while len(self.ZopeFind(self,obj_ids=[str(last)]))>0:
951: last+=1
952:
953: self.last=last
954: return last
955:
1.6 dwinter 956: def setActiveBasket(self,basketId,REQUEST=None):
1.4 dwinter 957: """store active basketId in a cookie"""
958: self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/")
1.66 dwinter 959: try:
960: qs=cgi.parse_qs(REQUEST['QUERY_STRING'])
961: del(qs['basketId'])
962: except:
963: qs={}
1.6 dwinter 964: if REQUEST:
1.49 dwinter 965: REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+urllib.urlencode(qs))
1.6 dwinter 966:
1.4 dwinter 967: def getActiveBasket(self):
968: """get active basket from cookie"""
969:
970: id= self.REQUEST.cookies.get('CDLIActiveBasket',None)
1.6 dwinter 971: if id:
972: obj=getattr(self,str(id),None)
973: else:
974: obj=None
1.4 dwinter 975: return obj
1.6 dwinter 976:
1.4 dwinter 977: def getActualUserName(self):
978: """get name of the actualuser"""
979: return str(self.REQUEST['AUTHENTICATED_USER'])
980:
1.77 dwinter 981: security.declareProtected('manage','addBasket')
1.4 dwinter 982: def addBasket(self,newBasketName):
983: """add a new basket"""
984:
985: ob=manage_addCDLIBasket(self,newBasketName)
986: return ob
1.72 dwinter 987:
1.6 dwinter 988: def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None):
1.4 dwinter 989: """store it"""
1.6 dwinter 990: if not ids:
991: ids=self.REQUEST.SESSION['fileIds']
1.83 dwinter 992:
993: if (type(ids) is not ListType) and (not isinstance(ids,Set)):
1.4 dwinter 994: ids=[ids]
995:
1.83 dwinter 996: if isinstance(ids,Set):
997: ids=list(ids)
998:
1.6 dwinter 999: if (submit.lower()=="store in new basket") or (submit.lower()=="new basket"):
1.4 dwinter 1000: basketRet=self.addBasket(newBasketName)
1001: self.setActiveBasket(basketRet.getId())
1002: basket=getattr(self,basketRet.getId())
1.6 dwinter 1003: elif (submit.lower()=="store in active basket") or (submit.lower()=="active basket"):
1.4 dwinter 1004: basket=self.getActiveBasket()
1.6 dwinter 1005:
1006: added=basket.addObjects(ids)
1007: back=self.REQUEST['HTTP_REFERER'].split("?")[0]+"?basketName="+basket.title+"&numberOfObjects="+str(added)
1008:
1009:
1010: if fromFileList:
1.7 dwinter 1011:
1.83 dwinter 1012: return self.cdli_main.findObjectsFromList(list=ids,basketName=basket.title,numberOfObjects=added)
1.6 dwinter 1013:
1.4 dwinter 1014: if RESPONSE:
1.6 dwinter 1015:
1.4 dwinter 1016: RESPONSE.redirect(back)
1017:
1.6 dwinter 1018: return True
1019:
1.4 dwinter 1020: def manage_addCDLIBasketContainerForm(self):
1021: """add the CDLIBasketContainer form"""
1022: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self)
1023: return pt()
1024:
1025: def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None):
1026: """add the basket"""
1027: ob=CDLIBasketContainer(id,title)
1028:
1029: self._setObject(id, ob)
1030:
1031: if RESPONSE is not None:
1032: RESPONSE.redirect('manage_main')
1033:
1.5 dwinter 1034: class CDLIBasket(Folder,CatalogAware):
1.4 dwinter 1035: """basket"""
1036:
1037: meta_type="CDLIBasket"
1.5 dwinter 1038: default_catalog="CDLIBasketCatalog"
1.4 dwinter 1039:
1.75 dwinter 1040: def searchInBasket(self,indexName,searchStr,regExp=False):
1041: """searchInBasket"""
1042:
1.81 casties 1043: lst=self.searchInLineIndexDocs(indexName,searchStr,uniq=True,regExp=regExp) #TODO: fix this
1.75 dwinter 1044: ret={}
1045:
1046: lv=self.getLastVersion()
1.76 dwinter 1047:
1048:
1.75 dwinter 1049: for obj in lv.content.getContent():
1050: id=obj[1].getId().split(".")[0]
1051: if id in lst:
1052:
1053: ret[id]=self.showWordInFile(id,searchStr,lineList=self.getLinesFromIndex(indexName,searchStr,id,regExp=regExp),regExp=regExp,indexName=indexName)
1054:
1055:
1056: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','searchResultsInBasket')).__of__(self)
1057: return pt(result=ret,indexName=indexName,regExp=regExp,word=searchStr)
1058:
1059:
1060:
1061:
1062: def searchInBasket_v1(self,searchStr):
1.74 dwinter 1063: """search occurences of searchStr in files im basket"""
1064: ret=[]
1065: lv=self.getLastVersion()
1066: logging.info("searching")
1067: for obj in lv.content.getContent():
1068: txt=obj[0].getData()
1069: for x in txt.split("\n"):
1070: logging.info("search %s"%x)
1071: if re.match(searchStr,x):
1072: ret.append(x)
1073:
1074: return "\n".join(ret)
1075:
1076:
1.4 dwinter 1077: def getFile(self,obj):
1078: return obj[1]
1079:
1080: def getFileLastVersion(self,obj):
1081: return obj[0]
1082:
1.5 dwinter 1083: def getFileNamesInLastVersion(self):
1084: """get content of the last version as list"""
1085:
1086: return [x[1].getId() for x in self.getLastVersion().getContent()]
1087:
1.37 dwinter 1088:
1.102 ! dwinter 1089: def isActual(self,obj,nummer):
! 1090: """teste ob im basket die aktuelle version ist, obj kann entweder ein CDLIFile sein oder eine
! 1091: eine pnummer, die auf ein CDLIFile verweist"""
! 1092: try:
! 1093: #logging.debug("isActual:"+repr(obj))
! 1094: if isinstance(obj, CDLIFile):
! 1095: actualNo=obj.getLastVersion().getVersionNumber()
! 1096: else:
! 1097: actualNo=self.cdliRoot.getFileObjectLastVersion(obj).getVersionNumber()
! 1098:
! 1099: if actualNo==nummer:
! 1100: return True , 0
! 1101: else:
! 1102: return False, actualNo
! 1103: except:
! 1104: logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
! 1105: logging.error(""" PARAMS: %s %s"""%(obj,nummer))
! 1106: return False, -1
! 1107: def isActualOld(self,obj):
1.4 dwinter 1108: """teste ob im basket die aktuelle version ist"""
1.85 dwinter 1109: try:
1.93 dwinter 1110: #logging.debug("isActual:"+repr(obj))
1.85 dwinter 1111: actualNo=obj[1].getLastVersion().getVersionNumber()
1112: storedNo=obj[0].getVersionNumber()
1113:
1.87 dwinter 1114:
1.93 dwinter 1115: #actualNo=self.getFileObjectLastVersion(obj.getId()).getVersionNumber()
1.85 dwinter 1116:
1.87 dwinter 1117: #if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash":
1118: # return False, -1
1.37 dwinter 1119:
1.85 dwinter 1120: if actualNo==storedNo:
1121: return True , 0
1122: else:
1123: return False, actualNo
1124: except:
1.93 dwinter 1125: logging.error( """is actual: %s (%s %s)"""%(repr(obj),sys.exc_info()[0],sys.exc_info()[1]))
1126:
1.12 dwinter 1127: return False, -1
1.85 dwinter 1128:
1.4 dwinter 1129: def history(self):
1130: """history"""
1131:
1132: ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
1133: if ext:
1134: return getattr(self,ext[0][1].getId())()
1135:
1136: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self)
1137: return pt()
1138:
1139: def getStorageFolderRoot(self):
1140: """root des storage folders"""
1141: return self.aq_parent.cdli_main
1142:
1143: def __init__(self,id,title,shortDescription="",comment=""):
1144: """init a CDLIBasket"""
1145:
1146: self.id=id
1147: self.title=title
1148: self.shortDescription=shortDescription
1149: self.comment=comment
1150:
1.72 dwinter 1151: def getActualUserName(self):
1152: """get name of the actualuser"""
1153:
1154: return str(self.REQUEST['AUTHENTICATED_USER'])
1155:
1.4 dwinter 1156:
1157: def getLastVersion(self):
1158: """hole letzte version"""
1.39 dwinter 1159:
1160: ids=[]
1161: idsTmp= self.objectIds()
1162: for x in idsTmp:
1163: try:
1164: ids.append(int(x))
1165: except:
1166: pass
1.4 dwinter 1167: ids.sort()
1.39 dwinter 1168:
1.4 dwinter 1169: if len(ids)==0:
1170: return None
1171: else:
1172: ob=getattr(self,str(ids[-1]))
1.39 dwinter 1173:
1174:
1.4 dwinter 1175: return ob
1176:
1177: def getVersions(self):
1178: """get versions"""
1179: versions=self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])
1180: return versions
1181:
1182:
1.37 dwinter 1183: def updateObjects(self,ids,RESPONSE=None,REQUEST=None):
1184: """update ids, ids not in the basket the add"""
1185: if type(ids) is not ListType:
1186: ids=[ids]
1187:
1188: lastVersion=self.getLastVersion()
1.39 dwinter 1189: oldContent=lastVersion.content.getContent()
1.37 dwinter 1190: newContent=[]
1191:
1192: #first copy the old
1193: for obj in oldContent:
1194: if obj[1].getId() not in ids:
1195: newContent.append(obj)
1196: #now add the new
1197:
1198: for id in ids:
1199: founds=self.CDLICatalog.search({'title':id})
1200:
1201: for found in founds:
1202: if found.getObject() not in oldContent:
1203: #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version
1204: newContent.append((found.getObject().getLastVersion(),found.getObject()))
1205:
1206:
1207: content=newContent
1208: user=self.getActualUserName()
1209:
1210: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
1211:
1.38 dwinter 1212: obj=self._getOb(ob.getId())
1.37 dwinter 1213: if RESPONSE:
1.38 dwinter 1214:
1.37 dwinter 1215: RESPONSE.redirect(obj.absolute_url())
1.38 dwinter 1216:
1217: return obj
1218:
1.72 dwinter 1219: def addObjectsWithVersion(self,ids,deleteOld=None,username=None,catalog=None):
1220: """generate a new version of the basket with objects added,
1221: hier wird jedoch nicht die letzte Version jedes Files hinzugefuegt, s
1222: ondern ids is ein Tupel mit der Id (d.h. der p-number) und der Versionsnummer.
1223: """
1224: logging.info("add to basket (%s)"%(self.getId()))
1225: lastVersion=self.getLastVersion()
1226:
1227: if not catalog:
1228: catalog=self.CDLICatalog
1229:
1230: if lastVersion is None:
1231: oldContent=[]
1232: else:
1233: oldContent=lastVersion.content.getContent()
1234:
1235: if deleteOld:
1236: oldContent=[]
1237:
1238: newContent=[]
1239: added=0
1240:
1241: for id,version in ids.iteritems():
1242: logging.info("adding %s %s"%(id,version))
1243: id=id.split(".")[0] # title nur die pnumber ohne atf
1244:
1245: try:
1246: founds=catalog.search({'title':id})
1247: except:
1248: founds=[]
1249: logging.info(" found %s "%(founds))
1250: for found in founds:
1251: if found.getObject() not in oldContent:
1252:
1253: #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version
1254: newContent.append((found.getObject().getVersions()[version-1][1],found.getObject()))
1255: added+=1
1256:
1257: content=oldContent+newContent
1258: if not username:
1259: logging.error("XXXXXXXXXXX %s"%repr(self))
1260: user=self.getActualUserName()
1261: else:
1262: user = username
1263:
1264: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content)
1265: logging.info("add to basket (%s) done"%(self.getId()))
1266: return added
1267:
1268:
1.19 dwinter 1269: def addObjects(self,ids,deleteOld=None,username=None):
1.4 dwinter 1270: """generate a new version of the basket with objects added"""
1.83 dwinter 1271:
1272: def swap(x):
1273: return (x[1],x[0])
1274:
1.100 dwinter 1275: logging.info("add to basket (%s)"%(repr(ids)))
1.65 dwinter 1276: logging.info("add to basket (%s)"%(self.getId()))
1.4 dwinter 1277: lastVersion=self.getLastVersion()
1278:
1279: if lastVersion is None:
1280: oldContent=[]
1281: else:
1.39 dwinter 1282: oldContent=lastVersion.content.getContent()
1.4 dwinter 1283:
1284: if deleteOld:
1285: oldContent=[]
1286:
1.6 dwinter 1287: added=0
1.83 dwinter 1288: # for id in ids:
1289: # logging.debug("adding:"+id)
1290: # try:
1291: # founds=self.CDLICatalog.search({'title':id})
1292: # except:
1293: # founds=[]
1294: #
1295: # for found in founds:
1296: # if found.getObject() not in oldContent:
1297: # #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version
1298: # newContent.append((found.getObject().getLastVersion(),found.getObject()))
1299: # added+=1
1300:
1.85 dwinter 1301: hash = md5.new(repr(makelist(ids))).hexdigest() # erzeuge hash als identification
1.83 dwinter 1302: #logging.debug("JJJJJJJ:"+repr(self.makelist(ids)))
1.93 dwinter 1303:
1.102 ! dwinter 1304: retrieved = self.CDLICache.retrieve(hash)
! 1305: if retrieved:
! 1306: newContent=Set(map(swap,retrieved))
1.83 dwinter 1307: else:
1.102 ! dwinter 1308: newContent=Set([(self.getFileObjectLastVersion(x),self.getFileObject(x)) for x in ids])
! 1309:
! 1310:
1.83 dwinter 1311:
1.100 dwinter 1312: #remove all Elements which are not stored
1313: if (None,None) in newContent:
1314: newContent.remove((None,None))
1.83 dwinter 1315: content=Set(oldContent).union(newContent)
1316: added = len(content)-len(oldContent)
1.19 dwinter 1317: if not username:
1318: user=self.getActualUserName()
1319: else:
1320: user = username
1.83 dwinter 1321:
1322: #logging.debug("content:"+repr(list(content)))
1323: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=list(content))
1.65 dwinter 1324: logging.info("add to basket (%s) done"%(self.getId()))
1.6 dwinter 1325: return added
1.4 dwinter 1326:
1.51 dwinter 1327:
1328:
1.72 dwinter 1329: def getContent(self):
1330: """print content"""
1331: ret=[]
1332:
1333: lv=self.getLastVersion()
1.102 ! dwinter 1334: #for obj in lv.content.getContent():
1.93 dwinter 1335: #logging.info("XXXXXXXXXX %s"%repr(obj))
1.102 ! dwinter 1336: # ret.append((obj[1].getId(),obj[0].versionNumber))
1.72 dwinter 1337:
1.102 ! dwinter 1338: return lv
1.72 dwinter 1339:
1.49 dwinter 1340: def getContentIds(self):
1341: """print basket content"""
1342: ret=[]
1343: lv=self.getLastVersion()
1.51 dwinter 1344: for obj in lv.content.getContent():
1.49 dwinter 1345: ret.append((obj[0].getId(),obj[1].getId()))
1346:
1347:
1348: return lv.getComment(),lv.getUser(),lv.getTime(),ret
1349:
1.37 dwinter 1350: def changeBasket(self,ids,submit,RESPONSE=None,REQUEST=None):
1351: """change a basket"""
1352: if submit=="update":
1353: return self.updateObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1354: elif submit=="delete":
1355: return self.deleteObjects(ids,RESPONSE=RESPONSE,REQUEST=REQUEST)
1356:
1.12 dwinter 1357: def deleteObjects(self,ids,RESPONSE=None,REQUEST=None):
1.4 dwinter 1358: """delete objects"""
1.12 dwinter 1359:
1360: if type(ids) is not ListType:
1361: ids=[ids]
1362:
1363: lastVersion=self.getLastVersion()
1.39 dwinter 1364: oldContent=lastVersion.content.getContent()
1.12 dwinter 1365: newContent=[]
1366: for obj in oldContent:
1367: if obj[1].getId() not in ids:
1368: newContent.append(obj)
1369:
1370:
1371: user=self.getActualUserName()
1372:
1373: ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent)
1374:
1375: if RESPONSE:
1376: obj=self._getOb(ob.getId())
1377: RESPONSE.redirect(obj.absolute_url())
1.4 dwinter 1378:
1379: def manage_addCDLIBasketForm(self):
1380: """add the CDLIBasketContainer form"""
1381: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasket.zpt')).__of__(self)
1382: return pt()
1383:
1384: def manage_addCDLIBasket(self,title,shortDescription="",comment="",RESPONSE=None):
1385: """add the basket"""
1386:
1387: id=str(self.getNewId())
1388:
1389: ob=CDLIBasket(id,title,shortDescription,comment)
1390:
1391: self._setObject(id, ob)
1392:
1393: if RESPONSE is not None:
1394: RESPONSE.redirect('manage_main')
1395: else:
1396: return ob
1397:
1.39 dwinter 1398: class CDLIBasketVersion(Implicit,Persistent,Folder):
1.4 dwinter 1399: """version of a basket"""
1400:
1401: meta_type="CDLIBasketVersion"
1.32 dwinter 1402: security=ClassSecurityInfo()
1.4 dwinter 1403:
1.39 dwinter 1404: def updateBasket(self):
1405: """update"""
1406: try:
1407: self._setObject('content',BasketContent(self.basketContent))
1408: except:
1409: try:
1410: if len(self.basketContent)>0:
1411: self.content.setContent(self.basketContent)
1412: except:
1413: print "error",self.getId(),self.aq_parent.getId()
1414: self.basketContent=[]
1415:
1416:
1.37 dwinter 1417: def containsNonActualFiles(self):
1418: """returns True if basket contains one or more non current files"""
1419:
1420: objs=self.getContent()
1421: for obj in objs:
1.102 ! dwinter 1422: if not self.isActual(obj[0],obj[1])[0]:
1.37 dwinter 1423: return True
1424: return False
1425:
1.72 dwinter 1426: def downloadListOfPnumbers(self):
1427: """download pnumbers of the basket as list"""
1428:
1429: basket_name=self.aq_parent.title
1430:
1431: ids=self.getContent() # get the list of objects
1432: logging.error(ids)
1433: ret="\n".join([x[1].getId().split(".")[0] for x in ids])
1434:
1435: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.txt" """%basket_name)
1436: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
1437: length=len(ret)
1438: self.REQUEST.RESPONSE.setHeader("Content-Length",length)
1439: self.REQUEST.RESPONSE.write(ret)
1440:
1.77 dwinter 1441: security.declareProtected('manage','downloadObjectsAsOneFile')
1.37 dwinter 1442: def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None,check="yes",current="no"):
1.4 dwinter 1443: """download all selected files in one file"""
1.93 dwinter 1444:
1.46 dwinter 1445: if self.temp_folder.downloadCounterBaskets > 10000:
1446: return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
1.45 dwinter 1447:
1448:
1.37 dwinter 1449: if (check=="yes") and self.containsNonActualFiles():
1450: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadObjectAsOneFile_check.zpt')).__of__(self)
1.46 dwinter 1451:
1.37 dwinter 1452: return pt(lock=lock)
1453:
1.46 dwinter 1454: else:
1455:
1456: return self.downloadObjectsAsOneFileFinally(lock=lock,procedure=procedure,REQUEST=REQUEST,current="no")
1457:
1.87 dwinter 1458: def downloadObjectsAsOneFileFinally(self,lock=None,procedure=None,REQUEST=None,current="no",repeat=None):
1.46 dwinter 1459: """print do the download"""
1.87 dwinter 1460:
1.93 dwinter 1461:
1.46 dwinter 1462: ret=""
1.4 dwinter 1463: lockedObjects={}
1464:
1.87 dwinter 1465:
1.93 dwinter 1466:
1.4 dwinter 1467: if lock:
1.87 dwinter 1468: logging.debug("------lock:"+repr(lock))
1.4 dwinter 1469: if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User':
1.87 dwinter 1470:
1.4 dwinter 1471: return "please login first"
1472:
1473: #check if a locked object exist in the basket.
1474: lockedObjects={}
1.39 dwinter 1475: for object in self.content.getContent():
1.102 ! dwinter 1476: obj=self.getFileObject(object[0])
! 1477: if (not str(obj.lockedBy)=="") and (not (str(obj.lockedBy)==str(self.REQUEST['AUTHENTICATED_USER']))):
! 1478: lockedObjects[obj.title]=repr(obj.lockedBy)
1.4 dwinter 1479:
1480:
1481: keys=lockedObjects.keys()
1482:
1483:
1484: if len(keys)>0 and (not procedure):
1485: self.REQUEST.SESSION['lockedObjects']=lockedObjects
1486: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self)
1.45 dwinter 1487:
1.87 dwinter 1488:
1.46 dwinter 1489: return pt()
1.4 dwinter 1490:
1491: elif not procedure: #keine fails gesperrt dann alle donwloaden
1492: procedure="downloadAll"
1493:
1.46 dwinter 1494:
1.87 dwinter 1495:
1496:
1497: threadName=repeat
1498: if not threadName or threadName=="":
1499: thread=DownloadBasketFinallyThread()
1500: threadName=thread.getName()[0:]
1501:
1502: if (not hasattr(self,'_v_downloadBasket')):
1503: self._v_downloadBasket={}
1504:
1505:
1506: self._v_downloadBasket[threadName]=thread
1507: logging.debug("dwonloadfinally:"+repr(self))
1.97 dwinter 1508:
1.96 dwinter 1509: if isinstance(self,CDLIBasketVersion):
1510: obj=self
1511: else:
1512: obj=self.aq_parent
1.95 dwinter 1513: logging.debug("dwonloadfinally2:"+repr(obj))
1514: logging.debug("dwonloadfinally2:"+repr(obj.aq_parent))
1515:
1.96 dwinter 1516: obj2=obj.aq_parent
1517: if not isinstance(obj2,CDLIBasket):
1.95 dwinter 1518: obj2=obj2.aq_parent
1519:
1520: basketID=obj2.getId()
1521: versionNumber=obj.getId()
1522: logging.debug("dwonloadfinally2:"+repr(basketID))
1523: logging.debug("dwonloadfinally2:"+repr(versionNumber))
1524:
1.97 dwinter 1525:
1.88 dwinter 1526: if lock:
1527: logging.debug("-----start locking")
1528: for object in self.content.getContent():
1.102 ! dwinter 1529: obj=self.ctx.getFileObject(object[0])
! 1530: if obj.lockedBy =='':
! 1531: obj.lockedBy=self.REQUEST['AUTHENTICATED_USER']
1.88 dwinter 1532: logging.debug("-----finished locking")
1533:
1534: #obj.lockedBy=user
1535: self._v_downloadBasket[threadName].set(lock,procedure,self.REQUEST['AUTHENTICATED_USER'],current,basketID,versionNumber)
1.45 dwinter 1536:
1.87 dwinter 1537: self._v_downloadBasket[threadName].start()
1.4 dwinter 1538:
1.87 dwinter 1539:
1540:
1541: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1542:
1543: if wait_template:
1544: return wait_template[0][1]()
1545: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
1546:
1.88 dwinter 1547: return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
1548: counter=self._v_downloadBasket[threadName].getCounter(),
1549: number=self._v_downloadBasket[threadName].getNumberOfFiles())
1.87 dwinter 1550: #_v_xmltrans.run()
1551:
1552: else:
1553: #recover thread, if lost
1554: if not hasattr(self,'_v_downloadBasket'):
1555: self._v_downloadBasket={}
1556: if not self._v_downloadBasket.get(threadName,None):
1557: for thread in threading.enumerate():
1558: if threadName == thread.getName():
1559: self._v_downloadBasket[threadName]=thread
1560:
1561: if self._v_downloadBasket.get(threadName,None) and (self._v_downloadBasket[threadName] is not None) and (not self._v_downloadBasket[threadName].end) :
1562:
1563: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1564: if wait_template:
1565: return wait_template[0][1]()
1.83 dwinter 1566:
1.87 dwinter 1567: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','downloadBasketWait.zpt')).__of__(self)
1.88 dwinter 1568: return pt(txt=self.absolute_url()+'/downloadObjectsAsOneFileFinally',threadName=threadName,
1569: counter=self._v_downloadBasket[threadName].getCounter(),
1570: number=self._v_downloadBasket[threadName].getNumberOfFiles())
1.87 dwinter 1571: else:
1572:
1573:
1574: logging.debug("FINISHED")
1575: if not self._v_downloadBasket.get(threadName,None):
1576: for thread in threading.enumerate():
1577: if threadName == thread.getName():
1578: self._v_downloadBasket[threadName]=thread
1579:
1580: #files = self._v_downloadBasket[threadName].result
1581: files=self.basketContainer.resultHash[threadName]
1.90 dwinter 1582: lockedFiles=self.basketContainer.resultLockedHash[threadName]
1.92 dwinter 1583:
1.87 dwinter 1584: # fh=file("/var/tmp/test")
1585: #ret =fh.read()
1586:
1587: if (not isinstance(self.aq_parent,CDLIBasket)):
1588: basket_name=self.aq_parent.aq_parent.title+"_V"+self.getId()
1589: else:
1590: basket_name=self.aq_parent.title+"_V"+self.getId()
1.86 dwinter 1591:
1592:
1593:
1.87 dwinter 1594: #write basketname to header of atf file
1595:
1.45 dwinter 1596:
1.87 dwinter 1597: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.atf" """%basket_name)
1598: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
1599: #length=len(ret)
1600: #self.REQUEST.RESPONSE.setHeader("Content-Length",length)
1.90 dwinter 1601:
1.87 dwinter 1602: ret="#basket: %s\n"%basket_name
1.90 dwinter 1603: self.REQUEST.RESPONSE.write(ret)
1604:
1.87 dwinter 1605: for fileName in files:
1.102 ! dwinter 1606: logging.debug("download: %s"%fileName)
1.91 dwinter 1607: try:
1.87 dwinter 1608: self.REQUEST.RESPONSE.write(file(fileName).read())
1.91 dwinter 1609: except:
1610: logging.error("downloadasonefile: cannot read %s"%fileName)
1.90 dwinter 1611:
1612:
1613: self.REQUEST.RESPONSE.write("\n# locked files\n")
1614: for fileName in lockedFiles:
1.92 dwinter 1615: self.REQUEST.RESPONSE.write("# %s by %s\n"%fileName)
1.90 dwinter 1616:
1617: self.REQUEST.RESPONSE.write("# locked files end\n")
1618:
1.87 dwinter 1619: del self.basketContainer.resultHash[threadName]
1.90 dwinter 1620: del self.basketContainer.resultLockedHash[threadName]
1.87 dwinter 1621:
1.4 dwinter 1622: def numberOfItems(self):
1623: """return anzahl der elemente im basket"""
1.39 dwinter 1624: return self.content.numberOfItems()
1.4 dwinter 1625:
1626: def getTime(self):
1627: """getTime"""
1628: #return self.bobobase_modification_time().ISO()
1629:
1630: if hasattr(self,'time'):
1631: return time.strftime("%Y-%m-%d %H:%M:%S",self.time)
1632: elif hasattr(self,'timefixed'):
1633: return self.timefixed
1634: else:
1635: setattr(self,'timefixed',self.bobobase_modification_time().ISO())
1636: return self.bobobase_modification_time().ISO()
1637:
1638: def getContent(self):
1639: """get Basket Content"""
1.102 ! dwinter 1640: logging.debug("retrieving content A")
! 1641: cnt = self.content
! 1642: logging.debug("retrieving content: obj %s"%cnt)
! 1643: tmp = self.content.getContent()
! 1644: logging.debug("got content")
! 1645: return tmp
1.4 dwinter 1646:
1647:
1648: def __init__(self,id,user,comment="",basketContent=[]):
1649: """ init a basket version"""
1650: self.id=id
1.74 dwinter 1651: self.comment=comment
1.39 dwinter 1652: self._setObject('content',BasketContent(basketContent))
1653: #self.basketContent=basketContent[0:]a
1.4 dwinter 1654: self.user=user
1655: self.time=time.localtime()
1656:
1657: def getUser(self):
1658: """get user"""
1659: return self.user
1660:
1661: def getComment(self):
1662: """get Comment"""
1663: return self.comment
1664:
1.77 dwinter 1665: security.declareProtected('manage','index_html')
1.4 dwinter 1666: def index_html(self):
1667: """view the basket"""
1.102 ! dwinter 1668: logging.debug("start index_html - Basket version")
1.37 dwinter 1669: if self.REQUEST.get('change',False):
1.38 dwinter 1670: ob=self.aq_parent.updateObjects(self.REQUEST['change'])
1671:
1672: self.REQUEST.RESPONSE.redirect(ob.absolute_url())#go to new basket, because changing generates a new basket
1.102 ! dwinter 1673: logging.debug("start index_html - Basket version:template")
1.4 dwinter 1674: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketVersionMain.zpt')).__of__(self)
1675: return pt()
1676:
1677: def getObjUrl(self,result):
1678: """getUrl of the version of the object"""
1.102 ! dwinter 1679:
! 1680: founds=self.CDLICatalog.search({'title':result})
1.4 dwinter 1681: if len(founds)>0:
1.12 dwinter 1682: return founds[0].getObject().getLastVersion().absolute_url()
1.4 dwinter 1683:
1684: else: #assume version number
1.102 ! dwinter 1685: splitted=result.split("_")
1.9 dwinter 1686: founds=self.CDLICatalog.search({'title':splitted[1]})
1.102 ! dwinter 1687: return founds[0].getObject().getLastVersion().absolute_url()+'/'+result
1.4 dwinter 1688:
1689: def manage_addCDLIBasketVersion(self,user,comment="",basketContent=[],RESPONSE=None):
1690: """add a version"""
1691:
1692: #check for already existing versions
1693:
1694: lastVersion=self.getLastVersion()
1695: if lastVersion is None:
1696: newId=str(1)
1697: else:
1698: newId=str(int(lastVersion.getId())+1)
1699:
1700: ob=CDLIBasketVersion(newId,user,comment,basketContent)
1701:
1702: self._setObject(newId, ob)
1703:
1704: if RESPONSE is not None:
1705: RESPONSE.redirect('manage_main')
1706: else:
1707: return ob
1708:
1.46 dwinter 1709: class CDLIFileObject(CatalogAware,extVersionedFileObject):
1.1 dwinter 1710: """CDLI file object"""
1711:
1712: meta_type="CDLI File Object"
1.25 dwinter 1713: default_catalog='CDLIObjectsCatalog'
1.1 dwinter 1714:
1.12 dwinter 1715: security=ClassSecurityInfo()
1716:
1.78 dwinter 1717: security.declareProtected('manage','index_html')
1.81 casties 1718:
1719: security.declarePublic('view')
1720: view = PageTemplateFile('zpt/viewCDLIFile.zpt', globals())
1721:
1722: security.declarePublic('editATF')
1723: editATF = PageTemplateFile('zpt/editATFFile.zpt', globals())
1724:
1.28 dwinter 1725: def PrincipiaSearchSource(self):
1726: """Return cataloguable key for ourselves."""
1727: return str(self)
1728:
1.89 dwinter 1729: def setAuthor(self, author):
1730: """change the author"""
1731: self.author = author
1732:
1.26 dwinter 1733: def makeThisVersionCurrent_html(self):
1.85 dwinter 1734: """form for mthis version current"""
1.26 dwinter 1735:
1736: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','makeThisVersionCurrent.zpt')).__of__(self)
1737: return pt()
1.81 casties 1738:
1739: security.declarePublic('makeThisVersionCurrent')
1.27 dwinter 1740: def makeThisVersionCurrent(self,comment,author,RESPONSE=None):
1.26 dwinter 1741: """copy this version to current"""
1742: parent=self.aq_parent
1.81 casties 1743: parent.manage_addVersionedFileObject(id=None,vC=comment,author=author,file=self.getData(),RESPONSE=RESPONSE)
1744: #newversion=parent.manage_addCDLIFileObject('',comment,author)
1745: #newversion.manage_upload(self.getData())
1.27 dwinter 1746:
1.81 casties 1747: #if RESPONSE is not None:
1748: # RESPONSE.redirect(self.aq_parent.absolute_url()+'/history')
1.27 dwinter 1749:
1.26 dwinter 1750: return True
1751:
1.52 dwinter 1752: def getFormattedData(self):
1753: """fromat text"""
1754: data=self.getData()
1.70 dwinter 1755: # return re.sub("\s\#lem"," #lem",data) #remove return vor #lem
1756: return re.sub("#lem"," #lem",data) #remove return vor #lem
1.52 dwinter 1757:
1.1 dwinter 1758:
1.40 dwinter 1759: security.declarePublic('getPNumber')
1760: def getPNumber(self):
1.46 dwinter 1761: """get the pnumber"""
1762: try:
1.49 dwinter 1763: txt=re.match("&[Pp](\d*)\s*=([^\r\n]*)",self.getData()[0:])
1.40 dwinter 1764: except:
1.49 dwinter 1765: txt=self.getData()[0:]
1.40 dwinter 1766:
1767: return "ERROR"
1768: try:
1769: return "P"+txt.group(1)
1770: except:
1771: return "ERROR"
1772:
1.12 dwinter 1773: security.declarePublic('getDesignation')
1774: def getDesignation(self):
1775: """get the designation out of the file"""
1.16 dwinter 1776: try:
1.46 dwinter 1777: txt=re.match("&[Pp](\d*)\s*=([^\r\n]*)",self.getData()[0:])
1.13 dwinter 1778: except:
1.46 dwinter 1779: txt=self.getData()[0:]
1.16 dwinter 1780:
1781: return "ERROR"
1.12 dwinter 1782: try:
1783: return txt.group(2)
1784: except:
1785: return "ERROR"
1.81 casties 1786:
1.12 dwinter 1787:
1.1 dwinter 1788: manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1')
1789:
1.81 casties 1790: def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',versionNumber=0,
1791: precondition='', content_type='',
1.48 dwinter 1792: from_tmp=False,REQUEST=None):
1.1 dwinter 1793: """Add a new File object.
1794: Creates a new File object 'id' with the contents of 'file'"""
1.48 dwinter 1795:
1.1 dwinter 1796: id=str(id)
1797: title=str(title)
1798: content_type=str(content_type)
1799: precondition=str(precondition)
1800:
1801: id, title = cookId(id, title, file)
1802:
1803: self=self.this()
1804:
1805: # First, we create the file without data:
1.81 casties 1806: self._setObject(id, CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=vC,time=time.localtime(),author=author))
1.80 casties 1807: fob = self._getOb(id)
1.45 dwinter 1808:
1.1 dwinter 1809: # Now we "upload" the data. By doing this in two steps, we
1810: # can use a database trick to make the upload more efficient.
1.48 dwinter 1811:
1812: if file and not from_tmp:
1.80 casties 1813: fob.manage_upload(file)
1.48 dwinter 1814: elif file and from_tmp:
1.81 casties 1815: fob.manage_file_upload(file) # manage_upload_from_tmp doesn't exist in ExtFile2
1816: # fob.manage_upload_from_tmp(file) # manage_upload_from_tmp doesn't exist in ExtFile2
1.1 dwinter 1817: if content_type:
1.80 casties 1818: fob.content_type=content_type
1.1 dwinter 1819:
1.81 casties 1820: #logging.debug("manage_add: lastversion=%s"%self.getData())
1821: logging.debug("reindex1: %s in %s"%(repr(self),repr(self.default_catalog)))
1.45 dwinter 1822: self.reindex_object()
1.81 casties 1823: #logging.debug("manage_add: fob_data=%s"%fob.getData())
1.80 casties 1824: logging.debug("reindex2: %s in %s"%(repr(fob), repr(fob.default_catalog)))
1.81 casties 1825: fob.index_object()
1.49 dwinter 1826:
1.85 dwinter 1827: self.CDLIRoot.updateOrAddToFileBTree(ob)
1.1 dwinter 1828: if REQUEST is not None:
1829: REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
1.3 dwinter 1830:
1.80 casties 1831:
1.46 dwinter 1832: class CDLIFile(extVersionedFile,CatalogAware):
1.3 dwinter 1833: """CDLI file"""
1834:
1.77 dwinter 1835: security=ClassSecurityInfo()
1.3 dwinter 1836: meta_type="CDLI file"
1.81 casties 1837: content_meta_type = ["CDLI File Object"]
1838:
1.3 dwinter 1839: default_catalog='CDLICatalog'
1.81 casties 1840:
1.78 dwinter 1841: security.declareProtected('manage','index_html')
1.81 casties 1842:
1.51 dwinter 1843: def getLastVersionData(self):
1844: """get last version data"""
1.81 casties 1845: return self.getData()
1.51 dwinter 1846:
1.52 dwinter 1847: def getLastVersionFormattedData(self):
1848: """get last version data"""
1.81 casties 1849: return self.getContentObject().getFormattedData()
1850:
1851: def getTextId(self):
1852: """returns P-number of text"""
1853: # assuming that its the beginning of the title
1854: return self.title[:7]
1.52 dwinter 1855:
1.51 dwinter 1856: #security.declarePublic('history')
1.26 dwinter 1857: def history(self):
1858: """history"""
1859:
1860: ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
1861: if ext:
1862: return getattr(self,ext[0][1].getId())()
1863:
1864: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','versionHistory')).__of__(self)
1865: return pt()
1866:
1867:
1.44 dwinter 1868: def getBasketFromId(self,basketid, context=None):
1869: """get basket from id"""
1870:
1871: if not context:
1872: context=self
1873:
1874: for basket in self.ZopeFind(context,obj_metatypes=["CDLIBasket"]):
1875: if basket[0]==basketid:
1876: return basket[1]
1877: else:
1878: None
1879:
1.12 dwinter 1880:
1.8 dwinter 1881: def isContainedInBaskets(self,context=None):
1882: """check is this file is part of any basket
1883: @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog
1884: has to exist.
1885: """
1886:
1887: if not context:
1888: context=self
1.12 dwinter 1889:
1890: ret=[]
1891: for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}):
1892: #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why?
1893: try:
1894: ret.append(x.getObject())
1895: except:
1896: pass
1897: return ret
1898: #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})]
1.5 dwinter 1899:
1900:
1.81 casties 1901: def _newContentObject(self, id, title='', versionNumber=0, versionComment=None, time=None, author=None):
1902: """factory for content objects. to be overridden in derived classes."""
1903: logging.debug("_newContentObject(CDLI)")
1904: return CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=versionComment,time=time,author=author)
1905:
1906:
1.5 dwinter 1907: def addCDLIFileObjectForm(self):
1908: """add a new version"""
1909:
1910: if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]:
1911: return "please login first"
1912: if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''):
1913: out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self)
1914: return out()
1915: else:
1916: return "Sorry file is locked by somebody else"
1917:
1.37 dwinter 1918: def manage_addCDLIFileObject(self,id,vC,author,
1919: file='',title='',
1920: precondition='',
1921: content_type='',
1922: changeName='no',newName='',
1.48 dwinter 1923: come_from=None,
1924: from_tmp=False,RESPONSE=None):
1.3 dwinter 1925: """add"""
1.48 dwinter 1926:
1.3 dwinter 1927: try: #TODO: der ganze vC unsinn muss ueberarbeitet werden
1928: vC=self.REQUEST['vC']
1929: except:
1930: pass
1931:
1.81 casties 1932: ob = self.addContentObject(id, vC, author, file, title, changeName=changeName, newName=newName, from_tmp=from_tmp,
1933: precondition=precondition, content_type=content_type)
1.3 dwinter 1934:
1.22 dwinter 1935: try:
1.81 casties 1936: #FIXME: wozu ist das gut?
1937: self.REQUEST.SESSION['objID_parent']=self.getId()
1.22 dwinter 1938: except:
1.81 casties 1939: pass
1.37 dwinter 1940:
1.85 dwinter 1941: #self.cdliRoot.updateOrAddToFileBTree(self)# now update the object in the cache
1942:
1943:
1.3 dwinter 1944: if RESPONSE:
1.81 casties 1945: if ob.getSize()==0:
1946: self.REQUEST.SESSION['objID']=ob.getId()
1.3 dwinter 1947: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)
1948: return pt()
1949: else:
1.37 dwinter 1950: if come_from and (come_from!=""):
1.81 casties 1951: RESPONSE.redirect(come_from+"?change="+self.getId())
1.37 dwinter 1952: else:
1953: RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title)
1.3 dwinter 1954: else:
1.81 casties 1955: return ob
1.3 dwinter 1956:
1957:
1958: def manage_addCDLIFileForm(self):
1959: """interface for adding the OSAS_root"""
1960: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self)
1961: return pt()
1962:
1963: def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None):
1964: """add the OSAS_root"""
1965: newObj=CDLIFile(id,title,lockedBy,author)
1.22 dwinter 1966:
1967: tryToggle=True
1968: tryCount=0
1969:
1970: self._setObject(id,newObj)
1.45 dwinter 1971: getattr(self,id).reindex_object()
1.22 dwinter 1972:
1.3 dwinter 1973: if RESPONSE is not None:
1974: RESPONSE.redirect('manage_main')
1975:
1.81 casties 1976:
1.69 dwinter 1977: def checkUTF8(data):
1978: """check utf 8"""
1979: try:
1980: data.encode('utf-8')
1981: return True
1982: except:
1983: return False
1984:
1.1 dwinter 1985:
1.45 dwinter 1986: def checkFile(filename,data,folder):
1987: """check the files"""
1988: # first check the file name
1989: fn=filename.split(".") # no extension
1.48 dwinter 1990:
1.45 dwinter 1991: if not fn[0][0]=="P":
1.46 dwinter 1992: return False,"P missing in the filename"
1.45 dwinter 1993: elif len(fn[0])!=7:
1.46 dwinter 1994: return False,"P number has not the right length 6"
1.69 dwinter 1995: elif not checkUTF8(data):
1996: return False,"not utf-8"
1.45 dwinter 1997: else:
1.69 dwinter 1998: return True,""
1999:
1.45 dwinter 2000:
1.25 dwinter 2001: def splitatf(fh,dir=None,ext=None):
1.2 dwinter 2002: """split it"""
1.4 dwinter 2003: ret=None
1.2 dwinter 2004: nf=None
1.25 dwinter 2005: i=0
1.49 dwinter 2006:
1.81 casties 2007: #ROC: why split \n first and then \r???
1.73 dwinter 2008: if (type(fh) is StringType) or (type(fh) is UnicodeType):
2009: iter=fh.split("\n")
2010: else:
2011: iter=fh.readlines()
2012:
2013: for lineTmp in iter:
1.66 dwinter 2014: lineTmp=lineTmp.replace(codecs.BOM_UTF8,'') # make sure that all BOM are removed..
2015: for line in lineTmp.split("\r"):
2016: #logging.log("Deal with: %s"%line)
2017: if ext:
2018: i+=1
2019: if (i%100)==0:
2020: ext.result+="."
2021: if i==10000:
2022: i=0
2023: ext.result+="<br>"
2024: #check if basket name is in the first line
2025: if line.find("#atf basket")>=0: #old convention
2026: ret=line.replace('#atf basket ','')
2027: ret=ret.split('_')[0]
2028: elif line.find("#basket:")>=0: #new convention
2029: ret=line.replace('#basket: ','')
2030: ret=ret.split('_')[0]
2031:
2032: else:
2033: if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile
2034: if nf:
2035: nf.close() #close last file
2036:
1.49 dwinter 2037:
1.66 dwinter 2038: filename=line[1:].split("=")[0].rstrip()+".atf"
2039: if dir:
2040: filename=os.path.join(dir,filename)
2041: nf=file(filename,"w")
2042: logging.info("open %s"%filename)
2043: if nf:
2044: nf.write(line.replace("\n","")+"\n")
2045:
2046: try:
2047: nf.close()
1.61 dwinter 2048: except:
1.66 dwinter 2049: pass
1.73 dwinter 2050:
2051: if not((type(fh) is StringType) or (type(fh) is UnicodeType)):
2052: fh.close()
1.5 dwinter 2053: return ret,len(os.listdir(dir))
1.4 dwinter 2054:
1.19 dwinter 2055:
1.46 dwinter 2056: class CDLIFileFolder(extVersionedFileFolder):
1.4 dwinter 2057: """CDLI File Folder"""
1.1 dwinter 2058:
1.19 dwinter 2059: security=ClassSecurityInfo()
1.1 dwinter 2060: meta_type="CDLI Folder"
1.81 casties 2061: file_meta_type=['CDLI file']
2062: folder_meta_type=['CDLI Folder']
2063:
2064: file_catalog='CDLICatalog'
2065:
1.45 dwinter 2066: #downloadCounter=0 # counts how many download for all files currently run, be mehr als 5 wird verweigert.
1.24 dwinter 2067: tmpStore2={}
1.81 casties 2068:
2069: def _newVersionedFile(self, id, title='', lockedBy=None, author=None):
2070: """factory for versioned files. to be overridden in derived classes."""
2071: logging.debug("_newVersionedFile(CDLI)")
2072: return CDLIFile(id, title, lockedBy=lockedBy, author=author)
2073:
1.19 dwinter 2074: def setTemp(self,name,value):
2075: """set tmp"""
2076:
2077: setattr(self,name,value)
2078:
1.81 casties 2079: deleteFileForm = PageTemplateFile("zpt/doDeleteFile", globals())
1.19 dwinter 2080:
1.81 casties 2081: def delete(self,ids,REQUEST=None):
2082: """delete these files"""
1.12 dwinter 2083: if type(ids) is not ListType:
2084: ids=[ids]
1.81 casties 2085:
2086: self.manage_delObjects(ids)
1.12 dwinter 2087:
1.81 casties 2088: if REQUEST is not None:
2089: return self.index_html()
2090:
2091:
1.4 dwinter 2092: def getVersionNumbersFromIds(self,ids):
2093: """get the numbers of the current versions of documents described by their ids"""
2094:
2095: ret=[]
2096: searchStr=" OR ".join(ids)
2097:
1.9 dwinter 2098: founds=self.CDLICatalog.search({'title':searchStr})
1.4 dwinter 2099:
2100: for found in founds:
1.81 casties 2101: lastVersion=found.getObject().getContentObject()
1.4 dwinter 2102: ret.append((found.getId,lastVersion))
2103:
2104: return ret
2105:
1.67 dwinter 2106: def getFile(self,fn):
2107: """get the content of the file fn"""
1.81 casties 2108: logging.debug("getFile: %s"%repr(fn))
2109: if not self.hasObject(fn):
2110: # search deeper
2111: founds=getattr(self, self.file_catalog).search({'textid':fn})
2112: if founds:
2113: obj=founds[0].getObject().getContentObject()
2114: else:
2115: return ""
1.67 dwinter 2116: else:
1.81 casties 2117: obj = self[fn].getContentObject()
1.68 dwinter 2118:
1.81 casties 2119: return obj.getData()[0:]
2120:
1.67 dwinter 2121:
1.14 dwinter 2122: def checkCatalog(self,fn):
2123: """check if fn is in the catalog"""
1.19 dwinter 2124: #TODO add checkCatalog
1.14 dwinter 2125:
1.19 dwinter 2126:
1.45 dwinter 2127: def findObjectsFromListWithVersion(self,list,author=None):
1.26 dwinter 2128: """find objects from a list with versions
2129: @param list: list of tuples (cdliFile,version)
2130: """
2131: #self.REQUEST.SESSION['fileIds']=list#store fieldIds in session for further usage
2132: #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
2133:
2134: pt=getattr(self,'filelistVersioned.html')
2135:
1.45 dwinter 2136: return pt(search=list,author=author)
1.26 dwinter 2137:
2138:
1.67 dwinter 2139: def getAllPNumbers(self):
2140: """get a list of all files (resp their p-numbers) stored"""
2141:
2142: ret=[x.getId for x in self.CDLICatalog()]
2143:
2144: return ret
2145:
1.83 dwinter 2146: def expandFile(self,fileId,fileTree):
2147: """wildcard in fileID suche alle Treffer"""
2148: founds=self.CDLICatalog({'title':fileId})
2149: for found in founds:
2150: fileTree.add(found.getId)
2151: logging.debug("ADDD:"+found.getId)
2152:
1.85 dwinter 2153: 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 2154: """findObjectsFromList (, TAB oder LINE separated)"""
1.15 dwinter 2155:
1.83 dwinter 2156: logging.debug("start: findObjectsFromList")
1.85 dwinter 2157: #logging.debug("start: findObjectsFromList"+repr(list))
2158:
2159:
1.6 dwinter 2160: if upload: # list from file upload
2161: txt=upload.read()
1.35 dwinter 2162:
2163: if enterList:
2164: txt=enterList
2165:
2166: if upload or enterList:
1.6 dwinter 2167: txt=txt.replace(",","\n")
2168: txt=txt.replace("\t","\n")
1.12 dwinter 2169: txt=txt.replace("\r","\n")
1.6 dwinter 2170: idsTmp=txt.split("\n")
2171: ids=[]
2172: for id in idsTmp: # make sure that no empty lines
2173: idTmp=id.lstrip().rstrip()
2174: if len(idTmp)>0:
2175:
2176: ids.append(idTmp)
2177:
2178: #self.REQUEST.SESSION['ids']=" OR ".join(ids)
1.12 dwinter 2179:
1.6 dwinter 2180: pt=getattr(self,'filelist.html')
1.7 dwinter 2181: self.REQUEST.SESSION['searchList']=ids
1.6 dwinter 2182: return pt(search=ids)
1.7 dwinter 2183:
1.6 dwinter 2184: if basketName:
1.7 dwinter 2185: #TODO: get rid of one of these..
2186:
1.6 dwinter 2187: pt=getattr(self,'filelist.html')
1.7 dwinter 2188: return pt(basketName=basketName,numberOfObjects=numberOfObjects)
1.6 dwinter 2189:
1.102 ! dwinter 2190:
! 2191: result =self.CDLICache.retrieve(hash)
! 2192: if result:
! 2193: logging.debug("give result from storage2")
! 2194: return hash,result
! 2195:
1.15 dwinter 2196: if list is not None: # got already a list
1.83 dwinter 2197:
2198: logging.debug(" ----List version")
1.6 dwinter 2199: ret=[]
1.83 dwinter 2200: fileTree=Set()
2201:
1.6 dwinter 2202: for fileId in list:
1.83 dwinter 2203:
2204: if fileId.find("*")>-1: #check for wildcards
2205: self.expandFile(fileId,fileTree)
2206:
1.35 dwinter 2207: elif len(fileId.split("."))==1:
1.6 dwinter 2208: fileId=fileId+".atf"
1.83 dwinter 2209: fileTree.add(fileId)
2210: #logging.debug(" -----:"+fileId)
2211: #ret+=self.CDLICatalog({'title':fileId})
2212: #x =self.getFileObject(fileId)
2213: #if x is not None:
2214: # ret.append(x)
1.35 dwinter 2215:
1.83 dwinter 2216:
2217:
2218: ids = fileTree & self.v_file_ids
1.85 dwinter 2219: #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
2220: l=makelist(fileTree)[0:]
1.93 dwinter 2221: #logging.debug("l-list:"+repr(l))
1.85 dwinter 2222: self.REQUEST.SESSION['fileIds']=l#store fieldIds in session for further usage
2223: self.REQUEST.SESSION['searchList']=l
2224: #self.REQUEST.SESSION['searchList']=['P000001.atf']
2225:
1.83 dwinter 2226:
1.85 dwinter 2227: hash = md5.new(repr(makelist(fileTree))).hexdigest() # erzeuge hash als identification
2228: self.REQUEST.SESSION['hash']=hash
2229: #TODO: do I need garbage collection for v_tmpStore ?
1.83 dwinter 2230:
1.84 dwinter 2231: #logging.debug("Hash:"+repr(hash))
1.85 dwinter 2232: #
2233: # if hasattr(self.cdliRoot,'v_tmpStore') and self.cdliRoot.v_tmpStore.has_key(hash):
2234: # logging.debug("asking for storage")
2235: # res=self.cdliRoot.v_tmpStore[hash]
2236: # if res:
2237: # if returnHash == True:
2238: # return hash,res
2239: # return res
1.83 dwinter 2240:
1.7 dwinter 2241: #TODO: get rid of one of these..
1.83 dwinter 2242: #ids=[x.getObject().getId() for x in ret]
2243: ret=[(self.getFileObject(x),self.getFileObjectLastVersion(x)) for x in ids]
1.84 dwinter 2244:
2245: #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
2246: #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
1.85 dwinter 2247:
1.25 dwinter 2248: if display:
2249: pt=getattr(self,'filelist.html')
2250:
2251: return pt(search=ids)
1.83 dwinter 2252: else:
2253: #self.REQUEST.SESSION['hash'] = ret # store in session
1.102 ! dwinter 2254:
1.83 dwinter 2255: #logging.debug("HHHHHHNEU:"+repr(self.makelist(ids)))
1.84 dwinter 2256: #logging.debug("HHHHHHNEU:"+repr(hash))
1.102 ! dwinter 2257: self.CDLICache.store(hash,ret)
! 2258:
1.85 dwinter 2259: if returnHash == True:
2260: return hash,ret
1.25 dwinter 2261: return ret
2262:
2263:
1.1 dwinter 2264:
1.7 dwinter 2265: if start:
2266: RESPONSE.redirect("filelist.html?start:int="+str(start))
1.85 dwinter 2267:
1.19 dwinter 2268: security.declareProtected('Manage','createAllFilesAsSingleFile')
1.1 dwinter 2269: def createAllFilesAsSingleFile(self,RESPONSE=None):
2270: """download all files"""
2271:
2272: def sortF(x,y):
2273: return cmp(x[0],y[0])
2274:
1.81 casties 2275: catalog=getattr(self,self.file_catalog)
1.1 dwinter 2276: #tf,tfilename=mkstemp()
1.66 dwinter 2277: if not hasattr(self.temp_folder,'downloadCounter'):
2278: self.temp_folder.downloadCounter=0
1.49 dwinter 2279:
2280: if getattr(self.temp_folder,'downloadCounter',0) > 5:
1.46 dwinter 2281: return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
1.45 dwinter 2282:
1.46 dwinter 2283: self.temp_folder.downloadCounter+=1
2284: self._p_changed=1
1.58 dwinter 2285: transaction.get().commit()
1.45 dwinter 2286:
1.1 dwinter 2287: list=[(x.getId,x) for x in catalog()]
2288: list.sort(sortF)
1.46 dwinter 2289:
1.45 dwinter 2290:
1.1 dwinter 2291:
2292: RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf")
2293: RESPONSE.setHeader("Content-Type","application/octet-stream")
1.46 dwinter 2294: tmp=""
1.1 dwinter 2295: for l in list:
2296: obj=l[1].getObject()
2297:
2298: if obj.meta_type=="CDLI file":
2299:
2300: #os.write(tf,obj.getLastVersion().data)
2301: if RESPONSE:
1.81 casties 2302: RESPONSE.write(obj.getData()[0:])
1.71 dwinter 2303: RESPONSE.write("\n")
1.46 dwinter 2304: self.temp_folder.downloadCounter-=1
2305: self._p_changed=1
1.58 dwinter 2306: transaction.get().commit()
1.1 dwinter 2307: #os.close(tf)
2308: #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename)
2309: return True
2310:
2311: def downloadFile(self,fn):
2312: """download fn - not used yet"""
2313: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId())
2314: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
2315: self.REQUEST.RESPONSE.write(file(fn).read())
2316:
2317:
2318:
2319: def hasParent(self):
2320: """returns true falls subfolder"""
2321:
1.81 casties 2322: if self.aq_parent.meta_type in self.folder_meta_type:
1.1 dwinter 2323: return True
2324: else:
2325: return False
2326:
2327: def getFolders(self):
2328: """get all subfolders"""
2329: ret=[]
1.81 casties 2330: folders=self.ZopeFind(self,obj_metatypes=self.folder_meta_type)
1.1 dwinter 2331: for folder in folders:
2332: ret.append((folder[1],
1.81 casties 2333: len(self.ZopeFind(folder[1],obj_metatypes=self.folder_meta_type)),
2334: len(self.ZopeFind(folder[1],obj_metatypes=self.file_meta_type))
1.1 dwinter 2335: ))
2336: return ret
2337:
2338:
1.77 dwinter 2339: security.declareProtected('manage','index_html')
1.1 dwinter 2340: def index_html(self):
2341: """main"""
2342: ext=self.ZopeFind(self,obj_ids=["index.html"])
2343: if ext:
2344: return ext[0][1]()
2345:
2346: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self)
2347: return pt()
2348:
1.22 dwinter 2349:
2350: manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals())
2351:
2352:
2353: def manage_addCDLIFileFolder(self, id, title='',
2354: createPublic=0,
2355: createUserF=0,
2356: REQUEST=None):
2357: """Add a new Folder object with id *id*.
2358:
2359: If the 'createPublic' and 'createUserF' parameters are set to any true
2360: value, an 'index_html' and a 'UserFolder' objects are created respectively
2361: in the new folder.
2362: """
2363: ob=CDLIFileFolder()
2364: ob.id=str(id)
2365: ob.title=title
2366: self._setObject(id, ob)
2367: ob=self._getOb(id)
2368:
2369: checkPermission=getSecurityManager().checkPermission
2370:
2371: if createUserF:
2372: if not checkPermission('Add User Folders', ob):
2373: raise Unauthorized, (
2374: 'You are not authorized to add User Folders.'
2375: )
2376: ob.manage_addUserFolder()
2377:
2378:
2379: if REQUEST is not None:
2380: return self.manage_main(self, REQUEST, update_menu=1)
2381:
2382: class CDLIRoot(Folder):
2383: """main folder for cdli"""
2384:
2385: meta_type="CDLIRoot"
1.81 casties 2386: downloadCounterBaskets=0 # counts the current basket downloads if counter > 10 no downloads are possible
2387:
2388: file_catalog = 'CDLICatalog'
2389:
2390: # word splitter for search
2391: splitter = {'words':cdliSplitter.wordSplitter(),
2392: 'graphemes':cdliSplitter.graphemeSplitter()}
2393:
1.51 dwinter 2394:
1.102 ! dwinter 2395: def unicodify(self,txt):
! 2396: return unicodify(txt)
! 2397: def invalidateOldCacheVersion(self):
! 2398: """loescht die alte Version des Cache"""
! 2399: del self.v_tmpStore
! 2400: return "done"
! 2401:
1.86 dwinter 2402: def viewATF(self,id,RESPONSE):
2403: """view an Object"""
2404: ob = self.CDLICatalog({'title':id})
2405: logging.debug(ob[0].getObject().getLastVersion().absolute_url()+"/view")
2406: if len(ob)>0:
2407: RESPONSE.redirect(ob[0].getObject().getLastVersion().absolute_url()+"/view")
2408: return "not found"
2409:
2410: def history(self,id,RESPONSE):
2411: """view an Object"""
2412: ob = self.CDLICatalog({'title':id})
2413: if len(ob)>0:
2414: RESPONSE.redirect(ob[0].absolute_url+"/history")
2415: return "not found"
2416:
2417:
2418: def downloadLocked(self,id,RESPONSE):
2419: """view an Object"""
2420: ob = self.CDLICatalog({'title':id})
2421: if len(ob)>0:
2422: RESPONSE.redirect(ob[0].absolute_url+"/downloadLocked")
2423: return "not found"
2424:
2425: def download(self,id,RESPONSE):
2426: """view an Object"""
2427: ob = self.CDLICatalog({'title':id})
2428: if len(ob)>0:
2429: RESPONSE.redirect(ob[0].getLastVersion().absolute_url())
2430: return "not found"
2431: def addCDLIFileObjectForm(self,id,RESPONSE):
2432: """view an Object"""
2433: ob = self.CDLICatalog({'title':id})
2434: if len(ob)>0:
2435: RESPONSE.redirect(ob[0].absolute_url+"/addCDLIFileObjectForm")
2436: return "not found"
2437:
2438: def addVersionedFileObjectForm(self,id,RESPONSE):
2439: """view an Object"""
2440: ob = self.CDLICatalog({'title':id})
2441: if len(ob)>0:
2442: RESPONSE.redirect(ob[0].absolute_url+"/addVersionedFileObjectForm")
2443: return "not found"
2444:
2445: def unlock(self,id,RESPONSE):
2446: """view an Object"""
2447: ob = self.CDLICatalog({'title':id})
2448: if len(ob)>0:
2449: RESPONSE.redirect(ob[0].absolute_url+"/unlock")
2450: return "not found"
2451:
1.83 dwinter 2452: def getFileObject(self,fileId):
1.85 dwinter 2453: """get an object"""
1.83 dwinter 2454: x=self.v_files.get(fileId)
2455: #logging.debug(x)
2456: return x
2457:
2458: def getFileObjectLastVersion(self,fileId):
1.85 dwinter 2459: """get an object"""
1.83 dwinter 2460: x=self.v_files_lastVersion.get(fileId)
1.95 dwinter 2461: #logging.debug("lastVersion: "+repr(x))
1.83 dwinter 2462: return x
2463:
1.85 dwinter 2464: def showFileIds(self):
2465: """showIds"""
2466: return self.v_file_ids
2467:
1.83 dwinter 2468: def generateFileBTree(self):
2469: """erzeuge einen Btree aus allen Files"""
2470: self.v_files = OOBTree()
2471: self.v_files_lastVersion = OOBTree()
2472: self.v_file_ids = Set()
2473:
2474: for x in self.CDLICatalog.searchResults():
2475:
2476: self.v_files.update({x.getId:x.getObject()})
2477: self.v_files_lastVersion.update({x.getId:x.getObject().getLastVersion()})
2478: self.v_file_ids.add(x.getId)
2479: logging.debug("add:"+x.getId+"XXX"+repr(x.getObject()))
2480:
1.85 dwinter 2481: return True
2482:
2483:
2484: def updateOrAddToFileBTree(self,obj):
2485: """update a BTree"""
2486: self.v_files.update({obj.getId():obj})
2487: self.v_files_lastVersion.update({obj.getId():obj.getLastVersion()})
2488:
2489: self.v_file_ids.add(obj.getId())
2490: logging.debug("update:"+obj.getId()+"XXX"+repr(obj))
2491:
2492: def deleteFromBTree(self,objId):
2493: """delete an obj"""
2494: self.v_files.pop(objId)
2495: self.v_files_lastVersion.pop(objId)
2496: self.v_file_ids.remove(objId)
2497:
2498:
2499:
1.73 dwinter 2500: def deleteFiles(self,ids):
1.81 casties 2501: """delete files"""
1.73 dwinter 2502: for id in ids:
2503: founds=self.CDLICatalog.search({'title':id.split(".")[0]})
2504: if founds:
1.81 casties 2505: logging.debug("deleting %s"%founds)
1.73 dwinter 2506: folder=founds[0].getObject().aq_parent #get the parent folder of the object
1.81 casties 2507: logging.debug("deleting from %s"%folder)
2508: cut=folder.delete([founds[0].getId]) #cut it out
2509:
1.73 dwinter 2510:
2511:
1.81 casties 2512: def searchText(self, query, index='graphemes'):
2513: """searches query in the fulltext index and returns a list of file ids/P-numbers"""
2514: # see also: http://www.plope.com/Books/2_7Edition/SearchingZCatalog.stx#2-13
2515: logging.debug("searchtext for '%s' in index %s"%(query,index))
2516: #import Products.ZCTextIndex.QueryParser
2517: #qp = QueryParser.QueryParser()
2518: #logging.debug()
2519: idxQuery = {index:{'query':query}}
2520: idx = getattr(self, self.file_catalog)
2521: # do search
2522: resultset = idx.search(query_request=idxQuery,sort_index='textid')
2523: # put only the P-Number in the result
2524: results = [res.getId[:7] for res in resultset]
2525: logging.debug("searchtext: found %d texts"%len(results))
2526: return results
2527:
2528:
2529: def getFile(self, pnum):
2530: """get the translit file with the given pnum"""
2531: f = getattr(self, self.file_catalog).search({'textid':pnum})
2532: if not f:
2533: return ""
1.71 dwinter 2534:
1.81 casties 2535: return f[0].getObject().getData()
2536:
1.57 dwinter 2537:
1.74 dwinter 2538: def showFile(self,fileId,wholePage=False):
1.71 dwinter 2539: """show a file
2540: @param fileId: P-Number of the document to be displayed
2541: """
1.81 casties 2542: f=getattr(self, self.file_catalog).search({'textid':fileId})
1.51 dwinter 2543: if not f:
2544: return ""
2545:
1.74 dwinter 2546: if wholePage:
1.81 casties 2547: logging.debug("show whole page")
2548: return f[0].getObject().getContentObject().view()
1.74 dwinter 2549: else:
2550: return f[0].getObject().getLastVersionFormattedData()
1.55 dwinter 2551:
1.56 dwinter 2552:
1.81 casties 2553: def showWordInFile(self,fileId,word,indexName='graphemes',regExp=False,):
2554: """get lines with word from FileId"""
2555: logging.debug("showwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId))
1.56 dwinter 2556:
1.81 casties 2557: file = formatAtfFullLineNum(self.getFile(fileId))
1.66 dwinter 2558: ret=[]
1.71 dwinter 2559:
1.81 casties 2560: # add whitespace before and whitespace and line-end to splitter bounds expressions
2561: bounds = self.splitter[indexName].bounds
2562: splitexp = "(%s|\s)(%%s)(%s|\s|\Z)"%(bounds,bounds)
2563: # clean word expression
2564: # TODO: this should use QueryParser itself
2565: # take out double quotes
2566: word = word.replace('"','')
2567: # take out ignorable signs
2568: ignorable = self.splitter[indexName].ignorex
2569: word = ignorable.sub('', word)
2570: # compile into regexp objects and escape parens
2571: wordlist = [re.compile(splitexp%re.escape(w)) for w in word.split(' ')]
2572:
2573: for line in file.splitlines():
1.71 dwinter 2574: for word in wordlist:
1.81 casties 2575: #logging.debug("showwordinfile: searching for %s in %s"%(word.pattern,ignoreable.sub('',line)))
2576: if word.search(ignorable.sub('',line)):
2577: line = formatAtfLineHtml(line)
2578: ret.append(line)
2579: break
2580:
1.66 dwinter 2581: return ret
1.56 dwinter 2582:
1.81 casties 2583:
2584: def showWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
2585: """
2586: get lines with word from all ids in list FileIds.
2587: returns dict with id:lines pairs.
2588: """
2589: logging.debug("showwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds))
1.51 dwinter 2590:
1.81 casties 2591: return dict([(id,self.showWordInFile(id, word, indexName, regExp)) for id in fileIds])
2592:
2593:
2594: def tagWordInFile(self,fileId,word,indexName='graphemes',regExp=False):
2595: """get text with word highlighted from FileId"""
2596: logging.debug("tagwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId))
2597:
2598: file=self.getFile(fileId)
2599: tagStart=u'<span class="found">'
2600: tagEnd=u'</span>'
2601: tagStr=tagStart + u'%%s' + tagEnd
1.66 dwinter 2602: ret=[]
1.71 dwinter 2603:
1.81 casties 2604: # add whitespace to splitter bounds expressions and compile into regexp object
2605: bounds = self.splitter[indexName].bounds
2606: wordsplit = re.compile("(%s|\s)"%bounds)
2607: # clean word expression
2608: # TODO: this should use QueryParser itself
2609: word = word.replace('"','') # take out double quotes
2610: # take out ignoreable signs
2611: ignorable = self.splitter[indexName].ignorex
2612: word = ignorable.sub('', word)
2613: # split search terms by blanks
2614: words = word.split(' ')
2615: # split search terms again (for grapheme search with words)
2616: splitwords = dict(((w,self.splitter[indexName].process([w])) for w in words))
1.71 dwinter 2617:
1.81 casties 2618: for line in file.splitlines():
1.79 casties 2619: line = unicodify(line)
1.81 casties 2620: # ignore lemma and other lines
2621: if line.lstrip().startswith('#lem:'):
2622: continue
2623: # ignore p-num line
2624: if line.startswith('&P'):
2625: continue
2626: # ignore version lines
2627: if line.startswith('#version'):
2628: continue
2629: # ignore atf type lines
2630: if line.startswith('#atf:'):
2631: continue
2632:
2633: # first scan
2634: hitwords = []
2635: for w in words:
2636: if ignorable.sub('',line).find(w) > -1:
2637: # word is in line
2638: # append split word for grapheme search with words
2639: hitwords.extend(splitwords[w])
2640: #hitwords.extend(wordsplit.split(w))
2641:
2642: # examine hits closer
2643: if hitwords:
2644: # split line into words
2645: parts = wordsplit.split(line)
2646: line = ""
2647: for p in parts:
2648: #logging.debug("tagwordinfile: searching for %s in %s"%(p,hitwords))
2649: # reassemble line
2650: if ignorable.sub('', p) in hitwords:
2651: #logging.debug("tagwordinfile: found %s in %s"%(p,hitwords))
2652: # this part was found
2653: line += tagStart + formatAtfHtml(p) + tagEnd
2654: else:
2655: line += formatAtfHtml(p)
2656:
2657: else:
2658: # no hits
2659: line = formatAtfHtml(line)
2660:
2661: ret.append(line)
2662:
2663: return u'<br>\n'.join(ret)
2664:
1.66 dwinter 2665:
2666:
1.81 casties 2667: def tagWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
2668: """
2669: get texts with highlighted word from all ids in list FileIds.
2670: returns dict with id:text pairs.
2671: """
2672: logging.debug("tagwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds))
2673: return dict([(id,self.tagWordInFile(id, word, indexName, regExp)) for id in fileIds])
2674:
1.56 dwinter 2675:
1.82 casties 2676: def getFileVersionList(self, pnum):
2677: """get the version history as a list for the translit file with the given pnum"""
2678: f = getattr(self, self.file_catalog).search({'textid':pnum})
2679: if not f:
2680: return []
2681:
2682: return f[0].getObject().getVersionList()
2683:
2684:
1.37 dwinter 2685: def URLquote(self,str):
2686: """quote url"""
2687: return urllib.quote(str)
2688:
2689: def URLunquote(self,str):
2690: """unquote url"""
2691: return urllib.unquote(str)
2692:
1.58 dwinter 2693: def URLquote_plus(self,str):
2694: """quote url"""
2695: return urllib.quote_plus(str)
2696:
2697: def URLunquote_plus(self,str):
2698: """unquote url"""
2699: return urllib.unquote_plus(str)
2700:
1.37 dwinter 2701:
1.26 dwinter 2702: def forceunlock(self):
2703: "break all locks"
2704: ret=[]
2705: for f in self.ZopeFind(self,obj_metatypes="CDLI file",search_sub=1):
2706: un=f[1].forceunlock()
1.39 dwinter 2707:
1.26 dwinter 2708: if un and un !="":
2709: ret.append((f[0],un))
1.46 dwinter 2710:
1.61 dwinter 2711: return ret
1.71 dwinter 2712:
1.61 dwinter 2713:
1.26 dwinter 2714: def getChangesByAuthor(self,author,n=100):
1.25 dwinter 2715: """getChangesByAuthor"""
1.26 dwinter 2716: zcat=self.CDLIObjectsCatalog
2717: res=zcat({'lastEditor':author,
1.25 dwinter 2718: 'sort_on':'getTime',
2719: 'sort_order':'descending',
2720: 'sort_limit':n})[:n ]
1.26 dwinter 2721:
2722: return res
2723:
2724: def getChangesByAuthor_html(self,author,n=100):
2725: """html output for changes by author"""
2726: tmp={}
2727: list=[]
2728: for x in self.getChangesByAuthor(author):
2729: nr=x.getObject().getVersionNumber()
2730: id=x.getObject().aq_parent.getId()
2731: #hinzufuegen, wenn Version neuer als die
2732: if tmp.get(id,(0,0))[1] < nr:
2733: tmp[id]=(x.getObject().aq_parent,nr)
2734:
2735:
1.45 dwinter 2736: return self.cdli_main.findObjectsFromListWithVersion(list=tmp.values(),author=author)
1.26 dwinter 2737:
1.25 dwinter 2738: def getLastChanges(self,n=100):
2739: """get the last n changes"""
2740: n=int(n)
2741: zcat=self.CDLICatalog
2742: return zcat({'sort_on':'getLastChangeDate',
2743: 'sort_order':'descending',
2744: 'sort_limit':n})[:n ]
2745:
2746:
2747: def getLastChanges_html(self,n=100):
2748: """get the last n changes"""
2749: list = [x.getId for x in self.getLastChanges(n)]
2750: return self.cdli_main.findObjectsFromList(list=list,display=True)
2751:
1.24 dwinter 2752: def refreshTxt(self,txt="",threadName=None):
1.22 dwinter 2753: """txt fuer refresh"""
2754:
1.24 dwinter 2755: return """ 2;url=%s?repeat=%s """%(self.absolute_url()+txt,threadName)
1.22 dwinter 2756:
1.87 dwinter 2757: def refreshTxtBasket(self,txt="",threadName=None):
2758: """txt fuer refresh"""
2759:
2760: return """ 2;url=%s?repeat=%s """%(txt,threadName)
2761:
1.22 dwinter 2762:
1.24 dwinter 2763: def getResult(self,threadName=None):
1.22 dwinter 2764: """result of thread"""
2765: try:
1.24 dwinter 2766: return self._v_uploadATF[threadName].getResult()
1.22 dwinter 2767: except:
2768: return "One moment, please"
2769:
1.24 dwinter 2770:
2771: def checkThreads(self):
2772: """check threads"""
1.42 dwinter 2773: ret="<html><body>"
2774: for thread in threading.enumerate():
1.45 dwinter 2775: ret+="<p>%s (%s): %s</p>"%(repr(thread),thread.getName(),thread.isAlive())
1.42 dwinter 2776:
2777: return ret
2778:
2779:
1.73 dwinter 2780: def uploadATFRPC(self,data,username):
2781: """upload an atffile via xml-rpc"""
2782: uploader=uploadATFThread()
2783:
2784: #generate an random id for the upload object
2785: from random import randint
2786: if (not self.REQUEST.SESSION.get('idTmp',None)):
2787:
2788: idTmp=str(randint(0,1000000000))
2789: self.REQUEST.SESSION['idTmp']=idTmp
2790: else:
2791: idTmp=self.REQUEST.SESSION.get('idTmp',None)
2792:
2793:
2794: uploader.set(data,0,username,idTmp)
2795:
2796: stObj=uploader.run()
2797:
2798: processor=uploadATFfinallyThread()
2799:
2800: basketname=stObj.returnValue['basketNameFromFile']
2801:
2802: processor.set("uploadchanged",basketname=basketname,SESSION=stObj.returnValue,username=username,serverport=self.REQUEST['SERVER_PORT'])
2803:
2804: processor.run()
2805:
2806:
2807: return generateXMLReturn(stObj.returnValue)
2808:
1.22 dwinter 2809: def uploadATF(self,repeat=None,upload=None,basketId=0,RESPONSE=None):
1.69 dwinter 2810: """upload an atf file / basket file"""
1.22 dwinter 2811: #self._v_uploadATF.returnValue=None
1.71 dwinter 2812:
2813: #generate an random id for the upload thread
1.60 dwinter 2814: from random import randint
1.61 dwinter 2815: if (not self.REQUEST.SESSION.get('idTmp',None)):
1.22 dwinter 2816:
1.60 dwinter 2817: idTmp=str(randint(0,1000000000))
2818: self.REQUEST.SESSION['idTmp']=idTmp
2819: else:
2820: idTmp=self.REQUEST.SESSION.get('idTmp',None)
2821:
1.71 dwinter 2822:
1.22 dwinter 2823: threadName=repeat
2824: if not threadName or threadName=="":
1.71 dwinter 2825: #new thread not called from the waiting page
1.22 dwinter 2826: tmpVar=False
1.24 dwinter 2827:
1.22 dwinter 2828: thread=uploadATFThread()
1.24 dwinter 2829: threadName=thread.getName()[0:]
1.36 dwinter 2830: if (not hasattr(self,'_v_uploadATF')):
1.24 dwinter 2831: self._v_uploadATF={}
2832:
2833: self._v_uploadATF[threadName]=thread
1.22 dwinter 2834: #self._xmltrans.start()
2835: #thread=Thread(target=self._v_uploadATF)
1.60 dwinter 2836: logging.info("set thread. extern")
2837: self._v_uploadATF[threadName].set(upload,basketId,self.REQUEST['AUTHENTICATED_USER'],idTmp,serverport=self.REQUEST['SERVER_PORT'])
1.22 dwinter 2838: #thread.start()
1.60 dwinter 2839: logging.info("start thread. extern")
1.24 dwinter 2840: self._v_uploadATF[threadName].start()
1.22 dwinter 2841:
2842:
1.24 dwinter 2843: self.threadName=self._v_uploadATF[threadName].getName()[0:]
1.22 dwinter 2844: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2845:
2846: if wait_template:
2847: return wait_template[0][1]()
2848: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1.24 dwinter 2849: return pt(txt='/uploadATF',threadName=threadName)
1.22 dwinter 2850: #_v_xmltrans.run()
2851:
2852: else:
2853: #recover thread, if lost
1.36 dwinter 2854: if (not hasattr(self,'_v_uploadATF')):
1.24 dwinter 2855: self._v_uploadATF={}
2856: if not self._v_uploadATF.get(threadName,None):
1.22 dwinter 2857: for thread in threading.enumerate():
2858: if threadName == thread.getName():
1.24 dwinter 2859: self._v_uploadATF[threadName]=thread
2860:
1.60 dwinter 2861: if self._v_uploadATF.get(threadName,None) and (not self._v_uploadATF[threadName].returnValue):
1.22 dwinter 2862:
2863:
2864: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2865: if wait_template:
2866: return wait_template[0][1]()
2867:
2868: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
2869:
1.24 dwinter 2870: return pt(txt='/uploadATF',threadName=threadName)
1.22 dwinter 2871:
2872: else:
1.60 dwinter 2873: tmp=getattr(self.temp_folder,idTmp).returnValue
1.71 dwinter 2874:
1.22 dwinter 2875: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
1.39 dwinter 2876:
1.47 dwinter 2877: 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 2878: basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
1.30 dwinter 2879:
2880: def redoUpload(self,threadName):
2881: """redo the upload"""
2882: tmp=self.cdli_main.tmpStore2[threadName]
2883: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
1.45 dwinter 2884: 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 2885: basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
2886:
1.22 dwinter 2887: def uploadATFfinally(self,procedure='',comment="",basketname='',unlock=None,repeat=None,RESPONSE=None):
2888: """nowupload the files"""
2889:
2890:
2891:
2892: threadName=repeat
2893: if not threadName or threadName=="":
1.24 dwinter 2894: thread=uploadATFfinallyThread()
2895: threadName=thread.getName()[0:]
1.36 dwinter 2896:
1.35 dwinter 2897: if (not hasattr(self,'_v_uploadATF')):
1.46 dwinter 2898: self._v_uploadATF={}
1.36 dwinter 2899:
1.43 dwinter 2900:
1.24 dwinter 2901: self._v_uploadATF[threadName]=thread
1.22 dwinter 2902:
1.60 dwinter 2903: idTmp=self.REQUEST.SESSION['idTmp']
2904: stObj=getattr(self.temp_folder,idTmp)
2905: 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 2906:
1.24 dwinter 2907: self._v_uploadATF[threadName].start()
1.22 dwinter 2908:
2909:
1.24 dwinter 2910:
1.22 dwinter 2911: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2912:
2913: if wait_template:
2914: return wait_template[0][1]()
2915: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
2916:
1.24 dwinter 2917: return pt(txt='/uploadATFfinally',threadName=threadName)
1.22 dwinter 2918: #_v_xmltrans.run()
2919:
2920: else:
2921: #recover thread, if lost
2922: if not hasattr(self,'_v_uploadATF'):
1.24 dwinter 2923: self._v_uploadATF={}
2924: if not self._v_uploadATF.get(threadName,None):
1.22 dwinter 2925: for thread in threading.enumerate():
2926: if threadName == thread.getName():
1.24 dwinter 2927: self._v_uploadATF[threadName]=thread
1.22 dwinter 2928:
1.24 dwinter 2929: 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 2930:
2931: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
2932: if wait_template:
2933: return wait_template[0][1]()
2934:
2935: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1.24 dwinter 2936: return pt(txt='/uploadATFfinally',threadName=threadName)
1.22 dwinter 2937: else:
1.85 dwinter 2938:
2939:
2940: idTmp=self.REQUEST.SESSION['idTmp']
2941: stObj=getattr(self.temp_folder,idTmp)
1.60 dwinter 2942: self.REQUEST.SESSION['idTmp']=None
1.85 dwinter 2943:
2944: #update changed
2945: logging.debug("dir:"+repr(stObj.returnValue['changed']))
2946: for x in stObj.returnValue['changed']:
2947: ob=self.CDLICatalog.search({'title':x[0]})
2948:
2949: self.cdliRoot.updateOrAddToFileBTree(ob[0].getObject())
1.22 dwinter 2950: if RESPONSE is not None:
2951: RESPONSE.redirect(self.absolute_url())
2952:
1.49 dwinter 2953: def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/atf", files=None,ext=None):
1.1 dwinter 2954: """import files"""
1.81 casties 2955: logging.debug("importFiles folderName=%s files=%s ext=%s"%(folderName,files,ext))
1.22 dwinter 2956: root=self.cdli_main
1.49 dwinter 2957: count=0
1.3 dwinter 2958: if not files:
2959: files=os.listdir(folderName)
2960:
1.1 dwinter 2961: for f in files:
2962: folder=f[0:3]
2963: f2=f[0:5]
1.85 dwinter 2964:
2965: #check if main folder PXX already exists
1.22 dwinter 2966: obj=self.ZopeFind(root,obj_ids=[folder])
1.81 casties 2967: logging.debug("importFiles: folder=%s f2=%s obj=%s"%(folder,f2,obj))
1.19 dwinter 2968: if ext:
1.65 dwinter 2969: ext.result="<p>adding: %s </p>"%f+ext.result
1.81 casties 2970:
1.85 dwinter 2971:
2972: if not obj: # if not create it
1.22 dwinter 2973: manage_addCDLIFileFolder(root,folder,folder)
2974: fobj=getattr(root,folder)
1.58 dwinter 2975: #transaction.get().commit()
1.81 casties 2976:
1.1 dwinter 2977: else:
2978: fobj=obj[0][1]
2979:
1.85 dwinter 2980: #check IF PYYYYY already exist
1.1 dwinter 2981: obj2=fobj.ZopeFind(fobj,obj_ids=[f2])
1.81 casties 2982: logging.debug("importFiles: fobj=%s obj2=%s"%(fobj,obj2))
1.1 dwinter 2983:
1.85 dwinter 2984: if not obj2:# if not create it
1.1 dwinter 2985: manage_addCDLIFileFolder(fobj,f2,f2)
2986: fobj2=getattr(fobj,f2)
2987:
2988: else:
2989: fobj2=obj2[0][1]
2990:
1.85 dwinter 2991: # not add the file
1.48 dwinter 2992: file2=os.path.join(folderName,f)
1.1 dwinter 2993: id=f
1.81 casties 2994: logging.debug("importFiles: addCDLIFile fobj2=%s, f=%s file2=%s"%(fobj2,repr(f),repr(file2)))
2995: fobj2.addFile(vC='',file=file(file2),author=author,newName=f)
1.66 dwinter 2996: count+=1
1.85 dwinter 2997:
2998: #now add the file to the storage
2999: ob = getattr(fobj2,f)
3000: self.cdliRoot.updateOrAddToFileBTree(ob)
3001:
1.81 casties 3002: if count%100==0:
3003: logging.debug("importfiles: committing")
1.66 dwinter 3004: transaction.get().commit()
1.81 casties 3005:
3006: transaction.get().commit()
1.3 dwinter 3007: return "ok"
1.22 dwinter 3008:
3009:
3010: manage_addCDLIRootForm=DTMLFile('dtml/rootAdd', globals())
1.1 dwinter 3011:
3012:
1.22 dwinter 3013: def manage_addCDLIRoot(self, id, title='',
1.1 dwinter 3014: createPublic=0,
3015: createUserF=0,
3016: REQUEST=None):
3017: """Add a new Folder object with id *id*.
3018:
3019: If the 'createPublic' and 'createUserF' parameters are set to any true
3020: value, an 'index_html' and a 'UserFolder' objects are created respectively
3021: in the new folder.
3022: """
1.22 dwinter 3023: ob=CDLIRoot()
1.1 dwinter 3024: ob.id=str(id)
3025: ob.title=title
1.61 dwinter 3026: try:
1.66 dwinter 3027: self._setObject(id, ob)
1.61 dwinter 3028: except:
1.66 dwinter 3029: pass
1.1 dwinter 3030: ob=self._getOb(id)
3031:
3032: checkPermission=getSecurityManager().checkPermission
3033:
3034: if createUserF:
3035: if not checkPermission('Add User Folders', ob):
3036: raise Unauthorized, (
3037: 'You are not authorized to add User Folders.'
3038: )
3039: ob.manage_addUserFolder()
3040:
3041:
3042: if REQUEST is not None:
1.22 dwinter 3043: return self.manage_main(self, REQUEST, update_menu=1)
3044:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>