pluto/handler/app.py

107 lines
3.0 KiB
Python
Executable File

#!/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)