messageboard-2020-08-05-1634.py
01234567890123456789012345678901234567890123456789012345678901234567890123456789









512851295130513151325133513451355136513751385139514051415142514351445145514651475148  51495150515151525153        515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180








55185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576








56405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680








669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731



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




    # then we need to
    # 1) update the histograms.php file with the correct file links, and
    # 2) delete the images that are now obsolete.
    epoch_string = EpochDisplayTime(time.time(), '%Y%m%d_%H%M%S_')

    ImageHistograms(
        flights,
        histogram_settings['histogram'],
        histogram_settings['histogram_history'],
        filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string,
        heartbeat=heartbeat)
    histogram_id_sequence = [
        'origin', 'destination',
        'day_of_month', 'day_of_week', 'hour',
        'bearing', 'distance', 'speed', 'vert_rate', 'altitude',
        'airline', 'aircraft', 'aircraft_length']
    path = WEBSERVER_PATH + WEBSERVER_IMAGE_RELATIVE_FOLDER
    files = os.listdir(path)
    lines = [
        '<head>',
        '<title>Flight Tracker: Histograms</title>',


        '</head>',
        '<body>',
        '<?php include "nav.html" ?>',
        '<div class="resp-iframe">'
    ]








    for histogram_id in histogram_id_sequence:
      pattern = re.compile('histogram[0-9_]*%s.png' % histogram_id)
      matching_files = sorted(
          [f for f in files if pattern.match(f)])
      # save the most recent; delete the others
      lines.append('<img id="%s" src="images/%s"><p>' % (
          histogram_id, matching_files[-1]))
      for f in matching_files[:-1]:
        RemoveFile(
            os.path.join(WEBSERVER_PATH, WEBSERVER_IMAGE_RELATIVE_FOLDER, f))

    lines.extend(['</div>', '</body>'])
    html = '\n'.join(lines)
    WriteFile(HISTOGRAM_IMAGE_HTML, html)

  return histogram_messages


def SaveFlightsByAltitudeDistanceCSV(
    flights,
    max_days=0,
    filename='flights_by_alt_dist.csv',
    precision=100):
  """Generates CSV of hour of day, altitude, and distance.

  Generates a csv with 26 columns:
  - col#1: altitude (in feet)




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





  RPi.GPIO.output(GPIO_SOFT_RESET[1], False)  # signal that reset received
  Log(msg)


def InterruptShutdownFromSignal(signalNumber, unused_frame):
  """Sets flag so main loop will terminate when it completes the iteration.

  The function signature is defined by the python language - i.e.: these two
  variables are passed automatically for registered signals.  This function is
  only triggered by an interrupt signal.
  """
  msg = '%d received termination signal %d (%s)' % (
      os.getpid(), signalNumber,
      signal.Signals(signalNumber).name)  # pylint: disable=E1101
  global SHUTDOWN_SIGNAL
  SHUTDOWN_SIGNAL = msg
  Log(msg)


def PerformGracefulShutdown(queues, shutdown, reboot):
  """Complete the graceful shutdown process by cleaning up.

  Args:
    queues: iterable of queues shared with child processes to be closed
    shutdown: tuple of shared flags with child processes to initiate shutdown
      in children
    reboot: boolean indicating whether we should trigger a reboot
  """
  reboot_msg = ''
  if reboot:
    reboot_msg = ' and rebooting'
  Log('Shutting down self (%d)%s' % (os.getpid(), reboot_msg))

  # TODO: the q.close() may have been blocking some of the shutdowns, since
  # it is blocking until the queue is fully drained. Let's see if we have
  # fewer problems without this code.
  #for q in queues:
  #  q.close()

  for v in shutdown:  # send the shutdown signal to child processes
    v.value = 1
  if RASPBERRY_PI:
    RPi.GPIO.cleanup()

  UpdateDashboard(True, failure_message=SHUTDOWN_SIGNAL)

  if reboot or REBOOT_SIGNAL:
    time.sleep(10)  # wait 10 seconds for children to shut down as well
    os.system('sudo reboot')
  sys.exit()


def FindRunningParents():
  """Returns proc ids of processes with identically-named python file running.

  In case there are multiple children processes spawned with the same name,
  such as via multiprocessing, this will only return the parent id (since a
  killed child process will likely just be respawned).




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




    # with process IDs 1106 & 1110.
    if SHUTDOWN_SIGNAL:
      Log('Race condition? Though this process %s is just in startup, '
          'SHUTDOWN_SIGNAL has already been set to True\n'
          'already_running_ids (PIDs detected when process started up): %s\n'
          'still_running_ids (PIDs detected at start of function call): %s\n'
          '\nProcess shutting down' %
          (str(os.getpid()), already_running_ids, still_running_ids))
      sys.exit()

    n = 0
    running_parents = FindRunningParents()
    while running_parents:

      if n == max_seconds:
        Log('Kill signal sent from this process %d to %s, but %s still '
            'running after waiting cume %d seconds; rebooting' % (
                os.getpid(),
                str(already_running_ids),
                str(running_parents), n+1))
        PerformGracefulShutdown((), (), True)
      if not n % 3:
        Log('Kill signal sent from this process %d to %s, but %s still '
            'running after waiting cume %d seconds' % (
                os.getpid(), str(already_running_ids), str(running_parents), n))
      n += 1
      time.sleep(1)
      running_parents = FindRunningParents()


