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----> |