]>
git.mar77i.info Git - hublib/blob - hub/app.py
3 from argparse
import ArgumentParser
4 from base64
import urlsafe_b64encode
5 from hashlib
import pbkdf2_hmac
6 from pathlib
import Path
7 from secrets
import token_urlsafe
8 from subprocess
import run
9 from traceback
import print_exception
10 from typing
import Generator
11 from urllib
.parse
import urlunsplit
13 from falcon
.asgi
import App
as FalconApp
14 from falcon
.constants
import MEDIA_HTML
15 from jinja2
import Environment
, FileSystemLoader
, select_autoescape
16 from redis
.asyncio
import StrictRedis
17 from uvicorn
import Config
, Server
19 from .static
import HubApp
, TemplateTreeFileApp
22 class App(TemplateTreeFileApp
, FalconApp
):
24 def scan_files(cls
, base_dir
: Path
) -> Generator
[Path
]:
25 for path
in base_dir
.iterdir():
26 if not path
.is_dir() and not cls
.is_ignored_filename(path
):
29 def scramble(self
, value
: str |
bytes) -> str:
30 if isinstance(value
, str):
31 value
= value
.encode()
33 if isinstance(secret
, str):
34 secret
= secret
.encode()
35 return urlsafe_b64encode(
36 pbkdf2_hmac("sha512", value
, secret
, 221100)
37 ).rstrip(b
"=").decode("ascii")
39 def uri_tail(self
, path
: Path
) -> str:
40 return self
.scramble(super().uri_tail(path
))
42 def __init__(self
, base_dir
: Path
, secret
: str, **kwargs
):
43 from .utils
import get_redis_pass
45 self
.secret
= secret
or token_urlsafe(64)
46 kwargs
.setdefault("media_type", MEDIA_HTML
)
47 FalconApp
.__init
__(self
, **kwargs
)
48 TemplateTreeFileApp
.__init
__(
49 self
, self
, base_dir
, "/derp", "root"
51 self
.env
= Environment(
52 loader
=FileSystemLoader(self
.base_dir
),
53 autoescape
=select_autoescape(),
54 extensions
=["hub.utils.StaticTag"],
57 self
.conn
= StrictRedis(
58 username
="default", password
=get_redis_pass("/etc/redis/redis.conf")
60 for base_dir
in self
.base_dir
.iterdir():
61 if base_dir
.is_dir() and not self
.is_ignored_filename(base_dir
):
62 self
.hubapps
[base_dir
.name
] = HubApp(
63 self
, base_dir
, base_uri
=f
"/derp/{base_dir.name}"
65 self
.add_error_handler(Exception, self
.print_exception
)
67 async def print_exception(self
, req
, resp
, ex
, params
) -> None:
68 print_exception(*sys
.exc_info())
71 class HubServer(Server
):
72 def __init__(self
, *args
, browser
, **kwargs
):
73 self
.browser
= browser
74 super().__init
__(*args
, **kwargs
)
76 async def startup(self
, sockets
: list[socket
.socket
] |
None = None) -> None:
77 await super().startup(sockets
)
78 root_app
= self
.config
.loaded_app
.app
79 print("Secret:", root_app
.secret
)
80 for uri
, file in root_app
.files_per_uris
.items():
81 if file.name
== "index.html":
84 raise ValueError("Root page not found!")
85 host
, port
, ssl
= self
.config
.host
, self
.config
.port
, bool(self
.config
.ssl
)
86 if port
and port
!= (80, 443)[ssl
]:
87 host
= f
"{host}:{port}"
88 url
= urlunsplit((f
"http{'s'[:ssl]}", host
, uri
, "", ""))
91 run([self
.browser
, url
])
96 ap
.add_argument("--secret")
97 ap
.add_argument("--browser", default
="xdg-open")
98 args
= ap
.parse_args()
99 app
= App(Path(__file__
).parents
[1] / "webroot", args
.secret
)
100 await app
.conn
.set("client_id", 0)
101 config
= Config(app
, port
=5000, log_level
="info")
102 config
.setup_event_loop()
103 hs
= HubServer(config
, browser
=args
.browser
)