diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..d9b274b Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bfc8877 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +# Byte-compiled / optimized / DLL files +passwords.txt +**passwords.txt +**/.idea/* +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/flexible_web_server/main.py b/flexible_web_server/main.py index d1855c1..ac4c878 100644 --- a/flexible_web_server/main.py +++ b/flexible_web_server/main.py @@ -4,53 +4,80 @@ import socket response_404 = """HTTP/1.0 404 NOT FOUND -

404 Not Found

""" response_500 = """HTTP/1.0 500 INTERNAL SERVER ERROR -

500 Internal Server Error

""" - response_template = """HTTP/1.0 200 OK %s """ - import machine import ntptime, utime from machine import RTC from time import sleep +seconds = ntptime.time() rtc = RTC() -try: - seconds = ntptime.time() -except: - seconds = 0 rtc.datetime(utime.localtime(seconds)) +adc = machine.ADC(0) +pin = machine.Pin(16, machine.Pin.OUT) +switch_pin = machine.Pin(10, machine.Pin.IN) + + def time(): body = """ - -

Time

-

%s

- - -""" % str(rtc.datetime()) + +

Time

+

%s

+ + + """ % str(rtc.datetime()) return response_template % body + def dummy(): body = "This is a dummy endpoint" return response_template % body + +def light(): + body = "{value: " + adc.read() + "}" + return response_template % body + + +def switch(): + body = "{state: " + switch_pin.value() + "}" + return response_template % body + + +def light_on(): + pin.value(0) + body = "You turned a light on!" + return response_template % body + + +def light_off(): + pin.value(1) + body = "You turned a light off!" + return response_template % body + + handlers = { 'time': time, 'dummy': dummy, + 'light_on': light_on, + 'light_off': light_off, + 'light': light, + 'switch': switch, } + def main(): s = socket.socket() ai = socket.getaddrinfo("0.0.0.0", 8080) @@ -60,7 +87,7 @@ def main(): s.bind(addr) s.listen(5) - print("Listening, connect your browser to http://:8080") + print("Listening, connect your browser to http://:8080/") while True: sleep(1) @@ -70,9 +97,12 @@ def main(): req = client_s.recv(4096) print("Request:") print(req) - try: + # The first line of a request looks like "GET /arbitrary/path/ HTTP/1.1". + # This grabs that first line and whittles it down to just "/arbitrary/path/" path = req.decode().split("\r\n")[0].split(" ")[1] + + # Given the path, identify the correct handler to use handler = handlers[path.strip('/').split('/')[0]] response = handler() except KeyError: @@ -81,9 +111,12 @@ def main(): response = response_500 print(str(e)) + # A handler returns an entire response in the form of a multi-line string. + # This breaks up the response into single strings, byte-encodes them, and + # joins them back together with b"\r\n". Then it sends that to the client. client_s.send(b"\r\n".join([line.encode() for line in response.split("\n")])) client_s.close() print() -main() +main() \ No newline at end of file diff --git a/passwords.txt b/passwords.txt deleted file mode 100644 index 9f2747f..0000000 --- a/passwords.txt +++ /dev/null @@ -1,2 +0,0 @@ -EarlGreyTea HotHotHot -MyHomeAccessPoint aueiUeh73NB