Skip to content

Commit b4057b2

Browse files
committed
mime types added
1 parent ab355a7 commit b4057b2

File tree

4 files changed

+813
-19
lines changed

4 files changed

+813
-19
lines changed

gurgleapps_webserver.py

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@
77
from response import Response
88
from request import Request
99

10+
1011
class GurgleAppsWebserver:
1112

12-
def __init__(self, wifi_ssid, wifi_password, port=80, timeout=20, doc_root="/www"):
13+
def __init__(self, wifi_ssid, wifi_password, port=80, timeout=20, doc_root="/www", log_level=0):
1314
print("GurgleApps.com Webserver")
1415
self.port = port
1516
self.timeout = timeout
1617
self.wifi_ssid = wifi_ssid
1718
self.wifi_password = wifi_password
1819
self.doc_root = doc_root
19-
self.function_routes=[]
20+
self.function_routes = []
21+
self.log_level = log_level
2022
# wifi client in station mode so we can connect to an access point
2123
self.wlan = network.WLAN(network.STA_IF)
2224
# activate the interface
@@ -50,21 +52,21 @@ def __init__(self, wifi_ssid, wifi_password, port=80, timeout=20, doc_root="/www
5052
print('point your browser to http://', status[0])
5153
try:
5254
pass
53-
#asyncio.run(self.start_server())
55+
# asyncio.run(self.start_server())
5456
except OSError as e:
5557
print(e)
5658
finally:
5759
asyncio.new_event_loop()
5860
print("exit constructor")
5961

6062
async def start_server(self):
61-
asyncio.create_task(asyncio.start_server(self.serve_request, "0.0.0.0", 80))
62-
while self.serving:
63-
await asyncio.sleep(1)
64-
63+
asyncio.create_task(asyncio.start_server(
64+
self.serve_request, "0.0.0.0", 80))
65+
while self.serving:
66+
await asyncio.sleep(1)
67+
6568
def add_function_route(self, route, function):
66-
self.function_routes.append({"route":route, "function":function})
67-
69+
self.function_routes.append({"route": route, "function": function})
6870

6971
async def serve_request(self, reader, writer):
7072
try:
@@ -107,16 +109,20 @@ async def serve_request(self, reader, writer):
107109
print("path_components: "+str(path_components))
108110
route_function, params = self.match_route(path_components)
109111
if route_function:
110-
print("calling function: "+str(route_function)+" with params: "+str(params))
112+
print("calling function: "+str(route_function) +
113+
" with params: "+str(params))
111114
await route_function(request, response, *params)
112115
return
113116
# perhaps it is a file
114117
file = self.get_file(self.doc_root + url)
115-
print("file: "+str(file))
118+
if self.log_level > 2:
119+
print("file: "+str(file))
116120
if file:
117121
print("file found so serving it")
118-
print(file)
119-
await response.send(file)
122+
content_type = self.get_content_type(url)
123+
if self.log_level > 1:
124+
print("content_type: "+str(content_type))
125+
await response.send(file, 200, content_type)
120126
return
121127
print("file not found")
122128
await response.send(self.html % "page not found "+url, status_code=404)
@@ -127,7 +133,7 @@ async def serve_request(self, reader, writer):
127133

128134
def get_file(self, filename):
129135
print("getFile: "+filename)
130-
try :
136+
try:
131137
# Check if the file exists
132138
if uos.stat(filename)[6] > 0:
133139
# Open the file in read mode
@@ -141,20 +147,21 @@ def get_file(self, filename):
141147
# print the error
142148
print(e)
143149
return False
144-
150+
145151
def get_path_components(self, path):
146152
return tuple(filter(None, path.split('/')))
147-
153+
148154
def match_route(self, path_components):
149155
for route in self.function_routes:
150156
route_pattern = list(filter(None, route["route"].split("/")))
151-
#print("route_pattern: "+str(route_pattern))
157+
# print("route_pattern: "+str(route_pattern))
152158
if len(route_pattern) != len(path_components):
153159
continue
154160
match = True
155161
params = []
156162
for idx, pattern_component in enumerate(route_pattern):
157-
print("pattern_component: "+pattern_component+" path_component: "+path_components[idx])
163+
print("pattern_component: "+pattern_component +
164+
" path_component: "+path_components[idx])
158165
if pattern_component.startswith('<') and pattern_component.endswith('>'):
159166
param_value = path_components[idx]
160167
params.append(param_value)
@@ -166,5 +173,23 @@ def match_route(self, path_components):
166173
return route["function"], params
167174
return None, []
168175

176+
def get_file_extension(self, file_path):
177+
file_parts = file_path.split('.')
178+
if len(file_parts) > 1:
179+
return file_parts[-1]
180+
return ''
169181

170182

183+
def get_content_type(self,file_path):
184+
extension = self.get_file_extension(file_path)
185+
content_type_map = {
186+
'html': 'text/html',
187+
'css': 'text/css',
188+
'js': 'application/javascript',
189+
'jpg': 'image/jpeg',
190+
'jpeg': 'image/jpeg',
191+
'png': 'image/png',
192+
'gif': 'image/gif',
193+
'ico': 'image/x-icon'
194+
}
195+
return content_type_map.get(extension, 'text/plain')

main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ async def background_task():
5757
async def run():
5858
await asyncio.gather(main(), background_task())
5959

60-
server = GurgleAppsWebserver(config.WIFI_SSID, config.WIFI_PASSWORD)
60+
server = GurgleAppsWebserver(config.WIFI_SSID, config.WIFI_PASSWORD, port=80, timeout=20, doc_root="/www", log_level=2)
6161
server.add_function_route("/set-delay/<delay>", set_delay)
6262
server.add_function_route("/stop", stop_flashing)
6363
server.add_function_route("/start", start_flashing)

www/led2.html

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<link rel="stylesheet" type="text/css" href="/styles.css">
7+
<title>GurgleApps.com Frequency Generator</title>
8+
</head>
9+
<body class="bg-gray-100">
10+
<div class="min-h-screen flex flex-col items-center justify-center">
11+
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
12+
<div class="flex justify-center mb-8">
13+
14+
<svg class="h-16 -w-auto" enable-background="new 0 0 1000 240" version="1.1" viewBox="0 0 1e3 240" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
15+
16+
<polygon points="875 0 750 38.1 625 0 500 38.1 375 0 250 38.1 125 0 0 38.1 0 203.7 125 240 250 203.7 375 240 500 203.7 625 240 750 203.7 875 240 1e3 203.7 1e3 38.1" fill="#F4738F"/>
17+
18+
<g fill="#fff">
19+
<path d="m89.3 159.2 13.3 4.4c0 1.3 0.1 2.6 0.1 3.9 0 12.4-3.1 17.5-9.3 15.3-9-3.2-13.7-12.9-13.9-29.3v-3.5c0-14.5 1.5-25.2 4.5-32s7-9.4 11.9-7.7l1.2 0.4c5.5 2.6 8.3 10.9 8.5 24.8l15.2 5.2c0.1-2.3 0.2-4.6 0.2-6.8 0-25.9-7.9-41.7-23.6-47.2-0.8-0.3-1.7-0.6-2.7-0.9-18.9-5-29.1 11.9-30.6 50.6-0.1 3-0.2 5.9-0.2 8.7 0 33.5 8.6 53.2 25.7 59.2 18.5 6.5 27.8-4.4 27.8-32.9l6.8 2.2v-20l-34.2-12.5-0.7 18.1z"/>
20+
<path d="m300.4 97.9c-3.4-7.3-7.2-11.7-11.5-13.2-15.6-5.3-23.5 5.8-23.6 33.5v0.6c0 27.4 6.6 43.4 19.8 48.3 6.8 1.8 11.4 0.1 13.9-5.1 0.1 2.6 0.1 5.1 0.1 7.2 0 8.1-0.6 13.3-1.9 15.9-1.4 2.8-3.8 3.6-7.1 2.4-0.5-0.2-1.1-0.4-1.7-0.8-3.9-1.9-5.8-5.8-5.8-11.8 0-0.7 0-1.3 0.1-1.9l-15.7-4.5c-0.1 1.3-0.1 2.6-0.1 3.8 0 6 0.9 11.2 2.7 15.5 2.1 5.3 6.1 9.7 11.7 13.4 2.7 1.7 5.4 3 8.1 4 3 1.1 6.1 1.6 9.1 1.7 5.8 0.3 10-2.4 12.4-8.1 2.4-5.6 3.7-13.8 4-24.4 0.2-10.7 0.3-38.5 0.3-83.4l-14.6-6-0.2 12.9zm-1.4 49.4c-3.3 3-6.3 4-9.1 3-1.2-0.4-2.4-1.3-3.5-2.6-3.3-3.6-4.9-10.8-4.9-21.7 0-1.3 0-2.7 0.1-4.1 0.4-13.1 2.8-19.6 7.1-19.3 0.7 0 1.4 0.2 2.1 0.4 3.3 1.2 6.1 4.8 8.3 11v33.3z"/>
21+
<path d="m353 70.5-16.4-5.5c0.4 20.9 0.5 43 0.5 66.5 0 16.7-0.1 34-0.3 52l16.6 4c-0.5-26.4-0.8-51.7-0.8-76 0.1-14.1 0.2-27.7 0.4-41z"/>
22+
<path d="m535.5 88.9c-5.5-1.9-9.9-0.4-13.1 4.5l-0.5-12.8-15.9-5.5c0.2 20.8 0.3 40.6 0.3 59.5 0 20.7-0.1 40.2-0.4 58.5l17.8 6.3c-0.5-16.6-0.7-30.9-0.7-43 2.8 6.8 6.5 11.1 11 13 0.5 0.2 1.1 0.5 1.6 0.6 13.3 4.7 20.1-6.2 20.4-32.5v-1.6c0-26.6-6.8-42.2-20.5-47zm-1.5 61.4c-1.1 0.4-2.1 0.4-3.2 0-2.6-0.9-5.2-4-7.8-9.2l-0.3-30.8c2.3-5 5.2-6.8 8.5-5.7 0.4 0.1 0.7 0.3 1.1 0.5 3.9 2.1 6 9.8 6.5 23.3 0 1.4 0.1 2.8 0.1 4.1 0 10.8-1.7 16.8-4.9 17.8z"/>
23+
<path d="m591.3 108.5c-5.5-1.9-9.9-0.4-13.1 4.5l-0.5-12.8-15.8-5.5c0.2 20.8 0.3 40.6 0.3 59.5 0 20.7-0.1 40.2-0.4 58.5l17.8 6.3c-0.5-16.6-0.7-30.9-0.7-43 2.8 6.8 6.5 11.1 11 13 0.5 0.2 1.1 0.5 1.6 0.6 13.3 4.7 20.1-6.2 20.4-32.5v-1.6c-0.1-26.6-7-42.2-20.6-47zm-1.6 61.4c-1.1 0.4-2.1 0.4-3.2 0-2.6-0.9-5.2-4-7.8-9.2l-0.3-30.8c2.3-5 5.2-6.8 8.5-5.7 0.4 0.1 0.7 0.3 1.1 0.5 3.9 2.1 6 9.8 6.5 23.3 0 1.4 0.1 2.8 0.1 4.1 0 10.9-1.6 16.8-4.9 17.8z"/>
24+
<path d="m774.1 85c-15.7-5.5-23.7 5.7-24.2 33.7v2.3c0 26.3 7.4 42.1 22.1 47.3 0.2 0.1 0.4 0.1 0.5 0.1 15.5 5.2 23.5-6 24.2-33.7 0-1 0.1-2 0.1-3.1 0-25.8-7.6-41.3-22.7-46.6zm6.3 60.8c-1.3 5.4-3.8 7.4-7.4 6.1l-0.5-0.2c-3.9-1.6-6.2-6.5-6.9-14.6-0.3-3.3-0.4-6.4-0.4-9.5 0-4.6 0.3-9.1 0.9-13.5 1-7.3 2.9-11.1 5.7-11.3 1-0.1 2 0 2.9 0.4 1.6 0.5 2.9 1.7 4 3.4 1.8 2.8 2.8 8.7 3.2 17.6 0 1.7 0.1 3.4 0.1 5 0.1 6.6-0.5 12.1-1.6 16.6z"/>
25+
<path d="m869.9 130.5c-1.7-6.3-4.1-11-7.2-14.2-3.1-3.1-6.4-5.3-9.7-6.5l-0.3-0.1c-3.5-1.2-6.6-1.3-9.5-0.3-2.8 1-4.9 4.2-6 9.8-1.5-8.1-3.9-13.4-7.4-15.7-1.4-0.9-2.8-1.7-4.3-2.2-1.9-0.7-3.8-0.9-5.7-0.7-3.2 0.4-5.9 3.3-8.3 8.7l-0.3-13.2-12.2-2.5c0.6 23.9 0.9 47.7 0.9 71.5v13.4l15.8 4.8-0.1-59.9c2.5-2.9 5.2-3.9 7.9-2.9l0.9 0.3c3 1.6 4.6 7.1 4.6 16.7v1c0 9.6-0.3 24.9-0.9 45.8l16.7 5.7c-0.5-13.9-0.7-26-0.7-36.3 0-7.6 0.1-14.1 0.4-19.7 1.7-4.3 4.1-5.9 7.2-4.8 0.5 0.2 1.1 0.4 1.7 0.8 3.9 2.4 5.9 9.8 5.9 22.4s-0.3 27.7-0.9 45.5l14.4 4.7v-47.5c-0.3-10.2-1.2-18.3-2.9-24.6z"/>
26+
<path d="m167.1 102.4 0.7 54.4c-1 4.5-3.4 7.3-7.2 8.4s-6.1-2.4-6.8-10.4c-0.2-2.6-0.3-6.3-0.3-11.1 0-9.5 0.4-23.2 1.3-41l-16.3 4.6c-0.5 12.7-0.7 23.6-0.7 32.8 0 17.9 0.9 29.5 2.7 34.7 2.6 7.9 8 10.6 16.1 8.3 0 0 0.1-0.1 0.2-0.1 8.2-2.4 13.3-7.2 15.1-14.6l0.7 12.6 12.3-5.1c-1.4-29.6-2.1-55.7-2.1-78.2l-15.7 4.7z"/>
27+
<path d="m224 87.7c-0.9 0.3-1.9 0.6-2.9 1-6.9 2.8-11.3 7.7-13.1 14.5l-0.7-12.6-12.3 5c1.4 29.6 2.1 56.5 2.1 80.6l16.4-4.8-0.7-56.8c1-5 3.6-8.2 7.9-9.7l0.3-0.1c3.7-1 5.6 2.6 5.6 11 0 0.8 0 1.7-0.1 2.6l14.9-5.9c0-10.7-1.7-18.1-5-22.1-2.9-3.3-7-4.2-12.4-2.7z"/>
28+
<path d="m397 106.1c-14.5 4.1-22 19.7-22.4 46.9v2.4c0 25.2 7.1 35.8 21.2 31.8 0.1 0 0.3-0.1 0.5-0.2 14.9-4.5 22.3-16.7 22.3-36.6l-15.9 4.9c0.2 1.7 0.3 3.2 0.3 4.6 0 6.6-1.9 10.6-5.8 12.1l-0.5 0.1c-4.4 1.2-6.6-4.9-6.6-18.3l29.9-8.5c0.2-3.4 0.3-6.6 0.3-9.5-0.1-24.2-7.8-34.1-23.3-29.7zm6.5 29.3-15.1 4.3c0.5-11 3.3-17.1 8.2-18.5 4.6-1.3 6.9 2.8 6.9 12.4v1.8z"/>
29+
<path d="m445.3 57.2c-5.2 32.6-12 72.5-20.4 119.6l17.6-2.1 5.6-33.7 20.9-6 5.4 28.3 17.1-8.9c-7.9-39.2-15-74.1-21.2-104.7l-25 7.5zm1.5 62.5c2.8-15 6.3-29.7 10.3-44.1 5.3 14.3 9.1 26.8 11.4 37.4l-21.7 6.7z"/>
30+
<path d="m651.9 143c-5.4-1.1-9.5-2.5-12.3-4.2-2-1.2-2.9-3.1-2.9-5.5 0-1 0.2-2.1 0.5-3.5 1-3.8 3-6.1 6-7 0.3-0.1 0.6-0.1 0.9-0.2 2.9-0.4 4.3 2 4.3 7.2 0 1.1-0.1 2.3-0.2 3.7l14.3-4.4c0.2-1.8 0.3-3.6 0.3-5.3 0-3.5-0.5-6.6-1.6-9.1-1.6-3.7-4.5-6.2-8.6-7.2-3-0.8-6.5-0.6-10.5 0.5-1.5 0.4-3.1 1-4.7 1.6-6 2.5-10.4 7.1-13.4 13.7-1.9 4.3-2.9 8.7-2.9 13.1 0 2.4 0.3 4.8 0.9 7.3 1.6 7 6.4 10.9 14.3 11.8s12 3.9 12.2 9v0.6c0 4.7-2.1 7.6-6.2 8.7l-0.3 0.1c-4.2 1.1-6.4-2.4-6.4-10.5v-1l-15.3 5.2c0.1 12 2.8 19.2 8.2 21.5 4.2 1.8 8.7 2 13.7 0.6 1.4-0.4 2.8-0.9 4.2-1.6 6.6-2.9 11.4-8 14.5-15.3 2-4.6 2.9-8.9 2.9-12.9 0-2.4-0.3-4.6-1-6.8-1.8-5.6-5.5-9-10.9-10.1z"/>
31+
<path d="m685.4 157.9c-1.9-1.7-4.2-2.2-7-1.4-2.7 0.8-5 2.5-6.9 5.3s-2.9 5.8-2.9 9c0 3.1 1 5.6 2.9 7.3s4.2 2.2 6.9 1.4 5-2.6 7-5.3c1.9-2.8 2.9-5.8 2.9-8.9 0-3.2-1-5.7-2.9-7.4z"/>
32+
<path d="m721.3 139.4c0 6.6-1.9 10.6-5.8 12.1l-0.4 0.1c-4.5 1.3-6.8-6.4-7.1-23.1v-2.6c0-15.5 2.3-23.9 7-25.2 4.6-1.3 6.9 2.8 6.9 12.4v1.9l14.4-5.3c0-1.1 0.1-2.1 0.1-3.2 0-18.1-6.7-25.3-20.2-21.5l-0.5 0.2c-14.6 4.4-22.2 20.2-22.6 47.4v2.4c0 25.2 7.1 35.8 21.2 31.8 0.1 0 0.3-0.1 0.5-0.2 14.9-4.5 22.3-16.2 22.3-35.1l-15.9 3.3c0 1.6 0.1 3.2 0.1 4.6z"/>
33+
</g>
34+
<g fill="#fff">
35+
<path d="m923.6 154.6c-5.5 1.6-11.6 0.5-11.6 0.5l3.9 31-1.7 29.2 8.9-2.7-0.2-53.2s-0.3-2 1.1-2.5 0.9 1.7 0.9 1.7l-0.2 53.7 9.1-2.6-1.8-28.7 4.4-33c0.1 0-7.2 5-12.8 6.6z"/>
36+
<path d="m924.2 108.8c8.8-2.6 16-11.9 16-20.7s-7.2-14-16-11.5c-8.8 2.6-16 11.9-16 20.7s7.2 14.1 16 11.5z"/>
37+
<path d="m956.2 139.3c-6.1 1.8-12.1 1.4-12.1 1.4l0.9 44.6-0.9 21.3 11.5-3.4-0.2-52.7s-0.4-2.1 1.3-2.7c1.6-0.5 1 1.8 1 1.8l-0.2 53.2 11.7-3.4-1.1-21.3 1.6-45c0 0.2-7.3 4.4-13.5 6.2z"/>
38+
<path d="m969.2 98.9 6.7 11.8 2.3 15.7 4.1-1.8-1.2-17s-9.4-20.1-11.7-19.4c-4.2 1.2-5.1 2.1-12.5 4.3-7.5 2.2-8.3 1.8-12.5 3-1.2 0.3-3.5 7-5.5 13.3-1.1-1.6-2.2-2.6-3.3-2.3-3.8 1.1-4.6 3.6-11.5 5.6-0.1 0-0.2 0.1-0.2 0.1-0.1 0-0.2 0.1-0.2 0.1-6.8 2-7.7 0-11.5 1.1s-11 19.6-11 22.1 10.2 7.9 10.2 7.9l4.2-0.4-2.8 10.8s5.1 0.9 11.2-0.8c6.1-1.9 12-5.9 12-5.9l-3.4-9.2 3-3.2s0.3-0.4 0.7-0.9l0.4 4.2 4.1-0.5-0.2-8.6c1.8-2.3 3.4-4.6 3.4-5.7 0-1-0.8-4.3-2-7.6l2.5-9.3-0.5 24.2-0.2 6.4s6.5 0.6 13-1.1c0.1 0 0.1 0 0.2-0.1 0.1 0 0.1 0 0.2-0.1 6.6-2.1 13-6.5 13-6.5l-0.2-6.3-0.8-23.9zm-50.9 31.9c-1.3 3.4-4.9 6-8 5.6-3-0.4-4.5-3.6-3.2-7.2 1.3-3.4 4.9-6 8-5.6 3 0.6 4.5 3.7 3.2 7.2zm5.2 7.4h-0.3c-3-0.4-4.5-3.6-3.2-7.2 1.2-3.2 4.4-5.7 7.4-5.6h0.6l5.4 0.7c0.7 0.1 1.3 0.4 1.8 0.7l-11.7 11.4z"/>
39+
<path d="m957 89c9.7-2.8 17.6-13.1 17.6-22.9s-7.9-15.5-17.6-12.7-17.6 13.1-17.6 22.9 7.8 15.6 17.6 12.7z"/>
40+
<path d="m980.3 167c-2.8 0.8-5.5 0.6-5.5 0.6l0.5 20.3-0.5 9.7 5.3-1.5-0.1-24.1s-0.2-1 0.6-1.2c0.7-0.2 0.5 0.8 0.5 0.8l-0.1 24.3 5.4-1.6-0.6-9.7 0.7-20.5c-0.1 0.2-3.5 2.1-6.2 2.9z"/>
41+
<path d="m991.5 152.5s-4.3-9.2-5.4-8.9c-1.9 0.6-2.3 1-5.7 1.9s-3.8 0.8-5.7 1.4c-1.1 0.3-4.2 11.6-4.2 11.6l0.6 7.7 1.8-0.3-0.2-7.4 1.8-6.9-0.2 11-0.1 2.9s3 0.3 5.9-0.5h0.1 0.1c3-1 5.9-2.9 5.9-2.9l-0.1-2.9-0.2-10.9 3 5.4 1 7.2 1.8-0.8-0.2-7.6z"/>
42+
<path d="m972.5 138.2c0 4.5 3.6 7.1 8 5.8s8-6 8-10.4-3.6-7.1-8-5.8-8 6-8 10.4z"/>
43+
<path d="m904.2 186c-1.6 0.5-1.9 0.7-4.8 1.6-2.9 0.8-3.1 0.7-4.8 1.2-0.9 0.3-3.5 7.7-3.5 7.7l0.6 5 1.6-0.3-0.1-4.8 1.6-4.6-0.2 7.1-2.7 9.4s3.9 0.6 7.7-0.5 7.6-4 7.6-4l-2.7-7.9-0.2-7 2.5 3.4 0.9 4.6 1.6-0.6-0.5-5c-0.1 0.1-3.7-5.5-4.6-5.3z"/>
44+
<path d="m899.4 186.6c3.7-1.1 6.7-5 6.7-8.8s-3-5.9-6.7-4.8-6.7 5-6.7 8.8 3 5.9 6.7 4.8z"/>
45+
<path d="m910.1 178.8c-0.6-1.5 2.6-5.4 0.7-6.7-2-1.5-5.9 1.5-5.9 1.5s1.8 0.8 2.5 2c0.6 1.3-1 4.1-0.6 5.4 1.6 3.5 6.6-0.7 6.6-0.7s-2.8-0.1-3.3-1.5z"/>
46+
<path d="m890.6 180.2c0.6-1.7 3.3-3.3 3.3-3.3s-5-1.3-6.6 3.1c-0.6 1.5 1.2 3.4 0.6 5.1-0.6 1.6-2.5 3.4-2.5 3.4s3.9 0.6 5.9-1.9c1.9-2.4-1.3-4.6-0.7-6.4z"/>
47+
<polygon points="894.7 220.7 896 220.3 898.2 208.8 894.7 209"/>
48+
<polygon points="903.1 218.3 904.4 217.9 904.4 206.2 900.9 208"/>
49+
</g>
50+
</svg>
51+
</div>
52+
<div class="flex gap-x-4">
53+
<div class="mb-4">
54+
<label for="onTime" class="block text-gray-700 font-semibold mb-2">On Time (sec):</label>
55+
<input type="number" id="onTime" name="onTime" class="w-full p-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500">
56+
</div>
57+
<div class="mb-4">
58+
<label for="offTime" class="block text-gray-700 font-semibold mb-2">Off Time (sec):</label>
59+
<input type="number" id="offTime" name="offTime" class="w-full p-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500">
60+
</div>
61+
</div>
62+
<div class="mb-4">
63+
<span id="status" class="text-gray-700 font-semibold">Status: Not Flashing</span>
64+
</div>
65+
<div class="flex justify-between">
66+
<button id="startBtn" class="bg-blue-600 text-white font-semibold py-2 px-4 rounded focus:outline-none hover:bg-blue-700">Start</button>
67+
<button id="stopBtn" class="bg-red-600 text-white font-semibold py-2 px-4 rounded focus:outline-none hover:bg-red-700">Stop</button>
68+
</div>
69+
</div>
70+
</div>
71+
<script>
72+
const statusElement = document.getElementById('status');
73+
const startBtn = document.getElementById('startBtn');
74+
const stopBtn = document.getElementById('stopBtn');
75+
const delayInput = document.getElementById('delay');
76+
77+
(async () => {
78+
const response = await fetch('/status');
79+
updateStatus(response);
80+
})();
81+
82+
async function updateStatus(response) {
83+
if (response.ok) {
84+
const json = await response.json();
85+
console.log(json)
86+
delayInput.value = json.delay;
87+
const statusText = json.status ? 'Flashing' : 'Not Flashing';
88+
statusElement.textContent = `Status: ${statusText} | Delay: ${json.delay} sec`;
89+
} else {
90+
statusElement.textContent = 'Error: ' + response.status;
91+
}
92+
}
93+
94+
startBtn.addEventListener('click', async () => {
95+
const response = await fetch('/start');
96+
updateStatus(response);
97+
});
98+
99+
stopBtn.addEventListener('click', async () => {
100+
const response = await fetch('/stop');
101+
updateStatus(response);
102+
});
103+
104+
delayInput.addEventListener('change', async () => {
105+
const delay = delayInput.value;
106+
const response = await fetch(`/set-delay/${delay}`);
107+
updateStatus(response);
108+
});
109+
</script>
110+
</body>
111+
</html>

0 commit comments

Comments
 (0)