Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import bottle
- from bottle import route, run, Bottle, request
- import sys, os, re, urllib
- import datetime #I think I need this
- import time #I think I need this
- from gevent import queue
- from gevent import Greenlet
- import gevent
- import StringIO
- from datetime import datetime
- #from gevent import pywsgi #Don't need this yet
- fcpHost = "127.0.0.1"
- import fcp
- #node = fcp.FCPNode(host=fcpHost, verbosity=fcp.DETAIL)
- jobs={}
- app = Bottle()
- #https://stackoverflow.com/questions/17262170/bottle-py-enabling-cors-for-jquery-ajax-requests#17262900
- # the decorator
- def enable_cors(fn):
- def _enable_cors(*args, **kwargs):
- # set CORS headers
- response.headers['Access-Control-Allow-Origin'] = '*'
- response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
- response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
- if bottle.request.method != 'OPTIONS':
- # actual request; reply with the actual response
- return fn(*args, **kwargs)
- return _enable_cors
- def delim_filter(config):
- bottle.debug(True)
- print("Entering delim_filter")
- ''' Matches a comma separated list of numbers. '''
- aconfig = config or "%20"
- print ("aconfig=" + aconfig)
- delimiter = urllib.unquote(aconfig).decode('utf8')
- print("delimiter=" + delimiter)
- regexp = r'(?!{a_delim})+({a_delim}(?!{a_delim})+)*'.format(a_delim=re.escape(delimiter))
- print("regexp="+regexp)
- def to_python(match):
- print("Converting Match")
- print("Math=" + match)
- ms = map(urllib.unquote(aconfig).decode,match.split())
- print( "ms=" + ms )
- return ms
- def to_url(astr):
- print("Converting to URL")
- print ("astr=" + astr)
- astr2 = delimiter.join(map(urllib.unquote(aconfig).decode,astr))
- print("astr2="+astr2)
- print astr2
- return astr2
- return regexp, to_python, to_url
- app.router.add_filter('delim', delim_filter)
- def split_urlArgs(url,delim=" ",
- decode='All',
- xfm_de=lambda a: urllib.unquote(a).decode('utf8'),
- xfm_split=lambda a, b: re.split(a,b), #Typically a is a regular expression and b a string
- fn_regexp = lambda a: r'(?!{a_delim})+({a_delim}(?!{a_delim})+)*'.format(a_delim=a) ):
- bottle.debug(True)
- ''' Matches a comma separated list of numbers. '''
- print("delimiter=" + delim)
- if decode == "Args":
- ms = xfm_split(fn_regexp(a),url)
- elif decode == "All":
- url2 = xfm_de(url) #Decode the URL
- delim= xfm_de(delim) #Decode the delimitor
- ms = xfm_split(fn_regexp(delim),url)
- elif decode == "None":
- ms = xfm_split(fn_regexp(delim),url) #SPlit the URL based on a regular expression.
- print( "ms=" + "["+",".join(ms) +"]" )
- return ms, delim
- def combine_urlArgs(args,delim=" ",
- encode='All',
- xfm_encode=lambda a: urllib.quote(a, safe=''),
- xfm_join=lambda a, b: a.join(b)): #Typically a is the delimiter and b is a list
- print("Converting to URL")
- print ("astr=" + args)
- if decode == "Args":
- astr2 = xfm_join(delim,(map(lambda a: xfm_encode,args)))
- elif decode == "All":
- astr2 = urllib.unquote(xfm_join(delim,args))
- elif decode=="None":
- astr2 = xfm_join(delim,args)
- print("astr2="+astr2)
- return astr2
- #@app.route('/<key>/%09/<cmd>/<args:delim:%09>') # %09 == tab
- #@app.route('/<key>/%20/<cmd>/<args:delim:%20>') # %20 == ' '
- #@app.route('/<key>/ /<cmd>/<args:delim: >') # %20 == ' '
- #@app.route('/<key>/%3B/<cmd>/<args:delim:%3B>') # %3B == ';'
- #@app.route('/<key>/;/<cmd>/<args:delim:;>') # %3B == ';'
- #@app.route('/<key>/%2C/<cmd>/<args:delim:%2C>') # %2C == ','
- #@app.route('/<key>/,/<cmd>/<args:delim:,>') # %2C == ','
- @app.route('/<key>/<sep>/<cmd>/<args:path>') # %2C == ','
- def mystery(key,cmd,args,sep=""):
- bottle.debug(True)
- print("engering mystery")
- print("sep=" + sep)
- if len(sep) > 0 : # True if seperator is a wild card
- args, sep = split_urlArgs(args,sep)
- if key == '1234': # %2C == ','
- print(key)
- print(cmd)
- print(args)
- #delimiter = urllib.unquote(aconfig).decode('utf8')
- #print(delimiter)
- result1 = os.popen("IFS=<a_dilim>".format(a_dilim=sep)).read()
- print("result1=" + result1)
- result2 = result1 + "<br>"
- print("result2=" + result2)
- cmd_str=cmd + sep + sep.join(args)
- print(cmd_str)
- result3 = result2 +os.popen(cmd_str).read()
- print("result3=" + result3)
- return "<pre>" + result3 + "</pre>"
- #return result3.replace("\n","<br>")
- #return ('key=' + key + '<br>' +
- # 'sep=' + sep + '<br>' +
- # 'cmd=' + cmd + '<br>' +
- # 'args=' + "[" + ",".join(args)+"]")
- def generateFreeWorker(job_or_uri,message=None,afile=None,fcpHost = "127.0.0.1",fcpPort= 9481,aBody=None,OutputType="HTML"):
- fw = FreeWorkerFactory(job_or_uri,message,afile,fcpHost,fcpPort,aBody,OutputType)
- return fw
- #class calbackExecuter:
- # __init__(self,calbacks):
- # self.callbacks=calbacks
- # def execute():
- # for c in self.calbacks():
- # c()
- class loggerContainer:
- def __init__(self,job=None,node=None,**kw):
- self.ready = False
- self.strBuff = StringIO.StringIO()
- self.job = job
- self.Brk = kw.get('Brk',"\n")
- self.body = kw.get('body',None) #The html body to write to.
- self.complete=False
- self.msgDict={}
- self.meseges=[None]*5
- self.msgPosNext=0
- self.msgPos=-1
- self.msgMax=5
- self.msgLnCnt=0
- self.node=node
- def filterMSG(self,msg): #We don't want to see the same log message too often
- t1=self.msgDict.get(msg,None)
- if t1 is not None: #isinstance(t1,datetime):
- t2=datetime.now()
- delta = t2 - t1 #https://stackoverflow.com/questions/2880713/time-difference-in-seconds-as-a-floating-point
- if delta.seconds>5:
- return True
- else:
- return False
- return True
- def do_logfunc(self,msgline,cb=None):
- print("self.msgPosNext="+str(self.msgPosNext))
- self.meseges[self.msgPosNext]={ "msg_str" : msgline,
- "time" : datetime.now()
- }
- self.msgPos=self.msgPosNext
- print("self.msgMax="+str(self.msgMax))
- self.msgPosNext=((self.msgPosNext+1)%(self.msgMax))
- self.msgDict[msgline]=datetime.now()
- if self.msgLnCnt<self.msgMax:
- self.msgLnCnt=self.msgLnCnt+1
- def logfunc(self,msgline,cb=None,HTML_lb="<br>"):
- if cb is None:
- cb=self.print_and_put_cb
- if self.filterMSG(msgline):
- self.do_logfunc(msgline,cb)
- cb(msgline)
- def bodyPut_cb(self,msg,HTML_lb="<br>"):
- self.body.put(self.msg_to_str(msg)+HTML_lb)
- def print_and_put_cb(self,msg,HTML_lb="<br>"):
- print self.msg_to_str(msg)
- if self.body is not None:
- self.bodyPut_cb(msg,HTML_lb)
- def msg_to_str(self,msg):
- if type(msg) == str:
- return msg
- elif type(msg) is dict: #isinstance(msg, collections.Mapping): #https://stackoverflow.com/questions/25231989/how-to-check-if-a-variable-is-a-dictionary-in-python
- return msg['msg_str']
- else:
- return "Empty Message"
- def tail(self,lines=0,cb=None,delta=None):
- if cb is None:
- cb=self.print_and_put_cb
- if lines == 0:
- N=self.msgMax
- else:
- N=min(self.msgMax,lines)
- for i in range(self.msgPost,self.msgPos-N+1,-1):
- msg_i=self.meseges[i%self.msgMax]
- if delta is not None:
- t2=datetime.now()
- t1=msg_i['time']
- delta2=t2-t1
- if delta2.delta.microseconds > delta.microseconds:
- break
- cb(self.meseges[i%self.msgMax])
- #self.body.put(msgline)
- def myLogger(self, level, msg):
- print("level="+level + " msg=" + msg)
- if level > self.job.verbosity:
- return
- if not msg.endswith(self.Brk):
- msg += "\n"
- strBuff.write(msg)
- self.isReady = True
- #strBuff.flush()
- #time.sleep(0.001)
- def getLogger(self): #THis might be redundant
- return self.myLogger
- def isReady(self):
- return self.ready
- def flush(self):
- val=self.strBuff.getvalue()
- self.strBuff.close()
- self.strBuff = StringIO.StringIO()
- self.isRead=False
- return val
- def getValue(self):
- self.strBuff.getValue()
- def readBuf(self):
- if self.ready:
- val = self.flush()
- ready = True
- return val, ready
- else:
- ready = False
- val = ""
- return val, ready
- return val, ready
- def isComplete(self): # We might also want to check for an EndMessage and wait if needed
- return self.complete
- #if self.job.msg['hdr'] == 'PutSuccessful':
- # return True
- #elif self.job.msg['hdr'] == 'PutFailed':
- # return True
- def callback(self, status, value):
- if status == 'PutSuccessful':
- self.complete=True
- elif status == 'PutFailed':
- self.complete=True
- #elif status == 'URIGenerated':
- # self.complete=True
- #self.msg=value
- def getCallback(self):
- return self.callback
- class FreeWorkerFactory:
- #self.job = None #A freenet job
- #self.g = None
- #self.body = None
- #self.OutputType =None
- def __init__(self,job_or_uri,**kw):
- self.kw={}
- self.kw['message']=kw.get('message',None)
- self.kw['file']=kw.get(file,None)
- self.loggerContainer=kw.get('loggerContainer',None)
- #if self.kw['logger'] is not None:
- # loggerContainer
- self.host=kw.get('host',"127.0.0.1")
- self.port=self.kw.get('port',9481)
- self.OutputType=self.kw.get('OutputType','HTML')
- #selffcpPort,aBody,OutputType
- if type(job_or_uri) is str:
- print("__init__" + "uri as input")
- if job_or_uri in jobs:
- print("uri in jobs")
- self.job=jobs[job_or_uri]
- else:
- print("making job")
- node = fcp.FCPNode(fcpHost,verbosity='fcp.DETAIL',port=self.kw)
- val = self.kw['message']
- ksk = job_or_uri
- uri = "KSK@" + ksk
- node.put("KSK@"+ksk, data=val, mimetype="text/plain", verbosity=fcp.DETAIL)
- self.job = node.get(uri, async=True)
- else:
- print("__init__"+"job as input")
- self.job=job_or_uri
- if self.OutputType == "HTML":
- self.Brk="<br>"
- elif self.OutputType == "UNIX":
- self.Brk="" #We won't use "\n" since print automatically generates the \n. Write can be used instead if one wants to explicitly use the /n
- self.body=None
- self.setBody(kw.get('body',None))
- #def freenetWorker(self):
- # # Empty Callback: http://echochamber.me/viewtopic.php?t=64825
- # #stop_me = lambda *_, **_: None
- def on_data(self):
- # we can poll the job
- while True:
- val, ready = self.loggerContainer.readBuf()
- if ready:
- print val
- self.body.put(val)
- if self.loggerContainer.isComplete():
- print "Yay! job complete"
- self.body.put(job.getResult()) #Returns the completion message.
- break
- else:
- print "Waiting" + datetime.now().strftime('%s(s) %m/%d/%Y')+self.Brk
- self.body.put("Waiting" + datetime.now().strftime('%s(s) %m/%d/%Y')+self.Brk)
- time.sleep(0.001)
- gevent.sleep(5) #This yields control to another greenlet
- self.on_finish() #Maybe we can sequence the greenlets instead of putting this here.
- def on_finish(self):
- self.body.put('</body></html>') #There should be a way to seperate these last two lines from this method.
- self.body.put(StopIteration)
- def header(self,start_response=None):
- if self.OutputType == "HTML":
- if start_response is not None:
- start_response('200 OK', [('Content-Type', 'text/html')])
- self.body.put(' ' * 1000)
- if self.OutputType == "HTML":
- self.body.put("<html><body><h1>Current Time:</h1>")
- def handle(self,environ=None, start_response=None,aBody=None):
- lambda a: self.start(self,enviorn,start_response)
- #g = Greenlet.spawn(on_data, body)
- def setBody(self,aBody=None):
- if aBody is None:
- if self.body is None:
- self.body = queue.Queue()
- self.g = Greenlet(self.on_data)
- self.loggerContainer.body=self.body
- else:
- self.body = aBody
- def start(self,environ=None, start_response=None,aBody=None): # Not sure
- #https://stackoverflow.com/questions/20824218/how-to-implement-someasyncworker-from-bottle-asynchronous-primer
- #g = Greenlet.spawn(current_time, lambda a: on_data(body))
- print("Set Body")
- self.setBody(aBody)
- print("header")
- self.header(start_response)
- print("start")
- self.g.start()
- return self.body, self.g
- #@enable_cors
- @app.post('/KSK/insert')
- def rest_test():
- fcpHost=request.json.get('host','127.0.0.1')
- fcpVerbosity=request.json.get('verbosity',fcp.NOISY)
- fcpPort=request.json.get('port',9481)
- val = request.json.get('message')
- ksk = request.json.get('ksk')
- uri = "KSK@" + ksk
- print "Inserting %s, containing '%s'" % (uri, val)
- # do the put - note that 'data=' inserts a string directly
- # note too that mimetype is optional, defaulting to text/plain
- #node.put("KSK@"+ksk, data=val, mimetype="text/plain")
- # ------------------------------------------
- # now, demonstrate asynchronous requests
- print "Launching asynchronous request"
- lgrCnt=loggerContainer()
- node = fcp.FCPNode(host=fcpHost,verbosity=fcp.NOISY,port=fcpPort,logfunc=lgrCnt.logfunc)
- job = node.put(uri, data=val, async=True) #, verbosity=fcp.DETAIL
- loggerContainer.job=job
- loggerContainer.node=node
- jobs["KSK@"+ksk]=job
- #node.logfunc=lgrCnt.logfunc
- job._log=lgrCnt.getLogger()
- job.callback=lgrCnt.getCallback()
- worker = FreeWorkerFactory(job,loggerContainer=lgrCnt)
- body, g = worker.start() #Returns the greenelet
- #body = gevent.queue.Queue()
- #worker = getFreenetWorker(job)
- #worker.on_data(body.put)
- #Finish https://stackoverflow.com/questions/20824218/how-to-implement-someasyncworker-from-bottle-asynchronous-primer
- #worker.on_finish(lambda: body.put(StopIteration)) # body.put('</body></html>')
- return body
- #yield job_waitt("KSK@"+ksk)
- #return "KSK Inserted" # We probably want to do wsomething smarter than this.
- # or we can await its completion
- #@app.route('/USK@<hashKey:nocomma>,<ecryptionKey:nocomma>,<encryption:nocomma>/<metaData:path>')
- #def hello(hashKey,ecryptionKey,encryption,metaData):
- #
- # mimetype, val1 = node.get(uri)
- # return ('hashKey=' + hashKey + '<br>' +
- # 'ecryptionKey=' + ecryptionKey + '<br>' +
- # 'encryption=' + encryption + '<br>' +
- # 'metaData=' + metaData)
- #
- #Regular eressions use a seperate filter; https://bottlepy.org/docs/dev/routing.html
- app.run(host='localhost', port=8082, debug=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement