01234567890123456789012345678901234567890123456789012345678901234567890123456789
152153154155156157158159160161162163164165166167168169170171 172173174175176177178179180181182183184185186187188189190191 255256257258259260261262263264265266267268269270271272273274 275276277278279280281282283284285286287288289290291292293294 359360361362363364365366367368369370371372373374375376377378 379380381382383384385386387388389390391392393394395396397398 11301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158 1159116011611162 11631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188 25322533253425352536253725382539254025412542254325442545254625472548254925502551 25522553255425552556255725582559256025612562256325642565256625672568256925702571 60496050605160526053605460556056605760586059606060616062606360646065606660676068 606960706071607260736074607560766077607860796080608160826083608460856086608760886089 | <----SKIPPED LINES----> # by hour throughout the day, over the last seven days, normalized to # flights per day. This allows those parameters to be fine-tuned in a # useful way. This file is the location, on the webserver, of that image, # which needs to be in alignment with the html page that displays it. HOURLY_IMAGE_FILE = 'hours.png' # This is all messages that have been sent to the board since the last time # the file was manually cleared. Newest messages are at the bottom. It is # visible at the webserver. #enumeration of all messages sent to board ALL_MESSAGE_FILE = 'secure/all_messages.txt' # This shows the most recent n messages sent to the board. Newest messages # are at the top for easier viewing of "what did I miss". ROLLING_MESSAGE_FILE = 'rolling_messages.txt' STDERR_FILE = 'secure/stderr.txt' BACKUP_FILE = 'secure/backup.txt' SERVICE_VERIFICATION_FILE = 'secure/service-verification.txt' UPTIMES_FILE = 'uptimes.php' CODE_HISTORY_FILE = 'code_history.php' FLAG_MSG_FLIGHT = 1 # basic flight details FLAG_MSG_INSIGHT = 2 # random tidbit about a flight FLAG_MSG_HISTOGRAM = 3 # histogram message FLAG_MSG_CLEAR = 4 # a blank message to clear the screen # user-entered message to display for some duration of time FLAG_MSG_PERSONAL = 5 FLAG_INSIGHT_LAST_SEEN = 0 FLAG_INSIGHT_DIFF_AIRCRAFT = 1 FLAG_INSIGHT_NTH_FLIGHT = 2 FLAG_INSIGHT_GROUNDSPEED = 3 FLAG_INSIGHT_ALTITUDE = 4 FLAG_INSIGHT_VERTRATE = 5 FLAG_INSIGHT_FIRST_DEST = 6 FLAG_INSIGHT_FIRST_ORIGIN = 7 FLAG_INSIGHT_FIRST_AIRLINE = 8 FLAG_INSIGHT_FIRST_AIRCRAFT = 9 FLAG_INSIGHT_LONGEST_DELAY = 10 FLAG_INSIGHT_FLIGHT_DELAY_FREQUENCY = 11 <----SKIPPED LINES----> #if running on raspberry, then need to prepend path to file names if RASPBERRY_PI: PICKLE_FLIGHTS = MESSAGEBOARD_PATH + PICKLE_FLIGHTS PICKLE_DASHBOARD = MESSAGEBOARD_PATH + PICKLE_DASHBOARD LOGFILE = MESSAGEBOARD_PATH + LOGFILE PICKLE_DUMP_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_DUMP_JSON_FILE PICKLE_FA_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_FA_JSON_FILE PICKLE_SCREENS = MESSAGEBOARD_PATH + PICKLE_SCREENS CODE_REPOSITORY = MESSAGEBOARD_PATH HISTOGRAM_CONFIG_FILE = WEBSERVER_PATH + HISTOGRAM_CONFIG_FILE CONFIG_FILE = WEBSERVER_PATH + CONFIG_FILE ROLLING_MESSAGE_FILE = WEBSERVER_PATH + ROLLING_MESSAGE_FILE ALL_MESSAGE_FILE = WEBSERVER_PATH + ALL_MESSAGE_FILE ROLLING_LOGFILE = WEBSERVER_PATH + ROLLING_LOGFILE STDERR_FILE = WEBSERVER_PATH + STDERR_FILE BACKUP_FILE = WEBSERVER_PATH + BACKUP_FILE SERVICE_VERIFICATION_FILE = WEBSERVER_PATH + SERVICE_VERIFICATION_FILE UPTIMES_FILE = WEBSERVER_PATH + UPTIMES_FILE CODE_HISTORY_FILE = WEBSERVER_PATH + CODE_HISTORY_FILE HISTOGRAM_IMAGE_HTML = WEBSERVER_PATH + HISTOGRAM_IMAGE_HTML HOURLY_IMAGE_FILE = ( WEBSERVER_PATH + WEBSERVER_IMAGE_RELATIVE_FOLDER + HOURLY_IMAGE_FILE) VERSION_REPOSITORY = WEBSERVER_PATH + VERSION_REPOSITORY TIMEZONE = 'US/Pacific' # timezone of display TZ = pytz.timezone(TIMEZONE) # iata codes that we don't need to expand KNOWN_AIRPORTS = ('SJC', 'SFO', 'OAK') SPLITFLAP_CHARS_PER_LINE = 22 SPLITFLAP_LINE_COUNT = 6 DIRECTIONS_4 = ['N', 'E', 'S', 'W'] DIRECTIONS_8 = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'] DIRECTIONS_16 = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] <----SKIPPED LINES----> AIRCRAFT_LENGTH['Bombardier Challenger 300 (twin-jet)'] = 20.92 AIRCRAFT_LENGTH['Bombardier Global Express (twin-jet)'] = (29.5 + 30.3) / 2 AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-200 (twin-jet)'] = 26.77 AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-700 (twin-jet)'] = 32.3 AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-900 (twin-jet)'] = 36.2 AIRCRAFT_LENGTH['Canadair Challenger (twin-jet)'] = 20.9 AIRCRAFT_LENGTH['Canadair Challenger 350 (twin-jet)'] = 20.9 AIRCRAFT_LENGTH['Cessna Caravan (single-turboprop)'] = 11.46 AIRCRAFT_LENGTH['Cessna Citation CJ2+ (twin-jet)'] = 14.53 AIRCRAFT_LENGTH['Cessna Citation CJ3 (twin-jet)'] = 15.59 AIRCRAFT_LENGTH['Cessna Citation Excel/XLS (twin-jet)'] = 16.0 AIRCRAFT_LENGTH['Cessna Citation II (twin-jet)'] = 14.54 AIRCRAFT_LENGTH['Cessna Citation Latitude (twin-jet)'] = 18.97 AIRCRAFT_LENGTH['Cessna Citation Sovereign (twin-jet)'] = 19.35 AIRCRAFT_LENGTH['Cessna Citation V (twin-jet)'] = 14.91 AIRCRAFT_LENGTH['Cessna Citation X (twin-jet)'] = 22.04 AIRCRAFT_LENGTH['Cessna Citation Mustang (twin-jet)'] = 12.37 AIRCRAFT_LENGTH['Cessna Skyhawk (piston-single)'] = 8.28 AIRCRAFT_LENGTH['Cessna Skylane (piston-single)'] = 8.84 AIRCRAFT_LENGTH['Cessna T206 Turbo Stationair (piston-single)'] = 8.61 AIRCRAFT_LENGTH['Dassault Falcon 900 (tri-jet)'] = 20.21 AIRCRAFT_LENGTH['Embraer 170/175 (twin-jet)'] = (29.90 + 31.68) / 2 AIRCRAFT_LENGTH['Embraer Phenom 300 (twin-jet)'] = 15.9 AIRCRAFT_LENGTH['EMBRAER 175 (long wing) (twin-jet)'] = 31.68 AIRCRAFT_LENGTH['Embraer ERJ-135 (twin-jet)'] = 26.33 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G550 (twin-jet)'] = 29.39 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream IV (twin-jet)'] = 26.92 AIRCRAFT_LENGTH['Learjet 45 (twin-jet)'] = 17.68 AIRCRAFT_LENGTH['McDonnell Douglas MD-11 (tri-jet)'] = 61.6 AIRCRAFT_LENGTH['Pilatus PC-12 (single-turboprop)'] = 14.4 def Log(message, file=None, rolling=None): """Write a message to a logfile along with a timestamp. Args: message: string message to write file: string representing file name and, if needed, path to the file to write to rolling: name of file that will keep only the last n files of file <----SKIPPED LINES----> if v.isdigit(): v = int(v) else: try: v = float(v) except ValueError: pass settings_dict[k] = v return settings_dict def RemoveSetting(configuration, setting): """Removes the named setting from the configuration file.""" configuration.pop(setting) configuration = BuildSettings(configuration) WriteFile(CONFIG_FILE, configuration) return configuration def WriteFile(filename, text, log_exception=False): """Writes the text to the file, returning boolean indicating success. Args: filename: string of the filename to open, potentially also including the full path. text: the text to write log_exception: boolean indicating whether to log an exception if file not found. Returns: Boolean indicating whether the write was successful. """ try: with open(filename, 'w') as content_file: content_file.write(text) except IOError: if log_exception: Log('Unable to write to '+filename) return False return True def PrependFileName(full_path, prefix): """Converts /dir/file.png to /dir/prefixfile.png.""" directory, file_name = os.path.split(full_path) file_name = prefix+file_name return os.path.join(directory, file_name) def UnpickleObjectFromFile( full_path, date_segmentation, max_days=None, filenames=False, heartbeat=False): """Load a repository of pickled data into memory. Args: <----SKIPPED LINES----> last_seen = [ f for f in flights[:-1] if DisplayFlightNumber(f) == this_flight_number] # Last time this same flight flew a materially different type of aircraft if last_seen and 'flight_number' in this_flight: last_flight = last_seen[-1] last_aircraft = last_flight.get('aircraft_type_friendly') last_aircraft_length = AIRCRAFT_LENGTH.get(last_aircraft, 0) this_aircraft = this_flight.get('aircraft_type_friendly') this_aircraft_length = AIRCRAFT_LENGTH.get(this_aircraft, 0) this_likely_commercial_flight = ( this_flight.get('origin_iata') and this_flight.get('destination_iata')) if (this_likely_commercial_flight and this_aircraft and not this_aircraft_length): Log('%s used in a flight with defined origin & destination but yet is ' 'missing length details' % this_aircraft, file=LOGFILE) likely_same_commercial_flight = ( last_flight.get('origin_iata') == this_flight.get('origin_iata') and last_flight.get( 'destination_iata') == this_flight.get('destination_iata') and last_flight.get( 'airline_call_sign') == this_flight.get('airline_call_sign')) this_aircraft_bigger = False last_aircraft_bigger = False if (likely_same_commercial_flight and this_aircraft_length > last_aircraft_length * ( 1 + percent_size_difference)): this_aircraft_bigger = True comparative_text = 'larger' elif (likely_same_commercial_flight and last_aircraft_length > this_aircraft_length * ( 1 + percent_size_difference)): last_aircraft_bigger = True comparative_text = 'smaller' <----SKIPPED LINES----> flights = UnpickleObjectFromFile(f, False) for (n, flight) in enumerate(flights): if n/25 == int(n/25): print(' - %d' % n) CreateFlightInsights( flights[:n+1], configuration.get('insights', 'hide'), {}) PickleObjectToFile(flight, tmp_f, False) if mtime == os.path.getmtime(f): shutil.move(tmp_f, f) else: print('Aborted: failed to bootstrap %s: file changed while in process' % full_path) return def ResetLogs(config): """Clears the non-scrolling logs if reset_logs in config.""" if 'reset_logs' in config: Log('Reset logs') for f in (STDERR_FILE, BACKUP_FILE, SERVICE_VERIFICATION_FILE): if RemoveFile(f): open(f, 'a').close() config.pop('reset_logs') config = BuildSettings(config) WriteFile(CONFIG_FILE, config) return config def CheckTemperature(): """Turn on fan if temperature exceeds threshold.""" if RASPBERRY_PI: temperature = gpiozero.CPUTemperature().temperature if temperature > TEMP_FAN_TURN_ON_CELSIUS: UpdateStatusLight(GPIO_FAN, True, 'Temperature: %.1f' % temperature) elif temperature < TEMP_FAN_TURN_OFF_CELSIUS: UpdateStatusLight(GPIO_FAN, False) pin_values = {} # caches last set value def SetPinMode(): <----SKIPPED LINES----> |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 1135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198 25422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582 606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101 | <----SKIPPED LINES----> # by hour throughout the day, over the last seven days, normalized to # flights per day. This allows those parameters to be fine-tuned in a # useful way. This file is the location, on the webserver, of that image, # which needs to be in alignment with the html page that displays it. HOURLY_IMAGE_FILE = 'hours.png' # This is all messages that have been sent to the board since the last time # the file was manually cleared. Newest messages are at the bottom. It is # visible at the webserver. #enumeration of all messages sent to board ALL_MESSAGE_FILE = 'secure/all_messages.txt' # This shows the most recent n messages sent to the board. Newest messages # are at the top for easier viewing of "what did I miss". ROLLING_MESSAGE_FILE = 'rolling_messages.txt' STDERR_FILE = 'secure/stderr.txt' BACKUP_FILE = 'secure/backup.txt' SERVICE_VERIFICATION_FILE = 'secure/service-verification.txt' UPTIMES_FILE = 'uptimes.php' CODE_HISTORY_FILE = 'code_history.php' # This keeps a log of all aircraft not yet cataloged in the AIRCRAFT_LENGTH dict NEW_AIRCRAFT_FILE = 'secure/new_aircraft.txt' FLAG_MSG_FLIGHT = 1 # basic flight details FLAG_MSG_INSIGHT = 2 # random tidbit about a flight FLAG_MSG_HISTOGRAM = 3 # histogram message FLAG_MSG_CLEAR = 4 # a blank message to clear the screen # user-entered message to display for some duration of time FLAG_MSG_PERSONAL = 5 FLAG_INSIGHT_LAST_SEEN = 0 FLAG_INSIGHT_DIFF_AIRCRAFT = 1 FLAG_INSIGHT_NTH_FLIGHT = 2 FLAG_INSIGHT_GROUNDSPEED = 3 FLAG_INSIGHT_ALTITUDE = 4 FLAG_INSIGHT_VERTRATE = 5 FLAG_INSIGHT_FIRST_DEST = 6 FLAG_INSIGHT_FIRST_ORIGIN = 7 FLAG_INSIGHT_FIRST_AIRLINE = 8 FLAG_INSIGHT_FIRST_AIRCRAFT = 9 FLAG_INSIGHT_LONGEST_DELAY = 10 FLAG_INSIGHT_FLIGHT_DELAY_FREQUENCY = 11 <----SKIPPED LINES----> #if running on raspberry, then need to prepend path to file names if RASPBERRY_PI: PICKLE_FLIGHTS = MESSAGEBOARD_PATH + PICKLE_FLIGHTS PICKLE_DASHBOARD = MESSAGEBOARD_PATH + PICKLE_DASHBOARD LOGFILE = MESSAGEBOARD_PATH + LOGFILE PICKLE_DUMP_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_DUMP_JSON_FILE PICKLE_FA_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_FA_JSON_FILE PICKLE_SCREENS = MESSAGEBOARD_PATH + PICKLE_SCREENS CODE_REPOSITORY = MESSAGEBOARD_PATH HISTOGRAM_CONFIG_FILE = WEBSERVER_PATH + HISTOGRAM_CONFIG_FILE CONFIG_FILE = WEBSERVER_PATH + CONFIG_FILE ROLLING_MESSAGE_FILE = WEBSERVER_PATH + ROLLING_MESSAGE_FILE ALL_MESSAGE_FILE = WEBSERVER_PATH + ALL_MESSAGE_FILE ROLLING_LOGFILE = WEBSERVER_PATH + ROLLING_LOGFILE STDERR_FILE = WEBSERVER_PATH + STDERR_FILE BACKUP_FILE = WEBSERVER_PATH + BACKUP_FILE SERVICE_VERIFICATION_FILE = WEBSERVER_PATH + SERVICE_VERIFICATION_FILE UPTIMES_FILE = WEBSERVER_PATH + UPTIMES_FILE CODE_HISTORY_FILE = WEBSERVER_PATH + CODE_HISTORY_FILE NEW_AIRCRAFT_FILE = WEBSERVER_PATH + NEW_AIRCRAFT_FILE HISTOGRAM_IMAGE_HTML = WEBSERVER_PATH + HISTOGRAM_IMAGE_HTML HOURLY_IMAGE_FILE = ( WEBSERVER_PATH + WEBSERVER_IMAGE_RELATIVE_FOLDER + HOURLY_IMAGE_FILE) VERSION_REPOSITORY = WEBSERVER_PATH + VERSION_REPOSITORY TIMEZONE = 'US/Pacific' # timezone of display TZ = pytz.timezone(TIMEZONE) # iata codes that we don't need to expand KNOWN_AIRPORTS = ('SJC', 'SFO', 'OAK') SPLITFLAP_CHARS_PER_LINE = 22 SPLITFLAP_LINE_COUNT = 6 DIRECTIONS_4 = ['N', 'E', 'S', 'W'] DIRECTIONS_8 = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'] DIRECTIONS_16 = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] <----SKIPPED LINES----> AIRCRAFT_LENGTH['Bombardier Challenger 300 (twin-jet)'] = 20.92 AIRCRAFT_LENGTH['Bombardier Global Express (twin-jet)'] = (29.5 + 30.3) / 2 AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-200 (twin-jet)'] = 26.77 AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-700 (twin-jet)'] = 32.3 AIRCRAFT_LENGTH['Canadair Regional Jet CRJ-900 (twin-jet)'] = 36.2 AIRCRAFT_LENGTH['Canadair Challenger (twin-jet)'] = 20.9 AIRCRAFT_LENGTH['Canadair Challenger 350 (twin-jet)'] = 20.9 AIRCRAFT_LENGTH['Cessna Caravan (single-turboprop)'] = 11.46 AIRCRAFT_LENGTH['Cessna Citation CJ2+ (twin-jet)'] = 14.53 AIRCRAFT_LENGTH['Cessna Citation CJ3 (twin-jet)'] = 15.59 AIRCRAFT_LENGTH['Cessna Citation Excel/XLS (twin-jet)'] = 16.0 AIRCRAFT_LENGTH['Cessna Citation II (twin-jet)'] = 14.54 AIRCRAFT_LENGTH['Cessna Citation Latitude (twin-jet)'] = 18.97 AIRCRAFT_LENGTH['Cessna Citation Sovereign (twin-jet)'] = 19.35 AIRCRAFT_LENGTH['Cessna Citation V (twin-jet)'] = 14.91 AIRCRAFT_LENGTH['Cessna Citation X (twin-jet)'] = 22.04 AIRCRAFT_LENGTH['Cessna Citation Mustang (twin-jet)'] = 12.37 AIRCRAFT_LENGTH['Cessna Skyhawk (piston-single)'] = 8.28 AIRCRAFT_LENGTH['Cessna Skylane (piston-single)'] = 8.84 AIRCRAFT_LENGTH['Cessna T206 Turbo Stationair (piston-single)'] = 8.61 AIRCRAFT_LENGTH['Cirrus SR-22 (piston-single)'] = 7.92 AIRCRAFT_LENGTH['Dassault Falcon 900 (tri-jet)'] = 20.21 AIRCRAFT_LENGTH['Embraer 170/175 (twin-jet)'] = (29.90 + 31.68) / 2 AIRCRAFT_LENGTH['Embraer Phenom 300 (twin-jet)'] = 15.9 AIRCRAFT_LENGTH['EMBRAER 175 (long wing) (twin-jet)'] = 31.68 AIRCRAFT_LENGTH['Embraer ERJ-135 (twin-jet)'] = 26.33 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G550 (twin-jet)'] = 29.39 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream IV (twin-jet)'] = 26.92 AIRCRAFT_LENGTH['Learjet 45 (twin-jet)'] = 17.68 AIRCRAFT_LENGTH['McDonnell Douglas MD-11 (tri-jet)'] = 61.6 AIRCRAFT_LENGTH['Pilatus PC-12 (single-turboprop)'] = 14.4 def Log(message, file=None, rolling=None): """Write a message to a logfile along with a timestamp. Args: message: string message to write file: string representing file name and, if needed, path to the file to write to rolling: name of file that will keep only the last n files of file <----SKIPPED LINES----> if v.isdigit(): v = int(v) else: try: v = float(v) except ValueError: pass settings_dict[k] = v return settings_dict def RemoveSetting(configuration, setting): """Removes the named setting from the configuration file.""" configuration.pop(setting) configuration = BuildSettings(configuration) WriteFile(CONFIG_FILE, configuration) return configuration def WriteFile(filename, text, log_exception=False, append=False): """Writes the text to the file, returning boolean indicating success. Args: filename: string of the filename to open, potentially also including the full path. text: the text to write log_exception: boolean indicating whether to log an exception on IOError. append: boolean indicating whether to append. True indicates we should append; False indicates we should write. Returns: Boolean indicating whether the write was successful. """ file_mode = 'w' if append: file_mode = 'a' text += '\n' try: with open(filename, file_mode) as content_file: content_file.write(text) except IOError: if log_exception: Log('Unable to write or append to %s' % filename) return False return True def PrependFileName(full_path, prefix): """Converts /dir/file.png to /dir/prefixfile.png.""" directory, file_name = os.path.split(full_path) file_name = prefix+file_name return os.path.join(directory, file_name) def UnpickleObjectFromFile( full_path, date_segmentation, max_days=None, filenames=False, heartbeat=False): """Load a repository of pickled data into memory. Args: <----SKIPPED LINES----> last_seen = [ f for f in flights[:-1] if DisplayFlightNumber(f) == this_flight_number] # Last time this same flight flew a materially different type of aircraft if last_seen and 'flight_number' in this_flight: last_flight = last_seen[-1] last_aircraft = last_flight.get('aircraft_type_friendly') last_aircraft_length = AIRCRAFT_LENGTH.get(last_aircraft, 0) this_aircraft = this_flight.get('aircraft_type_friendly') this_aircraft_length = AIRCRAFT_LENGTH.get(this_aircraft, 0) this_likely_commercial_flight = ( this_flight.get('origin_iata') and this_flight.get('destination_iata')) if (this_likely_commercial_flight and this_aircraft and not this_aircraft_length): Log('%s used in a flight with defined origin & destination but yet is ' 'missing length details' % this_aircraft, file=LOGFILE) WriteFile(NEW_AIRCRAFT_FILE, this_aircraft, append=True) likely_same_commercial_flight = ( last_flight.get('origin_iata') == this_flight.get('origin_iata') and last_flight.get( 'destination_iata') == this_flight.get('destination_iata') and last_flight.get( 'airline_call_sign') == this_flight.get('airline_call_sign')) this_aircraft_bigger = False last_aircraft_bigger = False if (likely_same_commercial_flight and this_aircraft_length > last_aircraft_length * ( 1 + percent_size_difference)): this_aircraft_bigger = True comparative_text = 'larger' elif (likely_same_commercial_flight and last_aircraft_length > this_aircraft_length * ( 1 + percent_size_difference)): last_aircraft_bigger = True comparative_text = 'smaller' <----SKIPPED LINES----> flights = UnpickleObjectFromFile(f, False) for (n, flight) in enumerate(flights): if n/25 == int(n/25): print(' - %d' % n) CreateFlightInsights( flights[:n+1], configuration.get('insights', 'hide'), {}) PickleObjectToFile(flight, tmp_f, False) if mtime == os.path.getmtime(f): shutil.move(tmp_f, f) else: print('Aborted: failed to bootstrap %s: file changed while in process' % full_path) return def ResetLogs(config): """Clears the non-scrolling logs if reset_logs in config.""" if 'reset_logs' in config: Log('Reset logs') for f in ( STDERR_FILE, BACKUP_FILE, SERVICE_VERIFICATION_FILE, NEW_AIRCRAFT_FILE): if RemoveFile(f): open(f, 'a').close() config.pop('reset_logs') config = BuildSettings(config) WriteFile(CONFIG_FILE, config) return config def CheckTemperature(): """Turn on fan if temperature exceeds threshold.""" if RASPBERRY_PI: temperature = gpiozero.CPUTemperature().temperature if temperature > TEMP_FAN_TURN_ON_CELSIUS: UpdateStatusLight(GPIO_FAN, True, 'Temperature: %.1f' % temperature) elif temperature < TEMP_FAN_TURN_OFF_CELSIUS: UpdateStatusLight(GPIO_FAN, False) pin_values = {} # caches last set value def SetPinMode(): <----SKIPPED LINES----> |