Skip to content

Commit

Permalink
[script.timers] 3.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Heckie75 committed Jun 30, 2023
1 parent 59c7e32 commit 145cccd
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 42 deletions.
11 changes: 6 additions & 5 deletions script.timers/addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.timers" name="Timers" version="3.6.0" provider-name="Heckie">
<addon id="script.timers" name="Timers" version="3.7.0" provider-name="Heckie">
<requires>
<import addon="xbmc.python" version="3.0.0" />
</requires>
Expand Down Expand Up @@ -66,6 +66,10 @@
<website>https://github.com/Heckie75/kodi-addon-timers</website>
<source>https://github.com/Heckie75/kodi-addon-timers</source>
<news>
v3.7.0 (2023-06-30)
- If you stop explicitly playback while a start-stop-timer is running there won't be another stop action anymore when this timer runs out.
- Added workaround that streamed video (probably mpeg-dash) immediately stops after timer has started (only happened if 'seek to correct time if timer starts belatedly' is activated)

v3.6.0 (2023-04-16)
- Smart shuffle mode for slideshows (try randomly to find folder that fits into timeframe)
- Fixed resuming slideshow at right position
Expand All @@ -87,10 +91,7 @@ v3.3.1 (2022-11-26)
- Bugfix: scheduled timers stop working that are scheduled after Sunday (week change Sun -> Mon)
- Refactoring

v3.3.0 (2022-10-08)
- Improved scheduler that enables scheduling to the second, reduces CPU load on idle and enables smoother fading
- Added fields for start and end time in order to schedule to the second (expert only)
- Fixed Zattoo PVR support and other audio/video addons
Complete changelog see https://github.com/Heckie75/kodi-addon-timers
</news>
<assets>
<icon>resources/assets/icon.png</icon>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,10 @@ msgctxt "#32288"
msgid "run addon"
msgstr "führe Addon aus"

msgctxt "#32289"
msgid "interrupt running timers"
msgstr "unterbreche laufende Timer"

msgctxt "#32300"
msgid "Opens a dialog where you can enter a duration for pause from now."
msgstr "Öffnet einen Dialog zur Eingabe der Dauer von jetzt an."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,10 @@ msgctxt "#32288"
msgid "run addon"
msgstr ""

msgctxt "#32289"
msgid "interrupt running timers"
msgstr ""

msgctxt "#32300"
msgid "Opens a dialog where you can enter a duration for pause from now."
msgstr ""
Expand Down
36 changes: 26 additions & 10 deletions script.timers/resources/lib/player/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from resources.lib.player.mediatype import AUDIO, PICTURE, TYPES, VIDEO
from resources.lib.player.playerstatus import PlayerStatus
from resources.lib.player.playlist import PlayList
from resources.lib.timer.notification import showNotification
from resources.lib.timer.timer import Timer
from resources.lib.utils import datetime_utils
from resources.lib.utils.vfs_utils import (convert_to_playlist,
Expand Down Expand Up @@ -33,6 +34,8 @@ def __init__(self) -> None:

self._resume_status: 'dict[PlayerStatus]' = dict()

self._running_stop_at_end_timer: 'tuple[Timer, bool]' = (None, False)

def playTimer(self, timer: Timer, dtd: datetime_utils.DateTimeDelta) -> None:

def _save_resume(_timer: Timer) -> None:
Expand Down Expand Up @@ -107,6 +110,9 @@ def _get_delay_for_seektime(_timer: Timer, _dtd: datetime_utils.DateTimeDelta) -
repeat=player_utils.REPEAT_ALL if timer.repeat else player_utils.REPEAT_OFF,
shuffled=timer.shuffle)

if timer.is_stop_at_end_timer():
self._running_stop_at_end_timer = (timer, False)

def _playAV(self, playlist: PlayList, startpos=0, seektime=None, repeat=player_utils.REPEAT_OFF, shuffled=False, speed=1.0) -> None:

self._playlist = playlist
Expand Down Expand Up @@ -163,7 +169,11 @@ def onPlayBackStopped(self) -> None:
self._skip_next_stop_event_until_started = False

else:
_rst = self._running_stop_at_end_timer
self._reset()
if _rst[0] and not _rst[1]:
self._running_stop_at_end_timer = (_rst[0], True)
showNotification(_rst[0], msg_id=32289)

def onPlayBackEnded(self) -> None:

Expand All @@ -174,6 +184,9 @@ def onPlayBackEnded(self) -> None:
elif AUDIO in self._resume_status:
self._resumeFormer(type=AUDIO, keep=True)

else:
self._reset()

def onPlayBackError(self) -> None:

