-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add seamless update framework. (#90)
* Update config.py * Update main.py * fix incorrect release version/beta version check * Update misc.py * Add test results, prepare README * Update README.md status badges. * Get most of it working. * Add test results, prepare README * Update README.md status badges. * more implementation, fix many problems * Update config.py * Add test results, prepare README * Update README.md status badges. * remaining fixes * Add test results, prepare README * Update README.md status badges. * move relevant code to utility libs * fix * Add test results, prepare README * Update README.md status badges. * remaining fixes * Add test results, prepare README * Update README.md status badges. * implement into HoloPatcher * Update __main__.py * Update requirements.txt * Add test results, prepare README * Update README.md status badges. * fix import order * sort around dependencies don't require requests/pycyrptodome for update logic... should always be an optional feature. * Add test results, prepare README * Update README.md status badges. * fix the unix-related issues * add missing unix dep to toolset * remaining cleanup * Add test results, prepare README * Update README.md status badges. * have logger output to console * Add test results, prepare README * Update README.md status badges. * Ensure new app has executable permission * Add test results, prepare README * Update README.md status badges. * Update config.py * Update os_helper.py * Add test results, prepare README * Update README.md status badges. * Got stuff done * Add test results, prepare README * Update README.md status badges. * fix the regex * Fix trailing comma in the json. * it is ready --------- Co-authored-by: GitHub Action <[email protected]>
- Loading branch information
1 parent
17855a3
commit 82d01a4
Showing
91 changed files
with
10,647 additions
and
8,470 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
defusedxml~=0.7 | ||
charset-normalizer>=2.0,<3.4 | ||
defusedxml>=0.7 | ||
charset-normalizer>=2.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
from __future__ import annotations | ||
|
||
import json | ||
import logging | ||
import sys | ||
|
||
from logging.handlers import RotatingFileHandler | ||
from typing import ClassVar | ||
|
||
from utility.error_handling import format_exception_with_variables | ||
|
||
|
||
class ColoredConsoleHandler(logging.StreamHandler): | ||
try: | ||
import colorama # type: ignore[import-untyped, reportMissingModuleSource] | ||
colorama.init() | ||
USING_COLORAMA = True | ||
except ImportError: | ||
USING_COLORAMA = False | ||
|
||
COLOR_CODES: ClassVar[dict[int, str]] = { | ||
logging.DEBUG: "\033[0;36m" if not USING_COLORAMA else colorama.Fore.CYAN, # Cyan | ||
logging.INFO: "\033[0;37m" if not USING_COLORAMA else colorama.Fore.WHITE, # White | ||
logging.WARNING: "\033[0;33m" if not USING_COLORAMA else colorama.Fore.YELLOW, # Yellow | ||
logging.ERROR: "\033[0;31m" if not USING_COLORAMA else colorama.Fore.RED, # Red | ||
logging.CRITICAL: "\033[1;41m" if not USING_COLORAMA else colorama.Back.RED, # Red background | ||
} | ||
|
||
RESET_CODE = "\033[0m" if not USING_COLORAMA else colorama.Style.RESET_ALL | ||
|
||
def format(self, record): | ||
msg = super().format(record) | ||
return f"{self.COLOR_CODES.get(record.levelno, '')}{msg}{self.RESET_CODE}" | ||
|
||
class CustomExceptionFormatter(logging.Formatter): | ||
def formatException(self, ei): | ||
etype, value, tb = ei | ||
return format_exception_with_variables(value, etype=etype, tb=tb) | ||
|
||
def format(self, record): | ||
result = super().format(record) | ||
if record.exc_info: | ||
# Here we use our custom exception formatting | ||
result += "\n" + self.formatException(record.exc_info) | ||
return result | ||
|
||
class JSONFormatter(logging.Formatter): | ||
def format(self, record): | ||
log_record = { | ||
"timestamp": self.formatTime(record, self.datefmt), | ||
"level": record.levelname, | ||
"name": record.name, | ||
"message": record.getMessage(), | ||
} | ||
if record.exc_info: | ||
# Your custom exception formatting is called here | ||
formatted_exception = super().formatException(record.exc_info) # Adjust this call as necessary | ||
log_record["exception"] = formatted_exception | ||
return json.dumps(log_record) | ||
|
||
class LogLevelFilter(logging.Filter): | ||
"""Filters (allows) all the log messages at or above a specific level.""" | ||
def __init__(self, passlevel: int, reject: bool = False): # noqa: FBT001, FBT002 | ||
super().__init__() | ||
self.passlevel: int = passlevel | ||
self.reject: bool = reject | ||
|
||
def filter(self, record): | ||
if self.reject: | ||
return record.levelno < self.passlevel | ||
return record.levelno >= self.passlevel | ||
|
||
def get_root_logger() -> logging.Logger: | ||
logger = logging.getLogger() | ||
if not logger.handlers: | ||
logger.setLevel(logging.DEBUG) | ||
|
||
log_levels = { | ||
logging.DEBUG: "pykotor_debug.log", | ||
logging.INFO: "pykotor_info.log", | ||
logging.WARNING: "pykotor_warning.log", | ||
logging.ERROR: "pykotor_error.log", | ||
logging.CRITICAL: "pykotor_critical.log", | ||
} | ||
|
||
for level, filename in log_levels.items(): | ||
handler = RotatingFileHandler(filename, maxBytes=1048576, backupCount=5) | ||
handler.setLevel(level) | ||
|
||
# Apply JSON formatting for DEBUG, CustomExceptionFormatter for others | ||
if level == logging.DEBUG: | ||
handler.setFormatter(JSONFormatter()) | ||
else: | ||
handler.setFormatter(CustomExceptionFormatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")) | ||
|
||
# Replacing StreamHandler with ColoredConsoleHandler | ||
console_handler = ColoredConsoleHandler() | ||
formatter = logging.Formatter("%(levelname)s(%(name)s): %(message)s") | ||
console_handler.setFormatter(formatter) | ||
logger.addHandler(console_handler) | ||
|
||
# Exclude lower level logs for handlers above DEBUG | ||
if level > logging.DEBUG: | ||
handler.addFilter(LogLevelFilter(level)) | ||
|
||
logger.addHandler(handler) | ||
|
||
return logger | ||
|
||
# Modify the handle_exception function if necessary | ||
def handle_exception(exc_type, exc_value, exc_traceback): | ||
if issubclass(exc_type, KeyboardInterrupt): | ||
sys.__excepthook__(exc_type, exc_value, exc_traceback) | ||
return | ||
|
||
logger = get_root_logger() | ||
logger.critical("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) | ||
|
||
sys.excepthook = handle_exception | ||
|
||
# Example usage | ||
if __name__ == "__main__": | ||
logger = get_root_logger() | ||
logger.debug("This is a debug message.") | ||
logger.info("This is an info message.") | ||
logger.warning("This is a warning message.") | ||
logger.error("This is an error message.") | ||
logger.critical("This is a critical message.") | ||
|
||
# Uncomment to test uncaught exception logging | ||
# raise RuntimeError("Test uncaught exception") |
File renamed without changes.
Oops, something went wrong.