import logging import os import sys import warnings from ruamel.yaml import YAML DEFAULT_ROOT_DESTINATION = "./icloud" DEFAULT_DRIVE_DESTINATION = "drive" DEFAULT_DRIVE_DESTINATION_EXPORT = "drive_export" DEFAULT_RETRY_LOGIN_INTERVAL_SEC = 600 # 10 minutes DEFAULT_SYNC_INTERVAL_SEC = 1800 # 30 minutes DEFAULT_CONFIG_FILE_NAME = "config.yaml" ENV_ICLOUD_PASSWORD_KEY = "ENV_ICLOUD_PASSWORD" ENV_CONFIG_FILE_PATH_KEY = "ENV_CONFIG_FILE_PATH" DEFAULT_LOGGER_LEVEL = "info" DEFAULT_LOG_FILE_NAME = "icloud.log" DEFAULT_CONFIG_FILE_PATH = os.path.join( os.path.dirname(os.path.dirname(__file__)), DEFAULT_CONFIG_FILE_NAME ) DEFAULT_COOKIE_DIRECTORY = "session_data" warnings.filterwarnings("ignore", category=DeprecationWarning) def read_config(config_path=DEFAULT_CONFIG_FILE_PATH): if not (config_path and os.path.exists(config_path)): print(f"Файл конфигурации не найден по адресу {config_path}.") return None with open(file=config_path, encoding="utf-8") as config_file: config = YAML().load(config_file) config["app"]["credentials"]["username"] = ( config["app"]["credentials"]["username"].strip() if config["app"]["credentials"]["username"] is not None else "" ) return config def get_logger_config(config): logger_config = {} if "logger" not in config["app"]: return None config_app_logger = config["app"]["logger"] logger_config["level"] = ( config_app_logger["level"].strip().lower() if "level" in config_app_logger else DEFAULT_LOGGER_LEVEL ) logger_config["filename"] = ( config_app_logger["filename"].strip().lower() if "filename" in config_app_logger else DEFAULT_LOG_FILE_NAME ) return logger_config def log_handler_exists(logger, handler_type, **kwargs): for handler in logger.handlers: if isinstance(handler, handler_type): if handler_type is logging.FileHandler: if handler.baseFilename.endswith(kwargs["filename"]): return True elif handler_type is logging.StreamHandler: if handler.stream is kwargs["stream"]: return True return False class ColorfulConsoleFormatter(logging.Formatter): grey = "\x1b[38;21m" blue = "\x1b[38;5;39m" yellow = "\x1b[38;5;226m" red = "\x1b[38;5;196m" bold_red = "\x1b[31;1m" reset = "\x1b[0m" def __init__(self, fmt): super().__init__() self.fmt = fmt self.formats = { logging.DEBUG: self.grey + self.fmt + self.reset, logging.INFO: self.blue + self.fmt + self.reset, logging.WARNING: self.yellow + self.fmt + self.reset, logging.ERROR: self.red + self.fmt + self.reset, logging.CRITICAL: self.bold_red + self.fmt + self.reset, } def format(self, record): log_fmt = self.formats.get(record.levelno) formatter = logging.Formatter(log_fmt) return formatter.format(record) def get_logger(): logger = logging.getLogger() logger_config = get_logger_config(config=read_config()) if logger_config: level_name = logging.getLevelName(level=logger_config["level"].upper()) logger.setLevel(level=level_name) if not log_handler_exists( logger=logger, handler_type=logging.FileHandler, filename=logger_config["filename"], ): file_handler = logging.FileHandler(logger_config["filename"]) file_handler.setFormatter( logging.Formatter( "%(asctime)s :: %(levelname)s :: %(name)s :: %(filename)s :: %(lineno)d :: %(message)s" ) ) logger.addHandler(file_handler) if not log_handler_exists( logger=logger, handler_type=logging.StreamHandler, stream=sys.stdout ): console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter( ColorfulConsoleFormatter( "%(asctime)s :: %(levelname)s :: %(name)s :: %(filename)s :: %(lineno)d :: %(message)s" ) ) logger.addHandler(console_handler) return logger LOGGER = get_logger()