Skip to content

Commit 98d46a9

Browse files
authored
Merge pull request #5 from gurgleapps/esp
Esp
2 parents 79d60f2 + 5334bd7 commit 98d46a9

File tree

5 files changed

+73
-23
lines changed

5 files changed

+73
-23
lines changed

gurgleapps_webserver.py

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def __init__(self, wifi_ssid, wifi_password, port=80, timeout=20, doc_root="/www
7474
async def start_server(self):
7575
print("start_server")
7676
server_task = asyncio.create_task(asyncio.start_server(
77-
self.serve_request, "0.0.0.0", 80))
77+
self.serve_request, "0.0.0.0", self.port))
7878
await server_task
7979

8080
# async def start_server(self):
@@ -90,6 +90,7 @@ def add_function_route(self, route, function):
9090
async def serve_request(self, reader, writer):
9191
gc.collect()
9292
try:
93+
response = Response(writer)
9394
url = ""
9495
method = ""
9596
content_length = 0
@@ -130,9 +131,26 @@ async def serve_request(self, reader, writer):
130131
if content_length > 0:
131132
post_data_raw = await reader.readexactly(content_length)
132133
print("POST data:", post_data_raw)
133-
post_data = json.loads(post_data_raw)
134+
content_type_header = "Content-Type: application/json" # default to JSON
135+
for header in headers:
136+
if header.lower().startswith("content-type:"):
137+
content_type_header = header
138+
break
139+
if "application/json" in content_type_header.lower():
140+
try:
141+
post_data = json.loads(post_data_raw)
142+
except ValueError as e:
143+
print("Error decoding JSON data:", e)
144+
# Handle the error (e.g., send an error response to the client)
145+
await response.send("Invalid JSON data", status_code=400)
146+
return
147+
elif "application/x-www-form-urlencoded" in content_type_header.lower():
148+
post_data = self.parse_form_data(post_data_raw.decode('utf-8'))
149+
else:
150+
# Handle unsupported content types
151+
await response.send("Unsupported content type", status_code=415)
152+
return
134153
request = Request(post_data)
135-
response = Response(writer)
136154
# check if the url is a function route and if so run the function
137155
path_components = self.get_path_components(url)
138156
print("path_components: "+str(path_components))
@@ -147,26 +165,50 @@ async def serve_request(self, reader, writer):
147165
if self.log_level > 0:
148166
print("file_path: "+str(file_path))
149167
# if uos.stat(file_path)[6] > 0:
150-
if self.file_exists(file_path):
168+
if self.file_exists(file_path): #serve a file
151169
content_type = self.get_content_type(url)
152170
if self.log_level > 1:
153171
print("content_type: "+str(content_type))
154172
await response.send_file(file_path, content_type=content_type)
155173
return
156-
if url == "/":
157-
print("root")
158-
files_and_folders = self.list_files_and_folders(self.doc_root)
174+
# perhaps it is a folder
175+
if self.dir_exists(file_path): #serve a folder
176+
files_and_folders = self.list_files_and_folders(file_path)
159177
await response.send_iterator(self.generate_root_page_html(files_and_folders))
160178
return
161-
html = self.generate_root_page_html(files_and_folders)
162-
await response.send(html)
163-
return
179+
# if url == "/":
180+
# print("root")
181+
# files_and_folders = self.list_files_and_folders(self.doc_root)
182+
# await response.send_iterator(self.generate_root_page_html(files_and_folders))
183+
# return
164184
print("file not found "+url)
165185
await response.send(self.html % "page not found "+url, status_code=404)
166186
if (url == "/shutdown"):
167187
self.serving = False
168188
except OSError as e:
169189
print(e)
190+
191+
def parse_form_data(self, form_data_raw):
192+
form_data = {}
193+
for pair in form_data_raw.split('&'):
194+
key, value = pair.split('=')
195+
form_data[self.url_decode(key)] = self.url_decode(value)
196+
return form_data
197+
198+
def url_decode(self, encoded_str):
199+
decoded_str = ""
200+
i = 0
201+
while i < len(encoded_str):
202+
if encoded_str[i] == '%':
203+
hex_code = encoded_str[i + 1:i + 3]
204+
char = chr(int(hex_code, 16))
205+
decoded_str += char
206+
i += 3
207+
else:
208+
decoded_str += encoded_str[i]
209+
i += 1
210+
return decoded_str
211+
170212

171213
def dir_exists(self, filename):
172214
try:
@@ -304,9 +346,14 @@ def blink_element(element, pin, duration=0.27):
304346
await asyncio.sleep(delay_between_digits if element != '.' else 2 * delay_between_digits)
305347
await asyncio.sleep(delay_between_repititions)
306348

