"""Common classes and functions. Attributes: settings (Settings): Program settings. """ import os import sys import json import time import logging import logging.handlers import datetime settings = None class Settings(object): """ Class representing all program settings. Attributes: apps (lst(AppConfig)): Apps listed in settings.json. languages (lst(Language)): Languages listed in json. settings_data (dict): All settings data listed in json. """ def __init__(self, apps, languages, settings_data): self.apps = apps self.languages = languages self.settings_data = settings_data def get_tracked_apps(self): return [self.apps[appid] for appid in self.apps if self.apps[appid].track] def get_tracked_languages(self): return [self.languages[lang_key] for lang_key in self.languages if self.languages[lang_key].track] def get(self, key, default=None): return self.settings_data.get(key, default) def __getitem__(self, key): return self.settings_data[key] class AppConfig(object): """ Class representing steam app data. Attributes: appid (int): App/Game id. track (bool): App track. ignore_zero_players (bool): Ignore zero players. stopwords (lst(str)): App wordcloud stopwords. """ def __init__(self, appid, track, ignore_zero_players, stopwords): self.appid = appid self.track = track self.ignore_zero_players = ignore_zero_players self.stopwords = stopwords def get_stopwords(self, lang_key): if lang_key in self.stopwords: return self.stopwords[lang_key] return [] class Language(object): """ Class representing language data. Attributes: lang_key (str): The key of the given language, ie 'english'. name (str): Nicely formatted name. steam_key (str): Language as represented on the steam servers. track (bool): Language track. """ def __init__(self, lang_key, name, steam_key, track): self.lang_key = lang_key self.name = name self.steam_key = steam_key self.track = track def pretty_time(seconds): """ Pretty time formatting. Args: seconds (int): Time in seconds. Returns: str: Nicely formatted time string. """ minutes, seconds = divmod(seconds, 60) hours, minutes = divmod(minutes, 60) if hours: return "%.0fh %.0fm %.0fs" % (hours, minutes, seconds) elif minutes: return "%.0fm %.0fs" % (minutes, seconds) return "%.0fs" % (seconds,) def get_settings(): """ Parse and return settings json. Return: Settings: Object storing json settings. """ global settings if settings: return settings k_settings_file_path = os.path.join(os.path.dirname(__file__), "settings/settings.json") if not os.path.isfile(k_settings_file_path): logging.error("Settings file doesn't exist! ({0})".format(k_settings_file_path)) sys.exit(1) with open(k_settings_file_path, "r") as settings_file: try: settings_data = json.load(settings_file) apps = {} for appid in settings_data["apps"]: app_data = settings_data["apps"][appid] apps[appid] = AppConfig( appid, app_data["track"], app_data["ignore_zero_players"], app_data.get("wordcloud_stopwords", {})) languages = {} for lang_key in settings_data["languages"]: lang_data = settings_data["languages"][lang_key] languages[lang_key] = Language( lang_key, lang_data["name"], lang_data["steam_key"], lang_data["track"] ) except (ValueError, KeyError): logging.error("Settings file ({0}) contains invalid json!".format(k_settings_file_path)) sys.exit(1) settings = Settings(apps, languages, settings_data) return settings def init_logging(log_name, log_level_name): """ Initialise app logging. """ full_log_path = os.path.join(os.path.dirname(__file__), "logs", log_name) if not os.path.exists(os.path.dirname(full_log_path)): print("Creating log dir '{0}'".format(os.path.dirname(full_log_path))) os.makedirs(os.path.dirname(full_log_path)) k_logging_format = "[%(asctime)s][%(name)s][%(module)s][%(levelname)s] %(message)s" if get_settings().get("log_to_console", True): console_handler = logging.StreamHandler(stream=sys.stdout) console_handler.setFormatter(logging.Formatter(k_logging_format)) log_level_name = log_level_name or get_settings().get("log_level").upper() log_level = getattr(logging, log_level_name) if not log_level: raise Exception("Unknown log level specified '{0}'".format(log_level_name)) console_handler.setLevel(log_level) logging.getLogger().addHandler(console_handler) file_handler = logging.handlers.TimedRotatingFileHandler( full_log_path, when=get_settings().get("log_when"), backupCount=get_settings().get("log_count"), utc=True ) file_handler.suffix = "%Y-%m-%d" file_handler.setFormatter(logging.Formatter(k_logging_format)) logging.getLogger().addHandler(file_handler) logging.getLogger().setLevel("INFO")