#!/usr/bin/env python3 # Twisted/Klein imports from twisted.logger import Logger from twisted.internet import reactor from klein import Klein # Other library imports from json import dumps, loads from json.decoder import JSONDecodeError from signal import signal, SIGINT # Project imports from settings import settings import util from agora import Agora from transactions import Transactions from irc import bot from notify import Notify from markets import Markets from money import Money # from sinks.nordigen import Nordigen # from sinks.truelayer import TrueLayer # from sinks.fidor import Fidor import sinks init_map = None # TODO: extend this with more def cleanup(sig, frame): if init_map: try: init_map["tx"].lc_es_checks.stop() init_map["agora"].lc_dash.stop() init_map["agora"].lc_cheat.stop() except: # noqa pass # noqa reactor.stop() signal(SIGINT, cleanup) # Handle Ctrl-C and run the cleanup routine def convert(data): if isinstance(data, bytes): return data.decode("ascii") if isinstance(data, dict): return dict(map(convert, data.items())) if isinstance(data, tuple): return map(convert, data) return data class WebApp(object): """ Our Klein webapp. """ app = Klein() def __init__(self): self.log = Logger("webapp") @app.route("/callback", methods=["POST"]) def callback(self, request): content = request.content.read() try: parsed = loads(content) except JSONDecodeError: self.log.error("Failed to parse JSON callback: {content}", content=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): auth_url = self.truelayer.create_auth_url() return f'Please sign in here.' # endpoint called after we finish setting up a connection above @app.route("/callback-truelayer", methods=["POST"]) def signin_callback(self, request): code = request.args[b"code"] self.truelayer.handle_authcode_received(code) return dumps(True) @app.route("/accounts", methods=["GET"]) def balance(self, request): accounts = self.truelayer.get_accounts() return dumps(accounts, indent=2) if __name__ == "__main__": init_map = { "notify": Notify(), "irc": bot(), "agora": Agora(), "markets": Markets(), "sinks": sinks.Sinks(), "tx": Transactions(), "webapp": WebApp(), "money": Money(), } # Merge all classes into each other util.xmerge_attrs(init_map) # Set up the loops to put data in ES init_map["tx"].setup_loops() # Run the WebApp init_map["webapp"].app.run(settings.App.BindHost, 8080)