Skip to content

Commit 0ad3c2c

Browse files
committed
Added example for using adafruit_templateengine with adafruit_httpserver
1 parent 5b0f3b4 commit 0ad3c2c

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

examples/directory_listing.tpl.html

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# SPDX-FileCopyrightText: 2023 Michal Pokusa
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
<html lang="en">
6+
7+
{% exec path = context.get("path") %}
8+
{% exec items = context.get("items") %}
9+
10+
<head>
11+
<meta charset="UTF-8">
12+
<title>Directory listing for /{{ path }}</title>
13+
</head>
14+
15+
<body>
16+
<h1>Directory listing for /{{ path }}</h1>
17+
18+
<input type="text" placeholder="Search...">
19+
20+
<ul>
21+
{# Going to parent directory if not alredy in #}
22+
{% if path %}
23+
<li><a href="?path=/{{ "".join(path.split('/')[:-1]) }}">..</a></li>
24+
{% endif %}
25+
26+
{# Listing items #}
27+
{% for item in items %}
28+
<li><a href="?path={{ f'/{path}/{item}' if path else f'/{item}' }}">{{ item }}</a></li>
29+
{% endfor %}
30+
31+
</ul>
32+
33+
{# Script for filtering items #}
34+
<script>
35+
const search = document.querySelector('input');
36+
const items = document.querySelectorAll('li');
37+
38+
search.addEventListener('keyup', (e) => {
39+
const term = e.target.value.toLowerCase();
40+
41+
items.forEach(item => {
42+
const text = item.innerText.toLowerCase();
43+
44+
if (text.indexOf(term) != -1) {
45+
item.style.display = 'list-item';
46+
} else {
47+
item.style.display = 'none';
48+
}
49+
});
50+
});
51+
</script>
52+
</body>
53+
54+
</html>

examples/httpserver_templates.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# SPDX-FileCopyrightText: 2023 Michal Pokusa
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
import os
5+
import re
6+
7+
import socketpool
8+
import wifi
9+
10+
from adafruit_httpserver import Server, Request, Response, FileResponse
11+
12+
try:
13+
from adafruit_templateengine import render_template
14+
except ImportError as e:
15+
raise ImportError("This example requires adafruit_templateengine library.") from e
16+
17+
18+
pool = socketpool.SocketPool(wifi.radio)
19+
server = Server(pool, "/static", debug=True)
20+
21+
# Create /static directory if it doesn't exist
22+
try:
23+
os.listdir("/static")
24+
except OSError as e:
25+
raise OSError("Please create a /static directory on the CIRCUITPY drive.") from e
26+
27+
28+
@server.route("/")
29+
def directory_listing(request: Request):
30+
path = request.query_params.get("path") or ""
31+
32+
# Remove .. and . from path
33+
path = re.sub(r"\/(\.\.|\.)\/|\/(\.\.|\.)|(\.\.|\.)\/", "/", path).strip("/")
34+
35+
if path:
36+
is_file = (
37+
os.stat(f"/static/{path}")[0] & 0b_11110000_00000000
38+
) == 0b_10000000_00000000
39+
else:
40+
is_file = False
41+
42+
# If path is a file, return it as a file response
43+
if is_file:
44+
return FileResponse(request, path)
45+
46+
# Otherwise, return a directory listing
47+
return Response(
48+
request,
49+
render_template(
50+
"directory_listing.tpl.html",
51+
context={
52+
"path": path,
53+
"items": os.listdir(f"/static/{path}"),
54+
},
55+
),
56+
content_type="text/html",
57+
)
58+
59+
60+
# Start the server.
61+
server.serve_forever(str(wifi.radio.ipv4_address))

0 commit comments

Comments
 (0)