Annotation of cdli/tools/uploadATF.py, revision 1.1
1.1 ! dwinter 1: import sys
! 2: from ZODB import DB
! 3: from ZEO import ClientStorage
! 4: from ZPublisher.HTTPResponse import HTTPResponse
! 5: from ZPublisher.HTTPRequest import HTTPRequest
! 6: from ZPublisher.BaseRequest import RequestContainer
! 7:
! 8: import logging
! 9: import os
! 10: import os.path
! 11: import tempfile
! 12: import codecs
! 13: from Products.cdli.cdli_files import CDLIRoot
! 14:
! 15: import pickle
! 16:
! 17: class StoreObject:
! 18: returnValue={}
! 19: def __init__(self,storeId):
! 20: self.storeId= storeId
! 21:
! 22:
! 23: def save(self):
! 24: pf = file("/tmp/"+self.storeId+".result","w")
! 25: pickle.dump(self.returnValue,pf)
! 26: pf.close()
! 27:
! 28:
! 29: class uploadATFThread:
! 30: """class for checking the files befor uploading"""
! 31:
! 32: def checkFile(self,filename,data,folder):
! 33: """check the files"""
! 34: # first check the file name
! 35: fn=filename.split(".") # no extension
! 36:
! 37: if not (fn[0][0]=="P" or fn[0][0]=="S"):
! 38: return False,"P/S missing in the filename"
! 39: elif len(fn[0])!=7:
! 40: return False,"P number has not the right length 6"
! 41: elif not checkUTF8(data):
! 42: return False,"not utf-8"
! 43: else:
! 44: return True,""
! 45:
! 46: def splitatf(self,fh,dir=None,ext=None):
! 47: """split it"""
! 48: ret=None
! 49: nf=None
! 50: i=0
! 51: fileCount=0
! 52: #ROC: why split \n first and then \r???
! 53: if isinstance(fh, basestring):
! 54: iter=fh.split("\n")
! 55: else:
! 56: iter=fh.readlines()
! 57:
! 58: for lineTmp in iter:
! 59: #if fileCount>10:
! 60: # break;
! 61: lineTmp=lineTmp.replace(codecs.BOM_UTF8,'') # make sure that all BOM are removed..
! 62: for line in lineTmp.split("\r"):
! 63: #logging.info("Deal with: %s"%line)
! 64:
! 65: i+=1
! 66: if (i%100)==0:
! 67: self.result.write(str(i)+"\n")
! 68: self.result.flush()
! 69: #check if basket name is in the first line
! 70: if line.find("#atf basket")>=0: #old convention
! 71: ret=line.replace('#atf basket ','')
! 72: ret=ret.split('_')[0]
! 73: elif line.find("#basket:")>=0: #new convention
! 74: ret=line.replace('#basket: ','')
! 75: ret=ret.split('_')[0]
! 76:
! 77: else:
! 78: if (len(line.lstrip())>0) and (line.lstrip()[0]=="&"): #newfile
! 79: if nf:
! 80: fileCount+=1
! 81: print fileCount
! 82: nf.close() #close file
! 83: #if fileCount>10:
! 84: # break
! 85:
! 86: filename=line[1:].split("=")[0].rstrip()+".atf"
! 87: if dir:
! 88: filename=os.path.join(dir,filename)
! 89: nf=file(filename,"w")
! 90: logging.debug("open %s"%filename)
! 91: if nf:
! 92: nf.write(line.replace("\n","")+"\n")
! 93:
! 94: try:
! 95: nf.close()
! 96:
! 97: except:
! 98: pass
! 99:
! 100: if not isinstance(fh, basestring):
! 101: fh.close()
! 102:
! 103: files = os.popen4('find %s' % dir)[1].read().rstrip().split('\n')
! 104: files.remove(dir)
! 105:
! 106: return ret,len(files)
! 107:
! 108:
! 109: def __init__(self):
! 110: """initialise"""
! 111: logging.getLogger().setLevel(logging.DEBUG)
! 112:
! 113:
! 114: def set(self,uploadId,basketId,username,serverport="8080"):
! 115: """set start values for the thread"""
! 116: self.result=file("/tmp/"+str(uploadId)+".out","w")
! 117: self.uploadId=uploadId
! 118: self.basketId=basketId
! 119: self.username=username
! 120: self.serverport=serverport
! 121:
! 122:
! 123: def __call__(self):
! 124: """call method """
! 125: self.run()
! 126: return True
! 127:
! 128: def getContext(self, app,serverport="8080"):
! 129: """get the context within the ZODB"""
! 130: resp = HTTPResponse(stdout=None)
! 131: env = {
! 132: 'SERVER_NAME':'localhost',
! 133: 'SERVER_PORT':serverport,
! 134: 'REQUEST_METHOD':'GET'
! 135: }
! 136: req = HTTPRequest(None, env, resp)
! 137: return app.__of__(RequestContainer(REQUEST = req))
! 138:
! 139: def run(self):
! 140:
! 141:
! 142: #find context within ZODB
! 143: storage=ClientStorage.ClientStorage(("localhost",8100));
! 144: db = DB(storage)
! 145: conn = db.open()
! 146: root = conn.root()
! 147: app = root['Application']
! 148: ctx = self.getContext(app,serverport=self.serverport)
! 149: logging.info("run intern")
! 150:
! 151: logging.info("call thread intern")
! 152: self.uploadATFThread(ctx,self.uploadId,self.basketId)
! 153:
! 154: #ctx.cdliRoot.cdli_main.tmpStore2[self.getName()[0:]]=self.returnValue
! 155:
! 156:
! 157:
! 158: def getResult(self):
! 159: """method for accessing result"""
! 160: ret=""
! 161: for x in self.result.readlines():
! 162: ret+=x
! 163:
! 164: return ret
! 165:
! 166: def uploadATFThread(self,ctx,uploadId,basketId=0):
! 167: """upload an atf file"""
! 168: #TODO: add comments
! 169: #TODO: finish uploadATF
! 170:
! 171:
! 172: logging.info("start, upload thread")
! 173: self.result.write("<html><body><h2>I got your file, start now to split it into single atf-files!</h2><p>\n")
! 174:
! 175: #make sure that id is a string and not an integer
! 176: basketId=str(basketId)
! 177: logging.info("basketID:"+basketId)
! 178: #TODO: make this configurable, at the moment, rootFolder for cdli has to be cdliRoot
! 179: ctx2=ctx.cdliRoot
! 180:
! 181: #get temporary file for staging the downloaded and splitted files
! 182: dir=tempfile.mkdtemp()
! 183:
! 184: logging.info("tmpfFile:"+str(dir))
! 185: changed=[] # changed files
! 186: errors=[] # files with errors
! 187: lockerrors=[] # files with errors
! 188:
! 189: newPs=[] # new p filed
! 190: psNotInCatalog=[] # files not in the catalog
! 191:
! 192: #split the uploadedd atf file
! 193: logging.info("start splitting")
! 194: basketNameFromFile,numberOfFiles=self.splitatf(file("/tmp/"+uploadId,'r'),dir)
! 195:
! 196: #find basketId if not set
! 197:
! 198: #get active abaket
! 199: if basketId == '0':
! 200: print ctx2
! 201: basketObj=ctx2.basketContainer.getActiveBasket()
! 202: if basketObj:
! 203: basketId=basketObj.getId()
! 204:
! 205: #if there is no active basket and no basketid given, id is empty, else get besketname and length
! 206: if basketId == '0':
! 207: basketNameFromId=""
! 208: basketLen=0
! 209: else:
! 210: basketNameFromId=getattr(ctx2.basketContainer,basketId).title
! 211: basketLen=getattr(ctx2.basketContainer,basketId).getLastVersion().numberOfItems()
! 212:
! 213: logging.info("got the file, upload thread")
! 214: self.result.write("""<html><body><h2>I got the files</h2><
! 215: p>I am computing the differences to the exisiting files</p>\n""")
! 216:
! 217: #start to check the files
! 218:
! 219: #workaround fuer memory fehler in listdir
! 220: #http://stackoverflow.com/questions/4098831/workaround-oserror-with-os-listdir
! 221: files = os.popen4('find %s' % dir)[1].read().rstrip().split('\n')
! 222: files.remove(dir)
! 223: n = len(dir)
! 224: if dir[-1] != os.path.sep:
! 225: n += 1
! 226: files = [f[n:] for f in files] # remove dir prefix
! 227:
! 228: #for fn in os.listdir(dir):
! 229: for fn in files:
! 230:
! 231: self.result.write("<p>process:%s</p>\n"%fn)
! 232: logging.debug(fn)
! 233: # check if file is in the catalog
! 234: #TODO: checkCatalog is not implemented yet
! 235: if ctx2.cdli_main.checkCatalog(fn):
! 236: psNotInCatalog.append(fn)
! 237:
! 238: #check if p-file already at the server
! 239: founds=ctx2.CDLICatalog.search({'title':fn})
! 240:
! 241: #if not than add filename to the list of newfiles
! 242: dataFile=file(os.path.join(dir,fn))
! 243: data=dataFile.read()
! 244: dataFile.close()
! 245: status,msg=self.checkFile(fn,data,dir)
! 246: #status=True
! 247:
! 248:
! 249: if not status: # error
! 250: errors.append((fn,msg))
! 251:
! 252: else:
! 253: if len(founds)==0:
! 254: newPs.append(fn)
! 255:
! 256: #if p file alread at the server
! 257: for found in founds:
! 258: #analyse the differences to the actual file
! 259: obj=found.getObject()
! 260:
! 261: if (not (str(obj.lockedBy))=='') and (not (str(obj.lockedBy)==str(self.username))):
! 262: lockerrors.append((fn,str(obj.lockedBy)))
! 263: else:
! 264:
! 265: diffs=obj.diff(data)
! 266: if diffs[0]>0:
! 267: changed.append((obj,diffs)) #hochladen
! 268:
! 269: #ready, set the returnValues
! 270: self.result.write("<h3>Done</h3></body></html>\n")
! 271:
! 272: stObj = StoreObject(uploadId);
! 273:
! 274: stObj.returnValue={}
! 275:
! 276: stObj.returnValue['errors']=errors
! 277:
! 278: stObj.returnValue['newPs']=newPs
! 279: stObj.returnValue['tmpdir']=dir
! 280: stObj.returnValue['basketLen']=basketLen
! 281: stObj.returnValue['numberOfFiles']=numberOfFiles
! 282: stObj.returnValue['basketNameFromId']=basketNameFromId
! 283: stObj.returnValue['basketNameFromFile']=basketNameFromFile
! 284: stObj.returnValue['basketId']=basketId
! 285: stObj.returnValue['dir']=dir
! 286: #stObj.returnValue['changed']=copy.copy(changed)
! 287: stObj.returnValue['changed']=[(x[0].getId(),x[1][0]) for x in changed]
! 288: #stObj.returnValue['lockerrors']=[x[0].getId() for x in lockerrors]
! 289: stObj.returnValue['lockerrors']=[x for x in lockerrors]
! 290: self.returnValue=True
! 291: #ctx2.cdli_main.setTemp('v_uploadATF_returnValue',True)
! 292:
! 293: stObj.save();
! 294:
! 295: def checkUTF8(data):
! 296: """check utf 8"""
! 297: if not isinstance(data, str):
! 298: logging.error("checkUTF8 data is not string! (%s)"%repr(data))
! 299:
! 300: try:
! 301: data.decode('utf-8')
! 302: logging.debug("checkUTF8: ok!")
! 303: return True
! 304: except:
! 305: logging.debug("checkUTF8: false!")
! 306: return False
! 307:
! 308: if __name__ == "__main__":
! 309: upload = uploadATFThread()
! 310: x=sys.argv;
! 311: print x
! 312: upload.set(sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4])
! 313: upload.run();
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>