pluto/handler/app.py

116 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 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
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 <a href="{auth_url}" target="_blank">here.</a>'
# 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(),
"nordigen": Nordigen(),
"truelayer": TrueLayer(),
"fidor": Fidor(),
"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)