def InitArduinoVariables():
  """Initializes variables for arduino threads with shared-memory queues."""
  to_remote_q = multiprocessing.Queue()
  to_servo_q = multiprocessing.Queue()
  to_main_q = multiprocessing.Queue()
  # shared flags to initiate shutdown
  shutdown_remote = multiprocessing.Value('i')
  shutdown_servo = multiprocessing.Value('i')
  shutdown = (shutdown_remote, shutdown_servo)

  return (to_remote_q, to_servo_q, to_main_q, shutdown)




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





    # check time & if appropriate, display next message from queue
    next_message_time = ManageMessageQueue(
        message_queue, next_message_time, configuration, screen_history)

    reboot = CheckRebootNeeded(
        startup_time, message_queue, json_desc_dict, configuration)

    CheckTemperature()

    if not SIMULATION:
      time.sleep(max(0, next_loop_time - time.time()))
      next_loop_time = time.time() + LOOP_DELAY_SECONDS
    else:
      SIMULATION_COUNTER += 1
      if simulation_slowdown:
        SimulationSlowdownNearFlight(flights, persistent_nearby_aircraft)

  if SIMULATION:
    SimulationEnd(message_queue, flights, screen_history)
  PerformGracefulShutdown(
      (to_remote_q, to_servo_q, to_main_q), shutdown, reboot)


if __name__ == "__main__":
  #interrupt, as in ctrl-c
  signal.signal(signal.SIGINT, InterruptShutdownFromSignal)

  #terminate, when another instance found or via kill
  signal.signal(signal.SIGTERM, InterruptShutdownFromSignal)

  if '-i' in sys.argv:
    BootstrapInsightList()
  else:
    main_settings = ReadAndParseSettings(CONFIG_FILE)
    if 'code_profiling_enabled' in main_settings:
      import cProfile
      cProfile.run(
          'main()', 'messageboard_stats-%s.profile' %
          EpochDisplayTime(time.time(), '%Y-%m-%d-%H%M'))
    else:
      main()

01234567890123456789012345678901234567890123456789012345678901234567890123456789









512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190








552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551 55525553555455555556555755585559      55605561556255635564556555665567556855695570557155725573557455755576557755785579








56435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683








669366946695669666976698669967006701670267036704670567066707670867096710671167126713 67146715671667176718671967206721672267236724672567266727672867296730673167326733



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




    # then we need to
    # 1) update the histograms.php file with the correct file links, and
    # 2) delete the images that are now obsolete.
    epoch_string = EpochDisplayTime(time.time(), '%Y%m%d_%H%M%S_')

    ImageHistograms(
        flights,
        histogram_settings['histogram'],
        histogram_settings['histogram_history'],
        filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string,
        heartbeat=heartbeat)
    histogram_id_sequence = [
        'origin', 'destination',
        'day_of_month', 'day_of_week', 'hour',
        'bearing', 'distance', 'speed', 'vert_rate', 'altitude',
        'airline', 'aircraft', 'aircraft_length']
    path = WEBSERVER_PATH + WEBSERVER_IMAGE_RELATIVE_FOLDER
    files = os.listdir(path)
    lines = [
        '<head>',
        '  <title>Flight Tracker: Histograms</title>',
        '  <meta content="text/html; charset=UTF-8" http-equiv="content-type">',
        '  <meta name="viewport" content="width=device-width,initial-scale=1">',
        '</head>',
        '<body>',
        '<?php include "nav.html" ?>',
        '<div class="resp-iframe">'
    ]
    open_image = (
        '<div class="content-cap-holder">\n'
        '  <div class="image-box"'
        'style="max-width:900px;min-width:300px;width:100%;">\n'
        '    <figure>\n')
    close_image = ('</figure>\n'
                   '  </div>\n'
                   '    </div>\n')
    for histogram_id in histogram_id_sequence:
      pattern = re.compile('histogram[0-9_]*%s.png' % histogram_id)
      matching_files = sorted(
          [f for f in files if pattern.match(f)])
      # save the most recent; delete the others
      lines.append('%s<img id="%s" src="images/%s">%s' % (
          open_image, histogram_id, matching_files[-1], close_image))
      for f in matching_files[:-1]:
        RemoveFile(
            os.path.join(WEBSERVER_PATH, WEBSERVER_IMAGE_RELATIVE_FOLDER, f))

    lines.extend(['</div>', '</body>'])
    html = '\n'.join(lines)
    WriteFile(HISTOGRAM_IMAGE_HTML, html)

  return histogram_messages


