01234567890123456789012345678901234567890123456789012345678901234567890123456789
6426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522 66896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729 |
<----SKIPPED LINES---->
% subscription_id)
curl.setopt(pycurl.HTTPHEADER, [
'X-Vestaboard-Api-Key:%s' % key, 'X-Vestaboard-Api-Secret:%s' % secret])
curl.setopt(pycurl.TIMEOUT_MS, timeout*1000)
curl.setopt(pycurl.POST, 1)
curl.setopt(pycurl.WRITEFUNCTION, lambda x: None) # to keep stdout clean
# preparing body the way pycurl.READDATA wants it
body_as_dict = {'characters': StringToCharArray(s)}
body_as_json_string = json.dumps(body_as_dict) # dict to json
body_as_file_object = io.StringIO(body_as_json_string)
# prepare and send. See also: pycurl.READFUNCTION to pass function instead
curl.setopt(pycurl.READDATA, body_as_file_object)
curl.setopt(pycurl.POSTFIELDSIZE, len(body_as_json_string))
web_publish_failure_msg = ''
try:
curl.perform()
status_msg = 'Web service published'
status_code = 'SUCCESS'
except pycurl.error as e:
timing_message = CurlTimingDetailsToString(curl)
web_publish_failure_msg = (
'curl.perform() failed with message %s; timing details: %s' %
(e, timing_message))
# Using the remote webservice failed, but maybe the local API will
# be more successful? If this succeeds, then we should not indicate
# a failure on the status light / dashboard, but we should still log
# the remote failure
Log(web_publish_failure_msg)
local_publish_error_msg = PublishMessageLocal(
s, timeout=timeout, update_dashboard=False)
if not local_publish_error_msg:
status_msg = (
'Local service published (1) because web service failed with %s'
% web_publish_failure_msg)
status_code = 'WARNING'
else:
status_msg = (
'Local service failed (2) with %s after web service failed with %s' %
(local_publish_error_msg, web_publish_failure_msg))
status_code = 'FAIL'
else:
# you may want to check HTTP response code, e.g.
timing_message = CurlTimingDetailsToString(curl)
status_code = curl.getinfo(pycurl.RESPONSE_CODE)
if status_code != 200:
web_publish_failure_msg = (
'Server returned HTTP status code %d for message %s; '
'timing details: %s' % (status_code, s, timing_message))
Log(web_publish_failure_msg)
local_publish_error_msg = PublishMessageLocal(
s, timeout=timeout, update_dashboard=False)
if not local_publish_error_msg:
status_msg = (
'Local service published (3) because web service failed with %s'
% web_publish_failure_msg)
status_code = 'WARNING'
else:
status_msg = (
'Local service failed (4) with %s after web service failed with %s'
% (local_publish_error_msg, web_publish_failure_msg))
status_code = 'FAIL'
# We've logged the error code from the external web service, but the
# Vestaboard local API was able to recover from the error, so we need not
# log the failure message / error code in the dashboard.
if not error_code:
web_publish_failure_msg = ''
curl.close()
UpdateStatusLight(
GPIO_ERROR_VESTABOARD_CONNECTION,
status_code=='FAIL', web_publish_failure_msg)
return status_msg, status_code
def PublishMessageLocal(
s,
local_key=LOCAL_KEY,
local_address=LOCAL_VESTABOARD_ADDRESS,
timeout=5,
update_dashboard=True):
"""Publishes a text string to a Vestaboard via local API.
The message is pushed to the vestaboard splitflap display by way of its
local API; see https://docs.vestaboard.com/local for more details.
Args:
s: String to publish.
local_key: string key from Vestaboard for local API access.
local_address: the address and port to the local Vestaboard service.
timeout: Max duration in seconds that we should wait to establish a
connection.
update_dashboard: Boolean indicating whether this method should update the
<----SKIPPED LINES---->
for message in messages_to_display:
# we cannot just unpack the tuple because messages of type
# FLAG_MSG_FLIGHT & FLAG_MSG_INSIGHT are 3-tuples (with the third
# element being the flight dictionary) whereas other message types
# are 2-tuples
message_type = message[0]
message_text = message[1]
# There may be one or several insight messages that were added to the
# message queue along with the flight at a time when the screen was
# enabled, but by the time it comes to display them, the screen is now
# disabled. These should not be displayed. Note that this check only
# needs to be done for insight messages because other message types
# are user initiated and so presumably should be displayed irrespective
# of when the user triggered it to be displayed.
if message_type == FLAG_MSG_INSIGHT and not MessageMeetsDisplayCriteria(
configuration):
publish_status_msg = (
'Message purged as no longer meets display criteria')
publish_status_code = 'WARN'
Log('Message %s purged' % message_text)
else:
if isinstance(message_text, str):
message_text = textwrap.wrap(
message_text,
width=SPLITFLAP_CHARS_PER_LINE)
display_message = Screenify(message_text, False)
Log(display_message, file=ALL_MESSAGE_FILE)
# Saving this to disk allows us to identify
# persistently whats currently on the screen
PickleObjectToFile(message, PICKLE_SCREENS, True)
screens.append(message)
MaintainRollingWebLog(display_message, 25)
if not SIMULATION:
splitflap_message = Screenify(message_text, True)
publish_status = PublishMessageWeb(splitflap_message)
publish_status_msg, publish_status_code = publish_status
<----SKIPPED LINES---->
|
01234567890123456789012345678901234567890123456789012345678901234567890123456789
6426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522 66896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729 |
<----SKIPPED LINES---->
% subscription_id)
curl.setopt(pycurl.HTTPHEADER, [
'X-Vestaboard-Api-Key:%s' % key, 'X-Vestaboard-Api-Secret:%s' % secret])
curl.setopt(pycurl.TIMEOUT_MS, timeout*1000)
curl.setopt(pycurl.POST, 1)
curl.setopt(pycurl.WRITEFUNCTION, lambda x: None) # to keep stdout clean
# preparing body the way pycurl.READDATA wants it
body_as_dict = {'characters': StringToCharArray(s)}
body_as_json_string = json.dumps(body_as_dict) # dict to json
body_as_file_object = io.StringIO(body_as_json_string)
# prepare and send. See also: pycurl.READFUNCTION to pass function instead
curl.setopt(pycurl.READDATA, body_as_file_object)
curl.setopt(pycurl.POSTFIELDSIZE, len(body_as_json_string))
web_publish_failure_msg = ''
try:
curl.perform()
status_msg = 'Web service published'
publish_status_code = 'SUCCESS'
except pycurl.error as e:
timing_message = CurlTimingDetailsToString(curl)
web_publish_failure_msg = (
'curl.perform() failed with message %s; timing details: %s' %
(e, timing_message))
# Using the remote webservice failed, but maybe the local API will
# be more successful? If this succeeds, then we should not indicate
# a failure on the status light / dashboard, but we should still log
# the remote failure
Log(web_publish_failure_msg)
local_publish_error_msg = PublishMessageLocal(
s, timeout=timeout, update_dashboard=False)
if not local_publish_error_msg:
status_msg = (
'Local service published (1) because web service failed with %s'
% web_publish_failure_msg)
publish_status_code = 'WARNING'
else:
status_msg = (
'Local service failed (2) with %s after web service failed with %s' %
(local_publish_error_msg, web_publish_failure_msg))
publish_status_code = 'FAILURE'
else:
# you may want to check HTTP response code, e.g.
timing_message = CurlTimingDetailsToString(curl)
status_code = curl.getinfo(pycurl.RESPONSE_CODE)
if status_code != 200:
web_publish_failure_msg = (
'Server returned HTTP status code %d for message %s; '
'timing details: %s' % (status_code, s, timing_message))
Log(web_publish_failure_msg)
local_publish_error_msg = PublishMessageLocal(
s, timeout=timeout, update_dashboard=False)
if not local_publish_error_msg:
status_msg = (
'Local service published (3) because web service failed with %s'
% web_publish_failure_msg)
publish_status_code = 'WARNING'
else:
status_msg = (
'Local service failed (4) with %s after web service failed with %s'
% (local_publish_error_msg, web_publish_failure_msg))
publish_status_code = 'FAILURE'
# We've logged the error code from the external web service, but the
# Vestaboard local API was able to recover from the error, so we need not
# log the failure message / error code in the dashboard.
if not error_code:
web_publish_failure_msg = ''
curl.close()
UpdateStatusLight(
GPIO_ERROR_VESTABOARD_CONNECTION,
publish_status_code=='FAILURE', web_publish_failure_msg)
return status_msg, publish_status_code
def PublishMessageLocal(
s,
local_key=LOCAL_KEY,
local_address=LOCAL_VESTABOARD_ADDRESS,
timeout=5,
update_dashboard=True):
"""Publishes a text string to a Vestaboard via local API.
The message is pushed to the vestaboard splitflap display by way of its
local API; see https://docs.vestaboard.com/local for more details.
Args:
s: String to publish.
local_key: string key from Vestaboard for local API access.
local_address: the address and port to the local Vestaboard service.
timeout: Max duration in seconds that we should wait to establish a
connection.
update_dashboard: Boolean indicating whether this method should update the
<----SKIPPED LINES---->
for message in messages_to_display:
# we cannot just unpack the tuple because messages of type
# FLAG_MSG_FLIGHT & FLAG_MSG_INSIGHT are 3-tuples (with the third
# element being the flight dictionary) whereas other message types
# are 2-tuples
message_type = message[0]
message_text = message[1]
# There may be one or several insight messages that were added to the
# message queue along with the flight at a time when the screen was
# enabled, but by the time it comes to display them, the screen is now
# disabled. These should not be displayed. Note that this check only
# needs to be done for insight messages because other message types
# are user initiated and so presumably should be displayed irrespective
# of when the user triggered it to be displayed.
if message_type == FLAG_MSG_INSIGHT and not MessageMeetsDisplayCriteria(
configuration):
publish_status_msg = (
'Message purged as no longer meets display criteria')
publish_status_code = 'WARNING'
Log('Message %s purged' % message_text)
else:
if isinstance(message_text, str):
message_text = textwrap.wrap(
message_text,
width=SPLITFLAP_CHARS_PER_LINE)
display_message = Screenify(message_text, False)
Log(display_message, file=ALL_MESSAGE_FILE)
# Saving this to disk allows us to identify
# persistently whats currently on the screen
PickleObjectToFile(message, PICKLE_SCREENS, True)
screens.append(message)
MaintainRollingWebLog(display_message, 25)
if not SIMULATION:
splitflap_message = Screenify(message_text, True)
publish_status = PublishMessageWeb(splitflap_message)
publish_status_msg, publish_status_code = publish_status
<----SKIPPED LINES---->
|