1: """CDLI extensions of the filearchive"""
2: from Products.versionedFile.extVersionedFile import *
3: from Products.ZCatalog.CatalogPathAwareness import CatalogAware
4: import os.path
5: import os
6: import urlparse
7: import urllib
8: import cgi
9: from OFS.OrderedFolder import OrderedFolder
10: from OFS.SimpleItem import SimpleItem
11: import time
12: from OFS.Folder import manage_addFolder
13: import re
14: from AccessControl import ClassSecurityInfo
15: from Acquisition import Implicit
16: from Globals import Persistent
17: from threading import Thread
18: from ZPublisher.HTTPRequest import HTTPRequest
19: from ZPublisher.HTTPResponse import HTTPResponse
20: from ZPublisher.BaseRequest import RequestContainer
21: import threading
22: import logging
23: import transaction
24: import copy
25: import codecs
26: import sys
27: from BTrees.IOBTree import IOBTree
28: import cdliSplitter
29: from sets import Set
30: import md5
31: from DownloadBasket import DownloadBasketFinallyThread
32: from types import *
33: import pickle
34: import tempfile
35:
36: from cdli_helpers import *
37:
38: class CDLIFileObject(CatalogAware,extVersionedFileObject):
39: """CDLI file object"""
40:
41: meta_type="CDLI File Object"
42: default_catalog='CDLIObjectsCatalog'
43:
44: security=ClassSecurityInfo()
45:
46: security.declareProtected('manage','index_html')
47:
48: security.declarePublic('view')
49: view = PageTemplateFile('zpt/viewCDLIFile.zpt', globals())
50:
51: security.declarePublic('editATF')
52: editATF = PageTemplateFile('zpt/editATFFile.zpt', globals())
53:
54: def PrincipiaSearchSource(self):
55: """Return cataloguable key for ourselves."""
56: return str(self)
57:
58: def setAuthor(self, author):
59: """change the author"""
60: self.author = author
61:
62: def makeThisVersionCurrent_html(self):
63: """form for mthis version current"""
64:
65: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','makeThisVersionCurrent.zpt')).__of__(self)
66: return pt()
67:
68: security.declarePublic('makeThisVersionCurrent')
69: def makeThisVersionCurrent(self,comment,author,RESPONSE=None):
70: """copy this version to current"""
71: parent=self.aq_parent
72: parent.manage_addVersionedFileObject(id=None,vC=comment,author=author,file=self.getData(),RESPONSE=RESPONSE)
73: #newversion=parent.manage_addCDLIFileObject('',comment,author)
74: #newversion.manage_upload(self.getData())
75:
76: #if RESPONSE is not None:
77: # RESPONSE.redirect(self.aq_parent.absolute_url()+'/history')
78:
79: return True
80:
81: def getFormattedData(self):
82: """fromat text"""
83: data=self.getData()
84: # return re.sub("\s\#lem"," #lem",data) #remove return vor #lem
85: return re.sub("#lem"," #lem",data) #remove return vor #lem
86:
87:
88: security.declarePublic('getPNumber')
89: def getPNumber(self):
90: """get the pnumber"""
91: try:
92: txt=re.match("&[Pp](\d*)\s*=([^\r\n]*)",self.getData()[0:])
93: except:
94: txt=self.getData()[0:]
95:
96: return "ERROR"
97: try:
98: return "P"+txt.group(1)
99: except:
100: return "ERROR"
101:
102: security.declarePublic('getDesignation')
103: def getDesignation(self):
104: """get the designation out of the file"""
105: try:
106: txt=re.match("&[Pp](\d*)\s*=([^\r\n]*)",self.getData()[0:])
107: except:
108: txt=self.getData()[0:]
109:
110: return "ERROR"
111: try:
112: return txt.group(2)
113: except:
114: return "ERROR"
115:
116:
117: manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1')
118:
119: def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',versionNumber=0,
120: precondition='', content_type='',
121: from_tmp=False,REQUEST=None):
122: """Add a new File object.
123: Creates a new File object 'id' with the contents of 'file'"""
124:
125: id=str(id)
126: title=str(title)
127: content_type=str(content_type)
128: precondition=str(precondition)
129:
130: id, title = cookId(id, title, file)
131:
132: self=self.this()
133:
134: # First, we create the file without data:
135: self._setObject(id, CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=vC,time=time.localtime(),author=author))
136: fob = self._getOb(id)
137:
138: # Now we "upload" the data. By doing this in two steps, we
139: # can use a database trick to make the upload more efficient.
140:
141: if file and not from_tmp:
142: fob.manage_upload(file)
143: elif file and from_tmp:
144: fob.manage_file_upload(file) # manage_upload_from_tmp doesn't exist in ExtFile2
145: # fob.manage_upload_from_tmp(file) # manage_upload_from_tmp doesn't exist in ExtFile2
146: if content_type:
147: fob.content_type=content_type
148:
149: #logging.debug("manage_add: lastversion=%s"%self.getData())
150: logging.debug("reindex1: %s in %s"%(repr(self),repr(self.default_catalog)))
151: self.reindex_object()
152: #logging.debug("manage_add: fob_data=%s"%fob.getData())
153: logging.debug("reindex2: %s in %s"%(repr(fob), repr(fob.default_catalog)))
154: fob.index_object()
155:
156: self.CDLIRoot.updateOrAddToFileBTree(ob)
157: if REQUEST is not None:
158: REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main')
159:
160:
161: class CDLIFile(extVersionedFile,CatalogAware):
162: """CDLI file"""
163:
164: security=ClassSecurityInfo()
165: meta_type="CDLI file"
166: content_meta_type = ["CDLI File Object"]
167:
168: default_catalog='CDLICatalog'
169:
170: security.declareProtected('manage','index_html')
171:
172: def getLastVersionData(self):
173: """get last version data"""
174: return self.getData()
175:
176: def getLastVersionFormattedData(self):
177: """get last version data"""
178: return self.getContentObject().getFormattedData()
179:
180: def getTextId(self):
181: """returns P-number of text"""
182: # assuming that its the beginning of the title
183: return self.title[:7]
184:
185: #security.declarePublic('history')
186: def history(self):
187: """history"""
188:
189: ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"])
190: if ext:
191: return getattr(self,ext[0][1].getId())()
192:
193: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','versionHistory')).__of__(self)
194: return pt()
195:
196:
197: def getBasketFromId(self,basketid, context=None):
198: """get basket from id"""
199:
200: if not context:
201: context=self
202:
203: for basket in self.ZopeFind(context,obj_metatypes=["CDLIBasket"]):
204: if basket[0]==basketid:
205: return basket[1]
206: else:
207: None
208:
209:
210: def isContainedInBaskets(self,context=None):
211: """check is this file is part of any basket
212: @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog
213: has to exist.
214: """
215:
216: if not context:
217: context=self
218:
219: ret=[]
220: for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}):
221: #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why?
222: try:
223: ret.append(x.getObject())
224: except:
225: pass
226: return ret
227: #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})]
228:
229:
230: def _newContentObject(self, id, title='', versionNumber=0, versionComment=None, time=None, author=None):
231: """factory for content objects. to be overridden in derived classes."""
232: logging.debug("_newContentObject(CDLI)")
233: return CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=versionComment,time=time,author=author)
234:
235:
236: def addCDLIFileObjectForm(self):
237: """add a new version"""
238:
239: if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]:
240: return "please login first"
241: if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''):
242: out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self)
243: return out()
244: else:
245: return "Sorry file is locked by somebody else"
246:
247: def manage_addCDLIFileObject(self,id,vC,author,
248: file='',title='',
249: precondition='',
250: content_type='',
251: changeName='no',newName='',
252: come_from=None,
253: from_tmp=False,RESPONSE=None):
254: """add"""
255:
256: try: #TODO: der ganze vC unsinn muss ueberarbeitet werden
257: vC=self.REQUEST['vC']
258: except:
259: pass
260:
261: ob = self.addContentObject(id, vC, author, file, title, changeName=changeName, newName=newName, from_tmp=from_tmp,
262: precondition=precondition, content_type=content_type)
263:
264: try:
265: #FIXME: wozu ist das gut?
266: self.REQUEST.SESSION['objID_parent']=self.getId()
267: except:
268: pass
269:
270: #self.cdliRoot.updateOrAddToFileBTree(self)# now update the object in the cache
271:
272:
273: if RESPONSE:
274: if ob.getSize()==0:
275: self.REQUEST.SESSION['objID']=ob.getId()
276: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self)
277: return pt()
278: else:
279: if come_from and (come_from!=""):
280: RESPONSE.redirect(come_from+"?change="+self.getId())
281: else:
282: RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title)
283: else:
284: return ob
285:
286:
287: def manage_addCDLIFileForm(self):
288: """interface for adding the OSAS_root"""
289: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self)
290: return pt()
291:
292: def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None):
293: """add the OSAS_root"""
294: newObj=CDLIFile(id,title,lockedBy,author)
295:
296: tryToggle=True
297: tryCount=0
298:
299: self._setObject(id,newObj)
300: getattr(self,id).reindex_object()
301:
302: if RESPONSE is not None:
303: RESPONSE.redirect('manage_main')
304:
305:
306: def checkUTF8(data):
307: """check utf 8"""
308: try:
309: data.encode('utf-8')
310: return True
311: except:
312: return False
313:
314:
315: def checkFile(filename,data,folder):
316: """check the files"""
317: # first check the file name
318: fn=filename.split(".") # no extension
319:
320: if not fn[0][0]=="P":
321: return False,"P missing in the filename"
322: elif len(fn[0])!=7:
323: return False,"P number has not the right length 6"
324: elif not checkUTF8(data):
325: return False,"not utf-8"
326: else:
327: return True,""
328:
329:
330: def splitatf(fh,dir=None,ext=None):
331: """split it"""
332: ret=None
333: nf=None
334: i=0
335:
336: #ROC: why split \n first and then \r???
337: if (type(fh) is StringType) or (type(fh) is UnicodeType):
338: iter=fh.split("\n")
339: else:
340: iter=fh.readlines()
341:
342: for lineTmp in iter:
343: lineTmp=lineTmp.replace(codecs.BOM_UTF8,'') # make sure that all BOM are removed..
344: for line in lineTmp.split("\r"):
345: #logging.log("Deal with: %s"%line)
346: if ext:
347: i+=1
348: if (i%100)==0:
349: ext.result+="."
350: if i==10000:
351: i=0
352: ext.result+="<br>"
353: #check if basket name is in the first line
354: if line.find("#atf basket")>=0: #old convention
355: ret=line.replace('#atf basket ','')
356: ret=ret.split('_')[0]
357: elif line.find("#basket:")>=0: #new convention
358: ret=line.replace('#basket: ','')
359: ret=ret.split('_')[0]
360:
361: else:
362: if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile
363: if nf:
364: nf.close() #close last file
365:
366:
367: filename=line[1:].split("=")[0].rstrip()+".atf"
368: if dir:
369: filename=os.path.join(dir,filename)
370: nf=file(filename,"w")
371: logging.info("open %s"%filename)
372: if nf:
373: nf.write(line.replace("\n","")+"\n")
374:
375: try:
376: nf.close()
377: except:
378: pass
379:
380: if not((type(fh) is StringType) or (type(fh) is UnicodeType)):
381: fh.close()
382: return ret,len(os.listdir(dir))
383:
384:
385: class CDLIFileFolder(extVersionedFileFolder):
386: """CDLI File Folder"""
387:
388: security=ClassSecurityInfo()
389: meta_type="CDLI Folder"
390: file_meta_type=['CDLI file']
391: folder_meta_type=['CDLI Folder']
392:
393: file_catalog='CDLICatalog'
394:
395: #downloadCounter=0 # counts how many download for all files currently run, be mehr als 5 wird verweigert.
396: tmpStore2={}
397:
398: def _newVersionedFile(self, id, title='', lockedBy=None, author=None):
399: """factory for versioned files. to be overridden in derived classes."""
400: logging.debug("_newVersionedFile(CDLI)")
401: return CDLIFile(id, title, lockedBy=lockedBy, author=author)
402:
403: def setTemp(self,name,value):
404: """set tmp"""
405:
406: setattr(self,name,value)
407:
408: deleteFileForm = PageTemplateFile("zpt/doDeleteFile", globals())
409:
410: def delete(self,ids,REQUEST=None):
411: """delete these files"""
412: if type(ids) is not ListType:
413: ids=[ids]
414:
415: self.manage_delObjects(ids)
416:
417: if REQUEST is not None:
418: return self.index_html()
419:
420:
421: def getVersionNumbersFromIds(self,ids):
422: """get the numbers of the current versions of documents described by their ids"""
423:
424: ret=[]
425: searchStr=" OR ".join(ids)
426:
427: founds=self.CDLICatalog.search({'title':searchStr})
428:
429: for found in founds:
430: lastVersion=found.getObject().getContentObject()
431: ret.append((found.getId,lastVersion))
432:
433: return ret
434:
435: def getFile(self,fn):
436: """get the content of the file fn"""
437: logging.debug("getFile: %s"%repr(fn))
438: if not self.hasObject(fn):
439: # search deeper
440: founds=getattr(self, self.file_catalog).search({'textid':fn})
441: if founds:
442: obj=founds[0].getObject().getContentObject()
443: else:
444: return ""
445: else:
446: obj = self[fn].getContentObject()
447:
448: return obj.getData()[0:]
449:
450:
451: def checkCatalog(self,fn):
452: """check if fn is in the catalog"""
453: #TODO add checkCatalog
454:
455:
456: def findObjectsFromListWithVersion(self,list,author=None):
457: """find objects from a list with versions
458: @param list: list of tuples (cdliFile,version)
459: """
460: #self.REQUEST.SESSION['fileIds']=list#store fieldIds in session for further usage
461: #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
462:
463: pt=getattr(self,'filelistVersioned.html')
464:
465: return pt(search=list,author=author)
466:
467:
468: def getAllPNumbers(self):
469: """get a list of all files (resp their p-numbers) stored"""
470:
471: ret=[x.getId for x in self.CDLICatalog()]
472:
473: return ret
474:
475: def expandFile(self,fileId,fileTree):
476: """wildcard in fileID suche alle Treffer"""
477: founds=self.CDLICatalog({'title':fileId})
478: for found in founds:
479: fileTree.add(found.getId)
480: logging.debug("ADDD:"+found.getId)
481:
482: 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):
483: """findObjectsFromList (, TAB oder LINE separated)"""
484:
485: logging.debug("start: findObjectsFromList")
486: #logging.debug("start: findObjectsFromList"+repr(list))
487:
488:
489: if upload: # list from file upload
490: txt=upload.read()
491:
492: if enterList:
493: txt=enterList
494:
495: if upload or enterList:
496: txt=txt.replace(",","\n")
497: txt=txt.replace("\t","\n")
498: txt=txt.replace("\r","\n")
499: idsTmp=txt.split("\n")
500: ids=[]
501: for id in idsTmp: # make sure that no empty lines
502: idTmp=id.lstrip().rstrip()
503: if len(idTmp)>0:
504:
505: ids.append(idTmp)
506:
507: #self.REQUEST.SESSION['ids']=" OR ".join(ids)
508:
509: pt=getattr(self,'filelist.html')
510: self.REQUEST.SESSION['searchList']=ids
511: return pt(search=ids)
512:
513: if basketName:
514: #TODO: get rid of one of these..
515:
516: pt=getattr(self,'filelist.html')
517: return pt(basketName=basketName,numberOfObjects=numberOfObjects)
518:
519:
520: result =self.CDLICache.retrieve(hash)
521: if result:
522: logging.debug("give result from storage2")
523: return hash,result
524:
525: if list is not None: # got already a list
526:
527: logging.debug(" ----List version")
528: ret=[]
529: fileTree=Set()
530:
531: for fileId in list:
532:
533: if fileId.find("*")>-1: #check for wildcards
534: self.expandFile(fileId,fileTree)
535:
536: elif len(fileId.split("."))==1:
537: fileId=fileId+".atf"
538: fileTree.add(fileId)
539: #logging.debug(" -----:"+fileId)
540: #ret+=self.CDLICatalog({'title':fileId})
541: #x =self.getFileObject(fileId)
542: #if x is not None:
543: # ret.append(x)
544:
545:
546:
547: ids = fileTree & self.v_file_ids
548: #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
549: l=makelist(fileTree)[0:]
550: #logging.debug("l-list:"+repr(l))
551: self.REQUEST.SESSION['fileIds']=l#store fieldIds in session for further usage
552: self.REQUEST.SESSION['searchList']=l
553: #self.REQUEST.SESSION['searchList']=['P000001.atf']
554:
555:
556: hash = md5.new(repr(makelist(fileTree))).hexdigest() # erzeuge hash als identification
557: self.REQUEST.SESSION['hash']=hash
558: #TODO: do I need garbage collection for v_tmpStore ?
559:
560: #logging.debug("Hash:"+repr(hash))
561: #
562: # if hasattr(self.cdliRoot,'v_tmpStore') and self.cdliRoot.v_tmpStore.has_key(hash):
563: # logging.debug("asking for storage")
564: # res=self.cdliRoot.v_tmpStore[hash]
565: # if res:
566: # if returnHash == True:
567: # return hash,res
568: # return res
569:
570: #TODO: get rid of one of these..
571: #ids=[x.getObject().getId() for x in ret]
572: ret=[(self.getFileObject(x),self.getFileObjectLastVersion(x)) for x in ids]
573:
574: #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage
575: #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds']
576:
577: if display:
578: pt=getattr(self,'filelist.html')
579:
580: return pt(search=ids)
581: else:
582: #self.REQUEST.SESSION['hash'] = ret # store in session
583:
584: #logging.debug("HHHHHHNEU:"+repr(self.makelist(ids)))
585: #logging.debug("HHHHHHNEU:"+repr(hash))
586: self.CDLICache.store(hash,ret)
587:
588: if returnHash == True:
589: return hash,ret
590: return ret
591:
592:
593:
594: if start:
595: RESPONSE.redirect("filelist.html?start:int="+str(start))
596:
597: security.declareProtected('Manage','createAllFilesAsSingleFile')
598: def createAllFilesAsSingleFile(self,RESPONSE=None):
599: """download all files"""
600:
601: def sortF(x,y):
602: return cmp(x[0],y[0])
603:
604: catalog=getattr(self,self.file_catalog)
605: #tf,tfilename=mkstemp()
606: if not hasattr(self.temp_folder,'downloadCounter'):
607: self.temp_folder.downloadCounter=0
608:
609: if getattr(self.temp_folder,'downloadCounter',0) > 5:
610: return """I am sorry, currently the server has to many requests for downloads, please come back later!"""
611:
612: self.temp_folder.downloadCounter+=1
613: self._p_changed=1
614: transaction.get().commit()
615:
616: list=[(x.getId,x) for x in catalog()]
617: list.sort(sortF)
618:
619:
620:
621: RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf")
622: RESPONSE.setHeader("Content-Type","application/octet-stream")
623: tmp=""
624: for l in list:
625: obj=l[1].getObject()
626:
627: if obj.meta_type=="CDLI file":
628:
629: #os.write(tf,obj.getLastVersion().data)
630: if RESPONSE:
631: RESPONSE.write(obj.getData()[0:])
632: RESPONSE.write("\n")
633: self.temp_folder.downloadCounter-=1
634: self._p_changed=1
635: transaction.get().commit()
636: #os.close(tf)
637: #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename)
638: return True
639:
640: def downloadFile(self,fn):
641: """download fn - not used yet"""
642: self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId())
643: self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream")
644: self.REQUEST.RESPONSE.write(file(fn).read())
645:
646:
647:
648: def hasParent(self):
649: """returns true falls subfolder"""
650:
651: if self.aq_parent.meta_type in self.folder_meta_type:
652: return True
653: else:
654: return False
655:
656: def getFolders(self):
657: """get all subfolders"""
658: ret=[]
659: folders=self.ZopeFind(self,obj_metatypes=self.folder_meta_type)
660: for folder in folders:
661: ret.append((folder[1],
662: len(self.ZopeFind(folder[1],obj_metatypes=self.folder_meta_type)),
663: len(self.ZopeFind(folder[1],obj_metatypes=self.file_meta_type))
664: ))
665: return ret
666:
667:
668: security.declareProtected('manage','index_html')
669: def index_html(self):
670: """main"""
671: ext=self.ZopeFind(self,obj_ids=["index.html"])
672: if ext:
673: return ext[0][1]()
674:
675: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self)
676: return pt()
677:
678:
679: manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals())
680:
681:
682: def manage_addCDLIFileFolder(self, id, title='',
683: createPublic=0,
684: createUserF=0,
685: REQUEST=None):
686: """Add a new Folder object with id *id*.
687:
688: If the 'createPublic' and 'createUserF' parameters are set to any true
689: value, an 'index_html' and a 'UserFolder' objects are created respectively
690: in the new folder.
691: """
692: ob=CDLIFileFolder()
693: ob.id=str(id)
694: ob.title=title
695: self._setObject(id, ob)
696: ob=self._getOb(id)
697:
698: checkPermission=getSecurityManager().checkPermission
699:
700: if createUserF:
701: if not checkPermission('Add User Folders', ob):
702: raise Unauthorized, (
703: 'You are not authorized to add User Folders.'
704: )
705: ob.manage_addUserFolder()
706:
707:
708: if REQUEST is not None:
709: return self.manage_main(self, REQUEST, update_menu=1)
710:
711: class CDLIRoot(Folder):
712: """main folder for cdli"""
713:
714: meta_type="CDLIRoot"
715: downloadCounterBaskets=0 # counts the current basket downloads if counter > 10 no downloads are possible
716:
717: file_catalog = 'CDLICatalog'
718:
719: # word splitter for search
720: splitter = {'words':cdliSplitter.wordSplitter(),
721: 'graphemes':cdliSplitter.graphemeSplitter()}
722:
723:
724: def unicodify(self,txt):
725: return unicodify(txt)
726: def invalidateOldCacheVersion(self):
727: """loescht die alte Version des Cache"""
728: del self.v_tmpStore
729: return "done"
730:
731: def viewATF(self,id,RESPONSE):
732: """view an Object"""
733: ob = self.CDLICatalog({'title':id})
734: logging.debug(ob[0].getObject().getLastVersion().absolute_url()+"/view")
735: if len(ob)>0:
736: RESPONSE.redirect(ob[0].getObject().getLastVersion().absolute_url()+"/view")
737: return "not found"
738:
739: def history(self,id,RESPONSE):
740: """view an Object"""
741: ob = self.CDLICatalog({'title':id})
742: if len(ob)>0:
743: RESPONSE.redirect(ob[0].absolute_url+"/history")
744: return "not found"
745:
746:
747: def downloadLocked(self,id,RESPONSE):
748: """view an Object"""
749: ob = self.CDLICatalog({'title':id})
750: if len(ob)>0:
751: RESPONSE.redirect(ob[0].absolute_url+"/downloadLocked")
752: return "not found"
753:
754: def download(self,id,RESPONSE):
755: """view an Object"""
756: ob = self.CDLICatalog({'title':id})
757: if len(ob)>0:
758: RESPONSE.redirect(ob[0].getLastVersion().absolute_url())
759: return "not found"
760: def addCDLIFileObjectForm(self,id,RESPONSE):
761: """view an Object"""
762: ob = self.CDLICatalog({'title':id})
763: if len(ob)>0:
764: RESPONSE.redirect(ob[0].absolute_url+"/addCDLIFileObjectForm")
765: return "not found"
766:
767: def addVersionedFileObjectForm(self,id,RESPONSE):
768: """view an Object"""
769: ob = self.CDLICatalog({'title':id})
770: if len(ob)>0:
771: RESPONSE.redirect(ob[0].absolute_url+"/addVersionedFileObjectForm")
772: return "not found"
773:
774: def unlock(self,id,RESPONSE):
775: """view an Object"""
776: ob = self.CDLICatalog({'title':id})
777: if len(ob)>0:
778: RESPONSE.redirect(ob[0].absolute_url+"/unlock")
779: return "not found"
780:
781: def getFileObject(self,fileId):
782: """get an object"""
783: x=self.v_files.get(fileId)
784: #logging.debug(x)
785: return x
786:
787: def getFileObjectLastVersion(self,fileId):
788: """get an object"""
789: x=self.v_files_lastVersion.get(fileId)
790: #logging.debug("lastVersion: "+repr(x))
791: return x
792:
793: def showFileIds(self):
794: """showIds"""
795: return self.v_file_ids
796:
797: def generateFileBTree(self):
798: """erzeuge einen Btree aus allen Files"""
799: self.v_files = OOBTree()
800: self.v_files_lastVersion = OOBTree()
801: self.v_file_ids = Set()
802:
803: for x in self.CDLICatalog.searchResults():
804:
805: self.v_files.update({x.getId:x.getObject()})
806: self.v_files_lastVersion.update({x.getId:x.getObject().getLastVersion()})
807: self.v_file_ids.add(x.getId)
808: logging.debug("add:"+x.getId+"XXX"+repr(x.getObject()))
809:
810: return True
811:
812:
813: def updateOrAddToFileBTree(self,obj):
814: """update a BTree"""
815: self.v_files.update({obj.getId():obj})
816: self.v_files_lastVersion.update({obj.getId():obj.getLastVersion()})
817:
818: self.v_file_ids.add(obj.getId())
819: logging.debug("update:"+obj.getId()+"XXX"+repr(obj))
820:
821: def deleteFromBTree(self,objId):
822: """delete an obj"""
823: self.v_files.pop(objId)
824: self.v_files_lastVersion.pop(objId)
825: self.v_file_ids.remove(objId)
826:
827:
828:
829: def deleteFiles(self,ids):
830: """delete files"""
831: for id in ids:
832: founds=self.CDLICatalog.search({'title':id.split(".")[0]})
833: if founds:
834: logging.debug("deleting %s"%founds)
835: folder=founds[0].getObject().aq_parent #get the parent folder of the object
836: logging.debug("deleting from %s"%folder)
837: cut=folder.delete([founds[0].getId]) #cut it out
838:
839:
840:
841: def searchText(self, query, index='graphemes'):
842: """searches query in the fulltext index and returns a list of file ids/P-numbers"""
843: # see also: http://www.plope.com/Books/2_7Edition/SearchingZCatalog.stx#2-13
844: logging.debug("searchtext for '%s' in index %s"%(query,index))
845: #import Products.ZCTextIndex.QueryParser
846: #qp = QueryParser.QueryParser()
847: #logging.debug()
848: idxQuery = {index:{'query':query}}
849: idx = getattr(self, self.file_catalog)
850: # do search
851: resultset = idx.search(query_request=idxQuery,sort_index='textid')
852: # put only the P-Number in the result
853: results = [res.getId[:7] for res in resultset]
854: logging.debug("searchtext: found %d texts"%len(results))
855: return results
856:
857:
858: def getFile(self, pnum):
859: """get the translit file with the given pnum"""
860: f = getattr(self, self.file_catalog).search({'textid':pnum})
861: if not f:
862: return ""
863:
864: return f[0].getObject().getData()
865:
866:
867: def showFile(self,fileId,wholePage=False):
868: """show a file
869: @param fileId: P-Number of the document to be displayed
870: """
871: f=getattr(self, self.file_catalog).search({'textid':fileId})
872: if not f:
873: return ""
874:
875: if wholePage:
876: logging.debug("show whole page")
877: return f[0].getObject().getContentObject().view()
878: else:
879: return f[0].getObject().getLastVersionFormattedData()
880:
881:
882: def showWordInFile(self,fileId,word,indexName='graphemes',regExp=False,):
883: """get lines with word from FileId"""
884: logging.debug("showwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId))
885:
886: file = formatAtfFullLineNum(self.getFile(fileId))
887: ret=[]
888:
889: # add whitespace before and whitespace and line-end to splitter bounds expressions
890: bounds = self.splitter[indexName].bounds
891: splitexp = "(%s|\s)(%%s)(%s|\s|\Z)"%(bounds,bounds)
892: # clean word expression
893: # TODO: this should use QueryParser itself
894: # take out double quotes
895: word = word.replace('"','')
896: # take out ignorable signs
897: ignorable = self.splitter[indexName].ignorex
898: word = ignorable.sub('', word)
899: # compile into regexp objects and escape parens
900: wordlist = [re.compile(splitexp%re.escape(w)) for w in word.split(' ')]
901:
902: for line in file.splitlines():
903: for word in wordlist:
904: #logging.debug("showwordinfile: searching for %s in %s"%(word.pattern,ignoreable.sub('',line)))
905: if word.search(ignorable.sub('',line)):
906: line = formatAtfLineHtml(line)
907: ret.append(line)
908: break
909:
910: return ret
911:
912:
913: def showWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
914: """
915: get lines with word from all ids in list FileIds.
916: returns dict with id:lines pairs.
917: """
918: logging.debug("showwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds))
919:
920: return dict([(id,self.showWordInFile(id, word, indexName, regExp)) for id in fileIds])
921:
922:
923: def tagWordInFile(self,fileId,word,indexName='graphemes',regExp=False):
924: """get text with word highlighted from FileId"""
925: logging.debug("tagwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId))
926:
927: file=self.getFile(fileId)
928: tagStart=u'<span class="found">'
929: tagEnd=u'</span>'
930: tagStr=tagStart + u'%%s' + tagEnd
931: ret=[]
932:
933: # add whitespace to splitter bounds expressions and compile into regexp object
934: bounds = self.splitter[indexName].bounds
935: wordsplit = re.compile("(%s|\s)"%bounds)
936: # clean word expression
937: # TODO: this should use QueryParser itself
938: word = word.replace('"','') # take out double quotes
939: # take out ignoreable signs
940: ignorable = self.splitter[indexName].ignorex
941: word = ignorable.sub('', word)
942: # split search terms by blanks
943: words = word.split(' ')
944: # split search terms again (for grapheme search with words)
945: splitwords = dict(((w,self.splitter[indexName].process([w])) for w in words))
946:
947: for line in file.splitlines():
948: line = unicodify(line)
949: # ignore lemma and other lines
950: if line.lstrip().startswith('#lem:'):
951: continue
952: # ignore p-num line
953: if line.startswith('&P'):
954: continue
955: # ignore version lines
956: if line.startswith('#version'):
957: continue
958: # ignore atf type lines
959: if line.startswith('#atf:'):
960: continue
961:
962: # first scan
963: hitwords = []
964: for w in words:
965: if ignorable.sub('',line).find(w) > -1:
966: # word is in line
967: # append split word for grapheme search with words
968: hitwords.extend(splitwords[w])
969: #hitwords.extend(wordsplit.split(w))
970:
971: # examine hits closer
972: if hitwords:
973: # split line into words
974: parts = wordsplit.split(line)
975: line = ""
976: for p in parts:
977: #logging.debug("tagwordinfile: searching for %s in %s"%(p,hitwords))
978: # reassemble line
979: if ignorable.sub('', p) in hitwords:
980: #logging.debug("tagwordinfile: found %s in %s"%(p,hitwords))
981: # this part was found
982: line += tagStart + formatAtfHtml(p) + tagEnd
983: else:
984: line += formatAtfHtml(p)
985:
986: else:
987: # no hits
988: line = formatAtfHtml(line)
989:
990: ret.append(line)
991:
992: return u'<br>\n'.join(ret)
993:
994:
995:
996: def tagWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False):
997: """
998: get texts with highlighted word from all ids in list FileIds.
999: returns dict with id:text pairs.
1000: """
1001: logging.debug("tagwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds))
1002: return dict([(id,self.tagWordInFile(id, word, indexName, regExp)) for id in fileIds])
1003:
1004:
1005: def getFileVersionList(self, pnum):
1006: """get the version history as a list for the translit file with the given pnum"""
1007: f = getattr(self, self.file_catalog).search({'textid':pnum})
1008: if not f:
1009: return []
1010:
1011: return f[0].getObject().getVersionList()
1012:
1013:
1014: def URLquote(self,str):
1015: """quote url"""
1016: return urllib.quote(str)
1017:
1018: def URLunquote(self,str):
1019: """unquote url"""
1020: return urllib.unquote(str)
1021:
1022: def URLquote_plus(self,str):
1023: """quote url"""
1024: return urllib.quote_plus(str)
1025:
1026: def URLunquote_plus(self,str):
1027: """unquote url"""
1028: return urllib.unquote_plus(str)
1029:
1030:
1031: def forceunlock(self,REQUEST=None,user=None):
1032: "break all locks"
1033: ret=[]
1034:
1035: for f in self.ZopeFind(self,obj_metatypes="CDLI file",search_sub=1):
1036: un=f[1].forceunlock(user=user)
1037: logging.info("check:"+f[0])
1038: if un and un !="":
1039: ret.append((f[0],un))
1040:
1041: if REQUEST is not None:
1042: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','breakLockResponse.zpt')).__of__(self)
1043:
1044: return pt(ret=ret)
1045:
1046: return ret
1047:
1048:
1049: def getLockedFiles(self,REQUEST=None,user=None):
1050: """hole alle gesperrten files"""
1051: ret={}
1052:
1053: for f in self.ZopeFind(self,obj_metatypes="CDLI file",search_sub=1):
1054: lb = f[1].lockedBy
1055: add=False
1056: if (lb is not None) and (lb!=""):
1057:
1058: if user is None:
1059: add=True
1060: else:
1061: if str(lb)==user:
1062: add=True
1063: if add==True:
1064: if not ret.has_key(lb):
1065: ret[lb]=[]
1066: ret[lb].append(f[0])
1067:
1068:
1069: if REQUEST is not None:
1070: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','showlockResponse.zpt')).__of__(self)
1071:
1072: return pt(ret=ret)
1073:
1074: return ret
1075:
1076: def getChangesByAuthor(self,author,n=100):
1077: """getChangesByAuthor"""
1078: zcat=self.CDLIObjectsCatalog
1079: res=zcat({'lastEditor':author,
1080: 'sort_on':'getTime',
1081: 'sort_order':'descending',
1082: 'sort_limit':n})[:n ]
1083:
1084: return res
1085:
1086: def getChangesByAuthor_html(self,author,n=100):
1087: """html output for changes by author"""
1088: tmp={}
1089: list=[]
1090: for x in self.getChangesByAuthor(author):
1091: nr=x.getObject().getVersionNumber()
1092: id=x.getObject().aq_parent.getId()
1093: #hinzufuegen, wenn Version neuer als die
1094: if tmp.get(id,(0,0))[1] < nr:
1095: tmp[id]=(x.getObject().aq_parent,nr)
1096:
1097:
1098: return self.cdli_main.findObjectsFromListWithVersion(list=tmp.values(),author=author)
1099:
1100: def getLastChanges(self,n=100):
1101: """get the last n changes"""
1102: n=int(n)
1103: zcat=self.CDLICatalog
1104: return zcat({'sort_on':'getLastChangeDate',
1105: 'sort_order':'descending',
1106: 'sort_limit':n})[:n ]
1107:
1108:
1109: def getLastChanges_html(self,n=100):
1110: """get the last n changes"""
1111: list = [x.getId for x in self.getLastChanges(n)]
1112: return self.cdli_main.findObjectsFromList(list=list,display=True)
1113:
1114: def refreshTxt(self,txt="",threadName=None):
1115: """txt fuer refresh"""
1116:
1117: return """ 2;url=%s?repeat=%s """%(self.absolute_url()+txt,threadName)
1118:
1119: def refreshTxtBasket(self,txt="",threadName=None):
1120: """txt fuer refresh"""
1121:
1122: return """ 2;url=%s?repeat=%s """%(txt,threadName)
1123:
1124:
1125: def getResult(self,threadName=None):
1126: """result of thread"""
1127: try:
1128: return self._v_uploadATF[threadName].getResult()
1129: except:
1130: return "One moment, please"
1131:
1132:
1133: def checkThreads(self):
1134: """check threads"""
1135: ret="<html><body>"
1136: for thread in threading.enumerate():
1137: ret+="<p>%s (%s): %s</p>"%(repr(thread),thread.getName(),thread.isAlive())
1138:
1139: return ret
1140:
1141:
1142: def uploadATFRPC(self,data,username):
1143: """upload an atffile via xml-rpc"""
1144: uploader=uploadATFThread()
1145:
1146: #generate an random id for the upload object
1147: from random import randint
1148: if (not self.REQUEST.SESSION.get('idTmp',None)):
1149:
1150: idTmp=str(randint(0,1000000000))
1151: self.REQUEST.SESSION['idTmp']=idTmp
1152: else:
1153: idTmp=self.REQUEST.SESSION.get('idTmp',None)
1154:
1155:
1156: uploader.set(data,0,username,idTmp)
1157:
1158: stObj=uploader.run()
1159:
1160: processor=uploadATFfinallyThread()
1161:
1162: basketname=stObj.returnValue['basketNameFromFile']
1163:
1164: processor.set("uploadchanged",basketname=basketname,SESSION=stObj.returnValue,username=username,serverport=self.REQUEST['SERVER_PORT'])
1165:
1166: processor.run()
1167:
1168:
1169: return generateXMLReturn(stObj.returnValue)
1170:
1171: def uploadATF(self,repeat=None,upload=None,basketId=0,RESPONSE=None):
1172: """upload an atf file / basket file"""
1173: #self._v_uploadATF.returnValue=None
1174:
1175: #generate an random id for the upload thread
1176: from random import randint
1177: if (not self.REQUEST.SESSION.get('idTmp',None)):
1178:
1179: idTmp=str(randint(0,1000000000))
1180: self.REQUEST.SESSION['idTmp']=idTmp
1181: else:
1182: idTmp=self.REQUEST.SESSION.get('idTmp',None)
1183:
1184:
1185: threadName=repeat
1186: if not threadName or threadName=="":
1187: #new thread not called from the waiting page
1188: tmpVar=False
1189:
1190: thread=uploadATFThread()
1191: threadName=thread.getName()[0:]
1192: if (not hasattr(self,'_v_uploadATF')):
1193: self._v_uploadATF={}
1194:
1195: self._v_uploadATF[threadName]=thread
1196: #self._xmltrans.start()
1197: #thread=Thread(target=self._v_uploadATF)
1198: logging.info("set thread. extern")
1199: self._v_uploadATF[threadName].set(upload,basketId,self.REQUEST['AUTHENTICATED_USER'],idTmp,serverport=self.REQUEST['SERVER_PORT'])
1200: #thread.start()
1201: logging.info("start thread. extern")
1202: self._v_uploadATF[threadName].start()
1203:
1204:
1205: self.threadName=self._v_uploadATF[threadName].getName()[0:]
1206: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1207:
1208: if wait_template:
1209: return wait_template[0][1]()
1210: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1211: return pt(txt='/uploadATF',threadName=threadName)
1212: #_v_xmltrans.run()
1213:
1214: else:
1215: #recover thread, if lost
1216: if (not hasattr(self,'_v_uploadATF')):
1217: self._v_uploadATF={}
1218: if not self._v_uploadATF.get(threadName,None):
1219: for thread in threading.enumerate():
1220: if threadName == thread.getName():
1221: self._v_uploadATF[threadName]=thread
1222:
1223: if self._v_uploadATF.get(threadName,None) and (not self._v_uploadATF[threadName].returnValue):
1224:
1225:
1226: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1227: if wait_template:
1228: return wait_template[0][1]()
1229:
1230: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1231:
1232: return pt(txt='/uploadATF',threadName=threadName)
1233:
1234: else:
1235: tmp=getattr(self.temp_folder,idTmp).returnValue
1236:
1237: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
1238:
1239: return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'],
1240: basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
1241:
1242: def redoUpload(self,threadName):
1243: """redo the upload"""
1244: tmp=self.cdli_main.tmpStore2[threadName]
1245: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self)
1246: return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'],
1247: basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId'])
1248:
1249: def uploadATFfinally(self,procedure='',comment="",basketname='',unlock=None,repeat=None,RESPONSE=None):
1250: """nowupload the files"""
1251:
1252:
1253:
1254: threadName=repeat
1255: if not threadName or threadName=="":
1256: thread=uploadATFfinallyThread()
1257: threadName=thread.getName()[0:]
1258:
1259: if (not hasattr(self,'_v_uploadATF')):
1260: self._v_uploadATF={}
1261:
1262:
1263: self._v_uploadATF[threadName]=thread
1264:
1265: idTmp=self.REQUEST.SESSION['idTmp']
1266: stObj=getattr(self.temp_folder,idTmp)
1267: 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'])
1268:
1269: self._v_uploadATF[threadName].start()
1270:
1271:
1272:
1273: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1274:
1275: if wait_template:
1276: return wait_template[0][1]()
1277: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1278:
1279: return pt(txt='/uploadATFfinally',threadName=threadName)
1280: #_v_xmltrans.run()
1281:
1282: else:
1283: #recover thread, if lost
1284: if not hasattr(self,'_v_uploadATF'):
1285: self._v_uploadATF={}
1286: if not self._v_uploadATF.get(threadName,None):
1287: for thread in threading.enumerate():
1288: if threadName == thread.getName():
1289: self._v_uploadATF[threadName]=thread
1290:
1291: if self._v_uploadATF.get(threadName,None) and (self._v_uploadATF[threadName] is not None) and (not self._v_uploadATF[threadName].end) :
1292:
1293: wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
1294: if wait_template:
1295: return wait_template[0][1]()
1296:
1297: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self)
1298: return pt(txt='/uploadATFfinally',threadName=threadName)
1299: else:
1300:
1301:
1302: idTmp=self.REQUEST.SESSION['idTmp']
1303: stObj=getattr(self.temp_folder,idTmp)
1304: self.REQUEST.SESSION['idTmp']=None
1305:
1306: #update changed
1307: logging.debug("dir:"+repr(stObj.returnValue['changed']))
1308: for x in stObj.returnValue['changed']:
1309: ob=self.CDLICatalog.search({'title':x[0]})
1310: try:
1311: self.cdliRoot.updateOrAddToFileBTree(ob[0].getObject())
1312: except:
1313: logging.error("uploadATFfinally - cannot update Object %s Error: %s %s"%(ob[1],sys.exc_info()[0],sys.exc_info()[1]))
1314: if RESPONSE is not None:
1315: RESPONSE.redirect(self.absolute_url())
1316:
1317: def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/atf", files=None,ext=None):
1318: """import files"""
1319: logging.debug("importFiles folderName=%s files=%s ext=%s"%(folderName,files,ext))
1320: root=self.cdli_main
1321: count=0
1322: if not files:
1323: files=os.listdir(folderName)
1324:
1325: for f in files:
1326: folder=f[0:3]
1327: f2=f[0:5]
1328:
1329: #check if main folder PXX already exists
1330: obj=self.ZopeFind(root,obj_ids=[folder])
1331: logging.debug("importFiles: folder=%s f2=%s obj=%s"%(folder,f2,obj))
1332: if ext:
1333: ext.result="<p>adding: %s </p>"%f+ext.result
1334:
1335:
1336: if not obj: # if not create it
1337: manage_addCDLIFileFolder(root,folder,folder)
1338: fobj=getattr(root,folder)
1339: #transaction.get().commit()
1340:
1341: else:
1342: fobj=obj[0][1]
1343:
1344: #check IF PYYYYY already exist
1345: obj2=fobj.ZopeFind(fobj,obj_ids=[f2])
1346: logging.debug("importFiles: fobj=%s obj2=%s"%(fobj,obj2))
1347:
1348: if not obj2:# if not create it
1349: manage_addCDLIFileFolder(fobj,f2,f2)
1350: fobj2=getattr(fobj,f2)
1351:
1352: else:
1353: fobj2=obj2[0][1]
1354:
1355: # not add the file
1356: file2=os.path.join(folderName,f)
1357: id=f
1358: logging.debug("importFiles: addCDLIFile fobj2=%s, f=%s file2=%s"%(fobj2,repr(f),repr(file2)))
1359: fobj2.addFile(vC='',file=file(file2),author=author,newName=f)
1360: count+=1
1361:
1362: #now add the file to the storage
1363: ob = getattr(fobj2,f)
1364: self.cdliRoot.updateOrAddToFileBTree(ob)
1365:
1366: if count%100==0:
1367: logging.debug("importfiles: committing")
1368: transaction.get().commit()
1369:
1370: transaction.get().commit()
1371: return "ok"
1372:
1373:
1374: manage_addCDLIRootForm=DTMLFile('dtml/rootAdd', globals())
1375:
1376:
1377: def manage_addCDLIRoot(self, id, title='',
1378: createPublic=0,
1379: createUserF=0,
1380: REQUEST=None):
1381: """Add a new Folder object with id *id*.
1382:
1383: If the 'createPublic' and 'createUserF' parameters are set to any true
1384: value, an 'index_html' and a 'UserFolder' objects are created respectively
1385: in the new folder.
1386: """
1387: ob=CDLIRoot()
1388: ob.id=str(id)
1389: ob.title=title
1390: try:
1391: self._setObject(id, ob)
1392: except:
1393: pass
1394: ob=self._getOb(id)
1395:
1396: checkPermission=getSecurityManager().checkPermission
1397:
1398: if createUserF:
1399: if not checkPermission('Add User Folders', ob):
1400: raise Unauthorized, (
1401: 'You are not authorized to add User Folders.'
1402: )
1403: ob.manage_addUserFolder()
1404:
1405:
1406: if REQUEST is not None:
1407: return self.manage_main(self, REQUEST, update_menu=1)
1408:
1409:
1410: import cdli_basket
1411:
1412:
1413: # Die folgenden Klassen sollte nicht mehr aus diesem Paket benutzt werden, sondern direkt aus
1414: # cdli_basket importiert werden.
1415: class uploadATFfinallyThread(cdli_basket.uploadATFfinallyThread):
1416: """depricates"""
1417: pass
1418:
1419: class tmpStore(cdli_basket.tmpStore):
1420: """depricated"""
1421: pass
1422:
1423: class uploadATFThread(cdli_basket.uploadATFThread):
1424: """depricated"""
1425: pass
1426:
1427: class CDLIBasketContainer(cdli_basket.CDLIBasketContainer):
1428: """depricated"""
1429: pass
1430:
1431: class CDLIBasket(cdli_basket.CDLIBasket):
1432: """depricated"""
1433: pass
1434:
1435: class CDLIBasketVersion(cdli_basket.CDLIBasketVersion):
1436: """depricated"""
1437: pass
1438:
1439: class BasketContent(cdli_basket.BasketContent):
1440: """depricated"""
1441: pass
1442:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>