349+
307350
def list_files_and_folders(self, path):
308351
entries = uos.ilistdir(path)
309352
files_and_folders = []
353+
# print("list_files_and_folders: "+path)
354+
# print("list_files_and_folders: "+self.doc_root)
355+
if path != self.doc_root and path != self.doc_root + '/':
356+
files_and_folders.append({"name": "..", "type": "directory"})
310357
for entry in entries:
311358
name = entry[0]
312359
mode = entry[1]
@@ -331,29 +378,31 @@ def generate_root_page_html(self, files_and_folders):
331378
<div class="relative flex min-h-screen flex-col justify-center overflow-hidden bg-gray-50 py-6 sm:py-12">
332379
<div class="relative bg-white px-6 pb-8 pt-10 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-lg sm:rounded-lg sm:px-10">
333380
<div class="mx-auto max-w-md">
334-
<img src="/img/logo.svg" class="h-12 w-auto" alt="GurgleApps.com">
381+
<a href="https://gurgleapps.com"><img src="/img/logo.svg" class="h-12 w-auto" alt="GurgleApps.com"></a>
335382
"""
336383
yield """
337384
<div class="divide-y divide-gray-300/50">
338385
<div class="space-y-6 py-8 text-base leading-7 text-gray-600">
339386
<h1 class="text-lg font-semibold">Welcome to GurgleApps.com Webserver</h1>
340387
<h12 class="text-base font-semibold">File List:</h2>
341-
<ul class="space-y-2 mt-3">
388+
<ul class="mt-3">
342389
"""
343390
folder_icon_svg = """
344-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-indigo-800">
391+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
345392
<path d="M19.5 21a3 3 0 003-3v-4.5a3 3 0 00-3-3h-15a3 3 0 00-3 3V18a3 3 0 003 3h15zM1.5 10.146V6a3 3 0 013-3h5.379a2.25 2.25 0 011.59.659l2.122 2.121c.14.141.331.22.53.22H19.5a3 3 0 013 3v1.146A4.483 4.483 0 0019.5 9h-15a4.483 4.483 0 00-3 1.146z" />
346393
</svg>
347394
"""
348395
file_icon_svg = """
349-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 fill-indigo-800">
396+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
350397
<path d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a1.875 1.875 0 01-1.875-1.875V5.25A3.75 3.75 0 009 1.5H5.625z" />
351398
<path d="M12.971 1.816A5.23 5.23 0 0114.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 013.434 1.279 9.768 9.768 0 00-6.963-6.963z" />
352399
</svg>
353400
"""
354-
for file_or_folder in files_and_folders:
355-
icon = folder_icon_svg if file_or_folder['type'] == 'directory' else file_icon_svg
356-
yield f"<li class='border-t pt-1'><a href='/{file_or_folder['name']}' class='flex items-center font-semibold text-slate-800 hover:text-indigo-800'>{icon}<p class='ml-2'>{file_or_folder['name']}</p></a></li>"
401+
for index, file_or_folder in enumerate(files_and_folders):
402+
icon = folder_icon_svg if file_or_folder['type'] == 'directory' else file_icon_svg
403+
text_class = 'text-blue-500' if file_or_folder['type'] == 'directory' else 'text-blue-600'
404+
bg_class = "" if index % 2 == 1 else "bg-gray-50"
405+
yield f"<li class='border-t border-gray-300 py-1.5 {bg_class}'><a href='/{file_or_folder['name']}' class='flex items-center font-semibold {text_class} hover:text-blue-700'>{icon}<p class='ml-2'>{file_or_folder['name']}</p></a></li>"
357406
yield "</ul>"
358407
# Closing tags for the body and container div
359408
yield """

response.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ async def send_file(self, file_path, status_code=200, content_type="text/html"):
3030
await self.send_headers(status_code, content_type, content_length=file_size)
3131

3232
#chunk_size = 1024 # Adjust the chunk size as needed
33-
chunk_size = 512 # Adjust the chunk size as needed
33+
#chunk_size = 512 # Adjust the chunk size as needed
34+
chunk_size = 256
3435
with open(file_path, "rb") as f:
3536
while True:
3637
chunk = f.read(chunk_size)

www/led.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
1414
<div class="flex justify-center mb-8">
1515

16-
<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">
16+
<a href="https://gurgleapps.com"><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">
1717

1818
<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"/>
1919

@@ -49,7 +49,7 @@
4949
<polygon points="894.7 220.7 896 220.3 898.2 208.8 894.7 209"/>
5050
<polygon points="903.1 218.3 904.4 217.9 904.4 206.2 900.9 208"/>
5151
</g>
52-
</svg>
52+
</svg></a>
5353
</div>
5454
<div class="mb-4">
5555
<label for="delay" class="block text-gray-700 font-semibold mb-2">Delay (sec):</label>

www/led2.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
1212
<div class="flex justify-center mb-8">
1313

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">
14+
<a href="https://gurgleapps.com"><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">
1515

1616
<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"/>
1717

@@ -47,7 +47,7 @@
4747
<polygon points="894.7 220.7 896 220.3 898.2 208.8 894.7 209"/>
4848
<polygon points="903.1 218.3 904.4 217.9 904.4 206.2 900.9 208"/>
4949
</g>
50-
</svg>
50+
</svg></a>
5151
</div>
5252
<div class="flex gap-x-4">
5353
<div class="mb-4">

0 commit comments

Comments
 (0)