122 lines
3.8 KiB
Python
122 lines
3.8 KiB
Python
# Copyright (C) 2020, 2023 by Thomas Lindner <tom@dl6tom.de>
|
|
# Copyright (C) 2020 by Cathy Hu <cathy.hu@fau.de>
|
|
# Copyright (C) 2020 by Martin Rey <martin.rey@mailbox.org>
|
|
#
|
|
# SPDX-License-Identifier: 0BSD
|
|
|
|
"""Entrypoint of Kibicara."""
|
|
|
|
from argparse import ArgumentParser
|
|
from asyncio import run as asyncio_run
|
|
from logging import DEBUG, INFO, WARNING, basicConfig, getLogger
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.staticfiles import StaticFiles
|
|
from hypercorn.asyncio import serve
|
|
from hypercorn.config import Config
|
|
from pytoml import load
|
|
from tortoise import Tortoise
|
|
|
|
from kibicara.config import config
|
|
from kibicara.platformapi import Spawner
|
|
from kibicara.webapi import router
|
|
|
|
logger = getLogger(__name__)
|
|
|
|
|
|
class Main:
|
|
"""Entrypoint for Kibicara.
|
|
|
|
Initializes the platform bots and starts the hypercorn webserver serving the
|
|
Kibicara application and the specified frontend on port 8000.
|
|
"""
|
|
|
|
def __init__(self):
|
|
parser = ArgumentParser()
|
|
parser.add_argument(
|
|
"-f",
|
|
"--config",
|
|
dest="configfile",
|
|
default="/etc/kibicara.conf",
|
|
help="path to config file",
|
|
)
|
|
parser.add_argument(
|
|
"-v",
|
|
"--verbose",
|
|
action="count",
|
|
help="Raise verbosity level",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
try:
|
|
with open(args.configfile) as configfile:
|
|
config.update(load(configfile))
|
|
except FileNotFoundError:
|
|
# run with default config
|
|
pass
|
|
|
|
LOGLEVELS = {
|
|
None: WARNING,
|
|
1: INFO,
|
|
2: DEBUG,
|
|
}
|
|
basicConfig(
|
|
level=LOGLEVELS.get(args.verbose, DEBUG),
|
|
format="%(asctime)s %(name)s %(message)s",
|
|
)
|
|
getLogger("aiosqlite").setLevel(WARNING)
|
|
asyncio_run(self.__run())
|
|
|
|
async def __run(self):
|
|
await Tortoise.init(
|
|
db_url=config["database_connection"],
|
|
modules={
|
|
"models": [
|
|
"kibicara.model",
|
|
"kibicara.platforms.email.model",
|
|
"kibicara.platforms.telegram.model",
|
|
"kibicara.platforms.test.model",
|
|
"kibicara.platforms.twitter.model",
|
|
]
|
|
},
|
|
)
|
|
await Tortoise.generate_schemas()
|
|
await Spawner.init_all()
|
|
await self.__start_webserver()
|
|
await Tortoise.close_connections()
|
|
|
|
async def __start_webserver(self):
|
|
class SinglePageApplication(StaticFiles):
|
|
async def get_response(self, path, scope):
|
|
response = await super().get_response(path, scope)
|
|
if response.status_code == 404:
|
|
response = await super().get_response(".", scope)
|
|
return response
|
|
|
|
app = FastAPI()
|
|
server_config = Config()
|
|
server_config.accesslog = "-"
|
|
server_config.behind_proxy = config["behind_proxy"]
|
|
server_config.keyfile = config["keyfile"]
|
|
server_config.certfile = config["certfile"]
|
|
if config["production"]:
|
|
server_config.bind = ["0.0.0.0:8000", "[::]:8000"]
|
|
api = FastAPI()
|
|
api.include_router(router)
|
|
app.mount("/api", api)
|
|
if not config["production"] and config["cors_allow_origin"]:
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=config["cors_allow_origin"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
if config["frontend_path"] is not None:
|
|
app.mount(
|
|
"/",
|
|
app=SinglePageApplication(directory=config["frontend_path"], html=True),
|
|
)
|
|
await serve(app, server_config)
|