|
|
| version 1.15, 2006/05/04 14:40:09 | version 1.115, 2010/03/19 14:01:41 |
|---|---|
| Line 1 | Line 1 |
| """CDLI extensions of the filearchive""" | """CDLI extensions of the filearchive""" |
| from Products.versionedFile.versionedFile import * | from Products.versionedFile.extVersionedFile import * |
| from Products.ZCatalog.CatalogPathAwareness import CatalogAware | from Products.ZCatalog.CatalogPathAwareness import CatalogAware |
| from tempfile import mkstemp,mkdtemp | |
| import os.path | import os.path |
| import os | import os |
| from types import * | |
| import urlparse | import urlparse |
| import urllib | |
| import cgi | |
| from OFS.OrderedFolder import OrderedFolder | from OFS.OrderedFolder import OrderedFolder |
| from OFS.SimpleItem import SimpleItem | from OFS.SimpleItem import SimpleItem |
| import time | import time |
| from OFS.Folder import manage_addFolder | from OFS.Folder import manage_addFolder |
| import re | import re |
| from AccessControl import ClassSecurityInfo | |
| from Acquisition import Implicit | |
| from Globals import Persistent | |
| from threading import Thread | |
| from ZPublisher.HTTPRequest import HTTPRequest | |
| from ZPublisher.HTTPResponse import HTTPResponse | |
| from ZPublisher.BaseRequest import RequestContainer | |
| import threading | |
| import logging | |
| import transaction | |
| import copy | |
| import codecs | |
| import sys | |
| from BTrees.IOBTree import IOBTree | |
| from BTrees.OOBTree import OOBTree | |
| import cdliSplitter | |
| from sets import Set | |
| import md5 | |
| from DownloadBasket import DownloadBasketFinallyThread | |
| from types import * | |
| import pickle | |
| import tempfile | |
| class Basket_old(Folder): | from cdli_helpers import * |
| """shopping basket - alte fassung """ | |
| meta_type="Basket" | class CDLIFileObject(CatalogAware,extVersionedFileObject): |
| _v_stack={} | """CDLI file object""" |
| def getObjUrl(self,objId): | meta_type="CDLI File Object" |
| """getUrl""" | default_catalog='CDLIObjectsCatalog' |
| founds=self.CDLICatalog.search({'title':objId}) | |
| if len(founds)>0: | |
| return founds[0].getObject().absolute_url() | |
| else: #assume version number | |
| splitted=objId.split("_") | |
| founds=self.CDLICatalog.search({'title':splitted[1]}) | |
| return founds[0].getObject().absolute_url()+'/'+objId | |
| def storeAllLink(self,results): | |
| """erzeuge link zum speicher aller results""" | |
| nr=self.REQUEST['_ZopeId'] | |
| if results: | security=ClassSecurityInfo() |
| self._v_stack[nr]=[x.getObject().getId() for x in results] | |
| return self.absolute_url()+"/storeAll?id="+nr | security.declareProtected('manage','index_html') |
| def storeAll(self,id): | security.declarePublic('view') |
| """store all""" | view = PageTemplateFile('zpt/viewCDLIFile.zpt', globals()) |
| try: | |
| results=self._v_stack[id] | |
| except: | |
| #TODO: write expired page | |
| return "expired" | |
| return self.storeInBasketForm(results) | security.declarePublic('editATF') |
| editATF = PageTemplateFile('zpt/editATFFile.zpt', globals()) | |
| def storeInBasketForm(self,ids): | def PrincipiaSearchSource(self): |
| """ store an object form""" | """Return cataloguable key for ourselves.""" |
| return str(self) | |
| if type(ids) is not ListType: | def setAuthor(self, author): |
| ids=[ids] | """change the author""" |
| self.REQUEST.SESSION['ids']=ids[0:] | self.author = author |
| self.REQUEST.SESSION['BACKLINK']=self.REQUEST['HTTP_REFERER'] | def makeThisVersionCurrent_html(self): |
| """form for mthis version current""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','storeBasketObject.zpt')).__of__(self) | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','makeThisVersionCurrent.zpt')).__of__(self) |
| return pt() | return pt() |
| def storeInBasket(self,username,ids=None,RESPONSE=None,REQUEST=None): | security.declarePublic('makeThisVersionCurrent') |
| """store it""" | def makeThisVersionCurrent(self,comment,author,RESPONSE=None): |
| """copy this version to current""" | |
| if not ids: | parent=self.aq_parent |
| ids=REQUEST.SESSION['ids'] | parent.manage_addVersionedFileObject(id=None,vC=comment,author=author,file=self.getData(),RESPONSE=RESPONSE) |
| #newversion=parent.manage_addCDLIFileObject('',comment,author) | |
| self.REQUEST.SESSION['basketUser']=username | #newversion.manage_upload(self.getData()) |
| baskets=self.ZopeFind(self,obj_ids=[username]) | |
| if len(baskets)>0: | |
| basket=baskets[0][1] | |
| else: | |
| manage_addBasketObject(self,username) | |
| basket=self._getOb(username) | |
| basket.addObjects(ids) | |
| back=self.REQUEST.SESSION.get('BACKLINK', None) | |
| if RESPONSE: | |
| RESPONSE.redirect(back) | |
| def showBasket(self,user=None,set=None,RESPONSE=None): | |
| """show the basket""" | |
| if user: | #if RESPONSE is not None: |
| self.REQUEST.SESSION['basketUser']=user | # RESPONSE.redirect(self.aq_parent.absolute_url()+'/history') |
| if not user and not set: | |
| user=self.REQUEST.SESSION.get('basketUser',None) | |
| if not user: | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','orizeBasketUser.zpt')).__of__(self) | |
| return pt() | |
| else: | |
| baskets=self.ZopeFind(self,obj_ids=[user]) | |
| if len(baskets)>0: | |
| RESPONSE.redirect(baskets[0][1].absolute_url()) | |
| return True | return True |
| else: | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','emptyBasket.zpt')).__of__(self) | |
| return pt() | |
| def manage_addBasket_oldForm(self): | |
| """add the basket form""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addBasket.zpt')).__of__(self) | |
| return pt() | |
| def manage_addBasket_old(self,id,title,RESPONSE=None): | def getFormattedData(self): |
| """add the basket""" | """fromat text""" |
| ob=Basket() | data=self.getData() |
| # return re.sub("\s\#lem"," #lem",data) #remove return vor #lem | |
| ob.id=str(id) | return re.sub("#lem"," #lem",data) #remove return vor #lem |
| ob.title=title | |
| self._setObject(id, ob) | |
| ob=self._getOb(id) | |
| if RESPONSE is not None: | |
| RESPONSE.redirect('manage_main') | |
| class BasketObject_old(Folder): | security.declarePublic('getPNumber') |
| """Basket Object - alte fassung""" | def getPNumber(self): |
| """get the pnumber""" | |
| meta_type="basketObject" | try: |
| def __init__(self): | txt=re.match("&[PpSs](\d*)\s*=([^\r\n]*)",self.getData()[0:]) |
| """init basket object""" | except: |
| self.contents=[] | txt=self.getData()[0:] |
| def numberOfItems(self): | |
| """return anzahl der elemente im basket""" | |
| return len(self.contents) | |
| def addObjects(self,ids): | return "ERROR" |
| """addObjects""" | try: |
| return "P"+txt.group(1) | |
| except: | |
| return "ERROR" | |
| for id in ids: | security.declarePublic('getDesignation') |
| founds=self.CDLICatalog.search({'title':id}) | def getDesignation(self): |
| for found in founds: | """get the designation out of the file""" |
| if found.getObject() not in self.contents: | try: |
| tm=self.contents[0:] | txt=re.match("&[PpSs](\d*)\s*=([^\r\n]*)",self.getData()[0:]) |
| tm.append(found.getObject()) | except: |
| self.contents=tm[0:] | txt=self.getData()[0:] |
| return True | return "ERROR" |
| try: | |
| return txt.group(2) | |
| except: | |
| return "ERROR" | |
| def index_html(self): | |
| """view the basket""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','basketObject_index_html.zpt')).__of__(self) | |
| return pt() | |
| def deleteObjects(self,ids,RESPONSE=None): | manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1') |
| """delete objects""" | |
| list = self.contents[0:] | |
| for content in list: | |
| if content.getId() in ids: | def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',versionNumber=0, |
| self.contents.remove(content) | precondition='', content_type='', |
| from_tmp=False,REQUEST=None): | |
| """Add a new File object. | |
| Creates a new File object 'id' with the contents of 'file'""" | |
| id=str(id) | |
| title=str(title) | |
| content_type=str(content_type) | |
| precondition=str(precondition) | |
| if RESPONSE: | id, title = cookId(id, title, file) |
| RESPONSE.redirect(self.absolute_url()) | |
| self=self.this() | |
| def unlockTest(self): | # First, we create the file without data: |
| """unlock all files of the testuser for debuggin""" | self._setObject(id, CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=vC,time=time.localtime(),author=author)) |
| for object in self.contents: | fob = self._getOb(id) |
| if str(object.lockedBy)=="test": | # Now we "upload" the data. By doing this in two steps, we |
| object.lockedBy="" | # can use a database trick to make the upload more efficient. |
| def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None): | if file and not from_tmp: |
| """download all selected files in one file""" | 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 | |
| if content_type: | |
| fob.content_type=content_type | |
| ret="" | #logging.debug("manage_add: lastversion=%s"%self.getData()) |
| lockedObjects={} | logging.debug("reindex1: %s in %s"%(repr(self),repr(self.default_catalog))) |
| self.reindex_object() | |
| #logging.debug("manage_add: fob_data=%s"%fob.getData()) | |
| logging.debug("reindex2: %s in %s"%(repr(fob), repr(fob.default_catalog))) | |
| fob.index_object() | |
| self.CDLIRoot.updateOrAddToFileBTree(ob) | |
| if REQUEST is not None: | |
| REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main') | |
| if lock: | |
| if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User': | class CDLIFile(extVersionedFile,CatalogAware): |
| """CDLI file""" | |
| return "please login first" | security=ClassSecurityInfo() |
| meta_type="CDLI file" | |
| content_meta_type = ["CDLI File Object"] | |
| #check if a locked object exist in the basket. | default_catalog='CDLICatalog' |
| lockedObjects={} | |
| for object in self.contents: | |
| if not object.lockedBy=="": | security.declareProtected('manage','index_html') |
| lockedObjects[object.title]=repr(object.lockedBy) | |
| def getLastVersionData(self): | |
| """get last version data""" | |
| return self.getData() | |
| def getLastVersionFormattedData(self): | |
| """get last version data""" | |
| return self.getContentObject().getFormattedData() | |
| def getTextId(self): | |
| """returns P-number of text""" | |
| # assuming that its the beginning of the title | |
| return self.title[:7] | |
| keys=lockedObjects.keys() | #security.declarePublic('history') |
| def history(self): | |
| """history""" | |
| ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"]) | |
| if ext: | |
| return getattr(self,ext[0][1].getId())() | |
| if len(keys)>0 and (not procedure): | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','versionHistory')).__of__(self) |
| self.REQUEST.SESSION['lockedObjects']=lockedObjects | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self) | |
| return pt() | return pt() |
| elif not procedure: #keine fails gesperrt dann alle donwloaden | |
| procedure="downloadAll" | |
| print procedure | def getBasketFromId(self,basketid, context=None): |
| for object in self.contents: | """get basket from id""" |
| if (procedure=="downloadAll") or (object.lockedBy=='') or (object.lockedBy==self.REQUEST['AUTHENTICATED_USER']): | if not context: |
| ret+=object.getLastVersion().data | context=self |
| if lock and object.lockedBy=='': | for basket in self.ZopeFind(context,obj_metatypes=["CDLIBasket"]): |
| object.lockedBy=self.REQUEST['AUTHENTICATED_USER'] | if basket[0]==basketid: |
| return basket[1] | |
| else: | |
| None | |
| self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="basket_%s.atf" """%self.getId()) | def isContainedInBaskets(self,context=None): |
| self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") | """check is this file is part of any basket |
| length=len(ret) | @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog |
| self.REQUEST.RESPONSE.setHeader("Content-Length",length) | has to exist. |
| self.REQUEST.RESPONSE.write(ret) | """ |
| if not context: | |
| context=self | |
| def manage_addBasket_oldObjectForm(self): | ret=[] |
| """add form""" | for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}): |
| #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why? | |
| try: | |
| ret.append(x.getObject()) | |
| except: | |
| pass | pass |
| return ret | |
| #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})] | |
| def manage_addBasket_oldObject(self,id,title='',RESPONSE=None): | |
| """add""" | |
| ob=BasketObject() | |
| ob.id=str(id) | |
| ob.title=title | |
| self._setObject(id, ob) | |
| ob=self._getOb(id) | |
| if RESPONSE is not None: | |
| RESPONSE.redirect('manage_main') | |
| class CDLIBasketContainer(OrderedFolder): | |
| """contains the baskets""" | |
| def _newContentObject(self, id, title='', versionNumber=0, versionComment=None, time=None, author=None): | |
| """factory for content objects. to be overridden in derived classes.""" | |
| logging.debug("_newContentObject(CDLI)") | |
| return CDLIFileObject(id,title,versionNumber=versionNumber,versionComment=versionComment,time=time,author=author) | |
| security=ClassSecurityInfo() | |
| meta_type="CDLIBasketContainer" | |
| def deleteBaskets(self,ids=None): | def addCDLIFileObjectForm(self): |
| """delete baskets, i.e. move them into trash folder""" | """add a new version""" |
| if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]: | |
| return "please login first" | |
| if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''): | |
| out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self) | |
| return out() | |
| else: | |
| return "Sorry file is locked by somebody else" | |
| found=self.ZopeFind(self,obj_ids=['trash']) | def manage_addCDLIFileObject(self,id,vC,author, |
| file='',title='', | |
| precondition='', | |
| content_type='', | |
| changeName='no',newName='', | |
| come_from=None, | |
| from_tmp=False,RESPONSE=None): | |
| """add""" | |
| if len(found)<1: | try: #TODO: der ganze vC unsinn muss ueberarbeitet werden |
| manage_addFolder(self, 'trash') | vC=self.REQUEST['vC'] |
| trash=self._getOb('trash') | except: |
| else: | pass |
| trash=found[0][1] | |
| if type(ids) is not ListType: | ob = self.addContentObject(id, vC, author, file, title, changeName=changeName, newName=newName, from_tmp=from_tmp, |
| ids=[ids] | precondition=precondition, content_type=content_type) |
| cut=self.manage_cutObjects(ids) | |
| trash.manage_pasteObjects(cut) | |
| def manageBaskets(self,ids,submit,REQUEST=None,RESPONSE=None): | try: |
| """manage baskets, delete or copy""" | #FIXME: wozu ist das gut? |
| if submit=="delete": | self.REQUEST.SESSION['objID_parent']=self.getId() |
| self.deleteBaskets(ids) | except: |
| pass | |
| #self.cdliRoot.updateOrAddToFileBTree(self)# now update the object in the cache | |
| if RESPONSE: | if RESPONSE: |
| RESPONSE.redirect(self.absolute_url()) | if ob.getSize()==0: |
| def getBasketIdfromName(self,basketname): | self.REQUEST.SESSION['objID']=ob.getId() |
| """get id from name""" | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self) |
| return pt() | |
| for basket in self.ZopeFind(self,obj_metatypes=["CDLIBasket"]): | |
| if basket[1].title==basketname: | |
| return basket[0] | |
| else: | else: |
| None | if come_from and (come_from!=""): |
| RESPONSE.redirect(come_from+"?change="+self.getId()) | |
| security.declareProtected('manage','uploadBasket_html') | |
| def uploadBasket_html(self,basketId='0'): | |
| """upload an atf file, html form""" | |
| basketId=str(basketId) | |
| if not basketId=='0': | |
| basketName=getattr(self.basketContainer,basketId).title | |
| else: | else: |
| basketName="" | RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title) |
| else: | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadBasket_html.zpt')).__of__(self) | return ob |
| return pt(basketId=basketId,basketName=basketName) | |
| def index_html(self): | |
| """stanadard ansicht""" | |
| ext=self.ZopeFind(self,obj_ids=["index.html"]) | |
| if ext: | |
| return ext[0][1]() | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketContainerMain')).__of__(self) | def manage_addCDLIFileForm(self): |
| """interface for adding the OSAS_root""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self) | |
| return pt() | return pt() |
| def getStorageFolderRoot(self): | def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None): |
| """root des storage folders""" | """add the OSAS_root""" |
| return self.cdli_main | newObj=CDLIFile(id,title,lockedBy,author) |
| def __init__(self,id,title): | |
| """ init basket container""" | |
| self.id=id | |
| self.title=title | |
| def getBaskets(self,sortField='title'): | |
| """get all baskets files""" | |
| def sortName(x,y): | |
| return cmp(x[1].title.lower(),y[1].title.lower()) | |
| def sortDate(x,y): | |
| return cmp(y[1].getLastVersion().getTime(),x[1].getLastVersion().getTime()) | |
| def sortComment(x,y): | |
| try: | tryToggle=True |
| xc=getattr(x[1],'comment','ZZZZZZZZZZZZZ').lower() | tryCount=0 |
| except: | |
| xc='ZZZZZZZZZZZZZ'.lower() | |
| try: | |
| yc=getattr(y[1],'comment','ZZZZZZZZZZZZZ').lower() | |
| except: | |
| yc='ZZZZZZZZZZZZZ'.lower() | |
| self._setObject(id,newObj) | |
| getattr(self,id).reindex_object() | |
| if (xc=='') or (xc=='ZZZZZZZZZZZZZ'.lower()): | if RESPONSE is not None: |
| RESPONSE.redirect('manage_main') | |
| try: | |
| xc=x[1].getLastVersion().getComment().lower() | |
| except: | |
| xc='ZZZZZZZZZZZZZ'.lower() | |
| if (yc=='') or (yc=='ZZZZZZZZZZZZZ'.lower()): | def checkUTF8(data): |
| """check utf 8""" | |
| try: | try: |
| yc=y[1].getLastVersion().getComment().lower() | data.encode('utf-8') |
| return True | |
| except: | except: |
| yc='ZZZZZZZZZZZZZ'.lower() | return False |
| return cmp(xc,yc) | |
| def sortAuthor(x,y): | |
| return cmp(x[1].getLastVersion().getUser().lower(),y[1].getLastVersion().getUser().lower()) | def checkFile(filename,data,folder): |
| """check the files""" | |
| # first check the file name | |
| fn=filename.split(".") # no extension | |
| if not (fn[0][0]=="P" or fn[0][0]=="S"): | |
| return False,"P/S missing in the filename" | |
| elif len(fn[0])!=7: | |
| return False,"P number has not the right length 6" | |
| elif not checkUTF8(data): | |
| return False,"not utf-8" | |
| else: | |
| return True,"" | |
| baskets=self.ZopeFind(self,obj_metatypes=['CDLIBasket']) | |
| def splitatf(fh,dir=None,ext=None): | |
| """split it""" | |
| ret=None | |
| nf=None | |
| i=0 | |
| if sortField=='title': | #ROC: why split \n first and then \r??? |
| baskets.sort(sortName) | if (type(fh) is StringType) or (type(fh) is UnicodeType): |
| elif sortField=='date': | iter=fh.split("\n") |
| baskets.sort(sortDate) | else: |
| elif sortField=='author': | iter=fh.readlines() |
| baskets.sort(sortAuthor) | |
| elif sortField=='comment': | for lineTmp in iter: |
| baskets.sort(sortComment) | lineTmp=lineTmp.replace(codecs.BOM_UTF8,'') # make sure that all BOM are removed.. |
| for line in lineTmp.split("\r"): | |
| #logging.info("Deal with: %s"%line) | |
| if ext: | |
| i+=1 | |
| if (i%100)==0: | |
| ext.result+="." | |
| if i==10000: | |
| i=0 | |
| ext.result+="<br>" | |
| #check if basket name is in the first line | |
| if line.find("#atf basket")>=0: #old convention | |
| ret=line.replace('#atf basket ','') | |
| ret=ret.split('_')[0] | |
| elif line.find("#basket:")>=0: #new convention | |
| ret=line.replace('#basket: ','') | |
| ret=ret.split('_')[0] | |
| return baskets | else: |
| if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile | |
| if nf: | |
| nf.close() #close last file | |
| filename=line[1:].split("=")[0].rstrip()+".atf" | |
| if dir: | |
| filename=os.path.join(dir,filename) | |
| nf=file(filename,"w") | |
| logging.info("open %s"%filename) | |
| if nf: | |
| nf.write(line.replace("\n","")+"\n") | |
| def getNewId(self): | try: |
| """createIds""" | nf.close() |
| last=getattr(self,'last',0) | except: |
| last +=1 | pass |
| while len(self.ZopeFind(self,obj_ids=[str(last)]))>0: | |
| last+=1 | |
| self.last=last | if not((type(fh) is StringType) or (type(fh) is UnicodeType)): |
| return last | fh.close() |
| return ret,len(os.listdir(dir)) | |
| def setActiveBasket(self,basketId,REQUEST=None): | |
| """store active basketId in a cookie""" | |
| self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/") | |
| if REQUEST: | class CDLIFileFolder(extVersionedFileFolder): |
| REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+REQUEST['QUERY_STRING']) | """CDLI File Folder""" |
| def getActiveBasket(self): | security=ClassSecurityInfo() |
| """get active basket from cookie""" | meta_type="CDLI Folder" |
| file_meta_type=['CDLI file'] | |
| folder_meta_type=['CDLI Folder'] | |
| id= self.REQUEST.cookies.get('CDLIActiveBasket',None) | file_catalog='CDLICatalog' |
| if id: | |
| obj=getattr(self,str(id),None) | |
| else: | |
| obj=None | |
| return obj | |
| def getActualUserName(self): | #downloadCounter=0 # counts how many download for all files currently run, be mehr als 5 wird verweigert. |
| """get name of the actualuser""" | tmpStore2={} |
| return str(self.REQUEST['AUTHENTICATED_USER']) | |
| def _newVersionedFile(self, id, title='', lockedBy=None, author=None): | |
| """factory for versioned files. to be overridden in derived classes.""" | |
| logging.debug("_newVersionedFile(CDLI)") | |
| return CDLIFile(id, title, lockedBy=lockedBy, author=author) | |
| def addBasket(self,newBasketName): | def setTemp(self,name,value): |
| """add a new basket""" | """set tmp""" |
| ob=manage_addCDLIBasket(self,newBasketName) | setattr(self,name,value) |
| return ob | |
| def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None): | deleteFileForm = PageTemplateFile("zpt/doDeleteFile", globals()) |
| """store it""" | |
| if not ids: | |
| ids=self.REQUEST.SESSION['fileIds'] | |
| def delete(self,ids,REQUEST=None): | |
| """delete these files""" | |
| if type(ids) is not ListType: | if type(ids) is not ListType: |
| ids=[ids] | ids=[ids] |
| if (submit.lower()=="store in new basket") or (submit.lower()=="new basket"): | self.manage_delObjects(ids) |
| basketRet=self.addBasket(newBasketName) | |
| self.setActiveBasket(basketRet.getId()) | |
| basket=getattr(self,basketRet.getId()) | |
| elif (submit.lower()=="store in active basket") or (submit.lower()=="active basket"): | |
| basket=self.getActiveBasket() | |
| added=basket.addObjects(ids) | |
| back=self.REQUEST['HTTP_REFERER'].split("?")[0]+"?basketName="+basket.title+"&numberOfObjects="+str(added) | |
| if fromFileList: | |
| return self.cdli_main.findObjectsFromList(list=self.REQUEST.SESSION['fileIds'],basketName=basket.title,numberOfObjects=added) | |
| if RESPONSE: | |
| RESPONSE.redirect(back) | |
| return True | |
| def manage_addCDLIBasketContainerForm(self): | |
| """add the CDLIBasketContainer form""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasketContainer.zpt')).__of__(self) | |
| return pt() | |
| def manage_addCDLIBasketContainer(self,id,title,RESPONSE=None): | |
| """add the basket""" | |
| ob=CDLIBasketContainer(id,title) | |
| self._setObject(id, ob) | |
| if RESPONSE is not None: | |
| RESPONSE.redirect('manage_main') | |
| class CDLIBasket(Folder,CatalogAware): | if REQUEST is not None: |
| """basket""" | return self.index_html() |
| meta_type="CDLIBasket" | |
| default_catalog="CDLIBasketCatalog" | |
| def getFile(self,obj): | |
| return obj[1] | |
| def getFileLastVersion(self,obj): | def getVersionNumbersFromIds(self,ids): |
| return obj[0] | """get the numbers of the current versions of documents described by their ids""" |
| def getFileNamesInLastVersion(self): | ret=[] |
| """get content of the last version as list""" | searchStr=" OR ".join(ids) |
| return [x[1].getId() for x in self.getLastVersion().getContent()] | founds=self.CDLICatalog.search({'title':searchStr}) |
| def isActual(self,obj): | for found in founds: |
| """teste ob im basket die aktuelle version ist""" | lastVersion=found.getObject().getContentObject() |
| actualNo=obj[1].getLastVersion().getVersionNumber() | ret.append((found.getId,lastVersion)) |
| storedNo=obj[0].getVersionNumber() | |
| founds=self.CDLICatalog.search({'title':obj[0].getId()}) | return ret |
| if len(founds)>0 and founds[0].getObject().aq_parent.getId()==".trash": | |
| return False, -1 | |
| if actualNo==storedNo: | def getFile(self,fn): |
| return True , 0 | """get the content of the file fn""" |
| logging.debug("getFile: %s"%repr(fn)) | |
| if not self.hasObject(fn): | |
| # search deeper | |
| founds=getattr(self, self.file_catalog).search({'textid':fn}) | |
| if founds: | |
| obj=founds[0].getObject().getContentObject() | |
| else: | else: |
| return False, actualNo | return "" |
| else: | |
| def history(self): | obj = self[fn].getContentObject() |
| """history""" | |
| ext=self.ZopeFind(self.aq_parent,obj_ids=["history_template.html"]) | |
| if ext: | |
| return getattr(self,ext[0][1].getId())() | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketHistory')).__of__(self) | |
| return pt() | |
| def getStorageFolderRoot(self): | |
| """root des storage folders""" | |
| return self.aq_parent.cdli_main | |
| def __init__(self,id,title,shortDescription="",comment=""): | |
| """init a CDLIBasket""" | |
| self.id=id | |
| self.title=title | |
| self.shortDescription=shortDescription | |
| self.comment=comment | |
| return obj.getData()[0:] | |
| def getLastVersion(self): | def checkCatalog(self,fn): |
| """hole letzte version""" | """check if fn is in the catalog""" |
| ids=[int(x[0]) for x in self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"])] | #TODO add checkCatalog |
| ids.sort() | |
| if len(ids)==0: | |
| return None | |
| else: | |
| ob=getattr(self,str(ids[-1])) | |
| return ob | |
| def getVersions(self): | |
| """get versions""" | |
| versions=self.ZopeFind(self,obj_metatypes=["CDLIBasketVersion"]) | |
| return versions | |
| def findObjectsFromListWithVersion(self,list,author=None): | |
| """find objects from a list with versions | |
| @param list: list of tuples (cdliFile,version) | |
| """ | |
| #self.REQUEST.SESSION['fileIds']=list#store fieldIds in session for further usage | |
| #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds'] | |
| pt=getattr(self,'filelistVersioned.html') | |
| def addObjects(self,ids,deleteOld=None): | return pt(search=list,author=author) |
| """generate a new version of the basket with objects added""" | |
| lastVersion=self.getLastVersion() | |
| if lastVersion is None: | def getAllPNumbers(self): |
| oldContent=[] | """get a list of all files (resp their p-numbers) stored""" |
| else: | |
| oldContent=lastVersion.basketContent[0:] | |
| if deleteOld: | ret=[x.getId for x in self.CDLICatalog()] |
| oldContent=[] | |
| newContent=[] | return ret |
| added=0 | |
| for id in ids: | |
| founds=self.CDLICatalog.search({'title':id}) | |
| def expandFile(self,fileId,fileTree): | |
| """wildcard in fileID suche alle Treffer""" | |
| founds=self.CDLICatalog({'title':fileId}) | |
| for found in founds: | for found in founds: |
| if found.getObject() not in oldContent: | fileTree.add(found.getId) |
| #TODO: was passiert wenn, man eine Object dazufŸgt, das schon da ist aber eine neuere version | logging.debug("ADDD:"+found.getId) |
| newContent.append((found.getObject().getLastVersion(),found.getObject())) | |
| added+=1 | |
| content=oldContent+newContent | |
| user=self.getActualUserName() | 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): |
| """findObjectsFromList (, TAB oder LINE separated)""" | |
| ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content) | |
| return added | logging.debug("start: findObjectsFromList") |
| #logging.debug("start: findObjectsFromList"+repr(list)) | |
| def deleteObjects(self,ids,RESPONSE=None,REQUEST=None): | |
| """delete objects""" | |
| if type(ids) is not ListType: | if upload: # list from file upload |
| ids=[ids] | txt=upload.read() |
| lastVersion=self.getLastVersion() | if enterList: |
| oldContent=lastVersion.basketContent[0:] | txt=enterList |
| newContent=[] | |
| for obj in oldContent: | |
| if obj[1].getId() not in ids: | |
| newContent.append(obj) | |
| if upload or enterList: | |
| txt=txt.replace(",","\n") | |
| txt=txt.replace("\t","\n") | |
| txt=txt.replace("\r","\n") | |
| idsTmp=txt.split("\n") | |
| ids=[] | |
| for id in idsTmp: # make sure that no empty lines | |
| idTmp=id.lstrip().rstrip() | |
| if len(idTmp)>0: | |
| user=self.getActualUserName() | ids.append(idTmp) |
| ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=newContent) | #self.REQUEST.SESSION['ids']=" OR ".join(ids) |
| if RESPONSE: | pt=getattr(self,'filelist.html') |
| obj=self._getOb(ob.getId()) | self.REQUEST.SESSION['searchList']=ids |
| RESPONSE.redirect(obj.absolute_url()) | return pt(search=ids) |
| def manage_addCDLIBasketForm(self): | if basketName: |
| """add the CDLIBasketContainer form""" | #TODO: get rid of one of these.. |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIBasket.zpt')).__of__(self) | |
| return pt() | |
| def manage_addCDLIBasket(self,title,shortDescription="",comment="",RESPONSE=None): | pt=getattr(self,'filelist.html') |
| """add the basket""" | return pt(basketName=basketName,numberOfObjects=numberOfObjects) |
| id=str(self.getNewId()) | |
| ob=CDLIBasket(id,title,shortDescription,comment) | result =self.CDLICache.retrieve(hash) |
| if result: | |
| logging.debug("give result from storage2") | |
| return hash,result | |
| self._setObject(id, ob) | if list is not None: # got already a list |
| if RESPONSE is not None: | logging.debug(" ----List version") |
| RESPONSE.redirect('manage_main') | ret=[] |
| else: | fileTree=Set() |
| return ob | |
| class CDLIBasketVersion(SimpleItem): | for fileId in list: |
| """version of a basket""" | |
| meta_type="CDLIBasketVersion" | if fileId.find("*")>-1: #check for wildcards |
| self.expandFile(fileId,fileTree) | |
| def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None): | elif len(fileId.split("."))==1: |
| """download all selected files in one file""" | fileId=fileId+".atf" |
| fileTree.add(fileId) | |
| #logging.debug(" -----:"+fileId) | |
| #ret+=self.CDLICatalog({'title':fileId}) | |
| #x =self.getFileObject(fileId) | |
| #if x is not None: | |
| # ret.append(x) | |
| ret="" | |
| lockedObjects={} | |
| if lock: | ids = fileTree & self.v_file_ids |
| #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage | |
| l=makelist(fileTree)[0:] | |
| #logging.debug("l-list:"+repr(l)) | |
| self.REQUEST.SESSION['fileIds']=l#store fieldIds in session for further usage | |
| self.REQUEST.SESSION['searchList']=l | |
| #self.REQUEST.SESSION['searchList']=['P000001.atf'] | |
| hash = md5.new(repr(makelist(fileTree))).hexdigest() # erzeuge hash als identification | |
| self.REQUEST.SESSION['hash']=hash | |
| #TODO: do I need garbage collection for v_tmpStore ? | |
| #logging.debug("Hash:"+repr(hash)) | |
| # | |
| # if hasattr(self.cdliRoot,'v_tmpStore') and self.cdliRoot.v_tmpStore.has_key(hash): | |
| # logging.debug("asking for storage") | |
| # res=self.cdliRoot.v_tmpStore[hash] | |
| # if res: | |
| # if returnHash == True: | |
| # return hash,res | |
| # return res | |
| if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User': | #TODO: get rid of one of these.. |
| #ids=[x.getObject().getId() for x in ret] | |
| ret=[(self.getFileObject(x),self.getFileObjectLastVersion(x)) for x in ids] | |
| return "please login first" | #self.REQUEST.SESSION['fileIds']=ids#store fieldIds in session for further usage |
| #self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds'] | |
| #check if a locked object exist in the basket. | if display: |
| lockedObjects={} | pt=getattr(self,'filelist.html') |
| for object in self.basketContent: | |
| if not object[1].lockedBy=="": | return pt(search=ids) |
| lockedObjects[object[1].title]=repr(object[1].lockedBy) | else: |
| #self.REQUEST.SESSION['hash'] = ret # store in session | |
| #logging.debug("HHHHHHNEU:"+repr(self.makelist(ids))) | |
| #logging.debug("HHHHHHNEU:"+repr(hash)) | |
| self.CDLICache.store(hash,ret) | |
| keys=lockedObjects.keys() | if returnHash == True: |
| return hash,ret | |
| return ret | |
| if len(keys)>0 and (not procedure): | |
| self.REQUEST.SESSION['lockedObjects']=lockedObjects | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','lockedObjects.zpt')).__of__(self) | |
| return pt() | |
| elif not procedure: #keine fails gesperrt dann alle donwloaden | if start: |
| procedure="downloadAll" | RESPONSE.redirect("filelist.html?start:int="+str(start)) |
| security.declareProtected('Manage','createAllFilesAsSingleFile') | |
| def createAllFilesAsSingleFile(self,RESPONSE=None): | |
| """download all files""" | |
| for object in self.basketContent: | def sortF(x,y): |
| return cmp(x[0],y[0]) | |
| if (procedure=="downloadAll") or (object[1].lockedBy=='') or (object[1].lockedBy==self.REQUEST['AUTHENTICATED_USER']): | catalog=getattr(self,self.file_catalog) |
| ret+=object[0].data | #tf,tfilename=mkstemp() |
| if not hasattr(self.temp_folder,'downloadCounter'): | |
| self.temp_folder.downloadCounter=0 | |
| if lock and object[1].lockedBy=='': | if getattr(self.temp_folder,'downloadCounter',0) > 5: |
| object[1].lockedBy=self.REQUEST['AUTHENTICATED_USER'] | return """I am sorry, currently the server has to many requests for downloads, please come back later!""" |
| basket_name=self.aq_parent.title+"_V"+self.getId() | self.temp_folder.downloadCounter+=1 |
| self._p_changed=1 | |
| transaction.get().commit() | |
| #write basketname to header of atf file | list=[(x.getId,x) for x in catalog()] |
| ret="#atf basket %s\n"%basket_name+ret | list.sort(sortF) |
| self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.atf" """%basket_name) | |
| self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") | |
| length=len(ret) | |
| self.REQUEST.RESPONSE.setHeader("Content-Length",length) | |
| self.REQUEST.RESPONSE.write(ret) | |
| def numberOfItems(self): | |
| """return anzahl der elemente im basket""" | |
| return len(self.basketContent) | |
| 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 | |
| else: | |
| setattr(self,'timefixed',self.bobobase_modification_time().ISO()) | |
| return self.bobobase_modification_time().ISO() | |
| def getContent(self): | |
| """get Basket Content""" | |
| return self.basketContent | |
| def __init__(self,id,user,comment="",basketContent=[]): | |
| """ init a basket version""" | |
| self.id=id | |
| self.coment=comment | |
| self.basketContent=basketContent[0:] | |
| self.user=user | |
| self.time=time.localtime() | |
| def getUser(self): | |
| """get user""" | |
| return self.user | |
| def getComment(self): | |
| """get Comment""" | |
| return self.comment | |
| def index_html(self): | |
| """view the basket""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','BasketVersionMain.zpt')).__of__(self) | |
| return pt() | |
| def getObjUrl(self,result): | RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf") |
| """getUrl of the version of the object""" | RESPONSE.setHeader("Content-Type","application/octet-stream") |
| objId=result[1].getTitle() | tmp="" |
| founds=self.CDLICatalog.search({'title':objId}) | for l in list: |
| if len(founds)>0: | obj=l[1].getObject() |
| return founds[0].getObject().getLastVersion().absolute_url() | |
| else: #assume version number | if obj.meta_type=="CDLI file": |
| splitted=objId.split("_") | |
| founds=self.CDLICatalog.search({'title':splitted[1]}) | |
| return founds[0].getObject().getLastVersion().absolute_url()+'/'+objId | |
| def manage_addCDLIBasketVersion(self,user,comment="",basketContent=[],RESPONSE=None): | #os.write(tf,obj.getLastVersion().data) |
| """add a version""" | if RESPONSE: |
| RESPONSE.write(obj.getData()[0:]) | |
| RESPONSE.write("\n") | |
| self.temp_folder.downloadCounter-=1 | |
| self._p_changed=1 | |
| transaction.get().commit() | |
| #os.close(tf) | |
| #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename) | |
| return True | |
| #check for already existing versions | def downloadFile(self,fn): |
| """download fn - not used yet""" | |
| self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId()) | |
| self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") | |
| self.REQUEST.RESPONSE.write(file(fn).read()) | |
| lastVersion=self.getLastVersion() | |
| if lastVersion is None: | |
| newId=str(1) | |
| else: | |
| newId=str(int(lastVersion.getId())+1) | |
| ob=CDLIBasketVersion(newId,user,comment,basketContent) | |
| self._setObject(newId, ob) | def hasParent(self): |
| """returns true falls subfolder""" | |
| if RESPONSE is not None: | if self.aq_parent.meta_type in self.folder_meta_type: |
| RESPONSE.redirect('manage_main') | return True |
| else: | else: |
| return ob | return False |
| class CDLIFileObject(versionedFileObject): | def getFolders(self): |
| """CDLI file object""" | """get all subfolders""" |
| ret=[] | |
| folders=self.ZopeFind(self,obj_metatypes=self.folder_meta_type) | |
| for folder in folders: | |
| ret.append((folder[1], | |
| len(self.ZopeFind(folder[1],obj_metatypes=self.folder_meta_type)), | |
| len(self.ZopeFind(folder[1],obj_metatypes=self.file_meta_type)) | |
| )) | |
| return ret | |
| meta_type="CDLI File Object" | |
| security=ClassSecurityInfo() | security.declareProtected('manage','index_html') |
| def index_html(self): | |
| """main""" | |
| ext=self.ZopeFind(self,obj_ids=["index.html"]) | |
| if ext: | |
| return ext[0][1]() | |
| def view(self): | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self) |
| """view file""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','viewCDLIFile.zpt')).__of__(self) | |
| return pt() | return pt() |
| security.declarePublic('getDesignation') | |
| def getDesignation(self): | |
| """get the designation out of the file""" | |
| try: | |
| txt=re.search("&[Pp](.*)= (.*)",self.data[0:]) | |
| except: | |
| print self.getId() | |
| txt=self.data[0:] | |
| print str(txt) | |
| return "ERROR" | manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals()) |
| try: | |
| return txt.group(2) | |
| except: | |
| return "ERROR" | |
| manage_addCDLIFileObjectForm=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject', version='1') | |
| def manage_addCDLIFileObject(self,id,vC='',author='', file='',title='',precondition='', content_type='', | def manage_addCDLIFileFolder(self, id, title='', |
| createPublic=0, | |
| createUserF=0, | |
| REQUEST=None): | REQUEST=None): |
| """Add a new File object. | """Add a new Folder object with id *id*. |
| Creates a new File object 'id' with the contents of 'file'""" | |
| id=str(id) | |
| title=str(title) | |
| content_type=str(content_type) | |
| precondition=str(precondition) | |
| id, title = cookId(id, title, file) | |
| self=self.this() | If the 'createPublic' and 'createUserF' parameters are set to any true |
| value, an 'index_html' and a 'UserFolder' objects are created respectively | |
| in the new folder. | |
| """ | |
| ob=CDLIFileFolder() | |
| ob.id=str(id) | |
| ob.title=title | |
| self._setObject(id, ob) | |
| ob=self._getOb(id) | |
| # First, we create the file without data: | checkPermission=getSecurityManager().checkPermission |
| self._setObject(id, CDLIFileObject(id,title,'',content_type, precondition)) | |
| self._getOb(id).versionComment=str(vC) | |
| self._getOb(id).time=time.localtime() | |
| setattr(self._getOb(id),'author',author) | if createUserF: |
| if not checkPermission('Add User Folders', ob): | |
| raise Unauthorized, ( | |
| 'You are not authorized to add User Folders.' | |
| ) | |
| ob.manage_addUserFolder() | |
| # 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) | |
| if content_type: | |
| self._getOb(id).content_type=content_type | |
| if REQUEST is not None: | if REQUEST is not None: |
| REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main') | return self.manage_main(self, REQUEST, update_menu=1) |
| class CDLIFile(versionedFile,CatalogAware): | class CDLIRoot(Folder): |
| """CDLI file""" | """main folder for cdli""" |
| meta_type="CDLI file" | meta_type="CDLIRoot" |
| default_catalog='CDLICatalog' | downloadCounterBaskets=0 # counts the current basket downloads if counter > 10 no downloads are possible |
| file_catalog = 'CDLICatalog' | |
| # word splitter for search | |
| splitter = {'words':cdliSplitter.wordSplitter(), | |
| 'graphemes':cdliSplitter.graphemeSplitter()} | |
| def redirect(self,RESPONSE,url): | |
| """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen""" | |
| timeStamp=time.time() | |
| if url.find("?")>-1: #giebt es schon parameter | |
| addStr="&time=%s" | |
| else: | |
| addStr="?time=%s" | |
| RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT') | |
| logging.error(email.Utils.formatdate()+' GMT') | |
| RESPONSE.redirect(url+addStr%timeStamp) | |
| def unicodify(self,txt): | |
| return unicodify(txt) | |
| def invalidateOldCacheVersion(self): | |
| """loescht die alte Version des Cache""" | |
| del self.v_tmpStore | |
| return "done" | |
| def viewATF(self,id,RESPONSE): | |
| """view an Object""" | |
| ob = self.CDLICatalog({'title':id}) | |
| logging.debug(ob[0].getObject().getLastVersion().absolute_url()+"/view") | |
| if len(ob)>0: | |
| RESPONSE.redirect(ob[0].getObject().getLastVersion().absolute_url()+"/view") | |
| return "not found" | |
| def history(self,id,RESPONSE): | |
| """view an Object""" | |
| ob = self.CDLICatalog({'title':id}) | |
| if len(ob)>0: | |
| RESPONSE.redirect(ob[0].absolute_url+"/history") | |
| return "not found" | |
| def downloadLocked(self,id,RESPONSE): | |
| """view an Object""" | |
| ob = self.CDLICatalog({'title':id}) | |
| if len(ob)>0: | |
| RESPONSE.redirect(ob[0].absolute_url+"/downloadLocked") | |
| return "not found" | |
| def download(self,id,RESPONSE): | |
| """view an Object""" | |
| ob = self.CDLICatalog({'title':id}) | |
| if len(ob)>0: | |
| logging.info("objekt:"+repr(ob[0])) | |
| #RESPONSE.redirect(ob[0].getLastVersion().absolute_url()) | |
| RESPONSE.redirect(ob[0].absolute_url+"/download") | |
| return "not found" | |
| def addCDLIFileObjectForm(self,id,RESPONSE): | |
| """view an Object""" | |
| ob = self.CDLICatalog({'title':id}) | |
| if len(ob)>0: | |
| RESPONSE.redirect(ob[0].absolute_url+"/addCDLIFileObjectForm") | |
| return "not found" | |
| def addVersionedFileObjectForm(self,id,RESPONSE): | |
| """view an Object""" | |
| ob = self.CDLICatalog({'title':id}) | |
| if len(ob)>0: | |
| RESPONSE.redirect(ob[0].absolute_url+"/addVersionedFileObjectForm") | |
| return "not found" | |
| def unlock(self,id,RESPONSE): | |
| """view an Object""" | |
| ob = self.CDLICatalog({'title':id}) | |
| if len(ob)>0: | |
| RESPONSE.redirect(ob[0].absolute_url+"/unlock") | |
| return "not found" | |
| def getFileObject(self,fileId): | |
| """get an object""" | |
| logging.debug("getFileObj:"+repr(fileId)) | |
| if isinstance(fileId,CDLIFileObject): # support for old baskets | |
| return fileId | |
| x=self.v_files.get(fileId) | |
| logging.debug("obj: "+repr(x)) | |
| if x==None: | |
| folder=fileId[0:3] | |
| f2=fileId[0:5] | |
| fObj = getattr(self.cdliRoot.cdli_main,folder); | |
| f2Obj = getattr(fObj,f2) | |
| o = getattr(f2Obj,fileId) | |
| logging.debug(o); | |
| self.updateOrAddToFileBTree(o) | |
| return o | |
| return x | |
| def getFileObjectLastVersion(self,fileId): | |
| """get an object""" | |
| x=self.v_files_lastVersion.get(fileId) | |
| logging.debug("lastVersion: "+repr(x)) | |
| if x==None: | |
| folder=fileId[0:3] | |
| f2=fileId[0:5] | |
| fObj = getattr(self.cdliRoot.cdli_main,folder); | |
| f2Obj = getattr(fObj,f2) | |
| o =getattr(f2Obj,fileId) | |
| logging.debug(o); | |
| return o.getLastVersion() | |
| return x | |
| def showFileIds(self): | |
| """showIds""" | |
| return self.v_file_ids | |
| def generateFileBTree(self): | |
| """erzeuge einen Btree aus allen Files""" | |
| self.v_files = OOBTree() | |
| self.v_files_lastVersion = OOBTree() | |
| self.v_file_ids = Set() | |
| for x in self.CDLICatalog.searchResults(): | |
| self.v_files.update({x.getId:x.getObject()}) | |
| self.v_files_lastVersion.update({x.getId:x.getObject().getLastVersion()}) | |
| self.v_file_ids.add(x.getId) | |
| logging.debug("add:"+x.getId+"XXX"+repr(x.getObject())) | |
| def isContainedInBaskets(self,context=None): | return True |
| """check is this file is part of any basket | |
| @param context: (optional) necessessary if CDLIBasketCatalog is not an (inherited) attribute of self, context.CDLIBasketCatalog | |
| has to exist. | |
| """ | |
| if not context: | |
| context=self | |
| ret=[] | def updateOrAddToFileBTree(self,obj): |
| for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()}): | """update a BTree""" |
| #if the basket x is deleted it seemes to be that x is sometimes still in the Catalog, why? | self.v_files.update({obj.getId():obj}) |
| try: | self.v_files_lastVersion.update({obj.getId():obj.getLastVersion()}) |
| ret.append(x.getObject()) | |
| except: | |
| pass | |
| return ret | |
| #return [x.getObject() for x in context.CDLIBasketCatalog.search({'getFileNamesInLastVersion':self.getId()})] | |
| self.v_file_ids.add(obj.getId()) | |
| #change everthing around to make it persistent... | |
| tmp = self.v_files | |
| self.v_files=tmp | |
| def addCDLIFileObjectForm(self): | tmp2=self.v_file_ids |
| """add a new version""" | self.v_file_ids=tmp2 |
| if str(self.REQUEST['AUTHENTICATED_USER']) in ["Anonymous User"]: | self.CDLICache.cleanCache() #be sure that the cache is clean |
| return "please login first" | logging.debug("update:"+obj.getId()+"XXX"+repr(obj)) |
| if (self.lockedBy==self.REQUEST['AUTHENTICATED_USER']) or (self.lockedBy==''): | |
| out=DTMLFile('dtml/fileAdd', globals(),Kind='CDLIFileObject',kind='CDLIFileObject',version=self.getVersion()).__of__(self) | |
| return out() | |
| else: | |
| return "Sorry file is locked by somebody else" | |
| def manage_addCDLIFileObject(self,id,vC,author,file='',title='',precondition='', content_type='',changeName='no',newName='', RESPONSE=None): | |
| """add""" | |
| try: #TODO: der ganze vC unsinn muss ueberarbeitet werden | |
| vC=self.REQUEST['vC'] | |
| except: | |
| pass | |
| def deleteFromBTree(self,objId): | |
| """delete an obj""" | |
| self.v_files.pop(objId) | |
| self.v_files_lastVersion.pop(objId) | |
| self.v_file_ids.remove(objId) | |
| if changeName=="yes": | |
| filename=file.filename | |
| self.title=filename[max(filename.rfind('/'), | |
| filename.rfind('\\'), | |
| filename.rfind(':'), | |
| )+1:] | |
| if not newName=='': | def deleteFiles(self,ids): |
| self.title=newName[0:] | """delete files""" |
| for id in ids: | |
| founds=self.CDLICatalog.search({'title':id.split(".")[0]}) | |
| if founds: | |
| logging.debug("deleting %s"%founds) | |
| folder=founds[0].getObject().aq_parent #get the parent folder of the object | |
| logging.debug("deleting from %s"%folder) | |
| cut=folder.delete([founds[0].getId]) #cut it out | |
| def searchText(self, query, index='graphemes'): | |
| """searches query in the fulltext index and returns a list of file ids/P-numbers""" | |
| # see also: http://www.plope.com/Books/2_7Edition/SearchingZCatalog.stx#2-13 | |
| logging.debug("searchtext for '%s' in index %s"%(query,index)) | |
| #import Products.ZCTextIndex.QueryParser | |
| #qp = QueryParser.QueryParser() | |
| #logging.debug() | |
| idxQuery = {index:{'query':query}} | |
| idx = getattr(self, self.file_catalog) | |
| # do search | |
| resultset = idx.search(query_request=idxQuery,sort_index='textid') | |
| # put only the P-Number in the result | |
| results = [res.getId[:7] for res in resultset] | |
| logging.debug("searchtext: found %d texts"%len(results)) | |
| return results | |
| def getFile(self, pnum): | |
| """get the translit file with the given pnum""" | |
| f = getattr(self, self.file_catalog).search({'textid':pnum}) | |
| if not f: | |
| return "" | |
| return f[0].getObject().getData() | |
| def showFile(self,fileId,wholePage=False): | |
| """show a file | |
| @param fileId: P-Number of the document to be displayed | |
| """ | |
| f=getattr(self, self.file_catalog).search({'textid':fileId}) | |
| if not f: | |
| return "" | |
| if wholePage: | |
| logging.debug("show whole page") | |
| return f[0].getObject().getContentObject().view() | |
| else: | |
| return f[0].getObject().getLastVersionFormattedData() | |
| positionVersionNum=getattr(self,'positionVersionNum','front') | |
| if positionVersionNum=='front': | def showWordInFile(self,fileId,word,indexName='graphemes',regExp=False,): |
| id="V%i"%self.getVersion()+"_"+self.title | """get lines with word from FileId""" |
| else: | logging.debug("showwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId)) |
| 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() | |
| file = formatAtfFullLineNum(self.getFile(fileId)) | |
| ret=[] | |
| manage_addCDLIFileObject(self,id,vC,author,file,id,precondition, content_type) | # add whitespace before and whitespace and line-end to splitter bounds expressions |
| objs=self.ZopeFind(self,obj_ids=[id])[0][1].setVersionNumber(int(self.getVersion())) | bounds = self.splitter[indexName].bounds |
| self.REQUEST.SESSION['objID_parent']=self.getId() | splitexp = "(%s|\s)(%%s)(%s|\s|\Z)"%(bounds,bounds) |
| # clean word expression | |
| # TODO: this should use QueryParser itself | |
| # take out double quotes | |
| word = word.replace('"','') | |
| # take out ignorable signs | |
| ignorable = self.splitter[indexName].ignorex | |
| word = ignorable.sub('', word) | |
| # compile into regexp objects and escape parens | |
| wordlist = [re.compile(splitexp%re.escape(w)) for w in word.split(' ')] | |
| for line in file.splitlines(): | |
| for word in wordlist: | |
| #logging.debug("showwordinfile: searching for %s in %s"%(word.pattern,ignoreable.sub('',line))) | |
| if word.search(ignorable.sub('',line)): | |
| line = formatAtfLineHtml(line) | |
| ret.append(line) | |
| break | |
| if RESPONSE: | return ret |
| obj=self.ZopeFind(self,obj_ids=[id])[0][1] | |
| if obj.getSize()==0: | |
| self.REQUEST.SESSION['objID']=obj.getId() | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','errorUploadFile')).__of__(self) | |
| return pt() | |
| else: | |
| RESPONSE.redirect(self.REQUEST['URL2']+'?uploaded=%s'%self.title) | |
| else: | def showWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False): |
| return self.ZopeFind(self,obj_ids=[id])[0][1] | """ |
| get lines with word from all ids in list FileIds. | |
| returns dict with id:lines pairs. | |
| """ | |
| logging.debug("showwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds)) | |
| return dict([(id,self.showWordInFile(id, word, indexName, regExp)) for id in fileIds]) | |
| def manage_addCDLIFileForm(self): | |
| """interface for adding the OSAS_root""" | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addCDLIFile.zpt')).__of__(self) | |
| return pt() | |
| def manage_addCDLIFile(self,id,title,lockedBy, author=None, RESPONSE=None): | def tagWordInFile(self,fileId,word,indexName='graphemes',regExp=False): |
| """add the OSAS_root""" | """get text with word highlighted from FileId""" |
| newObj=CDLIFile(id,title,lockedBy,author) | logging.debug("tagwordinfile word='%s' index=%s file=%s"%(word,indexName,fileId)) |
| self._setObject(id,newObj) | |
| if RESPONSE is not None: | file=self.getFile(fileId) |
| RESPONSE.redirect('manage_main') | tagStart=u'<span class="found">' |
| tagEnd=u'</span>' | |
| tagStr=tagStart + u'%%s' + tagEnd | |
| ret=[] | |
| # add whitespace to splitter bounds expressions and compile into regexp object | |
| bounds = self.splitter[indexName].bounds | |
| wordsplit = re.compile("(%s|\s)"%bounds) | |
| # clean word expression | |
| # TODO: this should use QueryParser itself | |
| word = word.replace('"','') # take out double quotes | |
| # take out ignoreable signs | |
| ignorable = self.splitter[indexName].ignorex | |
| word = ignorable.sub('', word) | |
| # split search terms by blanks | |
| words = word.split(' ') | |
| # split search terms again (for grapheme search with words) | |
| splitwords = dict(((w,self.splitter[indexName].process([w])) for w in words)) | |
| for line in file.splitlines(): | |
| line = unicodify(line) | |
| # ignore lemma and other lines | |
| if line.lstrip().startswith('#lem:'): | |
| continue | |
| # ignore p-num line | |
| if line.startswith('&P') or line.startswith('&S'): | |
| continue | |
| # ignore version lines | |
| if line.startswith('#version'): | |
| continue | |
| # ignore atf type lines | |
| if line.startswith('#atf:'): | |
| continue | |
| # first scan | |
| hitwords = [] | |
| for w in words: | |
| if ignorable.sub('',line).find(w) > -1: | |
| # word is in line | |
| # append split word for grapheme search with words | |
| hitwords.extend(splitwords[w]) | |
| #hitwords.extend(wordsplit.split(w)) | |
| # examine hits closer | |
| if hitwords: | |
| # split line into words | |
| parts = wordsplit.split(line) | |
| line = "" | |
| for p in parts: | |
| #logging.debug("tagwordinfile: searching for %s in %s"%(p,hitwords)) | |
| # reassemble line | |
| if ignorable.sub('', p) in hitwords: | |
| #logging.debug("tagwordinfile: found %s in %s"%(p,hitwords)) | |
| # this part was found | |
| line += tagStart + formatAtfHtml(p) + tagEnd | |
| else: | |
| line += formatAtfHtml(p) | |
| else: | |
| # no hits | |
| line = formatAtfHtml(line) | |
| ret.append(line) | |
| return u'<br>\n'.join(ret) | |
| def splitatf(fh,dir=None): | |
| """split it""" | |
| ret=None | |
| nf=None | |
| for line in fh.readlines(): | |
| #check if basket name is in the first line | |
| if line.find("#atf basket")>=0: | |
| ret=line.replace('#atf basket ','') | |
| ret=ret.split('_')[0] | |
| else: | |
| if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile | |
| if nf: | |
| nf.close() #close last file | |
| filename=line[1:].split("=")[0].rstrip()+".atf" | def tagWordInFiles(self,fileIds,word,indexName='graphemes',regExp=False): |
| if dir: | """ |
| filename=os.path.join(dir,filename) | get texts with highlighted word from all ids in list FileIds. |
| nf=file(filename,"w") | returns dict with id:text pairs. |
| if nf: | """ |
| nf.write(line) | logging.debug("tagwordinfiles word='%s' index=%s file=%s"%(word,indexName,fileIds)) |
| return dict([(id,self.tagWordInFile(id, word, indexName, regExp)) for id in fileIds]) | |
| nf.close() | |
| fh.close() | |
| return ret,len(os.listdir(dir)) | |
| class CDLIFileFolder(versionedFileFolder): | def getFileVersionList(self, pnum): |
| """CDLI File Folder""" | """get the version history as a list for the translit file with the given pnum""" |
| f = getattr(self, self.file_catalog).search({'textid':pnum}) | |
| if not f: | |
| return [] | |
| return f[0].getObject().getVersionList() | |
| def URLquote(self,str): | |
| """quote url""" | |
| return urllib.quote(str) | |
| def URLunquote(self,str): | |
| """unquote url""" | |
| return urllib.unquote(str) | |
| def URLquote_plus(self,str): | |
| """quote url""" | |
| return urllib.quote_plus(str) | |
| def URLunquote_plus(self,str): | |
| """unquote url""" | |
| return urllib.unquote_plus(str) | |
| def changeUserForPObjectFromFile(self,user,fname): | |
| """aendere user fuer alle p in fiele""" | |
| pns = file(os.path.join(package_home(globals()),'inputs',fname),"r") | |
| for p in pns.readlines(): | |
| p=p.lstrip().rstrip() | |
| logging.info(str(p+".atf")) | |
| pObj=self.getFileObject(p+".atf") | |
| if pObj is not None: | |
| logging.info(pObj) | |
| lv=pObj.getContentObject() | |
| logging.info("author:"+lv.author) | |
| lv.author=user | |
| lv.versionComment="XXXXXXX" | |
| def forceunlock(self,REQUEST=None,user=None,fid=None): | |
| "break all locks" | |
| if fid is not None: | |
| self.getFileObject(fid).forceunlock() | |
| return fid | |
| ret=[] | |
| meta_type="CDLI Folder" | for f in self.ZopeFind(self,obj_metatypes="CDLI file",search_sub=1): |
| filesMetaType=['CDLI file'] | un=f[1].forceunlock(user=user) |
| folderMetaType=['CDLI Folder'] | logging.info("check:"+f[0]) |
| default_catalog='CDLICatalog' | if un and un !="": |
| ret.append((f[0],un)) | |
| def delete(self,ids): | if REQUEST is not None: |
| """delete this file, i.e. move into a trash folder""" | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','breakLockResponse.zpt')).__of__(self) |
| found=self.ZopeFind(self,obj_ids=['.trash']) | return pt(ret=ret) |
| if len(found)<1: | return ret |
| manage_addCDLIFileFolder(self, '.trash',title="Trash") | |
| trash=self._getOb('.trash') | |
| else: | |
| trash=found[0][1] | |
| if type(ids) is not ListType: | |
| ids=[ids] | |
| cut=self.manage_cutObjects(ids) | |
| trash.manage_pasteObjects(cut) | |
| def getVersionNumbersFromIds(self,ids): | def getLockedFiles(self,REQUEST=None,user=None): |
| """get the numbers of the current versions of documents described by their ids""" | """hole alle gesperrten files""" |
| ret={} | |
| for nm,f in self.v_files.items(): | |
| lb = str(f.lockedBy) | |
| add=False | |
| if (lb is not None) and (lb!=""): | |
| if user is None: | |
| add=True | |
| else: | |
| if str(lb)==user: | |
| add=True | |
| if add==True: | |
| if not ret.has_key(lb): | |
| ret[lb]=[] | |
| ret[lb].append(nm) | |
| ret=[] | |
| searchStr=" OR ".join(ids) | |
| founds=self.CDLICatalog.search({'title':searchStr}) | if REQUEST is not None: |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','showlockResponse.zpt')).__of__(self) | |
| for found in founds: | return pt(ret=ret) |
| lastVersion=found.getObject().getLastVersion() | |
| ret.append((found.getId,lastVersion)) | |
| return ret | return ret |
| def checkCatalog(self,fn): | def getChangesByAuthor(self,author,n=100): |
| """check if fn is in the catalog""" | """getChangesByAuthor""" |
| zcat=self.CDLIObjectsCatalog | |
| res=zcat({'lastEditor':author, | |
| 'sort_on':'getTime', | |
| 'sort_order':'descending', | |
| 'sort_limit':n})[:n ] | |
| return res | |
| def uploadATF(self,upload,basketId=0,RESPONSE=None): | def getChangesByAuthor_html(self,author,n=100): |
| """upload an atf file""" | """html output for changes by author""" |
| #TODO: add comments | tmp={} |
| #TODO: finish uploadATF | list=[] |
| basketId=str(basketId) | for x in self.getChangesByAuthor(author): |
| nr=x.getObject().getVersionNumber() | |
| id=x.getObject().aq_parent.getId() | |
| #hinzufuegen, wenn Version neuer als die | |
| if tmp.get(id,(0,0))[1] < nr: | |
| tmp[id]=(x.getObject().aq_parent,nr) | |
| return self.cdli_main.findObjectsFromListWithVersion(list=tmp.values(),author=author) | |
| dir=mkdtemp() | def getLastChanges(self,n=100): |
| changed=[] | """get the last n changes""" |
| errors=[] | n=int(n) |
| newPs=[] | zcat=self.CDLICatalog |
| psNotInCatalog=[] | return zcat({'sort_on':'getLastChangeDate', |
| basketNameFromFile, numberOfFiles=splitatf(upload,dir) | 'sort_order':'descending', |
| 'sort_limit':n})[:n ] | |
| if basketId == '0': | |
| basketObj=self.basketContainer.getActiveBasket() | |
| if basketObj: | |
| basketId=basketObj.getId() | |
| if basketId == '0': | def getLastChanges_html(self,n=100): |
| basketNameFromId="" | """get the last n changes""" |
| basketLen=0 | list = [x.getId for x in self.getLastChanges(n)] |
| else: | return self.cdli_main.findObjectsFromList(list=list,display=True) |
| basketNameFromId=getattr(self.basketContainer,basketId).title | |
| basketLen=getattr(self.basketContainer,basketId).getLastVersion().numberOfItems() | |
| def refreshTxt(self,txt="",threadName=None): | |
| """txt fuer refresh""" | |
| for fn in os.listdir(dir): | return """ 2;url=%s?repeat=%s """%(self.absolute_url()+txt,threadName) |
| if self.checkCatalog(fn): | def refreshTxtBasket(self,txt="",threadName=None): |
| psNotInCatalog.append(fn) | """txt fuer refresh""" |
| return """ 2;url=%s?repeat=%s """%(txt,threadName) | |
| founds=self.CDLICatalog.search({'title':fn}) | |
| if len(founds)==0: | def getResult(self,threadName=None): |
| newPs.append(fn) | """result of thread""" |
| try: | |
| return self._v_uploadATF[threadName].getResult() | |
| except: | |
| return "One moment, please" | |
| for found in founds: | |
| obj=found.getObject() | |
| if (not obj.lockedBy=='') and (not obj.lockedBy==self.REQUEST['AUTHENTICATED_USER']): | def checkThreads(self): |
| errors.append(obj) | """check threads""" |
| else: | ret="<html><body>" |
| data=file(os.path.join(dir,fn)).read() | for thread in threading.enumerate(): |
| diffs=obj.diff(data) | ret+="<p>%s (%s): %s</p>"%(repr(thread),thread.getName(),thread.isAlive()) |
| if diffs[0]>0: | |
| changed.append((obj,diffs)) | |
| #hochladen | |
| self.REQUEST.SESSION['changed']=[x[0].getId() for x in changed] | |
| self.REQUEST.SESSION['errors']=[x.getId() for x in errors] | |
| self.REQUEST.SESSION['newPs']=newPs | |
| self.REQUEST.SESSION['tmpdir']=dir | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self) | return ret |
| return pt(changed=changed,errors=errors,dir=dir,newPs=newPs,basketLen=basketLen,numberOfFiles=numberOfFiles, | |
| basketNameFromId=basketNameFromId,basketNameFromFile=basketNameFromFile,basketId=basketId) | |
| def uploadATFfinally(self,procedure,comment="",basketname='',unlock=None,RESPONSE=None): | |
| """upload the files""" | |
| if procedure=="uploadchanged": | def uploadATFRPC(self,data,username): |
| uploadFns=self.REQUEST.SESSION['changed']+self.REQUEST.SESSION['newPs'] | """upload an atffile via xml-rpc""" |
| uploader=uploadATFThread() | |
| elif procedure=="uploadAll": | #generate an random id for the upload object |
| uploadFns=[] | from random import randint |
| for x in os.listdir(self.REQUEST.SESSION['tmpdir']): | if (not self.REQUEST.SESSION.get('idTmp',None)): |
| if not x in self.REQUEST.SESSION['errors']: | |
| uploadFns.append(x) | idTmp=str(randint(0,1000000000)) |
| self.REQUEST.SESSION['idTmp']=idTmp | |
| else: | else: |
| uploadFns=[] | idTmp=self.REQUEST.SESSION.get('idTmp',None) |
| for fn in uploadFns: | |
| founds=self.CDLICatalog.search({'title':fn}) | |
| if len(founds)>0: | |
| self.REQUEST.SESSION['author']=str(self.REQUEST['AUTHENTICATED_USER']) | |
| founds[0].getObject().manage_addCDLIFileObject('',comment,self.REQUEST.SESSION['author'],file=file(os.path.join(self.REQUEST.SESSION['tmpdir'],fn))) | uploader.set(data,0,username,idTmp) |
| stObj=uploader.run() | |
| processor=uploadATFfinallyThread() | |
| newPs=self.REQUEST.SESSION['newPs'] | basketname=stObj.returnValue['basketNameFromFile'] |
| if len(newPs)>0: | |
| tmpDir=self.REQUEST.SESSION['tmpdir'] | |
| self.cdli_main.importFiles(comment=comment,author=str(self.REQUEST['AUTHENTICATED_USER']) ,folderName=tmpDir, files=newPs) | processor.set("uploadchanged",basketname=basketname,SESSION=stObj.returnValue,username=username,serverport=self.REQUEST['SERVER_PORT']) |
| processor.run() | |
| #unlock | return generateXMLReturn(stObj.returnValue) |
| if unlock: | |
| unlockFns=[] | |
| for x in os.listdir(self.REQUEST.SESSION['tmpdir']): | |
| if not x in self.REQUEST.SESSION['errors']: | |
| unlockFns.append(x) | |
| for fn in unlockFns: | def uploadATF(self,repeat=None,upload=None,basketId=0,RESPONSE=None): |
| founds=self.CDLICatalog.search({'title':fn}) | """upload an atf file / basket file""" |
| if len(founds)>0: | #self._v_uploadATF.returnValue=None |
| self.REQUEST.SESSION['author']=str(self.REQUEST['AUTHENTICATED_USER']) | |
| founds[0].getObject().lockedBy="" | #generate an random id for the upload thread |
| from random import randint | |
| if (not self.REQUEST.SESSION.get('idTmp',None)): | |
| if not (basketname ==''): | idTmp=str(randint(0,1000000000)) |
| basketId=self.basketContainer.getBasketIdfromName(basketname) | self.REQUEST.SESSION['idTmp']=idTmp |
| else: | |
| idTmp=self.REQUEST.SESSION.get('idTmp',None) | |
| if not basketId: # create new basket | |
| ob=self.basketContainer.addBasket(basketname) | |
| basketId=ob.getId() | |
| basket=getattr(self.basketContainer,str(basketId)) | |
| ids=os.listdir(self.REQUEST.SESSION['tmpdir']) | |
| basket.addObjects(ids,deleteOld=True) | |
| if RESPONSE is not None: | threadName=repeat |
| RESPONSE.redirect(self.aq_parent.absolute_url()) | if not threadName or threadName=="": |
| #new thread not called from the waiting page | |
| tmpVar=False | |
| thread=uploadATFThread() | |
| threadName=thread.getName()[0:] | |
| if (not hasattr(self,'_v_uploadATF')): | |
| self._v_uploadATF={} | |
| def findObjectsFromList(self,start=None,upload=None,list=None,basketName=None,numberOfObjects=None,RESPONSE=None): | self._v_uploadATF[threadName]=thread |
| """findObjectsFromList (, TAB oder LINE separated)""" | #self._xmltrans.start() |
| #thread=Thread(target=self._v_uploadATF) | |
| logging.info("set thread. extern") | |
| self._v_uploadATF[threadName].set(upload,basketId,self.REQUEST['AUTHENTICATED_USER'],idTmp,serverport=self.REQUEST['SERVER_PORT']) | |
| #thread.start() | |
| logging.info("start thread. extern") | |
| self._v_uploadATF[threadName].start() | |
| if upload: # list from file upload | self.threadName=self._v_uploadATF[threadName].getName()[0:] |
| txt=upload.read() | wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template']) |
| txt=txt.replace(",","\n") | |
| txt=txt.replace("\t","\n") | |
| txt=txt.replace("\r","\n") | |
| idsTmp=txt.split("\n") | |
| ids=[] | |
| for id in idsTmp: # make sure that no empty lines | |
| idTmp=id.lstrip().rstrip() | |
| if len(idTmp)>0: | |
| ids.append(idTmp) | if wait_template: |
| return wait_template[0][1]() | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self) | |
| return pt(txt='/uploadATF',threadName=threadName) | |
| #_v_xmltrans.run() | |
| #self.REQUEST.SESSION['ids']=" OR ".join(ids) | else: |
| #recover thread, if lost | |
| if (not hasattr(self,'_v_uploadATF')): | |
| self._v_uploadATF={} | |
| if not self._v_uploadATF.get(threadName,None): | |
| for thread in threading.enumerate(): | |
| if threadName == thread.getName(): | |
| self._v_uploadATF[threadName]=thread | |
| pt=getattr(self,'filelist.html') | if self._v_uploadATF.get(threadName,None) and (not self._v_uploadATF[threadName].returnValue): |
| self.REQUEST.SESSION['searchList']=ids | |
| return pt(search=ids) | |
| if basketName: | |
| #TODO: get rid of one of these.. | |
| pt=getattr(self,'filelist.html') | wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template']) |
| return pt(basketName=basketName,numberOfObjects=numberOfObjects) | if wait_template: |
| return wait_template[0][1]() | |
| if list is not None: # got already a list | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self) |
| ret=[] | |
| for fileId in list: | |
| if len(fileId.split("."))==1: | |
| fileId=fileId+".atf" | |
| ret+=self.CDLICatalog({'title':fileId}) | return pt(txt='/uploadATF',threadName=threadName) |
| #TODO: get rid of one of these.. | |
| self.REQUEST.SESSION['fileIds']=[x.getObject().getId() for x in ret]#store fieldIds in session for further usage | |
| self.REQUEST.SESSION['searchList']=self.REQUEST.SESSION['fileIds'] | |
| return ret | |
| if start: | else: |
| RESPONSE.redirect("filelist.html?start:int="+str(start)) | tmp=getattr(self.temp_folder,idTmp).returnValue |
| print "nothing" | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self) |
| def createAllFilesAsSingleFile(self,RESPONSE=None): | return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'], |
| """download all files""" | basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId']) |
| def sortF(x,y): | def redoUpload(self,threadName): |
| return cmp(x[0],y[0]) | """redo the upload""" |
| tmp=self.cdli_main.tmpStore2[threadName] | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadCheck.zpt')).__of__(self) | |
| return pt(changed=tmp['changed'],lockerrors=tmp['lockerrors'],errors=tmp['errors'],dir=tmp['dir'],newPs=tmp['newPs'],basketLen=tmp['basketLen'],numberOfFiles=tmp['numberOfFiles'], | |
| basketNameFromId=tmp['basketNameFromId'],basketNameFromFile=tmp['basketNameFromFile'],basketId=tmp['basketId']) | |
| catalog=getattr(self,self.default_catalog) | def uploadATFfinally(self,procedure='',comment="",basketname='',unlock=None,repeat=None,RESPONSE=None): |
| #tf,tfilename=mkstemp() | """nowupload the files""" |
| threadName=repeat | |
| if not threadName or threadName=="": | |
| thread=uploadATFfinallyThread() | |
| threadName=thread.getName()[0:] | |
| if (not hasattr(self,'_v_uploadATF')): | |
| self._v_uploadATF={} | |
| list=[(x.getId,x) for x in catalog()] | |
| list.sort(sortF) | |
| RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%"all.atf") | self._v_uploadATF[threadName]=thread |
| RESPONSE.setHeader("Content-Type","application/octet-stream") | |
| for l in list: | idTmp=self.REQUEST.SESSION['idTmp'] |
| obj=l[1].getObject() | stObj=getattr(self.temp_folder,idTmp) |
| 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']) | |
| if obj.meta_type=="CDLI file": | self._v_uploadATF[threadName].start() |
| #os.write(tf,obj.getLastVersion().data) | |
| if RESPONSE: | |
| RESPONSE.write(obj.getLastVersion().data[0:]) | |
| #os.close(tf) | |
| #RESPONSE.redirect(self.absolute_url()+"/downloadFile?fn="%tfilename) | |
| return True | |
| def downloadFile(self,fn): | |
| """download fn - not used yet""" | |
| self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename=%s"""%self.getLastVersion().getId()) | |
| self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") | |
| self.REQUEST.RESPONSE.write(file(fn).read()) | |
| wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template']) | |
| if wait_template: | |
| return wait_template[0][1]() | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self) | |
| def hasParent(self): | return pt(txt='/uploadATFfinally',threadName=threadName) |
| """returns true falls subfolder""" | #_v_xmltrans.run() |
| if self.aq_parent.meta_type in self.folderMetaType: | |
| return True | |
| else: | else: |
| return False | #recover thread, if lost |
| if not hasattr(self,'_v_uploadATF'): | |
| self._v_uploadATF={} | |
| if not self._v_uploadATF.get(threadName,None): | |
| for thread in threading.enumerate(): | |
| if threadName == thread.getName(): | |
| self._v_uploadATF[threadName]=thread | |
| def getFolders(self): | if self._v_uploadATF.get(threadName,None) and (self._v_uploadATF[threadName] is not None) and (not self._v_uploadATF[threadName].end) : |
| """get all subfolders""" | |
| ret=[] | |
| folders=self.ZopeFind(self,obj_metatypes=self.folderMetaType) | |
| for folder in folders: | |
| ret.append((folder[1], | |
| len(self.ZopeFind(folder[1],obj_metatypes=self.folderMetaType)), | |
| len(self.ZopeFind(folder[1],obj_metatypes=self.filesMetaType)) | |
| )) | |
| return ret | |
| wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template']) | |
| if wait_template: | |
| return wait_template[0][1]() | |
| def getFolders_OLD(self): | pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','uploadATFWait.zpt')).__of__(self) |
| """get all subfolders""" | return pt(txt='/uploadATFfinally',threadName=threadName) |
| ret=[] | else: |
| folders=self.ZopeFind(self,obj_metatypes=self.folderMetaType) | |
| for folder in folders: | |
| ret.append((folder[1], | |
| len(self.ZopeFind(folder[1],obj_metatypes=self.folderMetaType)), | |
| len(getattr(self,self.default_catalog)({'path':folder[0]})) | |
| )) | |
| return ret | |
| def index_html(self): | |
| """main""" | |
| ext=self.ZopeFind(self,obj_ids=["index.html"]) | |
| if ext: | |
| return ext[0][1]() | |
| pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','CDLIFileFolderMain')).__of__(self) | idTmp=self.REQUEST.SESSION['idTmp'] |
| return pt() | stObj=getattr(self.temp_folder,idTmp) |
| self.REQUEST.SESSION['idTmp']=None | |
| def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/Documents/workspace/cdli/atf", files=None): | #update changed |
| """import files""" | logging.debug("dir:"+repr(stObj.returnValue['changed'])) |
| for x in stObj.returnValue['changed']: | |
| ob=self.CDLICatalog.search({'title':x[0]}) | |
| try: | |
| self.cdliRoot.updateOrAddToFileBTree(ob[0].getObject()) | |
| except: | |
| logging.error("uploadATFfinally - cannot update Object %s Error: %s %s"%(ob[1],sys.exc_info()[0],sys.exc_info()[1])) | |
| for x in stObj.returnValue['newPs']: | |
| obj=self.getFileObject(x) #updates the object in the cache | |
| logging.debug("Got:"+repr(obj)) | |
| if RESPONSE is not None: | |
| RESPONSE.redirect(self.absolute_url()) | |
| def importFiles(self,comment="",author="" ,folderName="/Users/dwinter/atf", files=None,ext=None): | |
| """import files""" | |
| logging.debug("importFiles folderName=%s files=%s ext=%s"%(folderName,files,ext)) | |
| root=self.cdli_main | |
| count=0 | |
| if not files: | if not files: |
| files=os.listdir(folderName) | files=os.listdir(folderName) |
| for f in files: | for f in files: |
| folder=f[0:3] | folder=f[0:3] |
| f2=f[0:5] | f2=f[0:5] |
| obj=self.ZopeFind(self,obj_ids=[folder]) | |
| if not obj: | #check if main folder PXX already exists |
| manage_addCDLIFileFolder(self,folder,folder) | obj=self.ZopeFind(root,obj_ids=[folder]) |
| fobj=getattr(self,folder) | logging.debug("importFiles: folder=%s f2=%s obj=%s"%(folder,f2,obj)) |
| if ext: | |
| ext.result="<p>adding: %s </p>"%f+ext.result | |
| if not obj: # if not create it | |
| manage_addCDLIFileFolder(root,folder,folder) | |
| fobj=getattr(root,folder) | |
| #transaction.get().commit() | |
| else: | else: |
| fobj=obj[0][1] | fobj=obj[0][1] |
| #check IF PYYYYY already exist | |
| obj2=fobj.ZopeFind(fobj,obj_ids=[f2]) | obj2=fobj.ZopeFind(fobj,obj_ids=[f2]) |
| logging.debug("importFiles: fobj=%s obj2=%s"%(fobj,obj2)) | |
| if not obj2: | if not obj2:# if not create it |
| manage_addCDLIFileFolder(fobj,f2,f2) | manage_addCDLIFileFolder(fobj,f2,f2) |
| fobj2=getattr(fobj,f2) | fobj2=getattr(fobj,f2) |
| else: | else: |
| fobj2=obj2[0][1] | fobj2=obj2[0][1] |
| file2=file(os.path.join(folderName,f)) | # not add the file |
| file2=os.path.join(folderName,f) | |
| id=f | id=f |
| manage_addCDLIFile(fobj2,f,'','') | logging.debug("importFiles: addCDLIFile fobj2=%s, f=%s file2=%s"%(fobj2,repr(f),repr(file2))) |
| id=f | fobj2.addFile(vC='',file=file(file2),author=author,newName=f) |
| ob=fobj2._getOb(f) | logging.debug("importfiles: fobj2.add") |
| ob.title=id | count+=1 |
| manage_addCDLIFileObject(ob,id,comment,author,file2,content_type='') | #now add the file to the storage |
| self.CDLICatalog.catalog_object(ob) | ob = getattr(fobj2,f) |
| #self.CDLICatalog.manage_catalogFoundItems(obj_ids=[id],search_sub=1) | logging.debug("importfiles: btree_start") |
| #self.CDLICatalog.manage_catalogObject(self.REQUEST, self.REQUEST.RESPONSE, 'CDLICatalog', urlparse.urlparse(ob.absolute_url())[1]) | #self.cdliRoot.updateOrAddToFileBTree(ob) |
| logging.debug("importfiles: btree_end") | |
| if count%100==0: | |
| logging.debug("importfiles: committing") | |
| transaction.get().commit() | |
| logging.debug("importfiles: committing") | |
| transaction.get().commit() | |
| logging.debug("importfiles: committing done") | |
| return "ok" | return "ok" |
| manage_addCDLIFileFolderForm=DTMLFile('dtml/folderAdd', globals()) | |
| manage_addCDLIRootForm=DTMLFile('dtml/rootAdd', globals()) | |
| def manage_addCDLIFileFolder(self, id, title='', | |
| def manage_addCDLIRoot(self, id, title='', | |
| createPublic=0, | createPublic=0, |
| createUserF=0, | createUserF=0, |
| REQUEST=None): | REQUEST=None): |
| Line 1275 def manage_addCDLIFileFolder(self, id, t | Line 1455 def manage_addCDLIFileFolder(self, id, t |
| value, an 'index_html' and a 'UserFolder' objects are created respectively | value, an 'index_html' and a 'UserFolder' objects are created respectively |
| in the new folder. | in the new folder. |
| """ | """ |
| ob=CDLIFileFolder() | ob=CDLIRoot() |
| ob.id=str(id) | ob.id=str(id) |
| ob.title=title | ob.title=title |
| try: | |
| self._setObject(id, ob) | self._setObject(id, ob) |
| except: | |
| pass | |
| ob=self._getOb(id) | ob=self._getOb(id) |
| checkPermission=getSecurityManager().checkPermission | checkPermission=getSecurityManager().checkPermission |
| Line 1295 def manage_addCDLIFileFolder(self, id, t | Line 1478 def manage_addCDLIFileFolder(self, id, t |
| return self.manage_main(self, REQUEST, update_menu=1) | return self.manage_main(self, REQUEST, update_menu=1) |
| import cdli_basket | |
| # Die folgenden Klassen sollte nicht mehr aus diesem Paket benutzt werden, sondern direkt aus | |
| # cdli_basket importiert werden. | |
| class uploadATFfinallyThread(cdli_basket.uploadATFfinallyThread): | |
| """depricates""" | |
| pass | |
| class tmpStore(cdli_basket.tmpStore): | |
| """depricated""" | |
| pass | |
| class uploadATFThread(cdli_basket.uploadATFThread): | |
| """depricated""" | |
| pass | |
| class CDLIBasketContainer(cdli_basket.CDLIBasketContainer): | |
| """depricated""" | |
| pass | |
| class CDLIBasket(cdli_basket.CDLIBasket): | |
| """depricated""" | |
| pass | |
| class CDLIBasketVersion(cdli_basket.CDLIBasketVersion): | |
| """depricated""" | |
| pass | |
| class BasketContent(cdli_basket.BasketContent): | |
| """depricated""" | |
| pass | |