kodi.plugin.video.peertube/service.py

154 lines
5.7 KiB
Python

# -*- coding: utf-8 -*-
"""
PeerTube service to perform action on torrents in background
Copyright (C) 2018 Cyrille Bollu
Copyright (C) 2021 Thomas Bétous
SPDX-License-Identifier: GPL-3.0-only
See LICENSE.txt for more information.
"""
import AddonSignals
import xbmc
import xbmcvfs
from resources.lib.kodi_utils import kodi
class PeertubePlayer(xbmc.Player):
# Initialize the attributes and call the parent class constructor
def __init__(self):
self.torrent_url = None
self.run_url = None
self.playback_started = False
super(xbmc.Player, self).__init__()
# TODO: Use the python3 format on Matrix
# super().__init__()
def debug(self, message):
"""Log a debug message with the name of the class as prefix
:param str message: message to log
"""
kodi.debug(message=message, prefix="PeertubePlayer")
def onAVStarted(self):
"""Callback called when Kodi has a video stream.
When it is called we consider that the video is actually being played
and we set the according flag.
"""
# Check if the file that is being played belongs to this add-on to not
# conflict with other add-ons or players.
if self.torrent_url is not None:
self.playback_started = True
self.debug(message="Playback started for {}".format(self.torrent_url))
def onPlayBackStopped(self):
"""Callback called when the playback stops
If the file was actually being played (i.e. onAVStarted() was called for
this file before), then we consider that the playback didn't encounter
any error and it was stopped willingly by the user. In this case we
pause the download of the torrent to avoid downloading in background a
video which may never be played again.
But if no file was being played, we ask the user if the download should
be paused or not: it supports the use case when the playback started
whereas the portion of the file that was downloaded was not big enough.
"""
# First check if the file that was being played belongs to this add-on
# to not conflict with other add-ons or players.
if self.torrent_url is not None:
# Then check if the playback actually started: if the playback
# didn't start (probably because there was a too small portion of
# the file that was downloaded), ask the user if the download of
# the torrent should be paused (Kodi do not call onPlayBackError()
# in this case for some reason...).
# Otherwise pause the torrent because we consider the user decided
# to stop the playback.
if self.playback_started:
self.debug(message="Playback stopped: pausing download...")
self.pause_torrent()
self.torrent_url = None
self.playback_started = False
else:
self.debug(message="Playback stopped but an error was"
" detected: asking the user if the"
" download must be stopped.")
if kodi.open_yes_no_dialog(title=kodi.get_string(30423),
message=kodi.get_string(30424)):
self.debug(message="Pausing the download...")
self.pause_torrent()
self.torrent_url = None
self.playback_started = False
def pause_torrent(self):
"""Pause download of the torrent self.torrent_url"""
# Get the torrent handle
torrent = xbmcvfs.File(self.torrent_url)
# Call seek() with -1 to pause the torrent.
torrent.seek(-1)
def update_torrent_info(self, data):
"""Save the information about the torrent being played currently
This function is called through AddonSignals when a video is played.
"""
self.torrent_url = data["torrent_url"]
self.run_url = data["run_url"]
self.debug(message="Received information:\nURL={}\nrun_url={}"
.format(self.torrent_url, self.run_url))
class PeertubeService():
"""
Class used to run a service when Kodi starts
"""
def __init__(self):
"""
Create an instance of PeertubePlayer that will always be active
(required to monitor the events and call the callbacks)
"""
self.player = PeertubePlayer()
def debug(self, message):
"""Log a debug message
:param str message: Message to log (will be prefixed with the name of
the class)
"""
kodi.debug(message=message, prefix="PeertubeService")
def run(self):
"""
Main loop of the PeertubeService class
"""
# Signal that is sent by the main script of the add-on
AddonSignals.registerSlot(kodi.addon_id,
"torrent_information",
self.player.update_torrent_info)
# Display a notification now that the service started.
self.debug("Service started")
if kodi.get_setting("service_start_notif") == "true":
kodi.notif_info(title=kodi.get_string(30400),
message=kodi.get_string(30401))
# Run the service until Kodi exits
monitor = xbmc.Monitor()
while not monitor.abortRequested():
if monitor.waitForAbort(1):
# Abort was requested while waiting. We must exit.
self.debug("Exiting")
break
if __name__ == "__main__":
# Create a PeertubeService instance
service = PeertubeService()
# Start the service
service.run()