messageboard-2022-11-24-1603.py
01234567890123456789012345678901234567890123456789012345678901234567890123456789









65496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589








66276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667











                            <----SKIPPED LINES---->




  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:
    Two-tuple:
    - Text string indicating how the message was displayed (web or local
      api), including error messages encountered if any.
    - Status code which is one of the text strings SUCCESS, WARNING, or FAILURE,
      indicating whether the web service was used (SUCCESS), the local service
      was used because the web service failed (WARNING), or both failed
      (FAILURE).
  """
  error_code = False
  curl = pycurl.Curl()

  # See https://stackoverflow.com/questions/31826814/
  # curl-post-request-into-pycurl-code
  # 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)




                            <----SKIPPED LINES---->




          '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_code, local_publish_error_msg = PublishMessageLocal(
          s, timeout=timeout, update_dashboard=False)
      if not local_publish_error_code:
        status_msg = (
            '(3) Web service failed with %s so local service used'
            % web_publish_failure_msg)
        publish_status_code = 'WARNING'
      else:
        status_msg = (
            '(4) Web service failed with %s; '
            'then local service failed with %s' %
            (web_publish_failure_msg, local_publish_error_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.




                            <----SKIPPED LINES---->





01234567890123456789012345678901234567890123456789012345678901234567890123456789









65496550655165526553655465556556655765586559656065616562656365646565656665676568 65696570657165726573657465756576657765786579658065816582658365846585658665876588








66266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666











                            <----SKIPPED LINES---->




  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:
    Two-tuple:
    - Text string indicating how the message was displayed (web or local
      api), including error messages encountered if any.
    - Status code which is one of the text strings SUCCESS, WARNING, or FAILURE,
      indicating whether the web service was used (SUCCESS), the local service
      was used because the web service failed (WARNING), or both failed
      (FAILURE).
  """

  curl = pycurl.Curl()

  # See https://stackoverflow.com/questions/31826814/
  # curl-post-request-into-pycurl-code
  # 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)




                            <----SKIPPED LINES---->




          '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_code, local_publish_error_msg = PublishMessageLocal(
          s, timeout=timeout, update_dashboard=False)
      if not local_publish_error_code:
        status_msg = (
            '(3) Web service failed with %s so local service used'
            % web_publish_failure_msg)
        publish_status_code = 'WARNING'
      else:
        status_msg = (
            '(4) Web service failed with %s; '
            'then local service failed with %s' %
            (web_publish_failure_msg, local_publish_error_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 publish_status_code != 'FAILURE':
    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.




                            <----SKIPPED LINES---->