Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions resources/lib/cabertoss.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@

def gather_log_files():
"""
Gather a list of the standard Kodi log files (Kodi.log, Kodi.old.log) and the latest crash log, if there is one.

@return: list of log files in form [type, path], where type is log, oldlog, or crashlog
Return a list of Kodi-related log files to copy: the main log, optional old log, and recent crash log(s).

The function inspects the configured LOG_PATH for kodi.log and kodi.old.log and attempts to locate platform-specific crash logs
(if present) in known crash-report directories. Crash logs are filtered to those modified within the last 3 days; the most
recent crash file is included (Windows may include the two most recent files because crash dumps come with accompanying stack traces).

Returns:
list: A list of entries [type, path], where `type` is one of 'log', 'oldlog', or 'crashlog' and `path` is the full filesystem path.
"""

# Basic log files
Expand Down Expand Up @@ -90,10 +95,19 @@ def gather_log_files():

def copy_log_files(log_files: List) -> bool:
"""
Actually copy the log files to the path in the addon settings

@param log_files: List list of log files to copy
@return bool: indicating success or failure
Copy the provided Kodi log files into a timestamped destination folder under the configured addon destination.

Detailed behavior:
- Expects log_files as a list of 2-element entries [type, path], where `type` is e.g. 'log', 'oldlog', or 'crashlog' and `path` is the source filesystem path.
- Creates a destination directory at Store.destination_path named "<hostname>_Kodi_Logs_<YYYY-MM-DD_HH-MM-SS>".
- For entries with type 'log' or 'oldlog', reads the source, sanitizes the content with clean_log(), and writes the sanitized content to a file with the same basename in the destination folder.
- For other types (e.g., crash logs), copies the source file to the destination folder unchanged.

Parameters:
log_files (List): list of log descriptors [type, path] to copy.

Returns:
bool: True if all files were copied (and sanitized when applicable) successfully; False if the input list is empty or an error occurred during processing.
"""
if not log_files:
Logger.error(LANGUAGE(32025))
Expand Down Expand Up @@ -128,6 +142,17 @@ def copy_log_files(log_files: List) -> bool:

# This is 'main'...
def run():
"""
Run the log collection and copying flow: initialize logging, load configuration, gather Kodi log files, copy them to the configured destination, notify the user, and stop logging.

This function performs the module's main orchestration. It:
- Starts the logger and loads addon configuration from settings.
- If no destination path is configured, shows an error notification and skips copying.
- Otherwise, notifies the user, gathers available log files, attempts to copy them to the configured destination, and notifies success (including number of files copied) or failure.
- Stops the logger before returning.

Side effects: starts/stops the logger, reads configuration, performs filesystem operations (reading, sanitizing, and copying log files), and shows user notifications. Returns None.
"""
Logger.start()
Store.load_config_from_settings()

Expand Down
14 changes: 10 additions & 4 deletions resources/lib/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@

def clean_log(content):
"""
Remove username/password details from log file content

@param content:
@return:
Sanitize log text by replacing embedded usernames and passwords with generic placeholders.

Replaces URL credentials (user:pass@), contents of <user>...</user>, and <pass>...</pass> with
`//USER:PASSWORD@`, `<user>USER</user>`, and `<pass>PASSWORD</pass>` respectively.

Parameters:
content (str): Log file content to sanitize.

Returns:
str: Sanitized content with credential data redacted.
"""
replaces = (('//.+?:.+?@', '//USER:PASSWORD@'), ('<user>.+?</user>', '<user>USER</user>'), ('<pass>.+?</pass>', '<pass>PASSWORD</pass>'),)

Expand Down
5 changes: 3 additions & 2 deletions resources/lib/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ def __init__(self):
@staticmethod
def load_config_from_settings():
"""
Load in the addon settings, at start or reload them if they have been changed
Log each setting as it is loaded
Load the addon's logging configuration from persistent settings.

Reads the 'log_path' setting and assigns it to Store.destination_path, then logs the resolved path (sanitized with clean_log). This is called at startup and when settings are reloaded; it has no return value.
"""
Logger.info("Loading configuration from settings")
Store.destination_path = ADDON.getSetting('log_path')
Expand Down