def SaveFlightsByAltitudeDistanceCSV(
    flights,
    max_days=0,
    filename='flights_by_alt_dist.csv',
    precision=100):
  """Generates CSV of hour of day, altitude, and distance.

  Generates a csv with 26 columns:
  - col#1: altitude (in feet)




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





  RPi.GPIO.output(GPIO_SOFT_RESET[1], False)  # signal that reset received
  Log(msg)


def InterruptShutdownFromSignal(signalNumber, unused_frame):
  """Sets flag so main loop will terminate when it completes the iteration.

  The function signature is defined by the python language - i.e.: these two
  variables are passed automatically for registered signals.  This function is
  only triggered by an interrupt signal.
  """
  msg = '%d received termination signal %d (%s)' % (
      os.getpid(), signalNumber,
      signal.Signals(signalNumber).name)  # pylint: disable=E1101
  global SHUTDOWN_SIGNAL
  SHUTDOWN_SIGNAL = msg
  Log(msg)


def PerformGracefulShutdown(shutdown, reboot):
  """Complete the graceful shutdown process by cleaning up.

  Args:

    shutdown: tuple of shared flags with child processes to initiate shutdown
      in children
    reboot: boolean indicating whether we should trigger a reboot
  """
  reboot_msg = ''
  if reboot:
    reboot_msg = ' and rebooting'
  Log('Shutting down self (%d)%s' % (os.getpid(), reboot_msg))







  for v in shutdown:  # send the shutdown signal to child processes
    v.value = 1
  if RASPBERRY_PI:
    RPi.GPIO.cleanup()

  UpdateDashboard(True, failure_message=SHUTDOWN_SIGNAL)

  if reboot or REBOOT_SIGNAL:
    time.sleep(10)  # wait 10 seconds for children to shut down as well
    os.system('sudo reboot')
  sys.exit()


def FindRunningParents():
  """Returns proc ids of processes with identically-named python file running.

  In case there are multiple children processes spawned with the same name,
  such as via multiprocessing, this will only return the parent id (since a
  killed child process will likely just be respawned).




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




    # with process IDs 1106 & 1110.
    if SHUTDOWN_SIGNAL:
      Log('Race condition? Though this process %s is just in startup, '
          'SHUTDOWN_SIGNAL has already been set to True\n'
          'already_running_ids (PIDs detected when process started up): %s\n'
          'still_running_ids (PIDs detected at start of function call): %s\n'
          '\nProcess shutting down' %
          (str(os.getpid()), already_running_ids, still_running_ids))
      sys.exit()

    n = 0
    running_parents = FindRunningParents()
    while running_parents:

      if n == max_seconds:
        Log('Kill signal sent from this process %d to %s, but %s still '
            'running after waiting cume %d seconds; rebooting' % (
                os.getpid(),
                str(already_running_ids),
                str(running_parents), n+1))
        PerformGracefulShutdown((), True)
      if not n % 3:
        Log('Kill signal sent from this process %d to %s, but %s still '
            'running after waiting cume %d seconds' % (
                os.getpid(), str(already_running_ids), str(running_parents), n))
      n += 1
      time.sleep(1)
      running_parents = FindRunningParents()


def InitArduinoVariables():
  """Initializes variables for arduino threads with shared-memory queues."""
  to_remote_q = multiprocessing.Queue()
  to_servo_q = multiprocessing.Queue()
  to_main_q = multiprocessing.Queue()
  # shared flags to initiate shutdown
  shutdown_remote = multiprocessing.Value('i')
  shutdown_servo = multiprocessing.Value('i')
  shutdown = (shutdown_remote, shutdown_servo)

  return (to_remote_q, to_servo_q, to_main_q, shutdown)




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





    # check time & if appropriate, display next message from queue
    next_message_time = ManageMessageQueue(
        message_queue, next_message_time, configuration, screen_history)

    reboot = CheckRebootNeeded(
        startup_time, message_queue, json_desc_dict, configuration)

    CheckTemperature()

    if not SIMULATION:
      time.sleep(max(0, next_loop_time - time.time()))
      next_loop_time = time.time() + LOOP_DELAY_SECONDS
    else:
      SIMULATION_COUNTER += 1
      if simulation_slowdown:
        SimulationSlowdownNearFlight(flights, persistent_nearby_aircraft)

  if SIMULATION:
    SimulationEnd(message_queue, flights, screen_history)
  PerformGracefulShutdown(shutdown, reboot)



if __name__ == "__main__":
  #interrupt, as in ctrl-c
  signal.signal(signal.SIGINT, InterruptShutdownFromSignal)

  #terminate, when another instance found or via kill
  signal.signal(signal.SIGTERM, InterruptShutdownFromSignal)

  if '-i' in sys.argv:
    BootstrapInsightList()
  else:
    main_settings = ReadAndParseSettings(CONFIG_FILE)
    if 'code_profiling_enabled' in main_settings:
      import cProfile
      cProfile.run(
          'main()', 'messageboard_stats-%s.profile' %
          EpochDisplayTime(time.time(), '%Y-%m-%d-%H%M'))
    else:
      main()