Skip to content

Commit 34db990

Browse files
authored
Merge pull request #38 from makermelissa/master
Add some of the recent improvements from PyPortal
2 parents 9fa02f6 + 32f08a8 commit 34db990

File tree

1 file changed

+73
-7
lines changed

1 file changed

+73
-7
lines changed

adafruit_matrixportal/network.py

+73-7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import os
2929
import time
3030
import gc
31+
from micropython import const
3132
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
3233
from adafruit_io.adafruit_io import IO_HTTP, AdafruitIO_RequestError
3334
import adafruit_requests as requests
@@ -70,6 +71,14 @@
7071
STATUS_DATA_RECEIVED = (0, 0, 100)
7172
STATUS_OFF = (0, 0, 0)
7273

74+
CONTENT_TEXT = const(1)
75+
CONTENT_JSON = const(2)
76+
CONTENT_IMAGE = const(3)
77+
78+
79+
class HttpError(Exception):
80+
"""HTTP Specific Error"""
81+
7382

7483
class Network:
7584
"""Class representing the Adafruit RGB Matrix Portal.
@@ -223,9 +232,32 @@ def wget(self, url, filename, *, chunk_size=12000):
223232
self.neo_status(STATUS_FETCHING)
224233
response = requests.get(url, stream=True)
225234

235+
headers = {}
236+
for title, content in response.headers.items():
237+
headers[title.lower()] = content
238+
239+
if response.status_code == 200:
240+
print("Reply is OK!")
241+
self.neo_status((0, 0, 100)) # green = got data
242+
else:
243+
if self._debug:
244+
if "content-length" in headers:
245+
print("Content-Length: {}".format(int(headers["content-length"])))
246+
if "date" in headers:
247+
print("Date: {}".format(headers["date"]))
248+
self.neo_status((100, 0, 0)) # red = http error
249+
raise HttpError(
250+
"Code {}: {}".format(
251+
response.status_code, response.reason.decode("utf-8")
252+
)
253+
)
254+
226255
if self._debug:
227256
print(response.headers)
228-
content_length = int(response.headers["content-length"])
257+
if "content-length" in headers:
258+
content_length = int(headers["content-length"])
259+
else:
260+
raise RuntimeError("Content-Length missing from headers")
229261
remaining = content_length
230262
print("Saving data to ", filename)
231263
stamp = time.monotonic()
@@ -392,8 +424,6 @@ def fetch(self, url, *, headers=None, timeout=10):
392424
gc.collect()
393425
response = requests.get(url, headers=headers, timeout=timeout)
394426
gc.collect()
395-
self.neo_status(STATUS_DATA_RECEIVED) # green = got data
396-
print("Reply is OK!")
397427

398428
return response
399429

@@ -403,10 +433,40 @@ def fetch_data(
403433
"""Fetch data from the specified url and perfom any parsing"""
404434
json_out = None
405435
values = []
436+
content_type = CONTENT_TEXT
406437

407438
response = self.fetch(url, headers=headers, timeout=timeout)
408439

409-
if json_path is not None:
440+
headers = {}
441+
for title, content in response.headers.items():
442+
headers[title.lower()] = content
443+
gc.collect()
444+
if self._debug:
445+
print("Headers:", headers)
446+
if response.status_code == 200:
447+
print("Reply is OK!")
448+
self.neo_status(STATUS_DATA_RECEIVED) # green = got data
449+
if "content-type" in headers:
450+
if "image/" in headers["content-type"]:
451+
content_type = CONTENT_IMAGE
452+
elif "application/json" in headers["content-type"]:
453+
content_type = CONTENT_JSON
454+
elif "application/javascript" in headers["content-type"]:
455+
content_type = CONTENT_JSON
456+
else:
457+
if self._debug:
458+
if "content-length" in headers:
459+
print("Content-Length: {}".format(int(headers["content-length"])))
460+
if "date" in headers:
461+
print("Date: {}".format(headers["date"]))
462+
self.neo_status((100, 0, 0)) # red = http error
463+
raise HttpError(
464+
"Code {}: {}".format(
465+
response.status_code, response.reason.decode("utf-8")
466+
)
467+
)
468+
469+
if content_type == CONTENT_JSON and json_path is not None:
410470
if isinstance(json_path, (list, tuple)) and (
411471
not json_path or not isinstance(json_path[0], (list, tuple))
412472
):
@@ -436,18 +496,24 @@ def fetch_data(
436496
raise
437497

438498
# extract desired text/values from json
439-
if json_path:
499+
if json_out and json_path:
440500
for path in json_path:
441501
try:
442502
values.append(self.json_traverse(json_out, path))
443503
except KeyError:
444504
print(json_out)
445505
raise
446-
elif regexp_path:
506+
elif content_type == CONTENT_TEXT and regexp_path:
447507
for regexp in regexp_path:
448508
values.append(re.search(regexp, response.text).group(1))
449509
else:
450-
values = response.text
510+
if json_out:
511+
# No path given, so return JSON as string for compatibility
512+
import json # pylint: disable=import-outside-toplevel
513+
514+
values = json.dumps(response.json())
515+
else:
516+
values = response.text
451517

452518
# we're done with the requests object, lets delete it so we can do more!
453519
json_out = None

0 commit comments

Comments
 (0)