--- cdli/cdli_files.py 2007/01/30 14:26:42 1.61 +++ cdli/cdli_files.py 2007/03/22 19:56:22 1.72 @@ -25,6 +25,7 @@ from BTrees.OOBTree import OOBTree import logging import transaction import copy +import codecs def unique(s): """Return a list of the elements in s, but without duplicates. @@ -174,8 +175,8 @@ class uploadATFfinallyThread(Thread): conn.close() #set flag for end of this method self.end=True - print "ended" - return True + logging.info("ended") + return True def __del__(self): """delete""" @@ -196,7 +197,7 @@ class uploadATFfinallyThread(Thread): #shall I only upload the changed files? if procedure=="uploadchanged": - changed=[x[0] for x in SESSION.get('changed',[])] + changed=[x[0] for x in SESSION.get('changed',[])] uploadFns=changed+SESSION.get('newPs',[]) #or all @@ -213,46 +214,64 @@ class uploadATFfinallyThread(Thread): uploadFns=[] #do first the changed files + i=0 for fn in uploadFns: + i+=1 founds=ctx2.CDLICatalog.search({'title':fn}) if len(founds)>0: SESSION['author']=str(username) - self.result+="
Changing : %s"%fn + self.result="
Changing : %s"%fn+self.result founds[0].getObject().manage_addCDLIFileObject('',comment,SESSION['author'],file=os.path.join(SESSION['tmpdir'],fn),from_tmp=True) - + if i==200: + i=0 + transaction.get().commit() + logging.info("changing: do commit") + transaction.get().commit() + logging.info("changing: last commit") + #now add the new files newPs=SESSION['newPs'] if len(newPs)>0: tmpDir=SESSION['tmpdir'] - self.result+="
Adding files
" + logging.info("adding start") + self.result="Adding files
"+self.result #TODO: make this configurable, at the moment base folder for the files has to be cdli_main ctx2.importFiles(comment=comment,author=str(username) ,folderName=tmpDir, files=newPs,ext=self) - + logging.info("adding finished") #unlock locked files? if unlock: - self.result+="Unlock files
" + logging.info("unlocking start") + self.result="Unlock files
"+self.result unlockFns=[] for x in os.listdir(SESSION['tmpdir']): if not x in SESSION['errors']: unlockFns.append(x) - + logging.info("unlocking have now what to unlock") + for fn in unlockFns: + #logging.info("will unlock: %s"%fn) founds=ctx2.CDLICatalog.search({'title':fn}) + #logging.info("found it: %s"%repr(founds)) if len(founds)>0: + #logging.info("unlock: %s"%founds[0].getObject().getId()) SESSION['author']=str(username) founds[0].getObject().lockedBy="" + logging.info("unlocking done") - #if a basketname is give, add files to the basket + #if a basketname is given, add files to the basket if not (basketname ==''): - self.result+="Add basket
" + logging.info("add to basket %s"%basketname) + self.result="Add to basket
"+self.result basketId=ctx2.basketContainer.getBasketIdfromName(basketname) if not basketId: # create new basket + logging.info("create basket %s"%basketname) + self.result="Create a new basket
"+self.result ob=ctx2.basketContainer.addBasket(basketname) basketId=ob.getId() basket=getattr(ctx2.basketContainer,str(basketId)) @@ -263,7 +282,7 @@ class uploadATFfinallyThread(Thread): RESPONSE.redirect(self.aq_parent.absolute_url()) - + logging.info("uploadfinally done") return True class tmpStore(SimpleItem): @@ -321,13 +340,17 @@ class uploadATFThread(Thread): app = root['Application'] ctx = self.getContext(app,serverport=self.serverport) logging.info("run intern") - ctx.temp_folder._setObject(idTmp,tmpStore(idTmp)) + try: + ctx.temp_folder._setObject(idTmp,tmpStore(idTmp)) + except: + logging.error("thread upload: %s %s"%sys.exc_info()[0:2]) + logging.info("call thread intern") self.uploadATFThread(ctx,self.upload,idTmp,self.basketId) #ctx.cdliRoot.cdli_main.tmpStore2[self.getName()[0:]]=self.returnValue - + transaction.get().commit() conn.close() @@ -389,7 +412,7 @@ class uploadATFThread(Thread): #start to check the files for fn in os.listdir(dir): - self.result+="process:%s
"%fn + self.result="process:%s
"%fn+self.result # check if file is in the catalog #TODO: checkCatalog is not implemented yet @@ -402,11 +425,13 @@ class uploadATFThread(Thread): #if not than add filename to the list of newfiles data=file(os.path.join(dir,fn)).read() - #status,msg=checkFile(fn,data,dir) - status=True - msg="" + status,msg=checkFile(fn,data,dir) + #status=True + + if not status: # error errors.append((fn,msg)) + else: if len(founds)==0: newPs.append(fn) @@ -417,7 +442,7 @@ class uploadATFThread(Thread): obj=found.getObject() if (not (str(obj.lockedBy))=='') and (not (str(obj.lockedBy)==str(self.username))): - lockerrors.append(fn) + lockerrors.append((fn,str(obj.lockedBy))) else: diffs=obj.diff(data) @@ -430,7 +455,7 @@ class uploadATFThread(Thread): stObj.returnValue={} stObj.returnValue['errors']=errors - + stObj.returnValue['newPs']=newPs stObj.returnValue['tmpdir']=dir stObj.returnValue['basketLen']=basketLen @@ -442,256 +467,11 @@ class uploadATFThread(Thread): #stObj.returnValue['changed']=copy.copy(changed) stObj.returnValue['changed']=[(x[0].getId(),x[1][0]) for x in changed] #stObj.returnValue['lockerrors']=[x[0].getId() for x in lockerrors] - print lockerrors - stObj.returnValue['lockerrors']=[x for x in lockerrors] + stObj.returnValue['lockerrors']=[x for x in lockerrors] self.returnValue=True #ctx2.cdli_main.setTemp('v_uploadATF_returnValue',True) - -class Basket_old(Folder): - """shopping basket - alte fassung """ - - meta_type="Basket" - _v_stack={} - - def getObjUrl(self,objId): - """getUrl""" - 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: - self._v_stack[nr]=[x.getObject().getId() for x in results] - - return self.absolute_url()+"/storeAll?id="+nr - - def storeAll(self,id): - """store all""" - try: - results=self._v_stack[id] - except: - #TODO: write expired page - return "expired" - - return self.storeInBasketForm(results) - - def storeInBasketForm(self,ids): - """ store an object form""" - - if type(ids) is not ListType: - ids=[ids] - self.REQUEST.SESSION['ids']=ids[0:] - - self.REQUEST.SESSION['BACKLINK']=self.REQUEST['HTTP_REFERER'] - - pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','storeBasketObject.zpt')).__of__(self) - return pt() - - def storeInBasket(self,username,ids=None,RESPONSE=None,REQUEST=None): - """store it""" - - if not ids: - ids=REQUEST.SESSION['ids'] - - self.REQUEST.SESSION['basketUser']=username - - 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: - self.REQUEST.SESSION['basketUser']=user - - 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 - 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): - """add the basket""" - ob=Basket() - - 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 BasketObject_old(Folder): - """Basket Object - alte fassung""" - - meta_type="basketObject" - def __init__(self): - """init basket object""" - self.contents=[] - - def numberOfItems(self): - """return anzahl der elemente im basket""" - num=len(self.contents) - - return num - - def addObjects(self,ids): - """addObjects""" - - for id in ids: - founds=self.CDLICatalog.search({'title':id}) - for found in founds: - if found.getObject() not in self.contents: - tm=self.contents[0:] - tm.append(found.getObject()) - self.contents=tm[0:] - - return True - - 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): - """delete objects""" - list = self.contents[0:] - for content in list: - - if content.getId() in ids: - self.contents.remove(content) - - - if RESPONSE: - RESPONSE.redirect(self.absolute_url()) - - - def unlockTest(self): - """unlock all files of the testuser for debuggin""" - for object in self.contents: - - if str(object.lockedBy)=="dahl": - object.lockedBy="" - - def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None): - """download all selected files in one file""" - - ret="" - lockedObjects={} - - if self.temp_folder.downloadCounter > 10: - return """I am sorry, currently the server has to many requests for downloads, please come back later!""" - - - if lock: - - if str(self.REQUEST['AUTHENTICATED_USER'])=='Anonymous User': - - return "please login first" - - #check if a locked object exist in the basket. - lockedObjects={} - for object in self.contents: - - if not object.lockedBy=="": - lockedObjects[object.title]=repr(object.lockedBy) - - - keys=lockedObjects.keys() - - - 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 - procedure="downloadAll" - - self.temp_folder.downloadCounter+=1 - self._p_changed=1 - - transaction.get().commit() - - for object in self.contents: - - if (procedure=="downloadAll") or (object.lockedBy=='') or (object.lockedBy==self.REQUEST['AUTHENTICATED_USER']): - ret+=object.getLastVersion().getData() - - if lock and object.lockedBy=='': - object.lockedBy=self.REQUEST['AUTHENTICATED_USER'] - - - self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="basket_%s.atf" """%self.getId()) - self.REQUEST.RESPONSE.setHeader("Content-Type","application/octet-stream") - length=len(ret) - self.REQUEST.RESPONSE.setHeader("Content-Length",length) - self.REQUEST.RESPONSE.write(ret) - self.temp_folder.downloadCounter-=1 - self._p_changed=1 - transaction.get().commit() - - - -def manage_addBasket_oldObjectForm(self): - """add form""" - pass - -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""" @@ -726,12 +506,19 @@ class CDLIBasketContainer(OrderedFolder) trash.manage_pasteObjects(cut) security.declareProtected('manage','manageBaskets') - def manageBaskets(self,ids,submit,REQUEST=None,RESPONSE=None): + def manageBaskets(self,submit,ids=None,basket1="",basket2="",REQUEST=None,RESPONSE=None): """manage baskets, delete or copy""" if submit=="delete": self.deleteBaskets(ids) - + elif submit=="join": + flag,msg=self.joinBasket("joinedBasket", ids) + logging.info("joining %s %s"%(flag,msg)) + + elif submit=="subtract": + logging.info("BBBb %s %s"%(basket1,basket2)) + flag,msg=self.subtractBasket("subtractedBasket", basket1,basket2) + logging.info("subtract %s %s"%(flag,msg)) if RESPONSE: RESPONSE.redirect(self.absolute_url()) @@ -795,7 +582,7 @@ class CDLIBasketContainer(OrderedFolder) ret+= "BASKET:"+com+"\t"+user+"\t"+time+"\n" for x in values: ret+= x[0]+"\t"+x[1]+"\n" - return ret + return ret def getBaskets(self,sortField='title'): """get all baskets files""" @@ -854,9 +641,83 @@ class CDLIBasketContainer(OrderedFolder) baskets.sort(sortComment) return baskets + + + def subtractBasket(self,newBasket,basket1,basket2): + """subtract basket2 from basket1 + (i.e. newbasket will contain alle elements of basket1 which are not in basket2), + if basket2 contains files which are not in basket1, then theses files fill be ignored + + @param newbasket: name of the new basket + @param basket1: basket where basket2 will be subtracted from + @param basket2: see above + + """ + logging.info("CCCCC %s %s"%(basket1,basket2)) + + try: + newB=self.addBasket(newBasket) + except: + return False, "cannot create the new basket" + + - - + + + bas2= getattr(self,basket2) + bas2content=bas2.getContent() + bas2ids=[x[0] for x in bas2content] + + + + bas1= getattr(self,basket1) + bas1content=bas1.getContent() + + + newBasketContent={} + + for id,version in bas1content: + if not (id in bas2ids): + newBasketContent[id]=version + + username=self.getActualUserName() + + logging.info("sbc %s"%newBasketContent) + newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog) + + return True, "" + + + def joinBasket(self,newBasket,oldBaskets): + """join two baskets + @param newbasket: name of the new basket + @param oldbaskets: list of baskets to be joined + """ + try: + newB=self.addBasket(newBasket) + except: + return False, "cannot create the new basket" + + newBasketContent={} + for ob in oldBaskets: + x= getattr(self,ob,None) + if x is None: + return False, "cannot find basket: %s"%ob + + ids=x.getContent() # hole den Inhalt + + for id,version in ids: + if newBasketContent.has_key(id): # p number gibt's schon + newBasketContent[id]=max(newBasketContent[id],version) # speichere die groessere Versionsnumber + else: + newBasketContent[id]=version + username=self.getActualUserName() + + logging.info("nbc %s"%newBasketContent) + newB.addObjectsWithVersion(newBasketContent,username=username,catalog=self.CDLICatalog) + + return True, "" + def getNewId(self): """createIds""" last=getattr(self,'last',0) @@ -870,11 +731,11 @@ class CDLIBasketContainer(OrderedFolder) def setActiveBasket(self,basketId,REQUEST=None): """store active basketId in a cookie""" self.REQUEST.RESPONSE.setCookie("CDLIActiveBasket",basketId,path="/") - try: - qs=cgi.parse_qs(REQUEST['QUERY_STRING']) - del(qs['basketId']) - except: - qs={} + try: + qs=cgi.parse_qs(REQUEST['QUERY_STRING']) + del(qs['basketId']) + except: + qs={} if REQUEST: REQUEST.RESPONSE.redirect(REQUEST['URL1']+'?'+urllib.urlencode(qs)) @@ -898,7 +759,7 @@ class CDLIBasketContainer(OrderedFolder) ob=manage_addCDLIBasket(self,newBasketName) return ob - + def storeInBasket(self,submit,ids=None,newBasketName=None,fromFileList=None,RESPONSE=None,REQUEST=None): """store it""" if not ids: @@ -1000,7 +861,11 @@ class CDLIBasket(Folder,CatalogAware): self.shortDescription=shortDescription self.comment=comment - + def getActualUserName(self): + """get name of the actualuser""" + + return str(self.REQUEST['AUTHENTICATED_USER']) + def getLastVersion(self): """hole letzte version""" @@ -1064,9 +929,59 @@ class CDLIBasket(Folder,CatalogAware): return obj + def addObjectsWithVersion(self,ids,deleteOld=None,username=None,catalog=None): + """generate a new version of the basket with objects added, + hier wird jedoch nicht die letzte Version jedes Files hinzugefuegt, s + ondern ids is ein Tupel mit der Id (d.h. der p-number) und der Versionsnummer. + """ + logging.info("add to basket (%s)"%(self.getId())) + lastVersion=self.getLastVersion() + + if not catalog: + catalog=self.CDLICatalog + + if lastVersion is None: + oldContent=[] + else: + oldContent=lastVersion.content.getContent() + + if deleteOld: + oldContent=[] + + newContent=[] + added=0 + + for id,version in ids.iteritems(): + logging.info("adding %s %s"%(id,version)) + id=id.split(".")[0] # title nur die pnumber ohne atf + + try: + founds=catalog.search({'title':id}) + except: + founds=[] + logging.info(" found %s "%(founds)) + for found in founds: + if found.getObject() not in oldContent: + + #TODO: was passiert wenn, man eine Object dazufgt, das schon da ist aber eine neuere version + newContent.append((found.getObject().getVersions()[version-1][1],found.getObject())) + added+=1 + + content=oldContent+newContent + if not username: + logging.error("XXXXXXXXXXX %s"%repr(self)) + user=self.getActualUserName() + else: + user = username + + ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content) + logging.info("add to basket (%s) done"%(self.getId())) + return added + + def addObjects(self,ids,deleteOld=None,username=None): """generate a new version of the basket with objects added""" - + logging.info("add to basket (%s)"%(self.getId())) lastVersion=self.getLastVersion() if lastVersion is None: @@ -1080,10 +995,11 @@ class CDLIBasket(Folder,CatalogAware): newContent=[] added=0 for id in ids: - try: - founds=self.CDLICatalog.search({'title':id}) - except: - founds=[] + try: + founds=self.CDLICatalog.search({'title':id}) + except: + founds=[] + for found in founds: if found.getObject() not in oldContent: #TODO: was passiert wenn, man eine Object dazufgt, das schon da ist aber eine neuere version @@ -1097,12 +1013,22 @@ class CDLIBasket(Folder,CatalogAware): user = username ob=manage_addCDLIBasketVersion(self,user,comment="",basketContent=content) - + logging.info("add to basket (%s) done"%(self.getId())) return added - + def getContent(self): + """print content""" + ret=[] + + lv=self.getLastVersion() + for obj in lv.content.getContent(): + logging.info("XXXXXXXXXX %s"%repr(obj)) + ret.append((obj[1].getId(),obj[0].versionNumber)) + + return ret + def getContentIds(self): """print basket content""" ret=[] @@ -1189,6 +1115,21 @@ class CDLIBasketVersion(Implicit,Persist return True return False + def downloadListOfPnumbers(self): + """download pnumbers of the basket as list""" + + basket_name=self.aq_parent.title + + ids=self.getContent() # get the list of objects + logging.error(ids) + ret="\n".join([x[1].getId().split(".")[0] for x in ids]) + + self.REQUEST.RESPONSE.setHeader("Content-Disposition","""attachement; filename="%s.txt" """%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) + security.declareProtected('View','downloadObjectsAsOneFile') def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None,check="yes",current="no"): """download all selected files in one file""" @@ -1231,7 +1172,7 @@ class CDLIBasketVersion(Implicit,Persist lockedObjects={} for object in self.content.getContent(): - if not object[1].lockedBy=="": + if (not str(object[1].lockedBy)=="") and (not (str(object[1].lockedBy)==str(self.REQUEST['AUTHENTICATED_USER']))): lockedObjects[object[1].title]=repr(object[1].lockedBy) @@ -1391,7 +1332,7 @@ class CDLIFileObject(CatalogAware,extVer newversion=parent.manage_addCDLIFileObject('',comment,author) - newversion.data=self.data[0:] + newversion.manage_upload(self.getData()) if RESPONSE is not None: RESPONSE.redirect(self.aq_parent.absolute_url()+'/history') @@ -1404,7 +1345,8 @@ class CDLIFileObject(CatalogAware,extVer def getFormattedData(self): """fromat text""" data=self.getData() - return re.sub("\s\#lem"," #lem",data) #remove return vor #lem +# return re.sub("\s\#lem"," #lem",data) #remove return vor #lem + return re.sub("#lem"," #lem",data) #remove return vor #lem def view(self): """view file""" @@ -1641,7 +1583,14 @@ def manage_addCDLIFile(self,id,title,loc if RESPONSE is not None: RESPONSE.redirect('manage_main') - +def checkUTF8(data): + """check utf 8""" + try: + data.encode('utf-8') + return True + except: + return False + def checkFile(filename,data,folder): """check the files""" @@ -1652,17 +1601,11 @@ def checkFile(filename,data,folder): return False,"P 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: - fn=os.path.join(folder,filename) - stin,out=os.popen4("/usr/bin/atfcheck.plx %s"%fn) - value=out.read() - ret= out.close() - - if value: - - return False,"atf checker error: %s"%value - else: - return True,"" + return True,"" + def splitatf(fh,dir=None,ext=None): """split it""" @@ -1671,40 +1614,42 @@ def splitatf(fh,dir=None,ext=None): i=0 for lineTmp in fh.readlines(): - for line in lineTmp.split("\r"): - if ext: - i+=1 - if (i%100)==0: - ext.result+="." - if i==10000: - i=0 - ext.result+="adding: %s
"%f + ext.result="adding: %s
"%f+ext.result if not obj: manage_addCDLIFileFolder(root,folder,folder) fobj=getattr(root,folder) @@ -2414,13 +2385,13 @@ class CDLIRoot(Folder): self.CDLICatalog.catalog_object(ob) #self.CDLICatalog.manage_catalogFoundItems(obj_ids=[id],search_sub=1) #self.CDLICatalog.manage_catalogObject(self.REQUEST, self.REQUEST.RESPONSE, 'CDLICatalog', urlparse.urlparse(ob.absolute_url())[1]) - count+=1 + count+=1 - if count > 1000: - print "committing" - transaction.get().commit() - count=0 - transaction.get().commit() + if count > 1000: + print "committing" + transaction.get().commit() + count=0 + transaction.get().commit() return "ok" @@ -2441,9 +2412,9 @@ def manage_addCDLIRoot(self, id, title=' ob.id=str(id) ob.title=title try: - self._setObject(id, ob) + self._setObject(id, ob) except: - pass + pass ob=self._getOb(id) checkPermission=getSecurityManager().checkPermission