#!/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 # 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 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") def set_tx(self, tx): self.tx = tx @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__": # Define Notify notify = Notify() # Define IRC and Agora irc = bot() agora = Agora() # Pass Notify to IRC and Agora irc.set_notify(notify) agora.set_notify(notify) # Pass Agora to Notify notify.set_agora(agora) # Pass IRC to Agora and Agora to IRC # This is to prevent recursive dependencies agora.set_irc(irc) irc.set_agora(agora) # Define Revolut revolut = Revolut() # Pass IRC to Revolut and Revolut to IRC revolut.set_irc(irc) irc.set_revolut(revolut) revolut.set_agora(agora) # Define Transactions tx = Transactions() # Pass Notify to Transactions tx.set_notify(notify) # Pass Agora and IRC to Transactions and Transactions to IRC tx.set_agora(agora) tx.set_irc(irc) tx.set_revolut(revolut) irc.set_tx(tx) agora.set_tx(tx) # Define WebApp webapp = WebApp() webapp.set_tx(tx) # Handle setting up JWT and request_token from an auth code if settings.Revolut.SetupToken == "1": deferLater(reactor, 1, revolut.setup_auth) else: # Schedule refreshing the access token using the refresh token deferLater(reactor, 1, revolut.get_new_token, True) # Check if the webhook is set up and set up if not deferLater(reactor, 4, revolut.setup_webhook) # Schedule repeatedly refreshing the access token lc = LoopingCall(revolut.get_new_token) lc.start(int(settings.Revolut.RefreshSec)) # Run the WebApp webapp.app.run("127.0.0.1", 8080)