self._reset()
Expand All @@ -195,7 +208,7 @@ def resumeFormerOrStop(self, timer: Timer) -> None:
if not timer.is_resuming_timer() or not self._resumeFormer(type=timer.media_type, keep=False):
if timer.media_type == PICTURE:
self.stopPlayer(PICTURE)
else:
elif timer != self._running_stop_at_end_timer[0] or not self._running_stop_at_end_timer[1]:
self.stop()

self._reset(type=timer.media_type)
Expand Down Expand Up @@ -286,7 +299,7 @@ def _seekTimeInPlaylist() -> None:

_totalTime = self.getTotalTime()
self._playlist_timeline.append(_totalTime)
if self._playlist and self._playlist.getposition() < self._playlist.size() - 1:
if self._playlist.getposition() < self._playlist.size() - 1:
self._seektime -= _totalTime
self._skip_next_stop_event_until_started = True
self.playnext()
Expand Down Expand Up @@ -322,10 +335,10 @@ def _seekTimeInPlaylist() -> None:
tries += 1

_totalTime = self.getTotalTime()
if tries == self._MAX_TRIES or _totalTime < 1:
if tries == self._MAX_TRIES or _totalTime < 10:
self._resetSeek()

elif self._seektime >= _totalTime:
elif self._playlist.size() and self._seektime >= _totalTime:
_seekTimeInPlaylist()

else:
Expand Down Expand Up @@ -355,6 +368,7 @@ def _reset(self, type=None) -> None:

self.setRepeat(player_utils.REPEAT_OFF)
self.setShuffled(False)
self._running_stop_at_end_timer = (None, False)

def getVolume(self) -> int:

Expand Down Expand Up @@ -389,9 +403,11 @@ def _getSlideshowStaytime(self) -> int:
return player_utils.get_slideshow_staytime()

def __str__(self) -> str:
return "Player[_seek_delayed_timer=%s, _default_volume=%i, _recent_volume=%i, _paused=%s, _seektime=%f, _resume_status=[%s]]" % (self._seek_delayed_timer,
self._default_volume or -1,
self._recent_volume or -1,
self._paused,
self._seektime or 0,
", ".join(["%s=%s" % (k, self._resume_status[k]) for k in self._resume_status]))
return "Player[_seek_delayed_timer=%s, _default_volume=%i, _recent_volume=%i, _paused=%s, _seektime=%f, _running_stop_at_end_timer=%s, _resume_status=[%s]]" % (self._seek_delayed_timer,
self._default_volume or -1,
self._recent_volume or -1,
self._paused,
self._seektime or 0,
str(
self._running_stop_at_end_timer),
", ".join(["%s=%s" % (k, self._resume_status[k]) for k in self._resume_status]))
13 changes: 13 additions & 0 deletions script.timers/resources/lib/timer/notification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import xbmcaddon
import xbmcgui
from resources.lib.timer.timer import Timer
from resources.lib.utils.vfs_utils import get_asset_path


def showNotification(timer: Timer, msg_id: int, icon="icon_timers.png") -> None:

if timer.notify:
addon = xbmcaddon.Addon()
icon_path = get_asset_path(icon)
xbmcgui.Dialog().notification(
timer.label, addon.getLocalizedString(msg_id), icon_path)
45 changes: 18 additions & 27 deletions script.timers/resources/lib/timer/scheduleraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
from resources.lib.player.player import Player
from resources.lib.player.player_utils import (get_types_replaced_by_type,
run_addon)
from resources.lib.timer.notification import showNotification
from resources.lib.timer.storage import Storage
from resources.lib.timer.timer import (END_TYPE_NO, FADE_IN_FROM_MIN,
FADE_OUT_FROM_CURRENT, STATE_ENDING,
STATE_RUNNING, STATE_STARTING,
STATE_WAITING,
from resources.lib.timer.timer import (FADE_IN_FROM_MIN, FADE_OUT_FROM_CURRENT,
STATE_ENDING, STATE_RUNNING,
STATE_STARTING, STATE_WAITING,
SYSTEM_ACTION_CEC_STANDBY,
SYSTEM_ACTION_HIBERNATE,
SYSTEM_ACTION_POWEROFF,
Expand All @@ -20,7 +20,6 @@
SYSTEM_ACTION_STANDBY, TIMER_WEEKLY,
Timer)
from resources.lib.utils.datetime_utils import DateTimeDelta, abs_time_diff
from resources.lib.utils.vfs_utils import get_asset_path


class SchedulerAction:
Expand Down Expand Up @@ -289,34 +288,34 @@ def perform(self, now: DateTimeDelta) -> None:
def _performPlayerAction(_now: DateTimeDelta) -> None:

if self.timerToPlayAV:
_showNotification(self.timerToPlayAV, msg_id=32280)
showNotification(self.timerToPlayAV, msg_id=32280)
self._player.playTimer(self.timerToPlayAV, _now)

elif self.timerToStopAV:
_showNotification(self.timerToStopAV, msg_id=32281)
showNotification(self.timerToStopAV, msg_id=32281)
self._player.resumeFormerOrStop(self.timerToStopAV)

elif self.timerToPauseAV and not self._player.isPaused():
_showNotification(self.timerToPauseAV, msg_id=32282)
showNotification(self.timerToPauseAV, msg_id=32282)
self._player.pause()

elif self.timerToUnpauseAV and self._player.isPaused():
_showNotification(self.timerToUnpauseAV, msg_id=32283)
showNotification(self.timerToUnpauseAV, msg_id=32283)
self._player.pause()

elif self.fader:
_showNotification(self.fader, msg_id=32284)
showNotification(self.fader, msg_id=32284)

for type in set(self._forceResumeResetTypes):
self._player.resetResumeStatus(type)

if not self.timerToPlayAV or self.timerToPlayAV.media_type != VIDEO:
if self.timerToPlaySlideshow:
_showNotification(self.timerToPlaySlideshow, msg_id=32286)
showNotification(self.timerToPlaySlideshow, msg_id=32286)
self._player.playTimer(self.timerToPlaySlideshow, _now)

elif self.timerToStopSlideshow:
_showNotification(self.timerToStopSlideshow, msg_id=32287)
showNotification(self.timerToStopSlideshow, msg_id=32287)
self._player.resumeFormerOrStop(self.timerToStopSlideshow)

def _setVolume(dtd: DateTimeDelta) -> None:
Expand All @@ -334,14 +333,6 @@ def _setVolume(dtd: DateTimeDelta) -> None:
self._player.setVolume(
max(ending_faders, key=lambda t: t.return_vol).return_vol)

def _showNotification(timer: Timer, msg_id: int, icon="icon_timers.png") -> None:

if timer.notify:
addon = xbmcaddon.Addon()
icon_path = get_asset_path(icon)
xbmcgui.Dialog().notification(
timer.label, addon.getLocalizedString(msg_id), icon_path)

def _consumeSingleRunTimers() -> None:

def _reset(timers: 'list[Timer]') -> None:
Expand All @@ -363,7 +354,7 @@ def _reset(timers: 'list[Timer]') -> None:
def _runScripts() -> None:

for timer in self.timersToRunScript:
_showNotification(timer, msg_id=32288)
showNotification(timer, msg_id=32288)
run_addon(timer.path)

def _performSystemAction() -> None:
Expand All @@ -372,27 +363,27 @@ def _performSystemAction() -> None:
pass

elif self.timerWithSystemAction.system_action == SYSTEM_ACTION_SHUTDOWN_KODI:
_showNotification(self.timerWithSystemAction, msg_id=32082)
showNotification(self.timerWithSystemAction, msg_id=32082)
xbmc.shutdown()

elif self.timerWithSystemAction.system_action == SYSTEM_ACTION_QUIT_KODI:
_showNotification(self.timerWithSystemAction, msg_id=32083)
showNotification(self.timerWithSystemAction, msg_id=32083)
xbmc.executebuiltin("Quit()")

elif self.timerWithSystemAction.system_action == SYSTEM_ACTION_STANDBY:
_showNotification(self.timerWithSystemAction, msg_id=32084)
showNotification(self.timerWithSystemAction, msg_id=32084)
xbmc.executebuiltin("Suspend()")

elif self.timerWithSystemAction.system_action == SYSTEM_ACTION_HIBERNATE:
_showNotification(self.timerWithSystemAction, msg_id=32085)
showNotification(self.timerWithSystemAction, msg_id=32085)
xbmc.executebuiltin("Hibernate()")

elif self.timerWithSystemAction.system_action == SYSTEM_ACTION_POWEROFF:
_showNotification(self.timerWithSystemAction, msg_id=32086)
showNotification(self.timerWithSystemAction, msg_id=32086)
xbmc.executebuiltin("Powerdown()")

elif self.timerWithSystemAction.system_action == SYSTEM_ACTION_CEC_STANDBY:
_showNotification(self.timerWithSystemAction, msg_id=32093)
showNotification(self.timerWithSystemAction, msg_id=32093)
xbmc.executebuiltin("CECStandby()")

def _adjustState() -> None:
Expand Down

0 comments on commit 145cccd

Please sign in to comment.