#!/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 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 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) if __name__ == "__main__": init_map = { "notify": Notify(), "irc": bot(), "agora": Agora(), "markets": Markets(), "revolut": Revolut(), "tx": Transactions(), "webapp": WebApp(), "money": Money(), } for classname, object_instance in init_map.items(): # notify, Notify for classname_inside, object_instance_inside in init_map.items(): if not classname == classname_inside: # irc, bot setattr(object_instance, classname_inside, object_instance_inside) # Handle setting up JWT and request_token from an auth code if settings.Revolut.SetupToken == "1": deferLater(reactor, 1, init_map["revolut"].setup_auth) else: # Schedule refreshing the access token using the refresh token deferLater(reactor, 1, init_map["revolut"].get_new_token, True) # Check if the webhook is set up and set up if not deferLater(reactor, 4, init_map["revolut"].setup_webhook) # Schedule repeatedly refreshing the access token lc = LoopingCall(init_map["revolut"].get_new_token) lc.start(int(settings.Revolut.RefreshSec)) # Set up the loops to put data in ES init_map["tx"].setup_loops() # Run the WebApp init_map["webapp"].app.run("127.0.0.1", 8080)