--- versionedFile/extVersionedFile.py 2006/10/05 06:38:26 1.2 +++ versionedFile/extVersionedFile.py 2008/10/29 12:12:25 1.30 @@ -1,3 +1,8 @@ +"""actual version of the versioned file folder with external filestorage, +using the ExtFile Product, this version replaces externaVersionedFile.py +DW 11.10.2006 +""" + from OFS.Folder import Folder from OFS.Image import File from OFS.Image import cookId @@ -13,29 +18,31 @@ from Products.ExtFile.ExtFile import * from Products.ZCatalog.CatalogPathAwareness import CatalogAware try: - from Products.ImageArchive.ImageArchive import manage_AddImageZogiLib + from Products.ImageArchive.ImageArchive import manage_AddImageZogiLib except: - print "no images" - + print "no images" from threading import Thread import shutil import tempfile import os.path import urllib - import time +import logging +import types + try: from Products.ECHO_content.ECHO_collection import ECHO_basis except: print "ECHO Elements not imported" class ECHO_basis: - """leer""" - manage_options=() + """leer""" + manage_options=() def sortv(x,y): return cmp(x[0],y[0]) + tdir = "/tmp/downloadVersionedFiles" class generateDownloadZip: @@ -51,22 +58,22 @@ class generateDownloadZip: def __call__(self): """call generate download zip""" storeTempDir=tempfile.tempdir - tempfile.tempdir=tdir + tempfile.tempdir=tdir tmpPath=tempfile.mktemp() - tmpZip=tempfile.mktemp()+".gtz" + tmpZip=tempfile.mktemp()+".tgz" tmpFn=os.path.split(tmpZip)[1] if not os.path.exists(tempfile.tempdir): os.mkdir(tempfile.tempdir) if not os.path.exists(tmpPath): - os.mkdir(tmpPath) + os.mkdir(tmpPath) - self.response="

1. step: getting the files

" + self.response="

1. step: getting the files

" for files in self.folder.ZopeFind(self.folder,obj_metatypes=['extVersionedFile']): - lastV=files[1].getLastVersion() + lastV=files[1].getContentObject() self.response+=str("

Get File: %s
\n"%lastV.title) savePath=os.path.join(tmpPath,lastV.title) @@ -75,7 +82,7 @@ class generateDownloadZip: fh.close() self.response+="

2. step: creating the downloadable file

" - self.response+="

Create gtar
" + self.response+="

Create gtar
" self.response+="

