01234567890123456789012345678901234567890123456789012345678901234567890123456789
639063916392639363946395639663976398639964006401640264036404640564066407640864096410 64116412641364146415641664176418641964206421642264236424642564266427642864296430 64326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523 73337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373 |
<----SKIPPED LINES---->
message_array = message_array[:expected_characters]
message_2d_array = []
for line_num in range(SPLITFLAP_LINE_COUNT):
message_2d_array.append(message_array[
line_num * SPLITFLAP_CHARS_PER_LINE :
(line_num + 1)*SPLITFLAP_CHARS_PER_LINE])
return message_2d_array
def PublishMessageWeb(
s,
subscription_id=SUBSCRIPTION_ID,
key=KEY,
secret=SECRET,
timeout=5):
"""Publishes a text string to a Vestaboard.
The message is pushed to the vestaboard splitflap display by way of its
web services; see https://docs.vestaboard.com/introduction for more details.
TODO: rewrite to use the easier-to-follow requests library, more in line
with PublishMessageLocal.
Args:
s: String to publish.
subscription_id: string subscription id from Vestaboard.
key: string key from Vestaboard.
secret: string secret from Vestaboard.
timeout: Max duration in seconds that we should wait to establish a
connection.
Returns:
Text string indicating how the message was displayed (web or local
api), and / or any error messages encountered.
"""
error_code = False
curl = pycurl.Curl()
# See https://stackoverflow.com/questions/31826814/
<----SKIPPED LINES---->
# Set URL value
curl.setopt(
pycurl.URL,
'https://platform.vestaboard.com/subscriptions/%s/message'
% 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))
failure_message = ''
try:
curl.perform()
status = 'Web service published'
except pycurl.error as e:
timing_message = CurlTimingDetailsToString(curl)
failure_message = (
'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(failure_message)
error_code = PublishMessageLocal(s, timeout=timeout, update_dashboard=False)
if not error_code:
status = (
'Local service published because web service failed with %s'
% failure_message)
else:
status = (
'Local service failed with %s after web service failed with %s' %
(error_code, failure_message))
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:
failure_message = (
'Server returned HTTP status code %d for message %s; '
'timing details: %s' % (status_code, s, timing_message))
Log(failure_message)
error_code = PublishMessageLocal(
s, timeout=timeout, update_dashboard=False)
if not error_code:
status = (
'Local service published because web service failed with %s'
% failure_message)
else:
status = (
'Local service failed with %s after web service failed with %s' %
(error_code, failure_message))
# 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:
failure_message = ''
curl.close()
UpdateStatusLight(
GPIO_ERROR_VESTABOARD_CONNECTION, error_code, failure_message)
return status
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
<----SKIPPED LINES---->
if new_flight_flag:
time_new_flight_found = time.time()
# Since we no longer need the memory-hogging prior persistent_path
# stored on the flights, we can remove it
if flights and 'persistent_path' in flights[-1]:
del flights[-1]['persistent_path']
flights.append(flight)
remote, servo = RefreshArduinos(
remote, servo,
to_remote_q, to_servo_q, to_main_q, shutdown,
flights, json_desc_dict, configuration, screen_history)
flight_meets_display_criteria, reason_flight_fails_criteria = (
FlightMeetsDisplayCriteria(flight, configuration, log=True))
# Initialize variables for saving in case details not populated by
# later code prior to saving in pickle
flight_aware_error_message = ''
time_flight_message_inserted = 0
time_insight_message_inserted = 0
if flight_meets_display_criteria:
personal_message = None # Any personal message displayed now cleared
flight_message = (
FLAG_MSG_FLIGHT, CreateMessageAboutFlight(flight), flight)
# display the next message about this flight now!
next_message_time = time.time()
message_queue.insert(0, flight_message)
time_flight_message_inserted = time.time()
# and delete any queued insight messages about other flights that have
# not yet displayed, since a newer flight has taken precedence
message_queue = DeleteMessageTypes(message_queue, (FLAG_MSG_INSIGHT,))
# Though we also manage the message queue outside this conditional
# as well, because it can take a half second to generate the flight
# insights, this allows this message to start displaying on the
# board immediately, so it's up there when it's most relevant
<----SKIPPED LINES---->
|
01234567890123456789012345678901234567890123456789012345678901234567890123456789
639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431 64336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524 73347335733673377338733973407341734273437344734573467347734873497350735173527353 73547355735673577358735973607361736273637364736573667367736873697370737173727373 |
<----SKIPPED LINES---->
message_array = message_array[:expected_characters]
message_2d_array = []
for line_num in range(SPLITFLAP_LINE_COUNT):
message_2d_array.append(message_array[
line_num * SPLITFLAP_CHARS_PER_LINE :
(line_num + 1)*SPLITFLAP_CHARS_PER_LINE])
return message_2d_array
def PublishMessageWeb(
s,
subscription_id=SUBSCRIPTION_ID,
key=KEY,
secret=SECRET,
timeout=5):
"""Publishes a text string to a Vestaboard.
The message is pushed to the vestaboard splitflap display by way of its
web services; see https://docs.vestaboard.com/introduction for more details;
if the web service fails, it then reattempts to publish using the local api.
TODO: rewrite to use the easier-to-follow requests library, more in line
with PublishMessageLocal.
Args:
s: String to publish.
subscription_id: string subscription id from Vestaboard.
key: string key from Vestaboard.
secret: string secret from Vestaboard.
timeout: Max duration in seconds that we should wait to establish a
connection.
Returns:
Text string indicating how the message was displayed (web or local
api), and / or any error messages encountered.
"""
error_code = False
curl = pycurl.Curl()
# See https://stackoverflow.com/questions/31826814/
<----SKIPPED LINES---->
# Set URL value
curl.setopt(
pycurl.URL,
'https://platform.vestaboard.com/subscriptions/%s/message'
% 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_failure_message = ''
try:
curl.perform()
status = 'Web service published'
except pycurl.error as e:
timing_message = CurlTimingDetailsToString(curl)
web_failure_message = (
'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_failure_message)
error_code = PublishMessageLocal(s, timeout=timeout, update_dashboard=False)
if not error_code:
status = (
'Local service published (1) because web service failed with %s'
% web_failure_message)
else:
status = (
'Local service failed (2) with %s after web service failed with %s' %
(error_code, web_failure_message))
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_failure_message = (
'Server returned HTTP status code %d for message %s; '
'timing details: %s' % (status_code, s, timing_message))
Log(web_failure_message)
error_code = PublishMessageLocal(
s, timeout=timeout, update_dashboard=False)
if not error_code:
status = (
'Local service published (3) because web service failed with %s'
% web_failure_message)
else:
status = (
'Local service failed (4) with %s after web service failed with %s'
% (error_code, web_failure_message))
# 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_failure_message = ''
curl.close()
UpdateStatusLight(
GPIO_ERROR_VESTABOARD_CONNECTION, error_code, web_failure_message)
return status
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
<----SKIPPED LINES---->
if new_flight_flag:
time_new_flight_found = time.time()
# Since we no longer need the memory-hogging prior persistent_path
# stored on the flights, we can remove it
if flights and 'persistent_path' in flights[-1]:
del flights[-1]['persistent_path']
flights.append(flight)
remote, servo = RefreshArduinos(
remote, servo,
to_remote_q, to_servo_q, to_main_q, shutdown,
flights, json_desc_dict, configuration, screen_history)
flight_meets_display_criteria, reason_flight_fails_criteria = (
FlightMeetsDisplayCriteria(flight, configuration, log=True))
# Initialize variables for saving in case details not populated by
# later code prior to saving in pickle
time_flight_message_inserted = 0
time_insight_message_inserted = 0
if flight_meets_display_criteria:
personal_message = None # Any personal message displayed now cleared
flight_message = (
FLAG_MSG_FLIGHT, CreateMessageAboutFlight(flight), flight)
# display the next message about this flight now!
next_message_time = time.time()
message_queue.insert(0, flight_message)
time_flight_message_inserted = time.time()
# and delete any queued insight messages about other flights that have
# not yet displayed, since a newer flight has taken precedence
message_queue = DeleteMessageTypes(message_queue, (FLAG_MSG_INSIGHT,))
# Though we also manage the message queue outside this conditional
# as well, because it can take a half second to generate the flight
# insights, this allows this message to start displaying on the
# board immediately, so it's up there when it's most relevant
<----SKIPPED LINES---->
|