CastagnaIT/plugin.video.netflix

View on GitHub
resources/lib/services/playback/action_manager.py

Summary

Maintainability
A
2 hrs
Test Coverage
# -*- coding: utf-8 -*-
"""
    Copyright (C) 2017 Sebastian Golasch (plugin.video.netflix)
    Copyright (C) 2018 Caphm (original implementation module)
    Common base for all playback action managers

    SPDX-License-Identifier: MIT
    See LICENSES/MIT.md for more information.
"""
from resources.lib.globals import G
from resources.lib.utils.logging import LOG


class ActionManager:
    """
    Base class for managers that handle executing of specific actions during playback
    """

    SETTING_ID = None  # ID of the settings.xml property

    def __init__(self):
        self._enabled = None
        self.videoid = None
        self.videoid_parent = None
        """If the 'videoid' variable is an episode, you get the parent videoid as tvshow or else return same videoid"""

    @property
    def name(self):
        """Name of this manager"""
        return self.__class__.__name__

    @property
    def enabled(self):
        """
        Indicates whether this instance is enabled or not.
        Loads the value from Kodi settings if it has not been set.
        """
        if self._enabled is None:
            LOG.debug('Loading enabled setting from store')
            self._enabled = G.ADDON.getSettingBool(self.SETTING_ID)

        return self._enabled

    @enabled.setter
    def enabled(self, enabled):
        self._enabled = enabled

    def call_initialize(self, data):
        """
        Initialize the manager with data when the addon initiates a playback.
        """
        self.videoid = data['videoid']
        self.videoid_parent = data['videoid_parent']
        self._call_if_enabled(self.initialize, data=data)
        LOG.debug('Initialized {}: {}', self.name, self)

    def call_on_playback_started(self, player_state):
        """
        Notify that the playback has actually started and supply initial
        player state
        """
        self._call_if_enabled(self.on_playback_started, player_state=player_state)

    def call_on_tick(self, player_state):
        """
        Notify that a playback tick has passed and supply current player state
        """
        self._call_if_enabled(self.on_tick, player_state=player_state)

    def call_on_avchange_delayed(self, player_state):
        """
        Notify that av-change event has been notified by Kodi,
        this callback is delayed of about 1sec to try group multiple av-change events in a single one,
        because Kodi can send multiple av-change events in a very short period of time, so we try catch the last one
        """
        self._call_if_enabled(self.on_playback_avchange_delayed, player_state=player_state)

    def call_on_playback_seek(self, player_state):
        """
        Notify that a playback has seek
        """
        self._call_if_enabled(self.on_playback_seek, player_state=player_state)

    def call_on_playback_pause(self, player_state):
        """
        Notify that the playback is actually in pause
        """
        self._call_if_enabled(self.on_playback_pause, player_state=player_state)

    def call_on_playback_resume(self, player_state):
        """
        Notify that the playback has been resumed
        """
        self._call_if_enabled(self.on_playback_resume, player_state=player_state)

    def call_on_playback_stopped(self, player_state):
        """
        Notify that a playback has stopped
        """
        self._call_if_enabled(self.on_playback_stopped, player_state=player_state)
        self.enabled = None

    def _call_if_enabled(self, target_func, **kwargs):
        if self.enabled:
            target_func(**kwargs)

    def initialize(self, data):
        """
        Initialize the manager for a new playback.
        If preconditions are not met, this should raise an exception so the
        manager will be disabled through the current playback.
        """
        raise NotImplementedError

    def on_playback_started(self, player_state):
        """
        This method is called when video playback starts
        NOTE: If possible never use sleep delay inside this method
              otherwise it delay the execution of subsequent action managers
        """

    def on_tick(self, player_state):
        """
        This method is called every second from the service,
        but only after the 'on_playback_started' method will be called.
        NOTE: If possible never use sleep delay inside this method
              otherwise it delay the execution of subsequent action managers
        """
        raise NotImplementedError

    def on_playback_seek(self, player_state):
        pass

    def on_playback_pause(self, player_state):
        pass

    def on_playback_resume(self, player_state):
        pass

    def on_playback_stopped(self, player_state):
        pass

    def on_playback_avchange_delayed(self, player_state):
        pass