sanic/sanic/pages/autoindex.py
2023-01-31 10:40:47 +02:00

89 lines
2.8 KiB
Python

from textwrap import dedent
from typing import Iterable, TypedDict
from html5tagger import E
from .base import BasePage
class FileInfo(TypedDict):
icon: str
file_name: str
file_access: str
file_size: str
class AutoIndex(BasePage): # no cov
EXTRA_STYLE = dedent(
f"""
#breadcrumbs a:hover {{ text-decoration: underline; }}
#breadcrumbs .path-0 a {{ text-decoration: none; }}
#breadcrumbs span::after {{
content: "/"; text-decoration: none; padding: 0 0.25em;
}}
#breadcrumbs .path-0 a::before {{ content: "🏠"; }}
#breadcrumbs > span > a {{ color: {BasePage.ACCENT}; }}
main a {{ color: inherit; font-weight: bold; }}
table.autoindex {{ width: 100%; }}
table.autoindex tr {{ display: flex; }}
table.autoindex tr:hover {{ background-color: #ddd; }}
table.autoindex td {{ margin: 0 0.5rem; }}
table.autoindex td:first-child {{ flex: 1; }}
table.autoindex td:nth-child(2) {{ text-align: right; }}
table.autoindex td:last-child {{ text-align: right; }}
@media (min-width: 915px) {{
table.autoindex {{ font-size: 1.75vw; }}
}}
@media (min-width: 1600px) {{
table.autoindex {{ font-size: 1.75rem; }}
}}
@media (prefers-color-scheme: dark) {{
table.autoindex tr:hover {{ background-color: #222; }}
}}
"""
)
TITLE = "File Browser"
def __init__(
self, files: Iterable[FileInfo], url: str, debug: bool
) -> None:
super().__init__(debug)
self.files = files
self.url = url
def _body(self) -> None:
with self.doc.main:
self._headline()
files = list(self.files)
if files:
self._file_table(files)
else:
self.doc.p("The folder is empty.")
def _headline(self):
"""Implement a heading with the current path, combined with
breadcrumb links"""
with self.doc.h1(id="breadcrumbs"):
p = self.url.split("/")[:-1]
for i in reversed(range(len(p))):
self.doc.span(class_=f"path-{i}").__enter__()
for i, part in enumerate(p):
path = "/".join(p[: i + 1]) + "/"
self.doc.a(part, href=path)
self.doc.__exit__(None, None, None)
def _file_table(self, files: Iterable[FileInfo]):
with self.doc.table(class_="autoindex container"):
for f in files:
self._file_row(**f)
def _file_row(
self,
icon: str,
file_name: str,
file_access: str,
file_size: str,
):
first = E.span(icon, class_="icon").a(file_name, href=file_name)
self.doc.tr.td(first).td(file_size).td(file_access)