app.py (2647B)
1 import os 2 import logging 3 import re 4 import lmdb 5 6 from srvaddrgen import DbKey 7 from srvaddrgen.btc import btc_reserve 8 from srvaddrgen.msg import Message 9 10 logging.basicConfig(level=logging.DEBUG) 11 logg = logging.getLogger() 12 13 path_btc = re.compile('^/bitcoin$') 14 15 reasons = { 16 400: 'Bad Request', 17 } 18 class Responder(Exception): 19 20 def __init__(self, responder_method): 21 self.m = responder_method 22 self.code = 200 23 self.reason = 'OK' 24 self.content = None 25 26 27 def get_status(self): 28 return str(self.code) + ' ' + self.reason 29 30 31 def get_content(self): 32 if self.content == None: 33 return b'' 34 if isinstance(self.content, bytes): 35 return self.content 36 return self.content.encode('utf-8') 37 38 39 def complete(self, content=None, reason=None): 40 self.content = content 41 if reason != None: 42 self.reason = reason 43 44 45 def croak(self, code, err=None, reason=None): 46 self.code = code 47 if reason != None: 48 self.reason = reason 49 else: 50 self.reason = reasons[code] 51 headers = [('Content-Type', 'text/plain')] 52 if err != None: 53 self.content = err 54 status = self.get_status() 55 self.m(status, headers) 56 return self.get_content() 57 58 59 def flush(self): 60 headers = [('Content-Type', 'text/plain')] 61 status = self.get_status() 62 self.m(status, headers) 63 return self.get_content() 64 65 66 def __str__(self): 67 if self.content == None: 68 return '' 69 return self.content 70 71 72 def application(environ, start_response): 73 o = Responder(start_response) 74 75 db_path = os.environ.get('SRVADDRGEN_DB_PATH', 'srvaddrgen_data') 76 dbenv = lmdb.open(db_path, readonly=False) 77 78 method = environ['REQUEST_METHOD'] 79 v = environ['PATH_INFO'] 80 r = None 81 82 if path_btc.match(v): 83 if method != 'POST': 84 o.croak(400, 'This endpoint accepts json POST only', reason='POST only') 85 dbenv.close() 86 return o.flush() 87 b = environ['wsgi.input'].read() 88 msg = None 89 try: 90 msg = Message.parse_json(b) 91 except KeyError as e: 92 o.croak(400, 'Missing message item: ' + str(e)) 93 dbenv.close() 94 return o.flush() 95 96 logg.debug('msg! ' + str(msg)) 97 msg.set_origin(environ['REMOTE_ADDR']) 98 try: 99 btc_reserve(o, msg, dbenv) 100 except Responder as e: 101 logg.error('btc failed: ' + str(o)) 102 o = e 103 104 else: 105 r.croak(404) 106 107 dbenv.close() 108 109 return o.flush()