28
28
import os
29
29
import time
30
30
import gc
31
+ from micropython import const
31
32
import adafruit_esp32spi .adafruit_esp32spi_socket as socket
32
33
from adafruit_io .adafruit_io import IO_HTTP , AdafruitIO_RequestError
33
34
import adafruit_requests as requests
70
71
STATUS_DATA_RECEIVED = (0 , 0 , 100 )
71
72
STATUS_OFF = (0 , 0 , 0 )
72
73
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
+
73
82
74
83
class Network :
75
84
"""Class representing the Adafruit RGB Matrix Portal.
@@ -223,9 +232,32 @@ def wget(self, url, filename, *, chunk_size=12000):
223
232
self .neo_status (STATUS_FETCHING )
224
233
response = requests .get (url , stream = True )
225
234
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
+
226
255
if self ._debug :
227
256
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" )
229
261
remaining = content_length
230
262
print ("Saving data to " , filename )
231
263
stamp = time .monotonic ()
@@ -392,8 +424,6 @@ def fetch(self, url, *, headers=None, timeout=10):
392
424
gc .collect ()
393
425
response = requests .get (url , headers = headers , timeout = timeout )
394
426
gc .collect ()
395
- self .neo_status (STATUS_DATA_RECEIVED ) # green = got data
396
- print ("Reply is OK!" )
397
427
398
428
return response
399
429
@@ -403,10 +433,40 @@ def fetch_data(
403
433
"""Fetch data from the specified url and perfom any parsing"""
404
434
json_out = None
405
435
values = []
436
+ content_type = CONTENT_TEXT
406
437
407
438
response = self .fetch (url , headers = headers , timeout = timeout )
408
439
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 :
410
470
if isinstance (json_path , (list , tuple )) and (
411
471
not json_path or not isinstance (json_path [0 ], (list , tuple ))
412
472
):
@@ -436,18 +496,24 @@ def fetch_data(
436
496
raise
437
497
438
498
# extract desired text/values from json
439
- if json_path :
499
+ if json_out and json_path :
440
500
for path in json_path :
441
501
try :
442
502
values .append (self .json_traverse (json_out , path ))
443
503
except KeyError :
444
504
print (json_out )
445
505
raise
446
- elif regexp_path :
506
+ elif content_type == CONTENT_TEXT and regexp_path :
447
507
for regexp in regexp_path :
448
508
values .append (re .search (regexp , response .text ).group (1 ))
449
509
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
451
517
452
518
# we're done with the requests object, lets delete it so we can do more!
453
519
json_out = None
0 commit comments