http: Add static file support
Static files are configured using a handful of config values. Static files can be handled remotely or locally for prod or dev environments, respectively. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
from typing import Sequence
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@@ -19,8 +20,16 @@ def required(name: str) -> str:
|
||||
return value
|
||||
|
||||
|
||||
def default(name: str, default: str) -> str:
|
||||
return os.getenv(name, default)
|
||||
def default(name: str, default_value: str) -> str:
|
||||
return os.getenv(name, default_value)
|
||||
|
||||
|
||||
def one_of_default(name: str, values: Sequence[str], default_value: str) -> str:
|
||||
value = default(name, default_value)
|
||||
if value not in values:
|
||||
required = ",".join(f'"{v}"' for v in values)
|
||||
raise ConfigError(name, f"must be one of {required}; got {value} instead")
|
||||
return value
|
||||
|
||||
|
||||
THUMBS_DIR = Path(default("THUMBS_DIR", "thumbs"))
|
||||
@@ -29,4 +38,11 @@ CACHE_DIR = Path(default("CACHE_DIR", "cache"))
|
||||
DB_SQLITE3_PATH = Path(default("DB_SQLITE3_PATH", "bans.db"))
|
||||
|
||||
HTTP_DOMAIN = required("HTTP_DOMAIN")
|
||||
HTTP_ROOT = default("HTTP_ROOT", r"/")
|
||||
HTTP_ROOT = default("HTTP_ROOT", r"")
|
||||
|
||||
STATIC_HANDLER = one_of_default("STATIC_HANDLER", ("remote", "local"), "local")
|
||||
STATIC_LOCAL_PATH = Path(default("STATIC_LOCAL_PATH", "static"))
|
||||
STATIC_LOCAL_FOLLOW_SYMLINKS = one_of_default(
|
||||
"STATIC_LOCAL_FOLLOW_SYMLINKS", ("yes", "true", "1", "no", "false", "0"), "true"
|
||||
) in ("yes", "true", "1")
|
||||
STATIC_ROOT = default("STATIC_ROOT", "/static")
|
||||
|
||||
@@ -15,14 +15,15 @@ from .db import get_db, search_db
|
||||
|
||||
|
||||
def route_url(url: str):
|
||||
if url in ("/" or ""):
|
||||
assert url == "" or url[0] == "/", "URL must be blank or start with a slash"
|
||||
if url in ("", "/"):
|
||||
return config.HTTP_ROOT
|
||||
elif config.HTTP_ROOT in ("/" or ""):
|
||||
return url
|
||||
elif url.startswith("/"):
|
||||
return f"{config.HTTP_ROOT}{url}"
|
||||
else:
|
||||
return f"{config.HTTP_ROOT}/{url}"
|
||||
return f"{config.HTTP_ROOT}{url}"
|
||||
|
||||
|
||||
def static_url(resource: str):
|
||||
return f"{config.STATIC_ROOT}/{resource}"
|
||||
|
||||
|
||||
_env = Environment(
|
||||
@@ -32,6 +33,7 @@ _env = Environment(
|
||||
_env.globals.update(
|
||||
{
|
||||
"route_url": route_url,
|
||||
"static_url": static_url,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -160,12 +162,23 @@ class IndexView(TemplateView):
|
||||
app = web.Application()
|
||||
app.add_routes(
|
||||
[
|
||||
web.get(route_url(r"/"), IndexView),
|
||||
web.get(route_url(r"/faq"), template_view_factory("faq.html")),
|
||||
web.get(route_url(r"/news"), template_view_factory("news.html")),
|
||||
web.get(config.HTTP_ROOT, IndexView),
|
||||
web.get(f"{config.HTTP_ROOT}/faq", template_view_factory("faq.html")),
|
||||
web.get(f"{config.HTTP_ROOT}/news", template_view_factory("news.html")),
|
||||
]
|
||||
)
|
||||
|
||||
if config.STATIC_HANDLER == "local":
|
||||
app.add_routes(
|
||||
[
|
||||
web.static(
|
||||
config.STATIC_ROOT,
|
||||
config.STATIC_LOCAL_PATH,
|
||||
follow_symlinks=config.STATIC_LOCAL_FOLLOW_SYMLINKS,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def run_app():
|
||||
web.run_app(app)
|
||||
|
||||
@@ -22,8 +22,10 @@ body {
|
||||
}
|
||||
|
||||
nav {
|
||||
/*
|
||||
position: fixed;
|
||||
top: 0;
|
||||
*/
|
||||
width: 100%;
|
||||
margin: 5px 0;
|
||||
text-align: left;
|
||||
@@ -155,6 +157,9 @@ table tr {
|
||||
{% endblock style %}
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
[ <a href="{{route_url("/")}}">Home</a> / <a href="{{route_url("/news")}}">News</a> / <a href="{{route_url("/faq")}}">FAQ</a> ]
|
||||
</nav>
|
||||
{% block body %}
|
||||
<header>
|
||||
{% block header %}
|
||||
@@ -172,9 +177,6 @@ table tr {
|
||||
</div>
|
||||
{% endblock header %}
|
||||
</header>
|
||||
<nav>
|
||||
[ <a href="{{route_url("/")}}">Home</a> / <a href="{{route_url("/news")}}">News</a> / <a href="{{route_url("/faq")}}">FAQ</a> ]
|
||||
</nav>
|
||||
<main>
|
||||
{% block main %}
|
||||
{% endblock main %}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<span class="file-thumb">
|
||||
<img src="{{post['thumb_path']}}" data-md5="{{post['md5']}}" loading="lazy">
|
||||
<img src="{{static_url(post['thumb_path'])}}" data-md5="{{post['md5']}}" loading="lazy">
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
25
example.env
25
example.env
@@ -7,9 +7,32 @@
|
||||
# Sqlite3 database path. Defaults to "bans.db"
|
||||
#DB_SQLITE3_PATH=bans.db
|
||||
|
||||
# Domain name of the server
|
||||
# Domain name of the server. This is required.
|
||||
HTTP_DOMAIN=domain.com
|
||||
|
||||
# Root of the HTTP server. Defaults to "/"
|
||||
# If you host other things on your domain, you may want to update this to be "/bans" or something.
|
||||
#HTTP_ROOT=/
|
||||
|
||||
# Static files handler. Defaults to "local"
|
||||
# Valid values are:
|
||||
# * local
|
||||
# * remote
|
||||
# Locally handled static files use the STATIC_LOCAL_PATH config value.
|
||||
# IN GENERAL, the "local" configuration should not be used in a production environment.
|
||||
#STATIC_HANDLER=local
|
||||
|
||||
# The local path to serve static files out of. Defaults to "static"
|
||||
# This is only used when STATIC_HANDLER is set to "local".
|
||||
#STATIC_LOCAL_PATH=static
|
||||
|
||||
# Whether to follow symlinks in the local static file handler. Defaults to "true"
|
||||
# This is only used when STATIC_HANDLER is set to "local".
|
||||
# Must be one of:
|
||||
# * 1, true, yes
|
||||
# * 0, false, no
|
||||
#STATIC_LOCAL_FOLLOW_SYMLINKS=true
|
||||
|
||||
# This is the URL to map static files to. Defaults to /static
|
||||
# This *WILL NOT* prepend the HTTP_ROOT path.
|
||||
#STATIC_ROOT=/static
|
||||
|
||||
Reference in New Issue
Block a user