#!/usr/bin/env python3 # Twisted/Klein imports # Other library imports from json import dumps from signal import SIGINT, signal from sys import argv import lib.antifraud import lib.logstash import lib.markets import lib.money import lib.transactions # New style classes import sinks import sources import util import ux from klein import Klein # Project imports from settings import settings from twisted.internet import reactor from twisted.internet.protocol import Factory init_map = None Factory.noisy = False # TODO: extend this with more def cleanup(sig, frame): to_cleanup = [] if hasattr(init_map["money"], "lc_es_checks"): to_cleanup.append(init_map["money"].lc_es_checks.stop) if hasattr(init_map["sources"].agora, "lc_dash"): to_cleanup.append(init_map["sources"].agora.lc_dash.stop) if hasattr(init_map["sources"].agora, "lc_cheat"): to_cleanup.append(init_map["sources"].agora.lc_cheat.stop) if hasattr(init_map["sources"].lbtc, "lc_dash"): to_cleanup.append(init_map["sources"].lbtc.lc_dash.stop) if hasattr(init_map["sources"].lbtc, "lc_cheat"): to_cleanup.append(init_map["sources"].lbtc.lc_cheat.stop) if hasattr(init_map["sinks"], "truelayer"): if hasattr(init_map["sinks"].truelayer, "lc"): to_cleanup.append(init_map["sinks"].truelayer.lc.stop) if hasattr(init_map["sinks"].truelayer, "lc_tx"): to_cleanup.append(init_map["sinks"].truelayer.lc_tx.stop) if hasattr(init_map["sinks"], "nordigen"): if hasattr(init_map["sinks"].nordigen, "lc"): to_cleanup.append(init_map["sinks"].nordigen.lc.stop) if hasattr(init_map["sinks"].nordigen, "lc_tx"): to_cleanup.append(init_map["sinks"].nordigen.lc_tx.stop) if init_map: for func in to_cleanup: try: func() except: # noqa print(f"Exception when stopping {func}") pass # noqa reactor.stop() signal(SIGINT, cleanup) # Handle Ctrl-C and run the cleanup routine class WebApp(util.Base): """ Our Klein webapp. """ app = Klein() # @app.route("/callback", methods=["POST"]) # def callback(self, request): # content = request.content.read() # try: # parsed = loads(content) # except JSONDecodeError: # self.log.error(f"Failed to parse JSON callback: {content}") # return dumps(False) # self.log.info("Callback received: {parsed}", parsed=parsed["data"]["id"]) # # self.tx.transaction(parsed) # return dumps(True) # set up another connection to a bank @app.route("/signin/", methods=["GET"]) def signin(self, request, account): auth_url = self.sinks.truelayer.create_auth_url(account) return f'Please sign in to {account} here.' # endpoint called after we finish setting up a connection above @app.route("/callback-truelayer", methods=["POST"]) def signin_callback_truelayer(self, request): code = request.args[b"code"] self.sinks.truelayer.handle_authcode_received(code) return dumps(True) @app.route("/callback-nordigen", methods=["GET"]) def signin_callback_nordigen(self, request): # code = request.args[b"code"] # self.sinks.truelayer.handle_authcode_received(code) return dumps(True) @app.route("/callback-verify", methods=["POST"]) def callback_verify(self, request): # code = request.args[b"code"] rtrn = self.ux.verify.handle_callback(request) return dumps(rtrn) @app.route("/accounts/", methods=["GET"]) def balance(self, request, account): accounts = self.sinks.truelayer.get_accounts(account) return dumps(accounts, indent=2) if __name__ == "__main__": if "--debug" in argv: util.debug = True init_map = { "ux": ux.UX(), "markets": lib.markets.Markets(), "sources": sources.Sources(), "sinks": sinks.Sinks(), "tx": lib.transactions.Transactions(), "webapp": WebApp(), "money": lib.money.Money(), "antifraud": lib.antifraud.AntiFraud(), } # Merge all classes into each other util.xmerge_attrs(init_map) # Let the classes know they have been merged for class_name, class_instance in init_map.items(): if hasattr(class_instance, "__xmerged__"): class_instance.__xmerged__() # Set up the loops to put data in ES # init_map["tx"].setup_loops() lib.logstash.init_logstash() # Run the WebApp init_map["webapp"].app.run(settings.App.BindHost, 8080)