This can take a while....
\n" fh=os.popen2("tar zcvf %s %s/*"%(tmpZip,tmpPath),1)[1] @@ -84,9 +91,6 @@ class generateDownloadZip: self.response+=c if c==")": self.response+="
\n" - - - shutil.rmtree(tmpPath) @@ -101,7 +105,7 @@ class generateDownloadZip: self.done=True - + def getResult(self): """get result""" return self.response @@ -115,28 +119,29 @@ class generateDownloadZip: class extVersionedFileFolder(Folder,ECHO_basis): """Folder with versioned files""" - - meta_type = "extVersionedFileFolder" security= ClassSecurityInfo() security.declareProtected('AUTHENTICATED_USER','addFileForm') - filesMetaType=['extVersionedFile'] + + file_meta_type=['extVersionedFile'] + if ECHO_basis: optTMP= Folder.manage_options+ECHO_basis.manage_options else: optTMP= Folder.manage_options manage_options =optTMP+( - {'label':'Generate Index.html','action':'generateIndexHTML'}, - {'label':'Generate Image Index.html','action':'generateIndexHTML_image'}, - {'label':'Generate history_template.html','action':'generateHistoryHTML'}, - {'label':'Import Folder','action':'importFolderForm'}, - {'label':'Export Folder','action':'exportFolder'}, - {'label':'Position of version number','action':'changeHistoryFileNamesForm'}, - ) + {'label':'Generate Index.html','action':'generateIndexHTML'}, + {'label':'Generate Image Index.html','action':'generateIndexHTML_image'}, + {'label':'Generate history_template.html','action':'generateHistoryHTML'}, + {'label':'Import directory','action':'importFolderForm'}, + {'label':'Export as file','action':'exportFolder'}, + {'label':'Import versionedFileFolder','action':'importVersionedFileFolderForm'}, + {'label':'Position of version number','action':'changeHistoryFileNamesForm'}, + ) - + def changeHistoryFileNamesForm(self): """change position of version num""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeHistoryFileNamesForm.zpt')).__of__(self) @@ -145,17 +150,14 @@ class extVersionedFileFolder(Folder,ECHO def changeHistoryFileNames(self,positionVersionNum="front",RESPONSE=None): """change position of version num""" - - - versions=self.ZopeFind(self,obj_metatypes=['extVersionedFileObject'],search_sub=1) if not (getattr(self,'positionVersionNum','front')==positionVersionNum): for version in versions: - + if positionVersionNum=="front": - + titleTmp=os.path.splitext(version[1].title) titleTmp2="_".join(titleTmp[0].split("_")[0:-1]) if len(titleTmp)>1: @@ -171,12 +173,9 @@ class extVersionedFileFolder(Folder,ECHO else: id=tmp[0]+"_"+version[1].getId().split("_")[0] - - version[1].aq_parent.manage_renameObjects(ids=[version[1].getId()],new_ids=[id]) version[1].title=id - self.positionVersionNum=positionVersionNum if RESPONSE: RESPONSE.redirect("manage_main") @@ -187,19 +186,70 @@ class extVersionedFileFolder(Folder,ECHO """form fuer folder import""" pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','importFolderForm.zpt')).__of__(self) return pt() - + def importFolder(self,path,comment="",author=None,lockedBy=None,RESPONSE=None): - """importiere inhalt eines folders""" - + """import contents of a folder on the server""" for fileName in os.listdir(path): - if os.path.isfile(os.path.join(path,fileName)): - manage_addextVersionedFile(self,fileName,'','') - id=fileName - ob=self._getOb(fileName) - ob.title=id - file2=file(os.path.join(path,fileName)) + fn = os.path.join(path,fileName) + if os.path.isfile(fn): + f = file(fn) + self.addFile(vC=comment, file=f, author=author) - obj=ob.manage_addextVersionedFileObject(id,comment,author,file2,content_type='') + if RESPONSE: + RESPONSE.redirect(self.REQUEST['URL1']) + + def importVersionedFileFolderForm(self): + """form fuer versionedFileFolder import""" + pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','importVersionedFileFolderForm.zpt')).__of__(self) + return pt() + + def importVersionedFileFolder(self,path,RESPONSE=None): + """import contents of a versionedFileFolder on the server""" + vff = getattr(self.aq_parent, path, None) + if vff is None: + return "SORRY, unable to import %s"%path + + tmpPath=tempfile.mktemp() + if not os.path.exists(tempfile.tempdir): + os.mkdir(tempfile.tempdir) + + if not os.path.exists(tmpPath): + os.mkdir(tmpPath) + + for (vfn, vf) in vff.getVersionedFiles(): + if vf.meta_type == 'versionedFile': + logging.error("importvff: importing %s of type %s!"%(vfn,vf.meta_type)) + title = vf.title + fob = vf.getLastVersion() + author = fob.getLastEditor() + vc = fob.getVersionComment() + # save file to filesystem + savePath=os.path.join(tmpPath,title) + fh=file(savePath,"w") + data = vf.getLastVersion().data + if isinstance(data, str): + # simple data object + fh.write(data) + else: + # chained data objects + while data is not None: + fh.write(data.data) + data = data.next + fh.close() + # and read in again + fh = file(savePath) + logging.error("importvff: comment=%s author=%s!"%(vc,author)) + self.addFile(vC=vc, file=fh, author=author) + # copy more fields + newfob = getattr(self, vfn).getContentObject() + newfob.vComment = fob.vComment + newfob.time = fob.time + logging.error("importvff: vc=%s time=%s of %s!"%(fob.vComment,fob.time,fob.getId())) + + else: + logging.error("importvff: unable to import %s of type %s!"%(vfn,vf.meta_type)) + + shutil.rmtree(tmpPath) if RESPONSE: RESPONSE.redirect(self.REQUEST['URL1']) @@ -219,13 +269,14 @@ class extVersionedFileFolder(Folder,ECHO downloadZip=generateDownloadZip(self,self.absolute_url()) downloadZip() return downloadZip.getResult() + ## if not threadName or threadName=="": ## threadStart=generateDownloadZip(self,self.absolute_url()) ## thread=Thread(target=threadStart) - + ## thread.start() - + ## self.zipThreads[thread.getName()[0:]]=threadStart ## self.zipThreads2[thread.getName()[0:]]=thread ## self.REQUEST.SESSION['threadName']=thread.getName()[0:] @@ -234,7 +285,7 @@ class extVersionedFileFolder(Folder,ECHO ## return wait_template[0][1]() ## pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','zip_wait.zpt')).__of__(self) ## return pt() - + ## else: ## self.REQUEST.SESSION['threadName']=threadName @@ -262,17 +313,17 @@ class extVersionedFileFolder(Folder,ECHO ## return pt() def downloadSet(self,fn): - """download prepared set""" - filename=os.path.join(tdir,fn) + """download prepared set""" + filename=os.path.join(tdir,fn) - - self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s" """%"downloadFileFolder.tgz") - self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") - len=os.stat(filename)[6] - self.REQUEST.RESPONSE.setHeader("Content-Length",len) - images=file(filename).read() - self.REQUEST.RESPONSE.write(images) - self.REQUEST.RESPONSE.close() + + self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s" """%"downloadFileFolder.tgz") + self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") + len=os.stat(filename)[6] + self.REQUEST.RESPONSE.setHeader("Content-Length",len) + images=file(filename).read() + self.REQUEST.RESPONSE.write(images) + self.REQUEST.RESPONSE.close() @@ -290,7 +341,7 @@ class extVersionedFileFolder(Folder,ECHO zt=ZopePageTemplate('index.html') self._setObject('index.html',zt) default_content_fn = os.path.join(package_home(globals()), - 'zpt/versionFileFolderMain_image.zpt') + 'zpt/versionFileFolderMain_image.zpt') text = open(default_content_fn).read() zt.pt_edit(text, 'text/html') @@ -309,7 +360,7 @@ class extVersionedFileFolder(Folder,ECHO zt=ZopePageTemplate('index.html') self._setObject('index.html',zt) default_content_fn = os.path.join(package_home(globals()), - 'zpt/versionFileFolderMain.zpt') + 'zpt/versionFileFolderMain.zpt') text = open(default_content_fn).read() zt.pt_edit(text, 'text/html') @@ -322,13 +373,11 @@ class extVersionedFileFolder(Folder,ECHO def generateIndexHTML(self,RESPONSE=None): """lege standard index.html an""" - - if not self.ZopeFind(self,obj_ids=['index.html']): zt=ZopePageTemplate('index.html') self._setObject('index.html',zt) default_content_fn = os.path.join(package_home(globals()), - 'zpt/versionFileFolderMain.zpt') + 'zpt/versionFileFolderMain.zpt') text = open(default_content_fn).read() zt.pt_edit(text, 'text/html') @@ -341,14 +390,11 @@ class extVersionedFileFolder(Folder,ECHO def generateHistoryHTML(self,RESPONSE=None): """lege standard index.html an""" - - - if not self.ZopeFind(self,obj_ids=['history_template.html']): zt=ZopePageTemplate('history_template.html') self._setObject('history_template.html',zt) default_content_fn = os.path.join(package_home(globals()), - 'zpt/versionHistory.zpt') + 'zpt/versionHistory.zpt') text = open(default_content_fn).read() zt.pt_edit(text, 'text/html') @@ -357,9 +403,7 @@ class extVersionedFileFolder(Folder,ECHO if RESPONSE is not None: RESPONSE.redirect('manage_main') - - - + def getVersionedFiles(self,sortField='title'): """get all versioned files""" @@ -368,45 +412,39 @@ class extVersionedFileFolder(Folder,ECHO return cmp(x[1].title.lower(),y[1].title.lower()) def sortDate(x,y): - return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime()) + return cmp(y[1].getContentObject().getTime(),x[1].getContentObject().getTime()) - def sortComment(x,y): - - - - try: - xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower() - except: - xc='ZZZZZZZZZZZZZ'.lower() - try: - yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower() - except: - yc='ZZZZZZZZZZZZZ'.lower() - - - if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()): - - try: - xc=x[1].getLastVersion().getVComment().lower() - except: - xc='ZZZZZZZZZZZZZ'.lower() - - if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()): - try: - yc=y[1].getLastVersion().getVComment().lower() - except: - yc='ZZZZZZZZZZZZZ'.lower() - - - return cmp(xc,yc) + try: + xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower() + except: + xc='ZZZZZZZZZZZZZ'.lower() + + try: + yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower() + except: + yc='ZZZZZZZZZZZZZ'.lower() + + if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()): + try: + xc=x[1].getContentObject().getVComment().lower() + except: + xc='ZZZZZZZZZZZZZ'.lower() + + if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()): + try: + yc=y[1].getContentObject().getVComment().lower() + except: + yc='ZZZZZZZZZZZZZ'.lower() + + return cmp(xc,yc) def sortAuthor(x,y): - return cmp(x[1].getLastVersion().lastEditor().lower(),y[1].getLastVersion().lastEditor().lower()) - - versionedFiles=self.ZopeFind(self,obj_metatypes=self.filesMetaType) + return cmp(x[1].getContentObject().lastEditor().lower(),y[1].getContentObject().lastEditor().lower()) + versionedFiles=self.objectItems(self.file_meta_type) + logging.debug("versionedfiles: %s of type %s"%(repr(versionedFiles),repr(self.file_meta_type))) if sortField=='title': versionedFiles.sort(sortName) @@ -421,7 +459,7 @@ class extVersionedFileFolder(Folder,ECHO def header_html(self): - """zusätzlicher header""" + """zusaetzlicher header""" ext=self.ZopeFind(self,obj_ids=["header.html"]) if ext: return ext[0][1]() @@ -451,36 +489,54 @@ class extVersionedFileFolder(Folder,ECHO return out() - def addFile(self,vC,file,author,newName='',content_type='',RESPONSE=None): + def addFile(self,vC,file,author='',newName='',content_type='',RESPONSE=None): """ add a new file""" + # is file is a real file or a zope download object? + isRealFile = type(file) is types.FileType + if newName=='': - filename=file.filename + logging.debug("fileobject: %s real:%s"%(repr(file),repr(isRealFile))) + if isRealFile: + filename = file.name + else: + filename=file.filename + id=filename[max(filename.rfind('/'), - filename.rfind('\\'), - filename.rfind(':'), - )+1:] + filename.rfind('\\'), + filename.rfind(':'), + )+1:] else: id=newName - vC=self.REQUEST.form['vC'] - manage_addextVersionedFile(self,id,'','') - #if (getattr(self,'commentNonEmpty',0)==1) and vC.strip()=="": - - - ob=self._getOb(id) - ob.title=id - file2=file - - obj=ob.manage_addextVersionedFileObject(id,vC,author,file2,content_type=content_type) - self.REQUEST.SESSION['objID']=ob.getId() - self.REQUEST.SESSION['objID_parent']=None + if vC is None: + vC=self.REQUEST.form['vC'] + + # get new extVersionedFile + vf = self._newVersionedFile(id,title=id) + logging.error("addFile id=%s vf=%s of %s"%(repr(id),repr(vf),repr(self))) + # add its content (and don't index) + obj=vf.addContentObject(id,vC,author=author,file=file,content_type=content_type,from_tmp=isRealFile,index=False) + # add file to this folder (this should do the indexing) + self._setObject(id,vf) + + try: + self.REQUEST.SESSION['objID']=vf.getId() + self.REQUEST.SESSION['objID_parent']=None + except: + pass if obj.getSize()==0: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self) return pt() - RESPONSE.redirect(self.REQUEST['URL1']) + if RESPONSE is not None: + RESPONSE.redirect(self.REQUEST['URL1']) + + + def _newVersionedFile(self, id, title='', lockedBy=None, author=None): + """factory for versioned files. to be overridden in derived classes.""" + return extVersionedFile(id, title, lockedBy=lockedBy, author=author) def deleteEmptyObject(self,submit,RESPONSE=None): @@ -495,14 +551,24 @@ class extVersionedFileFolder(Folder,ECHO RESPONSE.redirect(self.REQUEST['URL1']) + + security.declareProtected('AUTHENTICATED_USER','fixVersionNumbers') + def fixVersionNumbers(self): + """fix last version number of all files""" + for (id,vf) in self.getVersionedFiles(): + vf.fixVersionNumbers() + # recursively + for (id,vf) in self.objectItems(self.meta_type): + vf.fixVersionNumbers() + manage_addextVersionedFileFolderForm=DTMLFile('dtml/extfolderAdd', globals()) def manage_addextVersionedFileFolder(self, id, title='', - createPublic=0, - createUserF=0, - REQUEST=None): + createPublic=0, + createUserF=0, + REQUEST=None): """Add a new Folder object with id *id*. If the 'createPublic' and 'createUserF' parameters are set to any true @@ -520,11 +586,11 @@ def manage_addextVersionedFileFolder(sel if createUserF: if not checkPermission('Add User Folders', ob): raise Unauthorized, ( - 'You are not authorized to add User Folders.' - ) + 'You are not authorized to add User Folders.' + ) ob.manage_addUserFolder() - + if REQUEST is not None: return self.manage_main(self, REQUEST, update_menu=1) @@ -535,19 +601,53 @@ class extVersionedFileObject(ExtFile): security= ClassSecurityInfo() meta_type = "extVersionedFileObject" - manage_editForm =DTMLFile('dtml/fileEdit',globals(), + manage_editForm=DTMLFile('dtml/fileEdit',globals(), Kind='File',kind='file') manage_editForm._setName('manage_editForm') + def __init__(self, id, title='', versionNumber=0, versionComment=None, time=None, author=None): + """Initialize a new instance of extVersionedFileObject (taken from ExtFile)""" + ExtFile.__init__(self,id,title) + self.versionNumber = versionNumber + self.versionComment= versionComment + self.time = time + self.author = author + + security.declareProtected('manage','changeObject') + def changeObject(self,**args): + """modify any of the objects attributes""" + for arg in args: + if hasattr(self, arg): + logging.debug("changeObject %s: %s=%s"%(repr(self),arg,args[arg])) + setattr(self, arg, args[arg]) - - security.declarePublic('getTitle') - def getTitle(self): """get title""" return self.title - + + def getData(self): + """returns object content (calls ExtFile.index_html)""" + #logging.debug("+++++++getData1:"+repr(self.get_filename())) + filename = self.get_filename() + #return ExtFile.index_html(self) + try: + return file(filename).read() + except: + return ExtFile.index_html(self) + + + def getFileName(self): + """return filename""" + return self.get_filename() + + def addToFile(self,filehandle): + filehandle.write(self.getData()) + + def addToFile2(self,filename): + str="cat %s > %s"%(self.get_filename(),filename) + os.popen(str) + security.declarePublic('getVComment') def getVComment(self): """get the comment of this file""" @@ -556,14 +656,10 @@ class extVersionedFileObject(ExtFile): else: return self.vComment - + def manageVCommentForm(self): """add a comment""" - self.REQUEST.SESSION['refer']=self.REQUEST['HTTP_REFERER'] - - - pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addVComment')).__of__(self) return pt() @@ -590,22 +686,17 @@ class extVersionedFileObject(ExtFile): return self.versionComment security.declarePublic('getTime') - def getTime(self): """getTime""" #return self.bobobase_modification_time().ISO() if hasattr(self,'time'): return time.strftime("%Y-%m-%d %H:%M:%S",self.time) elif hasattr(self,'timefixed'): - return self.timefixed + return self.timefixed else: setattr(self,'timefixed',self.bobobase_modification_time().ISO()) return self.bobobase_modification_time().ISO() - - - - def download(self,REQUEST=None,RESPONSE=None): """download and lock""" @@ -619,13 +710,16 @@ class extVersionedFileObject(ExtFile): #self.REQUEST.RESPONSE.setHeader("Content-Length","str(len(txt)+1000)") self.content_type="application/octet-stream" - self.REQUEST.RESPONSE.redirect(self.absolute_url()) + return self.getData() + #self.REQUEST.RESPONSE.redirect(self.absolute_url()) #txt=urllib.urlopen(self.absolute_url()).read() #self.REQUEST.RESPONSE.write(txt) #self.REQUEST.close() + view = download + security.declareProtected('AUTHENTICATED_USER','downloadLocked') def downloadLocked(self): """download and lock""" @@ -640,13 +734,7 @@ class extVersionedFileObject(ExtFile): self.content_type="application/octet-stream" self.REQUEST.RESPONSE.redirect(self.absolute_url()) - def setVersionNumber(self,versionNumber): - """set version""" - self.versionNumber=versionNumber - - security.declarePublic('getVersionNumber') - def getVersionNumber(self): """get version""" return self.versionNumber @@ -656,10 +744,7 @@ class extVersionedFileObject(ExtFile): """get version""" return self.versionComment - - security.declarePublic('lastEditor') - def lastEditor(self): """last Editor""" if hasattr(self,'author'): @@ -677,14 +762,12 @@ class extVersionedFileObject(ExtFile): if jar is None or oid is None: return None return jar.db().history(oid)[0]['user_name'] - - manage_addextVersionedFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='extVersionedFileObject',kind='extVersionedFileObject', version='1') -def manage_addextVersionedFileObject(self,id,vC='',author='', file='',title='',precondition='', content_type='', - REQUEST=None): +def manage_addextVersionedFileObject(self,id,vC='',author='', file='',title='',versionNumber=0, + precondition='', content_type='', REQUEST=None): """Add a new File object. Creates a new File object 'id' with the contents of 'file'""" @@ -699,47 +782,54 @@ def manage_addextVersionedFileObject(sel self=self.this() # First, we create the file without data: - self._setObject(id, extVersionedFileObject(id,title,'',content_type, precondition)) - self._getOb(id).versionComment=str(vC) - self._getOb(id).time=time.localtime() - - setattr(self._getOb(id),'author',author) + self._setObject(id, extVersionedFileObject(id,title,versionNumber=versionNumber,versionComment=str(vC),author=author)) + fob = self._getOb(id) # Now we "upload" the data. By doing this in two steps, we # can use a database trick to make the upload more efficient. if file: - self._getOb(id).manage_upload(file) + fob.manage_upload(file) if content_type: - self._getOb(id).content_type=content_type + fob.content_type=content_type if REQUEST is not None: REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main') - class extVersionedFile(CatalogAware,Folder): """Versioniertes File""" - default_catalog='fileCatalog' + meta_type = 'extVersionedFile' + # meta_type of contained objects + content_meta_type = ['extVersionedFileObject'] + # default catalog for extVersionedFile objects + default_catalog = 'fileCatalog' - security= ClassSecurityInfo() + manage_options = Folder.manage_options+({'label':'Main Config','action':'changeVersionedFileForm'},) + - security.declarePublic('getTitle') - def getTitle(self): - """get title""" - return self.title + security=ClassSecurityInfo() - def PrincipiaSearchSource(self): - """Return cataloguable key for ourselves.""" - return str(self) - def __init__(self, id, title, lockedBy,author): """init""" self.id=id self.title=title self.lockedBy=lockedBy + if self.lockedBy is None: + self.lockedBy = '' self.author=author + self.lastVersionNumber=0 + self.lastVersionId=None + + security.declarePublic('getTitle') + def getTitle(self): + """get title""" + return self.title + + def PrincipiaSearchSource(self): + """Return cataloguable key for ourselves.""" + return str(self) def manageImagesForm(self): """manage Images attached to the file""" @@ -759,8 +849,6 @@ class extVersionedFile(CatalogAware,Fold return REQUEST.RESPONSE.redirect(self.REQUEST.SESSION['refer']) return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url()) - - def changeImages(self,caption=None,submit=None,id=None,REQUEST=None): """manage URL""" if submit=="change caption": @@ -773,14 +861,10 @@ class extVersionedFile(CatalogAware,Fold if image: self.manage_delObjects([image[0][1].getId()]) - if self.REQUEST.SESSION.has_key('refer'): - return REQUEST.RESPONSE.redirect(self.REQUEST.SESSION['refer']) - return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url()) - - + return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url()) def getImages(self): """get Images""" @@ -789,18 +873,14 @@ class extVersionedFile(CatalogAware,Fold return None else: return images - + security.declarePublic('getComment') def getComment(self): """get the comment of this file""" if not hasattr(self,'comment') or (not self.comment) or (self.comment.lstrip()==""): return "Add comment" - else: return self.comment - - - meta_type="extVersionedFile" def manageCommentForm(self): """add a comment""" @@ -819,52 +899,104 @@ class extVersionedFile(CatalogAware,Fold self.comment_date=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) return REQUEST.RESPONSE.redirect(self.aq_parent.absolute_url()) - - security.declarePublic('getLastChangeDate') + security.declarePublic('getLastChangeDate') def getLastChangeDate(self): """get last change date""" - lv=self.getLastVersion() - time=lv.getTime() - return time + lv=self.getContentObject() + if lv: + time=lv.getTime() + return time + return None def getLastEditor(self): """get last change date""" - lv=self.getLastVersion() + lv=self.getContentObject() le=lv.lastEditor() return le def getLockedBy(self): """get locked by""" + if self.lockedBy is None: + self.lockedBy = '' return str(self.lockedBy) - + + def getLastVersionNumber(self): + """returns the highest version number of all included objects""" + lv = self.findLastVersion() + if lv: + return lv.getVersionNumber() + else: + return 0 + + def findLastVersion(self): + """finds and returns the object with the highest version number""" + lvn=0 + lv=None + + for v in self.objectValues(self.content_meta_type): + logging.debug("findlastversion: check %s"%v.getId()) + if v.getVersionNumber() > lvn: + lvn=v.getVersionNumber() + lv=v + + if lv: + logging.debug("findlastversion: got %s"%lv.getId()) + return lv + security.declarePublic('getLastVersion') def getLastVersion(self): - """Last Version""" + """Last Version (old)""" tmp=0 - lastVersion=None - + lv=None - for version in self.ZopeFind(self): + for v in self.objectValues(self.content_meta_type): + #logging.debug("getlastversion: check %s"%v.getId()) + if v.getVersionNumber() > tmp: + tmp=v.getVersionNumber() + lv=v + + #ogging.debug("getlastversion: got %s"%lv.getId()) + return lv + + def getContentObject(self): + """returns the last version object""" + if not getattr(self, 'lastVersionId', None): + # find last version and save it + lv = self.findLastVersion() + if lv is None: + return None + self.lastVersionNumber = lv.getVersionNumber() + self.lastVersionId = lv.getId() - if hasattr(version[1],'versionNumber'): - - if int(version[1].versionNumber) > tmp: - tmp=int(version[1].versionNumber,) - lastVersion=version[1] - if lastVersion==None: - lastVersion=version[1] - lastVersion.versionNumber=1 - return lastVersion + return getattr(self, self.lastVersionId, None) + + security.declarePublic('getData') + def getData(self): + """Returns the content of the last version""" + logging.debug("+++++++getData2") + ob = self.getContentObject() + if ob is not None: + return ob.getData() + else: + return None + security.declarePublic('view') + def view(self,REQUEST=None,RESPONSE=None): + """Returns the last version's view""" + ob = self.getContentObject() + if ob is not None: + return ob.view(REQUEST=REQUEST,RESPONSE=RESPONSE) + else: + return None def diff(self,data): """differenz between lastversion and data""" d=Differ() - tmp=self.getLastVersion().getData() + tmp=self.getData() #print "XX",data,tmp try: - l=list(d.compare(data.splitlines(1),tmp.splitlines(1))) + l=list(d.compare(data.splitlines(1),tmp.splitlines(1))) except: return 0,"" plus=0 @@ -875,19 +1007,34 @@ class extVersionedFile(CatalogAware,Fold if a[0]=='-': minus+=1 - return max([plus,minus]),l + + security.declarePublic('index_html') def index_html(self): """main view""" - lastVersion=self.getLastVersion() + #lastVersion=self.getContentObject() #return "File:"+self.title+" Version:%i"%lastVersion.versionNumber," modified:",lastVersion.bobobase_modification_time()," size:",lastVersion.getSize(),"modified by:",lastVersion.lastEditor() - return "File: %s Version:%i modified:%s size:%s modified by:%s"%(self.title,lastVersion.versionNumber,lastVersion.getTime(),lastVersion.getSize(),lastVersion.lastEditor()) - + #return "File: %s Version:%i modified:%s size:%s modified by:%s"%(self.title,lastVersion.versionNumber,lastVersion.getTime(),lastVersion.getSize(),lastVersion.lastEditor()) + return self.history() - + def getVersionNr(self,nr): + """get version with number nr""" + tmp=0 + lastVersion=None + + + for version in self.ZopeFind(self): + + if hasattr(version[1],'versionNumber'): + + if int(version[1].versionNumber) ==nr : + return version[1] + + return None security.declarePublic('getVersion') def getVersion(self): + # TODO: this is ugly and it returns the next version number tmp=0 for version in self.ZopeFind(self): @@ -895,14 +1042,10 @@ class extVersionedFile(CatalogAware,Fold if int(version[1].versionNumber) > tmp: tmp=int(version[1].versionNumber,) - return tmp+1 - - - security.declareProtected('AUTHENTICATED_USER','unlock') + return tmp+1 def history(self): """history""" - ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"]) if ext: return getattr(self,ext[0][1].getId())() @@ -919,6 +1062,19 @@ class extVersionedFile(CatalogAware,Fold ret.sort(sortv) return ret + def getVersionList(self): + """get a list of dicts with author, comment, filename, etc, of all versions""" + vl = [] + for v in self.objectValues(self.content_meta_type): + vl.append({'versionNumber':getattr(v,'versionNumber',0), + 'title':v.getTitle(), + 'id':v.getId(), + 'date':v.getTime(), + 'author':getattr(v,'author',''), + 'comment':getattr(v,'versionComment','') + }) + return vl + security.declareProtected('AUTHENTICATED_USER','forceunlock') def forceunlock(self,RESPONSE=None): """unlock""" @@ -939,10 +1095,70 @@ class extVersionedFile(CatalogAware,Fold else: return "Sorry, not locked by you! (%s,%s)"%(self.lockedBy,self.REQUEST['AUTHENTICATED_USER']) + + def _newContentObject(self, id, title='', versionNumber=0, versionComment=None, time=None, author=None): + """factory for content objects. to be overridden in derived classes.""" + return extVersionedFileObject(id,title,versionNumber=versionNumber,versionComment=versionComment,time=time,author=author) + + + def addContentObject(self,id,vC,author=None,file=None,title='',changeName='no',newName='',from_tmp=False,index=True, + precondition='', content_type=''): + """add""" + + if changeName=="yes": + filename=file.filename + self.title=filename[max(filename.rfind('/'), + filename.rfind('\\'), + filename.rfind(':'), + )+1:] + + if not newName=='': + self.title=newName[0:] + + posVersNum=getattr(self,'positionVersionNum','front') + + versNum = self.getLastVersionNumber() + 1 + + if posVersNum=='front': + id="V%i_%s"%(versNum,self.title) + else: + fn=os.path.splitext(self.title) + if len(fn)>1: + id=fn[0]+"_V%i%s"%(versNum,fn[1]) + else: + id=fn[0]+"_V%i"%versNum + # what does this do? + id, title = cookId(id, title, file) + self=self.this() + + # First, we create the file without data: + self._setObject(id, self._newContentObject(id,title,versionNumber=versNum,versionComment=str(vC), + time=time.localtime(),author=author)) + fob = self._getOb(id) + + # Now we "upload" the data. By doing this in two steps, we + # can use a database trick to make the upload more efficient. + if file and not from_tmp: + fob.manage_upload(file) + elif file and from_tmp: + fob.manage_file_upload(file) # manage_upload_from_tmp doesn't exist in ExtFile2 + # fob.manage_upload_from_tmp(file) # manage_upload_from_tmp doesn't exist in ExtFile2 + fob.content_type=content_type + + self.lastVersionNumber = versNum + self.lastVersionId = id + + #logging.debug("addcontentobject: lastversion=%s"%self.getData()) + #logging.debug("addcontentobject: fob_data=%s"%fob.getData()) + if index and self.default_catalog: + logging.debug("reindex1: %s in %s"%(repr(self),repr(self.default_catalog))) + self.reindex_object() + + return fob + security.declareProtected('AUTHENTICATED_USER','addVersionedFileObjectForm') - def addVersionedFileObjectForm(self): """add a new version""" @@ -951,14 +1167,15 @@ class extVersionedFile(CatalogAware,Fold if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''): ext=self.ZopeFind(self.aq_parent,obj_ids=["addNewVersion.dtml"]) if ext: - return ext[0][1]('',globals(),version=self.getVersion(),lastComment=self.getLastVersion().getVersionComment(),AUTHENTICATED_USER=self.REQUEST.AUTHENTICATED_USER) + return ext[0][1]('',globals(),version=self.getVersion(),lastComment=self.getContentObject().getVersionComment(),AUTHENTICATED_USER=self.REQUEST.AUTHENTICATED_USER) else: out=DTMLFile('dtml/fileAdd', globals(),Kind='VersionedFileObject',kind='versionedFileObject',version=self.getVersion()).__of__(self) return out() else: return "Sorry file is locked by somebody else" + - def manage_addVersionedFileObject(self,id,vC,author,file='',title='',precondition='', content_type='',changeName='no',newName='', RESPONSE=None): + def manage_addVersionedFileObject(self,id,vC,author,file='',title='',precondition='', content_type='',changeName='no',newName='', from_tmp=False, RESPONSE=None): """add""" try: #der ganze vC unsinn muss ueberarbeitet werden vC=self.REQUEST['vC'] @@ -966,77 +1183,51 @@ class extVersionedFile(CatalogAware,Fold pass author=self.REQUEST['author'] - - if changeName=="yes": - filename=file.filename - self.title=filename[max(filename.rfind('/'), - filename.rfind('\\'), - filename.rfind(':'), - )+1:] - - - if not newName=='': - self.title=newName[0:] - - - - - positionVersionNum=getattr(self,'positionVersionNum','front') - - if positionVersionNum=='front': - id="V%i"%self.getVersion()+"_"+self.title - else: - tmp=os.path.splitext(self.title) - if len(tmp)>1: - id=tmp[0]+"_V%i"%self.getVersion()+tmp[1] - else: - id=tmp[0]+"_V%i"%self.getVersion() + ob = self.addContentObject(id, vC, author, file, title, changeName=changeName, newName=newName, from_tmp=from_tmp, + precondition=precondition, content_type=content_type) - - manage_addextVersionedFileObject(self,id,vC,author,file,id,precondition, content_type) - objs=self.ZopeFind(self,obj_ids=[id])[0][1].setVersionNumber(int(self.getVersion())) self.REQUEST.SESSION['objID_parent']=self.getId() - if getattr(self,'defaultFileCatalog',None): - - self.reindex_object() - if RESPONSE: - obj=self.ZopeFind(self,obj_ids=[id])[0][1] - if obj.getSize()==0: - self.REQUEST.SESSION['objID']=obj.getId() + if ob.getSize()==0: + self.REQUEST.SESSION['objID']=ob.getId() pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self) return pt() else: - RESPONSE.redirect(self.REQUEST['URL2']) - + RESPONSE.redirect(self.absolute_url()+'/history') else: - return self.ZopeFind(self,obj_ids=[id])[0][1] - - security.declareProtected('AUTHENTICATED_USER','downloadLocked') + return ob - def download(self): - """download and lock""" - self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId()) - self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") - - #try: - # txt=self.getLastVersion.index_html() - #except: - # txt=self.getLastVersion.index_html(REQUEST,RESPONSE) + changeVersionedFileForm = PageTemplateFile('zpt/changeVersionedFile', globals()) + + def manage_changeVersionedFile(self,title,vC,author,comment,RESPONSE=None): + """Change VersionedFile metadata""" + self.title = title + self.author = author + cob = self.getContentObject() + if cob: + if vC: + cob.vComment=vC - #self.REQUEST.RESPONSE.setHeader("Content-Length","str(len(txt)+1000)") - - self.content_type="application/octet-stream" - #self.REQUEST.RESPONSE.write("bl") - #self.REQUEST.RESPONSE.write(txt) - #self.REQUEST.close() + if comment=='': + cob.versionComment=None + else: + cob.versionComment=comment + + if RESPONSE: + RESPONSE.redirect('manage_main') + + + def download(self): + """download""" + + txt=self.REQUEST['URL1']+'/'+self.getId()+'/'+self.getContentObject().getId()+'/download' + + self.REQUEST.RESPONSE.redirect(txt) - #self.getLastVersion().content_type="application/octet-stream" - self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'/'+self.getId()+'/'+self.getLastVersion().getId()) security.declareProtected('AUTHENTICATED_USER','downloadLocked') def downloadLocked(self): @@ -1047,8 +1238,30 @@ class extVersionedFile(CatalogAware,Fold if not self.lockedBy=="": return "cannot be locked because is already locked by %s"%self.lockedBy self.lockedBy=self.REQUEST['AUTHENTICATED_USER'] - self.getLastVersion().content_type="application/octet-stream" - self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'/'+self.getId()+'/'+self.getLastVersion().getId()) + self.getContentObject().content_type="application/octet-stream" + self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+'/'+self.getId()+'/'+self.getContentObject().getId()) + + + security.declareProtected('AUTHENTICATED_USER','fixVersionNumbers') + def fixVersionNumbers(self): + """check last version number and id""" + if not hasattr(self, 'lastVersionId'): + self.lastVersionNumber = 0 + self.lastVersionId = None + + lv = self.getContentObject() + if lv is not None: + lvn = lv.getVersionNumber() + if lvn == 0: + lvn = 1 + lv.versionNumber = 1 + self.lastVersionNumber = lvn + self.lastVersionId = lv.getId() + else: + self.lastVersionNumber = 0 + self.lastVersionId = None + logging.debug("fixing last version number of %s to %s (%s)"%(self.getId(),self.lastVersionNumber,self.lastVersionId)) + def manage_addextVersionedFileForm(self): """interface for adding the OSAS_root""" @@ -1059,7 +1272,7 @@ def manage_addextVersionedFile(self,id,t """add the OSAS_root""" newObj=extVersionedFile(id,title,lockedBy,author) self._setObject(id,newObj) - + if RESPONSE is not None: RESPONSE.redirect('manage_main')