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