X-Git-Url: https://git.mar77i.info/?a=blobdiff_plain;f=hub%2Fapp.py;h=2f1b84936f1247f3832a4714b4dca3fc8982ffc4;hb=3c5ec422ace644d848d2f845b0f3ef8de73462ef;hp=8dfb5425b704c111d87513354b6965f1578ca98f;hpb=c0e574584af0d45070e5fa81fcbcd1dccc2c5a42;p=hublib diff --git a/hub/app.py b/hub/app.py index 8dfb542..2f1b849 100644 --- a/hub/app.py +++ b/hub/app.py @@ -1,77 +1,73 @@ -from argparse import ArgumentParser -from itertools import chain -from secrets import token_urlsafe import socket -from subprocess import run import sys +from argparse import ArgumentParser +from pathlib import Path +from subprocess import run from traceback import print_exception -from typing import List, Optional from urllib.parse import urlunsplit -from falcon.asgi import App +from falcon.asgi import App as FalconApp from falcon.constants import MEDIA_HTML +from jinja2 import Environment, FileSystemLoader, select_autoescape from uvicorn import Config, Server -from .staticresource import StaticResource -from .hub import Hub +from .hubapp import RootApp, HubApp -class HubApp(App): - def __init__(self, secret, browser, hubapp, *args, **kwargs): +class App(FalconApp): + def __init__(self, secret, **kwargs): kwargs.setdefault("media_type", MEDIA_HTML) - super().__init__(*args, **kwargs) - self.secret = secret or token_urlsafe(64) - self.hub = Hub(self.secret) - self.sr = StaticResource(self.secret, hubapp, self.hub.master_ws_uri) - self.browser = browser - self.hub.add_routes(self) - self.sr.add_routes(self) + super().__init__(**kwargs) + self.base_dir = Path(__file__).parents[1] / "webroot" + self.env = Environment( + loader=FileSystemLoader(self.base_dir), + autoescape=select_autoescape(), + extensions=["hub.utils.StaticTag"], + ) + self.hubapps = {"root": RootApp(self, self.base_dir, "/derp", secret)} + for base_dir in self.base_dir.iterdir(): + if not base_dir.is_dir() or RootApp.is_ignored_filename(base_dir): + continue + self.hubapps[base_dir.name] = HubApp( + self, base_dir, base_uri=f"/derp/{base_dir.name}" + ) self.add_error_handler(Exception, self.print_exception) async def print_exception(self, req, resp, ex, params): print_exception(*sys.exc_info()) -def get_app(): - ap = ArgumentParser() - ap.add_argument("--secret") - ap.add_argument("--browser", default="firefox") - ap.add_argument("--hubapp", default="first") - args = ap.parse_args() - return HubApp(args.secret, args.browser, args.hubapp) - - class HubServer(Server): - async def startup(self, sockets: Optional[List[socket.socket]] = None) -> None: - await super().startup(sockets) - config = self.config - protocol_name = "https" if config.ssl else "http" - host = "0.0.0.0" if config.host is None else config.host - if ":" in host: - # It's an IPv6 address. - host = f"[{host.rstrip(']').lstrip('[')}]" + def __init__(self, *args, browser, **kwargs): + self.browser = browser + super().__init__(*args, **kwargs) - port = config.port - if port == 0: - try: - port = next( - chain.from_iterable((server.sockets for server in getattr(self, "servers", ()))) - ).getsockname()[1] - except StopIteration: - pass - if {"http": 80, "https": 443}[protocol_name] != port: - host = f"{host}:{port}" - app = config.loaded_app.app - print("master_uri", app.sr.master_uri) - master_url = urlunsplit((protocol_name, host, app.sr.master_uri, "", "")) - print("secret:", app.secret) - if not app.browser: - print("master url", master_url) + async def startup(self, sockets: list[socket.socket] | None = None) -> None: + await super().startup(sockets) + root_app = self.config.loaded_app.app.hubapps["root"] + print("Secret:", root_app.secret) + for uri, file in root_app.files_per_uris.items(): + if file.name == "index.html": + break else: - run([app.browser, master_url]) + raise ValueError("Root page not found!") + host, port, ssl = self.config.host, self.config.port, bool(self.config.ssl) + if port and port != (80, 443)[ssl]: + host = f"{host}:{port}" + url = urlunsplit((f"http{'s'[:ssl]}", host, uri, "", "")) + print("URL:", url) + if self.browser: + run([self.browser, url]) -def main(): - HubServer( - Config("hub.app:get_app", factory=True, port=5000, log_level="info") - ).run() +async def main(): + ap = ArgumentParser() + ap.add_argument("--secret") + ap.add_argument("--browser", default="xdg-open") + args = ap.parse_args() + app = App(args.secret) + await app.hubapps["root"].setup() + config = Config(app, port=5000, log_level="info") + config.setup_event_loop() + hs = HubServer(config, browser=args.browser) + await hs.serve()