# Main script import logging import os import signal import sys from datetime import datetime from time import sleep import importlib import psutil import pytz from diskcache import Cache from core.cleanup import CleanupTimer from core.config import config, MAX_SPOT_AGE, WEB_SERVER_PORT, SERVER_OWNER_CALLSIGN from core.constants import SOFTWARE_VERSION from core.utils import QRZ_CALLSIGN_DATA_CACHE from server.webserver import WebServer # Globals spots = Cache('.spots_cache') status_data = {} providers = [] cleanup_timer = None run = True # Shutdown function def shutdown(sig, frame): logging.info("Stopping program, this may take a few seconds...") global run run = False for p in providers: if p.enabled: p.stop() cleanup_timer.stop() QRZ_CALLSIGN_DATA_CACHE.close() spots.close() # Utility method to get a data provider based on the class specified in its config entry. def get_provider_from_config(config_providers_entry): module = importlib.import_module('providers.' + config_providers_entry["class"].lower()) provider_class = getattr(module, config_providers_entry["class"]) return provider_class(config_providers_entry) # Main function if __name__ == '__main__': # Set up logging root = logging.getLogger() root.setLevel(logging.INFO) handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.INFO) formatter = logging.Formatter("%(message)s") handler.setFormatter(formatter) root.addHandler(handler) logging.info("Starting...") startup_time = datetime.now(pytz.UTC) status_data["software-version"] = SOFTWARE_VERSION status_data["server-owner-callsign"] = SERVER_OWNER_CALLSIGN # Shut down gracefully on SIGINT signal.signal(signal.SIGINT, shutdown) for entry in config["providers"]: providers.append(get_provider_from_config(entry)) # Set up data providers for p in providers: p.setup(spots=spots) # Start data providers for p in providers: if p.enabled: p.start() # Set up timer to clear spot list of old data cleanup_timer = CleanupTimer(spots=spots, cleanup_interval=60) cleanup_timer.start() # Set up web server web_server = WebServer(spots=spots, status_data=status_data, port=WEB_SERVER_PORT) web_server.start() logging.info("Startup complete.") # While running, update the status information at a regular interval while run: sleep(5) status_data["uptime"] = str(datetime.now(pytz.UTC) - startup_time).split(".")[0] status_data["mem_use_mb"] = round(psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024), 3) status_data["num_spots"] = len(spots) status_data["providers"] = list(map(lambda p: {"name": p.name, "enabled": p.enabled, "status": p.status, "last_updated": p.last_update_time, "last_spot": p.last_spot_time}, providers)) status_data["cleanup"] = {"status": cleanup_timer.status, "last_ran": cleanup_timer.last_cleanup_time} status_data["webserver"] = {"status": web_server.status, "last_api_access": web_server.last_api_access_time, "last_page_access": web_server.last_page_access_time}