From 9ec7d535c0b75a98ee864cd7983be0db1d351b55 Mon Sep 17 00:00:00 2001 From: bossanova808 Date: Wed, 16 Oct 2024 02:49:58 +0000 Subject: [PATCH] [script.service.playbackresumer] 2.0.7 --- script.service.playbackresumer/addon.xml | 7 +- script.service.playbackresumer/default.py | 6 +- .../resources/lib/common.py | 216 ------------------ .../resources/lib/monitor.py | 10 +- .../resources/lib/playback_resumer.py | 11 +- .../resources/lib/player.py | 123 +++++----- .../resources/lib/store.py | 49 ++-- 7 files changed, 107 insertions(+), 315 deletions(-) delete mode 100644 script.service.playbackresumer/resources/lib/common.py diff --git a/script.service.playbackresumer/addon.xml b/script.service.playbackresumer/addon.xml index aaa1fde08..e5831e184 100644 --- a/script.service.playbackresumer/addon.xml +++ b/script.service.playbackresumer/addon.xml @@ -1,7 +1,8 @@ - + + @@ -15,7 +16,9 @@ https://github.com/bossanova808/script.service.playbackresumer https://forum.kodi.tv/showthread.php?tid=355383 bossanova808@gmail.com - v2.0.6 - Add support for non-library videos + v2.0.7 +- Remove old common code, use new module + icon.png diff --git a/script.service.playbackresumer/default.py b/script.service.playbackresumer/default.py index c6618256c..bf2510975 100644 --- a/script.service.playbackresumer/default.py +++ b/script.service.playbackresumer/default.py @@ -1,6 +1,6 @@ -# -*- coding: utf-8 -*- - +from bossanova808 import exception_logger from resources.lib import playback_resumer if __name__ == "__main__": - playback_resumer.run() + with exception_logger.log_exception(): + playback_resumer.run() diff --git a/script.service.playbackresumer/resources/lib/common.py b/script.service.playbackresumer/resources/lib/common.py deleted file mode 100644 index 6e7b9f1de..000000000 --- a/script.service.playbackresumer/resources/lib/common.py +++ /dev/null @@ -1,216 +0,0 @@ -# -*- coding: utf-8 -*- - -""" - -Handy utility functions & constants for Kodi Addons -For Kodi Matrix & later -By bossanova808 - freely released -VERSION 0.2.7 2024-04-19 - -Changelog: -0.2.7 - Fix getting the major Kodi version (& change float -> int), as it was failing on e.g. 'RC' being in the string apparently -0.2.6 - (SkinPatcher) - add float KODI_VERSION_FLOAT constant, alongside string KODI_VERSION -0.2.5 - (Skin) - move to storing copy of latest in bossanova808 repo and adding this mini changelog - -For latest version - ALWAYS COPY BACK ANY CHANGES, plus do changelog, and a version & date bump above: -https://github.com/bossanova808/repository.bossanova808/blob/main/latest-common/common.py - - -""" - -import sys -import traceback - -import xbmc -import xbmcvfs -import xbmcgui -import xbmcaddon -import json - - -ADDON = xbmcaddon.Addon() -ADDON_NAME = ADDON.getAddonInfo('name') -ADDON_ID = ADDON.getAddonInfo('id') -ADDON_ICON = ADDON.getAddonInfo('icon') -ADDON_AUTHOR = ADDON.getAddonInfo('author') -ADDON_VERSION = ADDON.getAddonInfo('version') -ADDON_ARGUMENTS = f'{sys.argv}' -CWD = ADDON.getAddonInfo('path') -LANGUAGE = ADDON.getLocalizedString -PROFILE = xbmcvfs.translatePath(ADDON.getAddonInfo('profile')) -KODI_VERSION = xbmc.getInfoLabel('System.BuildVersion') -KODI_VERSION_INT = int(KODI_VERSION.split(".")[0]) -USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" -HOME_WINDOW = xbmcgui.Window(10000) -WEATHER_WINDOW = xbmcgui.Window(12600) - - -""" -Determine if we are unit testing outside of Kodi, or actually running within Kodi -Because we're using Kodi stubs https://romanvm.github.io/Kodistubs/ we can't rely on 'import xbmc' failing -So we use this hack - Kodi will return a user agent string, but Kodistrubs just returns and empty string. -If we are unit testing, change logs -> print - -In other files, minimal code to make this work is: - -# Small hack to allow for unit testing - see common.py for explanation -if not xbmc.getUserAgent(): - sys.path.insert(0, '../../..') # modify this depending on actual level - assumes resources/lib/something/file.py - -from resources.lib.store import Store -from resources.lib.common import * -..etc - -""" - -unit_testing = False - -# Testing outside of Kodi -if not xbmc.getUserAgent(): - - xbmc = None - unit_testing = True - KODI_VERSION = 'N/A' - - print("\nNo user agent, must be unit testing.\n") - - def log(message, exception_instance=None, level=None): - print(f'DEBUG: {message}') - if exception_instance: - print(f'EXCPT: {traceback.format_exc(exception_instance)}') - - -# Running inside of Kodi -else: - - def log(message, exception_instance=None, level=xbmc.LOGDEBUG): - """ - Log a message to the Kodi debug log, if debug logging is turned on. - - :param message: required, the message to log - :param exception_instance: optional, an instance of some Exception - :param level: optional, the Kodi log level to use, default LOGDEBUG but can override with level=xbmc.LOGINFO - """ - - message = f'### {ADDON_NAME} {ADDON_VERSION} - {message}' - message_with_exception = message + f' ### Exception: {traceback.format_exc(exception_instance)}' - - if exception_instance is None: - xbmc.log(message, level) - else: - xbmc.log(message_with_exception, level) - - def set_property(window, name, value=""): - """ - Set a property on a window. - To clear a property, provide an empty string - - :param window: Required. The Kodi window on which to set the property. - :param name: Required. Name of the property. - :param value: Optional (defaults to ""). Set the property to this value. An empty string clears the property. - """ - if value is None: - window.clearProperty(name) - - value = str(value) - if value: - log(f'Setting window property {name} to value {value}') - window.setProperty(name, value) - else: - log(f'Clearing window property {name}') - window.clearProperty(name) - - def get_property(window, name): - """ - Return the value of a window property - :param window: the Kodi window to get the property value from - :param name: the name of the property to get - :return: the value of the window property - """ - return window.getProperty(name) - - - def get_property_as_bool(window, name): - """ - Return the value of a window property as a boolean - :param window: the Kodi window to get the property value from - :param name: the name of the property to get - :return: the value of the window property in boolean form - """ - return window.getProperty(name).lower() == "true" - - - def send_kodi_json(human_description, json_string): - """ - Send a JSON command to Kodi, logging the human description, command, and result as returned. - - :param human_description: Required. A human sensible description of what the command is aiming to do/retrieve. - :param json_string: Required. The json command to send. - :return the json object loaded from the result string - """ - log(f'KODI JSON RPC command: {human_description} [{json_string}]') - result = xbmc.executeJSONRPC(json_string) - log(f'KODI JSON RPC result: {result}') - return json.loads(result) - - - def get_setting(setting): - """ - Helper function to get string type from settings - - :param setting: The addon setting to return - :return: the setting value - """ - return ADDON.getSetting(setting).strip() - - - def get_setting_as_bool(setting): - """ - Helper function to get bool type from settings - - :param setting: The addon setting to return - :return: the setting value as boolean - """ - return get_setting(setting).lower() == "true" - - - def notify(message, notification_type=xbmcgui.NOTIFICATION_ERROR, duration=5000): - """ - Send a notification to the user via the Kodi GUI - - :param message: the message to send - :param notification_type: xbmcgui.NOTIFICATION_ERROR (default), xbmcgui.NOTIFICATION_WARNING, or xbmcgui.NOTIFICATION_INFO - :param duration: time to display notification in milliseconds, default 5000 - :return: None - """ - dialog = xbmcgui.Dialog() - - dialog.notification(ADDON_NAME, - message, - notification_type, - duration) - - def is_playback_paused(): - """ - Helper function to return Kodi player state. - (Odd this is needed, it should be a testable state on Player really..) - - :return: boolean indicating player paused state - """ - return bool(xbmc.getCondVisibility("Player.Paused")) - - -def footprints(startup=True): - """ - Log the startup of an addon, and key Kodi details that are helpful for debugging - - :param startup: optional, default True. If true, log the startup of an addon, otherwise log the exit. - """ - if startup: - log(f'Starting...', level=xbmc.LOGINFO) - log(f'Kodi System.BuildVersion: {KODI_VERSION}, which is Kodi major version: {KODI_VERSION_INT}', level=xbmc.LOGINFO) - log(f'Addon arguments: {ADDON_ARGUMENTS}', level=xbmc.LOGINFO) - else: - log(f'Exiting...', level=xbmc.LOGINFO) - - diff --git a/script.service.playbackresumer/resources/lib/monitor.py b/script.service.playbackresumer/resources/lib/monitor.py index 2d652d196..3ceb33588 100644 --- a/script.service.playbackresumer/resources/lib/monitor.py +++ b/script.service.playbackresumer/resources/lib/monitor.py @@ -1,5 +1,6 @@ import xbmc -from .common import * +from bossanova808.logger import Logger +# noinspection PyPackages from .store import Store @@ -7,12 +8,11 @@ class KodiEventMonitor(xbmc.Monitor): def __init__(self, *args, **kwargs): xbmc.Monitor.__init__(self) - log('KodiEventMonitor __init__') + Logger.debug('KodiEventMonitor __init__') def onSettingsChanged(self): - log('onSettingsChanged - reload them.') + Logger.info('onSettingsChanged - reload them.') Store.load_config_from_settings() def onAbortRequested(self): - log('onAbortRequested') - log("Abort Requested") + Logger.debug('onAbortRequested') diff --git a/script.service.playbackresumer/resources/lib/playback_resumer.py b/script.service.playbackresumer/resources/lib/playback_resumer.py index 825faee0b..6d633c037 100644 --- a/script.service.playbackresumer/resources/lib/playback_resumer.py +++ b/script.service.playbackresumer/resources/lib/playback_resumer.py @@ -1,9 +1,13 @@ -from .common import * +from bossanova808.utilities import * +# noinspection PyPackages from .store import Store import xbmc +# noinspection PyPackages from .monitor import KodiEventMonitor +# noinspection PyPackages from .player import KodiPlayer + def run(): """ This is 'main' @@ -12,7 +16,7 @@ def run(): """ footprints() # load settings and create the store for our globals - config = Store() + Store() Store.kodi_event_monitor = KodiEventMonitor(xbmc.Monitor) Store.kodi_player = KodiPlayer(xbmc.Player) @@ -26,6 +30,3 @@ def run(): break footprints(False) - - - diff --git a/script.service.playbackresumer/resources/lib/player.py b/script.service.playbackresumer/resources/lib/player.py index e203a4ef3..1138f2ea0 100644 --- a/script.service.playbackresumer/resources/lib/player.py +++ b/script.service.playbackresumer/resources/lib/player.py @@ -1,6 +1,10 @@ from random import randint -from .common import * +from bossanova808.logger import Logger +from bossanova808.notify import Notify +from bossanova808.utilities import * + +# noinspection PyPackages from .store import Store import json import time @@ -15,48 +19,48 @@ class KodiPlayer(xbmc.Player): def __init__(self, *args): xbmc.Player.__init__(self) - log('KodiPlayer __init__') + Logger.debug('KodiPlayer __init__') def onPlayBackPaused(self): - log('onPlayBackPaused') + Logger.info('onPlayBackPaused') Store.paused_time = time.time() - log(f'Playback paused at: {Store.paused_time}') + Logger.info(f'Playback paused at: {Store.paused_time}') def onPlayBackEnded(self): # video ended normally (user didn't stop it) - log("onPlayBackEnded") + Logger.info("onPlayBackEnded") self.update_resume_point(-1) self.autoplay_random_if_enabled() def onPlayBackStopped(self): - log("onPlayBackStopped") + Logger.info("onPlayBackStopped") self.update_resume_point(-2) def onPlayBackSeek(self, time, seekOffset): - log(f'onPlayBackSeek time {time}, seekOffset {seekOffset}') + Logger.info(f'onPlayBackSeek time {time}, seekOffset {seekOffset}') try: self.update_resume_point(self.getTime()) except RuntimeError: - log("Could not get playing time - seeked past end?") + Logger.warning("Could not get playing time - seeked past end? Clearing resume point.") self.update_resume_point(0) pass def onPlayBackSeekChapter(self, chapter): - log(f'onPlayBackSeekChapter chapter: {chapter}') + Logger.info(f'onPlayBackSeekChapter chapter: {chapter}') try: self.update_resume_point(self.getTime()) except RuntimeError: - log("Could not get playing time - seeked past end?") + Logger.warning("Could not get playing time - seeked past end? Clearing resume point.") self.update_resume_point(0) pass def onAVStarted(self): - log("onAVStarted") + Logger.info("onAVStarted") # Clean up - get rid of any data about any files previously played Store.clear_old_play_details() if not self.isPlayingVideo(): - log("Not playing a video - skipping: " + self.getPlayingFile()) + Logger.info("Not playing a video - skipping: " + self.getPlayingFile()) return xbmc.sleep(1500) # give it a bit to start playing and let the stopped method finish @@ -69,7 +73,7 @@ def onAVStarted(self): try: self.update_resume_point(self.getTime()) except RuntimeError: - log('Could not get current playback time from player') + Logger.error('Could not get current playback time from player') for i in range(0, Store.save_interval_seconds): # Shutting down or not playing video anymore...stop handling playback @@ -92,7 +96,7 @@ def update_resume_point(self, seconds): # short circuit if we haven't got a record of the file that is currently playing if not Store.currently_playing_file_path: - log("No valid currently_playing_file_path found - therefore not setting resume point") + Logger.info("No valid currently_playing_file_path found - therefore not setting resume point") return # -1 indicates that the video has stopped playing @@ -103,7 +107,7 @@ def update_resume_point(self, seconds): for i in range(0, 30): if Store.kodi_event_monitor.abortRequested(): - log("Kodi is shutting down, and will save resume point") + Logger.info("Kodi is shutting down, so Kodi will save resume point") # Kodi is shutting down while playing a video. return @@ -115,19 +119,19 @@ def update_resume_point(self, seconds): # Short circuit if current time < Kodi's ignoresecondsatstart setting if 0 < seconds < Store.ignore_seconds_at_start: - log(f'Not updating resume point as current time ({seconds}) is below Kodi\'s ignoresecondsatstart' - f' setting of {Store.ignore_seconds_at_start}') + Logger.info(f'Not updating resume point as current time ({seconds}) is below Kodi\'s ignoresecondsatstart' + f' setting of {Store.ignore_seconds_at_start}') return # Short circuits # Weird library ID if Store.library_id and Store.library_id < 0: - log(f"No/invalid library id ({Store.library_id}) for {Store.currently_playing_file_path}") + Logger.info(f"No/invalid library id ({Store.library_id}) for {Store.currently_playing_file_path}") return # Kodi doing its normal stopping thing if seconds == -2: - log("Not updating Kodi native resume point because the file was stopped normally, so Kodi should do it itself") + Logger.info("Not updating Kodi native resume point because the file was stopped normally, so Kodi should do it itself") return # At this point if seconds is < 0, it is -1 meaning end of file/clear resume point if seconds < 0: @@ -137,22 +141,22 @@ def update_resume_point(self, seconds): # if current time > Kodi's ignorepercentatend setting percent_played = int((seconds * 100) / Store.length_of_currently_playing_file) if percent_played > (100 - Store.ignore_percent_at_end): - log(f'Not updating resume point as current percent played ({percent_played}) is above Kodi\'s ignorepercentatend' - f' setting of {Store.ignore_percent_at_end}') + Logger.info(f'Not updating resume point as current percent played ({percent_played}) is above Kodi\'s ignorepercentatend' + f' setting of {Store.ignore_percent_at_end}') return # OK, BELOW HERE, we're probably going to set a resume point # First update the resume point in the tracker file for later retrieval if needed - log(f'Setting custom resume seconds to {seconds}') + Logger.info(f'Setting custom resume seconds to {seconds}') with open(Store.file_to_store_resume_point, 'w') as f: f.write(str(seconds)) # Log what we are doing if seconds == 0: - log(f'Removing resume point for: {Store.currently_playing_file_path}, type: {Store.type_of_video}, library id: {Store.library_id}') + Logger.info(f'Removing resume point for: {Store.currently_playing_file_path}, type: {Store.type_of_video}, library id: {Store.library_id}') else: - log(f'Setting resume point for: {Store.currently_playing_file_path}, type: {Store.type_of_video}, library id: {Store.library_id}, to: {seconds} seconds') + Logger.info(f'Setting resume point for: {Store.currently_playing_file_path}, type: {Store.type_of_video}, library id: {Store.library_id}, to: {seconds} seconds') # Determine the JSON-RPC setFooDetails method to use and what the library id name is based of the type of video id_name = None @@ -169,7 +173,7 @@ def update_resume_point(self, seconds): get_method = 'VideoLibrary.GetMusicVideoDetails' id_name = 'musicvideoid' else: - log(f'Did not recognise type of video [{Store.type_of_video}] - assume non-library video') + Logger.info(f'Did not recognise type of video [{Store.type_of_video}] - assume non-library video') method = 'Files.SetFileDetails' get_method = 'Files.GetFileDetails' @@ -180,11 +184,11 @@ def update_resume_point(self, seconds): } if id_name: params = { - id_name: Store.library_id, - "resume": { - "position": seconds, - "total": Store.length_of_currently_playing_file - } + id_name: Store.library_id, + "resume": { + "position": seconds, + "total": Store.length_of_currently_playing_file + } } else: params = { @@ -236,20 +240,20 @@ def resume_if_was_playing(self): with open(Store.file_to_store_resume_point, 'r') as f: try: resume_point = float(f.read()) - except Exception as e: - log("Error reading resume point from file, therefore not resuming.") + except Exception: + Logger.error("Error reading resume point from file, therefore not resuming.") return # neg 1 means the video wasn't playing when Kodi ended if resume_point < 0: - log("Not resuming playback because nothing was playing when Kodi last closed") + Logger.info("Not resuming playback because nothing was playing when Kodi last closed") return False with open(Store.file_to_store_last_played, 'r') as f: full_path = f.read() str_timestamp = '%d:%02d' % (resume_point / 60, resume_point % 60) - log(f'Will resume playback at {str_timestamp} of {full_path}') + Logger.info(f'Will resume playback at {str_timestamp} of {full_path}') self.play(full_path) @@ -258,7 +262,7 @@ def resume_if_was_playing(self): if not self.isPlayingVideo() and not Store.kodi_event_monitor.abortRequested(): xbmc.sleep(100) else: - notify(f'Resuming playback at {str_timestamp}', xbmcgui.NOTIFICATION_INFO) + Notify.info(f'Resuming playback at {str_timestamp}') self.seekTime(resume_point) return True @@ -275,7 +279,7 @@ def get_random_library_video(self): if not Store.video_types_in_library['episodes'] \ and not Store.video_types_in_library['movies'] \ and not Store.video_types_in_library['musicvideos']: - log('No episodes, movies, or music videos exist in the Kodi library. Cannot autoplay a random video.') + Logger.warning('No episodes, movies, or music videos exist in the Kodi library. Cannot autoplay a random video.') return random_int = randint(0, 2) @@ -294,28 +298,28 @@ def get_random_library_video(self): if not Store.video_types_in_library[result_type]: return self.get_random_library_video() # get a different one - log(f'Getting a random video from: {result_type}') + Logger.info(f'Getting a random video from: {result_type}') query = { - "jsonrpc": "2.0", - "id": "randomLibraryVideo", - "method": "VideoLibrary." + method, - "params": { - "limits": { - "end": 1 - }, - "sort": { - "method": "random" - }, - "properties": [ - "file" - ] - } + "jsonrpc": "2.0", + "id": "randomLibraryVideo", + "method": "VideoLibrary." + method, + "params": { + "limits": { + "end": 1 + }, + "sort": { + "method": "random" + }, + "properties": [ + "file" + ] + } } - log(f'Executing JSON-RPC: {json.dumps(query)}') + Logger.info(f'Executing JSON-RPC: {json.dumps(query)}') json_response = json.loads(xbmc.executeJSONRPC(json.dumps(query))) - log(f'JSON-RPC VideoLibrary.{method} response: {json.dumps(json_response)}') + Logger.info(f'JSON-RPC VideoLibrary.{method} response: {json.dumps(json_response)}') # found a video! if json_response['result']['limits']['total'] > 0: @@ -323,7 +327,7 @@ def get_random_library_video(self): return json_response['result'][result_type][0]['file'] # no videos of this type else: - log("There are no " + result_type + " in the library") + Logger.info("There are no " + result_type + " in the library") Store.video_types_in_library[result_type] = False return self.get_random_library_video() @@ -335,7 +339,7 @@ def autoplay_random_if_enabled(self): if Store.autoplay_random: - log("Autoplay random is enabled in addon settings, so will play a new random video now.") + Logger.info("Autoplay random is enabled in addon settings, so will play a new random video now.") video_playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) @@ -343,10 +347,9 @@ def autoplay_random_if_enabled(self): if not self.isPlayingVideo() \ and (video_playlist.getposition() == -1 or video_playlist.getposition() == video_playlist.size()): full_path = self.get_random_library_video() - log("Auto-playing next random video because nothing is playing and playlist is empty: " + full_path) + Logger.info("Auto-playing next random video because nothing is playing and playlist is empty: " + full_path) self.play(full_path) - notify(f'Auto-playing random video: {full_path}', xbmcgui.NOTIFICATION_INFO) + Notify.info(f'Auto-playing random video: {full_path}') else: - log(f'Not auto-playing random as playlist not empty or something is playing.') - log(f'Current playlist position: {video_playlist.getposition()}, playlist size: {video_playlist.size()}') - + Logger.info(f'Not auto-playing random as playlist not empty or something is playing.') + Logger.info(f'Current playlist position: {video_playlist.getposition()}, playlist size: {video_playlist.size()}') diff --git a/script.service.playbackresumer/resources/lib/store.py b/script.service.playbackresumer/resources/lib/store.py index bc3e354b2..76730f8c5 100644 --- a/script.service.playbackresumer/resources/lib/store.py +++ b/script.service.playbackresumer/resources/lib/store.py @@ -1,4 +1,5 @@ -from .common import * +from bossanova808.utilities import * +from bossanova808.logger import Logger import os import json import xml.etree.ElementTree as ElementTree @@ -59,21 +60,21 @@ def __init__(self): root = None try: root = ElementTree.parse(advancedsettings_file).getroot() - log("Found and parsed advancedsettings.xml") + Logger.info("Found and parsed advancedsettings.xml") except (ElementTree.ParseError, IOError): - log("Could not find/parse advancedsettings.xml, will use defaults") + Logger.info("Could not find/parse advancedsettings.xml, will use defaults") if root is not None: element = root.find('./video/ignoresecondsatstart') if element is not None: - log("Found advanced setting ignoresecondsatstart") + Logger.info("Found advanced setting ignoresecondsatstart") Store.ignore_seconds_at_start = int(element.text) element = root.find('./video/ignorepercentatend') if element is not None: - log("Found advanced setting ignorepercentatend") + Logger.info("Found advanced setting ignorepercentatend") Store.ignore_percent_at_end = int(element.text) - log(f"Using ignoresecondsatstart: {Store.ignore_seconds_at_start}, ignorepercentatend: {Store.ignore_percent_at_end}") + Logger.info(f"Using ignoresecondsatstart: {Store.ignore_seconds_at_start}, ignorepercentatend: {Store.ignore_percent_at_end}") @staticmethod def clear_old_play_details(): @@ -81,7 +82,7 @@ def clear_old_play_details(): As soon as a new file is played, clear out all old references to anything that was being stored as the currently playing file :return: """ - log("New playback - clearing legacy now playing details") + Logger.info("New playback - clearing legacy now playing details") Store.library_id = None Store.currently_playing_file_path = None Store.type_of_video = None @@ -98,7 +99,7 @@ def load_config_from_settings(): Load in the addon settings, at start or reload them if they have been changed :return: """ - log("Loading configuration") + Logger.info("Loading configuration") Store.save_interval_seconds = int(float(ADDON.getSetting("saveintervalsecs"))) Store.resume_on_startup = get_setting_as_bool("resumeonstartup") @@ -107,9 +108,9 @@ def load_config_from_settings(): @staticmethod def log_configuration(): - log(f'Will save a resume point every {Store.save_interval_seconds} seconds') - log(f'Resume on startup: {Store.resume_on_startup}') - log(f'Autoplay random video: {Store.autoplay_random}') + Logger.info(f'Will save a resume point every {Store.save_interval_seconds} seconds') + Logger.info(f'Resume on startup: {Store.resume_on_startup}') + Logger.info(f'Autoplay random video: {Store.autoplay_random}') @staticmethod def is_excluded(full_path): @@ -123,32 +124,32 @@ def is_excluded(full_path): if not full_path: return True - log(f'Store.isExcluded(): Checking exclusion settings for [{full_path}]') + Logger.info(f'Store.isExcluded(): Checking exclusion settings for [{full_path}]') - if (full_path.find("pvr://") > -1) and getSettingAsBool('ExcludeLiveTV'): - log('Store.isExcluded(): Video is PVR (Live TV), which is currently set as an excluded source.') + if (full_path.find("pvr://") > -1) and get_setting_as_bool('ExcludeLiveTV'): + Logger.info('Store.isExcluded(): Video is PVR (Live TV), which is currently set as an excluded source.') return True if (full_path.find("http://") > -1 or full_path.find("https://") > -1) and get_setting_as_bool('ExcludeHTTP'): - log("Store.isExcluded(): Video is from an HTTP/S source, which is currently set as an excluded source.") + Logger.info("Store.isExcluded(): Video is from an HTTP/S source, which is currently set as an excluded source.") return True exclude_path = get_setting('exclude_path') if exclude_path and get_setting_as_bool('ExcludePathOption'): if full_path.find(exclude_path) > -1: - log(f'Store.isExcluded(): Video is playing from [{exclude_path}], which is set as excluded path 1.') + Logger.info(f'Store.isExcluded(): Video is playing from [{exclude_path}], which is set as excluded path 1.') return True exclude_path2 = get_setting('exclude_path2') if exclude_path2 and get_setting_as_bool('ExcludePathOption2'): if full_path.find(exclude_path2) > -1: - log(f'Store.isExcluded(): Video is playing from [{exclude_path2}], which is set as excluded path 2.') + Logger.info(f'Store.isExcluded(): Video is playing from [{exclude_path2}], which is set as excluded path 2.') return True exclude_path3 = get_setting('exclude_path3') if exclude_path3 and get_setting_as_bool('ExcludePathOption3'): if full_path.find(exclude_path3) > -1: - log(f'Store.isExcluded(): Video is playing from [{exclude_path3}], which is set as excluded path 3.') + Logger.info(f'Store.isExcluded(): Video is playing from [{exclude_path3}], which is set as excluded path 3.') return True return False @@ -163,7 +164,7 @@ def update_current_playing_file_path(filepath): """ if Store.is_excluded(filepath): - log("Skipping excluded filepath: " + filepath) + Logger.info("Skipping excluded filepath: " + filepath) Store.currently_playing_file_path = None return @@ -173,7 +174,7 @@ def update_current_playing_file_path(filepath): with open(Store.file_to_store_last_played, 'w+', encoding='utf8') as f: f.write(filepath) - log(f'Last played file set to: {filepath}') + Logger.info(f'Last played file set to: {filepath}') # check if it is a library video and if so store the library_id and type_of_video query = { @@ -190,19 +191,19 @@ def update_current_playing_file_path(filepath): "id": "fileDetailsCheck" } - log(f'Executing JSON-RPC: {json.dumps(query)}') + Logger.info(f'Executing JSON-RPC: {json.dumps(query)}') json_response = json.loads(xbmc.executeJSONRPC(json.dumps(query))) - log(f'JSON-RPC Files.GetFileDetails response: {json.dumps(json_response)}') + Logger.info(f'JSON-RPC Files.GetFileDetails response: {json.dumps(json_response)}') try: Store.type_of_video = json_response['result']['filedetails']['type'] except KeyError: Store.library_id = -1 - log(f"ERROR: Kodi did not return even an 'unknown' file type for: {Store.currently_playing_file_path}") + Logger.info(f"ERROR: Kodi did not return even an 'unknown' file type for: {Store.currently_playing_file_path}") if Store.type_of_video in ['episode', 'movie', 'musicvideo']: Store.library_id = json_response['result']['filedetails']['id'] else: Store.library_id = None - log(f'Kodi type: {Store.type_of_video}, library id: {Store.library_id}') \ No newline at end of file + Logger.info(f'Kodi type: {Store.type_of_video}, library id: {Store.library_id}')