Created
May 25, 2023 07:59
-
-
Save haveyouwantto/7022e089b049826c3fd08e0e5bba9085 to your computer and use it in GitHub Desktop.
PicoJMBox for ESP32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import network | |
import uos | |
import usocket as socket | |
import ujson as json | |
import _thread | |
from time import sleep_ms | |
ap = network.WLAN(network.AP_IF) | |
ap.active(True) | |
ap.config(essid="PicoJMBox") | |
print(ap.config('txpower')) | |
server_info = json.dumps({"capabilities":{"play":False,"midi":True},"themeColor":"#288cd1","serverName":"PicoJMBox (ESP32)"}) | |
def url_decode(s) : | |
r = str(s).split('%') | |
try : | |
b = r[0].encode() | |
for i in range(1, len(r)) : | |
try : | |
b += bytes([int(r[i][:2], 16)]) + r[i][2:].encode() | |
except : | |
b += b'%' + r[i].encode() | |
return b.decode('UTF-8') | |
except : | |
return str(s) | |
# Start the server | |
def start_server(): | |
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
server_socket.bind(('', 80)) | |
server_socket.listen(5) | |
print("Server started, listening on port 80...") | |
try: | |
while True: | |
try: | |
client_socket, client_address = server_socket.accept() | |
_thread.start_new_thread(handle_request, (client_socket,)) | |
sleep_ms(500) | |
except OSError: | |
pass | |
except KeyboardInterrupt: | |
server_socket.close() | |
# Handle the HTTP request | |
def handle_request(client): | |
request = client.recv(1024) | |
request_lines = request.decode().split('\r\n') | |
http = request_lines[0].split(' ') | |
method, path = http[0], http[1] | |
path = url_decode(path) | |
file = 'midi/'+'/'.join(path.split('/')[3:]) | |
print(path) | |
if method == 'GET': | |
if path.startswith('/api/info'): | |
serve_info(client) | |
elif path.startswith('/api/list'): | |
serve_list(file, client) | |
elif path.startswith('/api/midi'): | |
serve_midi(file, client) | |
elif path == '/': | |
serve_file('/index.html', client) | |
else: | |
serve_file(path, client) | |
client.close() | |
# Serve a file from the webui directory | |
def serve_file(filename, client): | |
try: | |
with open('ui' + filename, 'rb') as file: | |
client.send(b"HTTP/1.1 200 OK\r\nServer: PicoJMBox\r\nCache-Control: public, max-age=3600\r\n\r\n") | |
while True: | |
chunk = file.read(1024) | |
if not chunk: | |
break | |
client.send(chunk) | |
except OSError: | |
not_found(client) | |
# Serve server info | |
def serve_info(client): | |
client.send(b"HTTP/1.1 200 OK\r\nServer: PicoJMBox\r\nContent-Type: application/json\r\n\r\n") | |
client.send(server_info) | |
def list_files(directory): | |
files = uos.listdir(directory) | |
file_list = [] | |
for file in files: | |
file_path = directory + '/' + file | |
stat = uos.stat(file_path) | |
file_info = { | |
"date": stat[8]*1000, | |
"size": stat[6], | |
'name': file, | |
'isDir': stat[0] & 0x4000 == 0x4000 # Check if directory flag is set | |
} | |
file_list.append(file_info) | |
return file_list | |
# Serve the list of MIDI files and directories | |
def serve_list(directory,client): | |
try: | |
client.send(b"HTTP/1.1 200 OK\r\nServer: PicoJMBox\r\nContent-Type: application/json\r\n\r\n") | |
client.send(json.dumps(list_files(directory))) | |
except OSError: | |
not_found(client) # Return an empty list if the path does not exist or an error occurs | |
# Serve the original MIDI file | |
def serve_midi(filename,client): | |
try: | |
with open(filename, 'rb') as file: | |
client.send(b"HTTP/1.1 200 OK\r\nServer: PicoJMBox\r\nContent-Type: audio/midi\r\nCache-Control: public, max-age=3600\r\n\r\n") | |
while True: | |
chunk = file.read(1024) | |
if not chunk: | |
break | |
client.send(chunk) | |
except OSError: | |
not_found(client) | |
# Serve a "404 Not Found" response | |
def not_found(client): | |
client.send(b"HTTP/1.1 404 Not Found\r\nServer: PicoJMBox\r\nContent-Type: text/plain\r\n\r\n404 Not Found") | |
# Start the server | |
start_server() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment