import socket
import sys
from argparse import ArgumentParser
-from itertools import chain
from pathlib import Path
-from secrets import token_urlsafe
from subprocess import run
from traceback import print_exception
from urllib.parse import urlunsplit
from jinja2 import Environment, FileSystemLoader, select_autoescape
from uvicorn import Config, Server
-from .hubapp import HubApp, RootApp
+from .hubapp import RootApp, HubApp
class App(FalconApp):
self.base_dir = Path(__file__).parents[1] / "webroot"
self.env = Environment(
loader=FileSystemLoader(self.base_dir),
- autoescape=select_autoescape,
+ autoescape=select_autoescape(),
extensions=["hub.utils.StaticTag"],
)
- self.secret = secret or token_urlsafe(64)
- self.hubapps = {}
- RootApp(self, self.base_dir)
+ 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 HubApp.is_ignored_filename(base_dir):
+ if not base_dir.is_dir() or RootApp.is_ignored_filename(base_dir):
continue
- HubApp(self, base_dir)
+ self.hubapps[base_dir.name] = HubApp(
+ self, base_dir, base_uri=f"/derp/{base_dir.name}"
+ )
self.add_error_handler(Exception, self.print_exception)
- def get_hubapp_by_name(self, name):
- return self.hubapps[name]
-
async def print_exception(self, req, resp, ex, params):
print_exception(*sys.exc_info())
async def startup(self, sockets: list[socket.socket] | None = 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('[')}]"
-
- 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:
+ 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}"
- app = config.loaded_app.app
- print("Secret:", app.secret)
- for key, value in app.hubapps["root"].files_per_uris.items():
- if Path(value.path.name).stem == "index.html":
- url = urlunsplit((protocol_name, host, key, "", ""))
- print("URL:", url)
- if self.browser:
- run([self.browser, url])
-
-
-app: App
+ url = urlunsplit((f"http{'s'[:ssl]}", host, uri, "", ""))
+ print("URL:", url)
+ if self.browser:
+ run([self.browser, url])
async def main():
- global app
ap = ArgumentParser()
ap.add_argument("--secret")
- ap.add_argument("--browser", default="firefox")
+ ap.add_argument("--browser", default="xdg-open")
args = ap.parse_args()
app = App(args.secret)
- config = Config("hub.app:app", port=5000, log_level="info")
+ 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()