#!/usr/bin/env python3 # Twisted/Klein imports from twisted.logger import Logger from twisted.internet import reactor from twisted.internet.task import LoopingCall, deferLater 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 revolut import Revolut 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.yapily import Yapily from sinks.truelayer import TrueLayer from sinks.fidor import Fidor init_map = None 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) def setup_call_loops(token_setting, function_init, function_continuous, delay, function_post_start=None): if token_setting == "1": deferLater(reactor, 1, function_init) else: deferLater(reactor, 1, function_continuous, True) if function_post_start: deferLater(reactor, 4, function_post_start) lc = LoopingCall(function_continuous) lc.start(delay) if __name__ == "__main__": init_map = { "notify": Notify(), "irc": bot(), "agora": Agora(), "markets": Markets(), "revolut": Revolut(), # "nordigen": Nordigen(), # "yapily": Yapily(), "truelayer": TrueLayer(), "fidor": Fidor(), "tx": Transactions(), "webapp": WebApp(), "money": Money(), } util.xmerge_attrs(init_map) setup_call_loops( token_setting=settings.Revolut.SetupToken, function_init=init_map["revolut"].setup_auth, function_continuous=init_map["revolut"].get_new_token, delay=int(settings.Revolut.RefreshSec), function_post_start=init_map["revolut"].setup_webhook, ) setup_call_loops( token_setting=settings.TrueLayer.SetupToken, function_init=init_map["truelayer"].setup_auth, function_continuous=init_map["truelayer"].get_new_token, delay=int(settings.TrueLayer.RefreshSec), ) # 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)