]> git.mar77i.info Git - hublib/blobdiff - hub/app.py
big cleanup and refactoring #1
[hublib] / hub / app.py
index 24212d0972581d1e6e7bef054074c80f8b229c6b..2f1b84936f1247f3832a4714b4dca3fc8982ffc4 100644 (file)
@@ -1,16 +1,73 @@
+import socket
+import sys
 from argparse import ArgumentParser
+from pathlib import Path
+from subprocess import run
+from traceback import print_exception
+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 .cryptresource import CryptResource
+from .hubapp import RootApp, HubApp
 
 
-def get_app():
-    app = App(media_type=MEDIA_HTML)
+class App(FalconApp):
+    def __init__(self, secret, **kwargs):
+        kwargs.setdefault("media_type", MEDIA_HTML)
+        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())
+
+
+class HubServer(Server):
+    def __init__(self, *args, browser, **kwargs):
+        self.browser = browser
+        super().__init__(*args, **kwargs)
+
+    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:
+            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])
+
+
+async def main():
     ap = ArgumentParser()
     ap.add_argument("--secret")
+    ap.add_argument("--browser", default="xdg-open")
     args = ap.parse_args()
-    cr = CryptResource(args.secret)
-    cr.register_on(app)
-    return app
+    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()