from falcon.constants import MEDIA_HTML, MEDIA_JS, MEDIA_TEXT
from falcon.status_codes import HTTP_OK
+from jinja2 import Template
from .websocket import WebSocketHub
-from .utils import scramble
MEDIA_CSS = "text/css"
-
class StaticFile:
media_types_per_suffix = {
".html": MEDIA_HTML,
".css": MEDIA_CSS,
".txt": MEDIA_TEXT,
}
+ content: str | None
def __init__(self, path):
self.path = path
class StaticTemplateFile(StaticFile):
TEMPLATE_SUFFIX = ".j2"
+ content: Template | None
def __init__(self, path, hubapp):
super().__init__(path)
self.hubapp = hubapp
self.context = {"hubapp": self.hubapp}
- self.template = hubapp.app.env.get_template(
- str(path.relative_to(hubapp.app.env.loader.searchpath[0]))
- )
- def get(self):
- return self.template.render(self.context)
+ def get(self) -> str:
+ mtime = self.path.stat().st_mtime
+ if mtime != self.mtime:
+ env = self.hubapp.app.env
+ self.content = env.get_template(
+ str(self.path.relative_to(env.loader.searchpath[0]))
+ )
+ self.mtime = mtime
+ return self.content.render(self.context)
@classmethod
def get_media_type(cls, path):
or "master" in uri_tail[:start].split(slash)
)
- def uri_from(self, path):
- if isinstance(path, Path) and path.is_absolute():
- uri_tail = str(path.relative_to(self.base_dir))
+ def _uri_tail(self, path, suffix):
+ if isinstance(path, Path):
+ if path.is_absolute():
+ path = path.relative_to(self.base_dir)
+ uri_tail = str(path)
else:
uri_tail = str(path)
- suffix = StaticTemplateFile.TEMPLATE_SUFFIX
if uri_tail.endswith(suffix):
uri_tail = uri_tail[:-len(suffix)]
if self.is_master_uri(uri_tail):
- uri_tail = scramble(self.app.secret, uri_tail)
+ return self.app.scramble(uri_tail)
elif uri_tail == "index.html":
- uri_tail = ""
+ return ""
+ return uri_tail
+
+ def uri_from(self, path) -> str | Path:
+ uri_tail = self._uri_tail(path, StaticTemplateFile.TEMPLATE_SUFFIX)
name = self.name
if name == "root":
name = ""
- if name and uri_tail:
- name = f"{name}/"
- return f"/{name}{uri_tail}"
+ return f"/{name}{'/' if name and uri_tail else ''}{uri_tail}"
def scan_files(self, base_dir):
stack = [base_dir.iterdir()]