From 20e6c8f7338e147dfd9e348b082c51394a6fa920 Mon Sep 17 00:00:00 2001 From: bossanova808 Date: Wed, 30 Oct 2024 05:02:37 +0000 Subject: [PATCH] [script.cabertoss] 1.0.1 --- script.cabertoss/addon.xml | 17 +++-- script.cabertoss/changelog.txt | 10 ++- .../resource.language.en_gb/strings.po | 4 ++ script.cabertoss/resources/lib/cabertoss.py | 64 +++++++++++-------- script.cabertoss/resources/lib/clean.py | 15 +++++ script.cabertoss/resources/lib/store.py | 5 +- script.cabertoss/resources/settings.xml | 6 +- 7 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 script.cabertoss/resources/lib/clean.py diff --git a/script.cabertoss/addon.xml b/script.cabertoss/addon.xml index 2b3af72c7..5accc741e 100644 --- a/script.cabertoss/addon.xml +++ b/script.cabertoss/addon.xml @@ -1,5 +1,5 @@ - + @@ -14,16 +14,21 @@ A script to quickly toss your Kodi logs from your Kodi client machine to somewhe When something unexpected or bad happens, just run this add-on to copy the latest Kodi logs to your chosen destination. -Even better, bind this to a remote button (use `Runscript(script.cabertoss)`) - so you can carry on with your relaxing and deal with the issue later (without having to wade through all the stuff you did after the issue happened!). +Even better, bind this to a remote button (use `Runscript(script.cabertoss)`) - so you can carry on with your relaxing at the time, and deal with the issue later (without having to wade through all the stuff you did after the issue happened!). all GPL-3.0-only https://github.com/bossanova808/script.cabertoss https://github.com/bossanova808/script.cabertoss - - - - v1.0.0 Initial release + https://forum.kodi.tv/showthread.php?tid=379304 + bossanova808@gmail.com + v1.0.1 +- Improve compatibility with network shares +- Improve compatibility with Windows and *ELEC +- Add hostname to logs folder, helps if using with multiple systems +- Don't copy crashlogs older than three days +- Language improvements +- Add 'Working...' notification to make more responsive (copying larger log files can take a moment) resources/icon.png diff --git a/script.cabertoss/changelog.txt b/script.cabertoss/changelog.txt index 0b70def21..dce72535f 100644 --- a/script.cabertoss/changelog.txt +++ b/script.cabertoss/changelog.txt @@ -1,4 +1,12 @@ +v1.0.1 +- Improve compatibility with network shares +- Improve compatibility with Windows and *ELEC +- Add hostname to logs folder, helps if using with multiple systems +- Don't copy crashlogs older than three days +- Language improvements +- Add 'Working...' notification to make more responsive (copying larger log files can take a moment) + v1.0.0 -Initial release +- Initial release diff --git a/script.cabertoss/resources/language/resource.language.en_gb/strings.po b/script.cabertoss/resources/language/resource.language.en_gb/strings.po index cfbf3d954..9a82849d8 100644 --- a/script.cabertoss/resources/language/resource.language.en_gb/strings.po +++ b/script.cabertoss/resources/language/resource.language.en_gb/strings.po @@ -48,3 +48,7 @@ msgstr " msgctxt "#32029" msgid "Something went wrong, (ironically) check your logs!" msgstr " + +msgctxt "#32030" +msgid "Working..." +msgstr " \ No newline at end of file diff --git a/script.cabertoss/resources/lib/cabertoss.py b/script.cabertoss/resources/lib/cabertoss.py index d8ac42833..d8915ff51 100644 --- a/script.cabertoss/resources/lib/cabertoss.py +++ b/script.cabertoss/resources/lib/cabertoss.py @@ -1,7 +1,10 @@ # -*- coding: utf-8 -*- import os from datetime import datetime -import re +from time import sleep +from datetime import datetime, timedelta +import socket + import xbmc import xbmcvfs from bossanova808.constants import * @@ -9,18 +12,7 @@ from bossanova808.logger import Logger from bossanova808.notify import Notify from resources.lib.store import Store - - -def clean_log(content): - """ - Remove username/password details from log file content - - @param content: - @return: - """ - for pattern, repl in Store.replaces: - sanitised = re.sub(pattern, repl, content) - return sanitised +from resources.lib.clean import * def gather_log_files(): @@ -36,37 +28,57 @@ def gather_log_files(): log_files.append(['oldlog', os.path.join(LOG_PATH, 'kodi.old.log')]) # Can we find a crashlog? - # @TODO - check support for CoreElec & add Android if possible... + # @TODO - add Android support if possible..? crashlog_path = '' items = [] filematch = None if xbmc.getCondVisibility('system.platform.osx'): + Logger.info("System is OSX") crashlog_path = os.path.join(os.path.expanduser('~'), 'Library/Logs/DiagnosticReports/') filematch = 'Kodi' elif xbmc.getCondVisibility('system.platform.ios'): + Logger.info("System is IOS") crashlog_path = '/var/mobile/Library/Logs/CrashReporter/' filematch = 'Kodi' elif xbmc.getCondVisibility('system.platform.linux'): + Logger.info("System is Linux") crashlog_path = os.path.expanduser('~') # not 100% accurate (crashlogs can be created in the dir kodi was started from as well) filematch = 'kodi_crashlog' elif xbmc.getCondVisibility('system.platform.windows'): + Logger.info("System is Windows") crashlog_path = LOG_PATH - filematch = 'crashlog' + filematch = 'kodi_' elif xbmc.getCondVisibility('system.platform.android'): + Logger.info("System is Android") Logger.info(LANGUAGE(32023)) + # If *ELEC, we can be more specific + if xbmc.getCondVisibility('System.HasAddon(service.coreelec.settings)') or xbmc.getCondVisibility('System.HasAddon(service.libreelec.settings)'): + Logger.info("System is *ELEC") + crashlog_path = LOG_PATH + filematch = 'kodi_crashlog_' + if crashlog_path and os.path.isdir(crashlog_path): lastcrash = None dirs, possible_crashlog_files = xbmcvfs.listdir(crashlog_path) for item in possible_crashlog_files: - if filematch in item and os.path.isfile(os.path.join(crashlog_path, item)): - items.append(os.path.join(crashlog_path, item)) - items.sort(key=lambda f: os.path.getmtime(f)) - if not xbmc.getCondVisibility('system.platform.windows'): - lastcrash = [items[-1]] - else: - lastcrash = items[-2:] + item_with_path = os.path.join(crashlog_path, item) + if filematch in item and os.path.isfile(item_with_path): + if filematch in item: + # Don't bother with older crashlogs + three_days_ago = datetime.now() - timedelta(days=3) + if three_days_ago < datetime.fromtimestamp(os.path.getmtime(item_with_path)): + items.append(os.path.join(crashlog_path, item)) + + items.sort(key=lambda f: os.path.getmtime(f)) + # Windows crashlogs are a dmp and stacktrace combo... + if xbmc.getCondVisibility('system.platform.windows'): + lastcrash = items[-2:] + else: + lastcrash = items[-1:] + if lastcrash: + # Logger.info(f"lastcrash {lastcrash}") for crashfile in lastcrash: log_files.append(['crashlog', crashfile]) @@ -88,7 +100,7 @@ def copy_log_files(log_files: []): Notify.error(LANGUAGE(32025)) return - now_folder_name = 'Kodi_Logs_' + datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + now_folder_name = f"{socket.gethostname()}_Kodi_Logs_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}" now_destination_path = os.path.join(Store.destination_path, now_folder_name) try: @@ -100,11 +112,11 @@ def copy_log_files(log_files: []): with open(xbmcvfs.translatePath(file[1]), 'r', encoding='utf-8') as current: content = current.read() sanitised = clean_log(content) - with open(xbmcvfs.translatePath(os.path.join(now_destination_path,os.path.basename(file[1]))), 'w+', encoding='utf-8') as output: + with xbmcvfs.File(os.path.join(xbmcvfs.translatePath(now_destination_path),os.path.basename(file[1])), 'w') as output: output.write(sanitised) else: Logger.info(f'Copying {file[0]} {file[1]}') - if not xbmcvfs.copy(file[1], os.path.join(now_destination_path,os.path.basename(file[1]))): + if not xbmcvfs.copy(file[1], os.path.join(now_destination_path, os.path.basename(file[1]))): return False return True @@ -116,13 +128,13 @@ def copy_log_files(log_files: []): # This is 'main'... def run(): - footprints() Store.load_config_from_settings() if not Store.destination_path: Notify.error(LANGUAGE(32027)) else: + Notify.info(LANGUAGE(32030)) log_file_list = gather_log_files() result = copy_log_files(log_file_list) if result: diff --git a/script.cabertoss/resources/lib/clean.py b/script.cabertoss/resources/lib/clean.py new file mode 100644 index 000000000..23c743b53 --- /dev/null +++ b/script.cabertoss/resources/lib/clean.py @@ -0,0 +1,15 @@ +import re + + +def clean_log(content): + """ + Remove username/password details from log file content + + @param content: + @return: + """ + replaces = (('//.+?:.+?@', '//USER:PASSWORD@'), ('.+?', 'USER'), ('.+?', 'PASSWORD'),) + + for pattern, repl in replaces: + sanitised = re.sub(pattern, repl, content) + return sanitised diff --git a/script.cabertoss/resources/lib/store.py b/script.cabertoss/resources/lib/store.py index ba348a7de..5168dd851 100644 --- a/script.cabertoss/resources/lib/store.py +++ b/script.cabertoss/resources/lib/store.py @@ -1,5 +1,6 @@ from bossanova808.constants import * from bossanova808.logger import Logger +from resources.lib.clean import * class Store: @@ -12,7 +13,6 @@ class Store: # Static class variables, referred to elsewhere by Store.whatever # https://docs.python.org/3/faq/programming.html#how-do-i-create-static-class-data-and-static-class-methods - replaces = (('//.+?:.+?@', '//USER:PASSWORD@'), ('.+?', 'USER'), ('.+?', 'PASSWORD'),) destination_path = None def __init__(self): @@ -29,7 +29,8 @@ def load_config_from_settings(): """ Logger.info("Loading configuration from settings") Store.destination_path = ADDON.getSetting('log_path') - Logger.info(f'Logs will be tossed to: {Store.destination_path}') + + Logger.info(f'Logs will be tossed to: {clean_log(Store.destination_path)}') diff --git a/script.cabertoss/resources/settings.xml b/script.cabertoss/resources/settings.xml index 21e400133..69481d86a 100644 --- a/script.cabertoss/resources/settings.xml +++ b/script.cabertoss/resources/settings.xml @@ -7,10 +7,14 @@ 0 + + files + + true true - 32026 + 32001