mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-06-04 23:36:12 +00:00
Version 1.1.63
alpha ready for beta testing
This commit is contained in:
parent
0200df3225
commit
3f6fe0a9e7
25 changed files with 6278 additions and 4069 deletions
273
service.py
273
service.py
|
@ -7,8 +7,8 @@ import sys
|
|||
import time
|
||||
from datetime import datetime
|
||||
|
||||
import xbmcaddon
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
|
||||
|
@ -16,152 +16,142 @@ import xbmcvfs
|
|||
|
||||
_addon = xbmcaddon.Addon(id='plugin.video.emby')
|
||||
addon_path = _addon.getAddonInfo('path').decode('utf-8')
|
||||
base_resource_path = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
|
||||
sys.path.append(base_resource_path)
|
||||
base_resource = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
|
||||
sys.path.append(base_resource)
|
||||
|
||||
#################################################################################################
|
||||
|
||||
import KodiMonitor
|
||||
import Utils as utils
|
||||
from ClientInformation import ClientInformation
|
||||
from ConnectionManager import ConnectionManager
|
||||
from UserClient import UserClient
|
||||
from Player import Player
|
||||
from WebSocketClient import WebSocketThread
|
||||
from LibrarySync import LibrarySync
|
||||
import userclient
|
||||
import clientinfo
|
||||
import initialsetup
|
||||
import kodimonitor
|
||||
import librarysync
|
||||
import player
|
||||
import utils
|
||||
import videonodes
|
||||
import websocket_client as wsc
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
||||
class Service():
|
||||
|
||||
KodiMonitor = KodiMonitor.Kodi_Monitor()
|
||||
clientInfo = ClientInformation()
|
||||
|
||||
addonName = clientInfo.getAddonName()
|
||||
logLevel = UserClient().getLogLevel()
|
||||
WINDOW = xbmcgui.Window(10000)
|
||||
|
||||
newWebSocketThread = None
|
||||
newUserClient = None
|
||||
newLibraryThread = None
|
||||
warn_auth = True
|
||||
welcome_msg = True
|
||||
server_online = True
|
||||
warn_auth = True
|
||||
|
||||
def __init__(self, *args):
|
||||
userclient_running = False
|
||||
websocket_running = False
|
||||
library_running = False
|
||||
kodimonitor_running = False
|
||||
|
||||
addonName = self.addonName
|
||||
clientInfo = self.clientInfo
|
||||
logLevel = self.logLevel
|
||||
|
||||
utils.window('getLogLevel', value=str(logLevel))
|
||||
utils.window('kodiProfile_emby', value=xbmc.translatePath("special://profile"))
|
||||
def __init__(self):
|
||||
|
||||
self.clientInfo = clientinfo.ClientInfo()
|
||||
self.addonName = self.clientInfo.getAddonName()
|
||||
logLevel = userclient.UserClient().getLogLevel()
|
||||
self.monitor = xbmc.Monitor()
|
||||
|
||||
utils.window('emby_logLevel', value=str(logLevel))
|
||||
utils.window('emby_kodiProfile', value=xbmc.translatePath("special://profile"))
|
||||
|
||||
# Initial logging
|
||||
self.logMsg("Starting Monitor", 0)
|
||||
self.logMsg("======== START %s ========" % addonName, 0)
|
||||
self.logMsg("Platform: %s" % (clientInfo.getPlatform()), 0)
|
||||
self.logMsg("======== START %s ========" % self.addonName, 0)
|
||||
self.logMsg("Platform: %s" % (self.clientInfo.getPlatform()), 0)
|
||||
self.logMsg("KODI Version: %s" % xbmc.getInfoLabel('System.BuildVersion'), 0)
|
||||
self.logMsg("%s Version: %s" % (addonName, clientInfo.getVersion()), 0)
|
||||
self.logMsg("%s Version: %s" % (self.addonName, self.clientInfo.getVersion()), 0)
|
||||
self.logMsg("Using plugin paths: %s" % (utils.settings('useDirectPaths') != "true"), 0)
|
||||
self.logMsg("Log Level: %s" % logLevel, 0)
|
||||
|
||||
# Reset window props for profile switch
|
||||
utils.window('Server_online', clear=True)
|
||||
utils.window('Server_status', clear=True)
|
||||
utils.window('startup', clear=True)
|
||||
utils.window('OnWakeSync', clear=True)
|
||||
utils.window('kodiScan', clear=True)
|
||||
utils.window('minDBVersionCheck', clear=True)
|
||||
|
||||
# Set min DB version
|
||||
utils.window('minDBVersion', value="1.1.52")
|
||||
properties = [
|
||||
|
||||
embyProperty = utils.window('Emby.nodes.total')
|
||||
propNames = [
|
||||
|
||||
"index","path","title","content",
|
||||
"inprogress.content","inprogress.title",
|
||||
"inprogress.content","inprogress.path",
|
||||
"nextepisodes.title","nextepisodes.content",
|
||||
"nextepisodes.path","unwatched.title",
|
||||
"unwatched.content","unwatched.path",
|
||||
"recent.title","recent.content","recent.path",
|
||||
"recentepisodes.title","recentepisodes.content",
|
||||
"recentepisodes.path","inprogressepisodes.title",
|
||||
"inprogressepisodes.content","inprogressepisodes.path"
|
||||
"emby_online", "emby_serverStatus", "emby_onWake",
|
||||
"emby_syncRunning", "emby_dbCheck", "emby_kodiScan",
|
||||
"emby_shouldStop", "emby_currUser", "emby_dbScan", "emby_sessionId"
|
||||
]
|
||||
for prop in properties:
|
||||
utils.window(prop, clear=True)
|
||||
|
||||
if embyProperty:
|
||||
totalNodes = int(embyProperty)
|
||||
for i in range(totalNodes):
|
||||
for prop in propNames:
|
||||
utils.window('Emby.nodes.%s.%s' % (str(i), prop), clear=True)
|
||||
# Clear playlist properties
|
||||
xbmcgui.Window(10101).clearProperties()
|
||||
# Clear video nodes properties
|
||||
videonodes.VideoNodes().clearProperties()
|
||||
|
||||
# Set the minimum database version
|
||||
utils.window('emby_minDBVersion', value="1.1.63")
|
||||
|
||||
def logMsg(self, msg, lvl=1):
|
||||
|
||||
className = self.__class__.__name__
|
||||
utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl))
|
||||
utils.logMsg("%s %s" % (self.addonName, className), msg, lvl)
|
||||
|
||||
|
||||
def ServiceEntryPoint(self):
|
||||
|
||||
# Important: Threads depending on abortRequest will not trigger
|
||||
# if profile switch happens more than once.
|
||||
monitor = self.monitor
|
||||
kodiProfile = xbmc.translatePath("special://profile")
|
||||
|
||||
# Server auto-detect
|
||||
ConnectionManager().checkServer()
|
||||
initialsetup.InitialSetup().setup()
|
||||
|
||||
# Initialize important threads
|
||||
user = UserClient()
|
||||
player = Player()
|
||||
ws = WebSocketThread()
|
||||
library = LibrarySync()
|
||||
user = userclient.UserClient()
|
||||
ws = wsc.WebSocket_Client()
|
||||
library = librarysync.LibrarySync()
|
||||
kplayer = player.Player()
|
||||
# Sync and progress report
|
||||
lastProgressUpdate = datetime.today()
|
||||
|
||||
while not self.KodiMonitor.abortRequested():
|
||||
while not monitor.abortRequested():
|
||||
|
||||
if utils.window('emby_kodiProfile') != kodiProfile:
|
||||
# Profile change happened, terminate this thread and others
|
||||
self.logMsg(
|
||||
"Kodi profile was: %s and changed to: %s. Terminating old Emby thread."
|
||||
% (kodiProfile, utils.window('emby_kodiProfile')), 1)
|
||||
|
||||
break
|
||||
|
||||
# Before proceeding, need to make sure:
|
||||
# 1. Server is online
|
||||
# 2. User is set
|
||||
# 3. User has access to the server
|
||||
|
||||
if utils.window("kodiProfile_emby") != kodiProfile:
|
||||
# Profile change happened, terminate this thread
|
||||
self.logMsg("Kodi profile was: %s and changed to: %s. Terminating old Emby thread." % (kodiProfile, utils.window("kodiProfile_emby")), 1)
|
||||
break
|
||||
|
||||
if utils.window('Server_online') == "true":
|
||||
if utils.window('emby_online') == "true":
|
||||
|
||||
# Emby server is online
|
||||
# Verify if user is set and has access to the server
|
||||
if (user.currUser is not None) and user.HasAccess:
|
||||
|
||||
# If an item is playing
|
||||
# If an item is playing
|
||||
if xbmc.Player().isPlaying():
|
||||
try:
|
||||
# Update and report progress
|
||||
playTime = xbmc.Player().getTime()
|
||||
playtime = xbmc.Player().getTime()
|
||||
totalTime = xbmc.Player().getTotalTime()
|
||||
currentFile = player.currentFile
|
||||
currentFile = kplayer.currentFile
|
||||
|
||||
# Update positionticks
|
||||
if player.played_information.get(currentFile) is not None:
|
||||
player.played_information[currentFile]['currentPosition'] = playTime
|
||||
if kplayer.played_info.get(currentFile) is not None:
|
||||
kplayer.played_info[currentFile]['currentPosition'] = playtime
|
||||
|
||||
td = datetime.today() - lastProgressUpdate
|
||||
secDiff = td.seconds
|
||||
|
||||
# Report progress to Emby server
|
||||
if (secDiff > 3):
|
||||
player.reportPlayback()
|
||||
kplayer.reportPlayback()
|
||||
lastProgressUpdate = datetime.today()
|
||||
|
||||
elif utils.window('commandUpdate') == "true":
|
||||
elif utils.window('emby_command') == "true":
|
||||
# Received a remote control command that
|
||||
# requires updating immediately
|
||||
utils.window('commandUpdate', clear=True)
|
||||
player.reportPlayback()
|
||||
lastProgressUpdate = da4tetime.today()
|
||||
utils.window('emby_command', clear=True)
|
||||
kplayer.reportPlayback()
|
||||
lastProgressUpdate = datetime.today()
|
||||
|
||||
except Exception as e:
|
||||
self.logMsg("Exception in Playback Monitor Service: %s" % e, 1)
|
||||
|
@ -169,27 +159,34 @@ class Service():
|
|||
else:
|
||||
# Start up events
|
||||
self.warn_auth = True
|
||||
if utils.settings('supressConnectMsg') == "false":
|
||||
if self.welcome_msg:
|
||||
# Reset authentication warnings
|
||||
self.welcome_msg = False
|
||||
# Get additional users
|
||||
additionalUsers = user.AdditionalUser
|
||||
if additionalUsers:
|
||||
add = ", %s" % ", ".join(additionalUsers)
|
||||
else:
|
||||
add = ""
|
||||
xbmcgui.Dialog().notification("Emby server", "Welcome %s%s!" % (user.currUser, add), icon="special://home/addons/plugin.video.emby/icon.png", time=2000, sound=False)
|
||||
if utils.settings('connectMsg') == "true" and self.welcome_msg:
|
||||
# Reset authentication warnings
|
||||
self.welcome_msg = False
|
||||
# Get additional users
|
||||
additionalUsers = user.AdditionalUser
|
||||
if additionalUsers:
|
||||
add = ", %s" % ", ".join(additionalUsers)
|
||||
else:
|
||||
add = ""
|
||||
xbmcgui.Dialog().notification(
|
||||
heading="Emby server",
|
||||
message="Welcome %s%s!" % (user.currUser, add),
|
||||
icon="special://home/addons/plugin.video.emby/icon.png",
|
||||
time=2000,
|
||||
sound=False)
|
||||
|
||||
# Start monitoring kodi events
|
||||
if not self.kodimonitor_running:
|
||||
self.kodimonitor_running = kodimonitor.KodiMonitor()
|
||||
|
||||
# Start the Websocket Client
|
||||
if (self.newWebSocketThread is None):
|
||||
self.newWebSocketThread = "Started"
|
||||
if not self.websocket_running:
|
||||
self.websocket_running = True
|
||||
ws.start()
|
||||
# Start the Library Sync Thread
|
||||
if (self.newLibraryThread is None):
|
||||
self.newLibraryThread = "Started"
|
||||
# Start the syncing thread
|
||||
if not self.library_running:
|
||||
self.library_running = True
|
||||
library.start()
|
||||
|
||||
else:
|
||||
|
||||
if (user.currUser is None) and self.warn_auth:
|
||||
|
@ -204,20 +201,19 @@ class Service():
|
|||
# Verify access with an API call
|
||||
user.hasAccess()
|
||||
|
||||
if utils.window('Server_online') != "true":
|
||||
if utils.window('emby_online') != "true":
|
||||
# Server went offline
|
||||
break
|
||||
|
||||
if self.KodiMonitor.waitForAbort(5):
|
||||
if monitor.waitForAbort(5):
|
||||
# Abort was requested while waiting. We should exit
|
||||
break
|
||||
|
||||
else:
|
||||
# Wait until Emby server is online
|
||||
# or Kodi is shut down.
|
||||
while not self.KodiMonitor.abortRequested():
|
||||
while not monitor.abortRequested():
|
||||
|
||||
if user.getServer() == "":
|
||||
if user.getServer() == False:
|
||||
# No server info set in add-on settings
|
||||
pass
|
||||
|
||||
|
@ -226,8 +222,14 @@ class Service():
|
|||
# Alert the user and suppress future warning
|
||||
if self.server_online:
|
||||
self.logMsg("Server is offline.", 1)
|
||||
utils.window('Server_online', value="false")
|
||||
xbmcgui.Dialog().notification("Error connecting", "%s Server is unreachable." % self.addonName, icon="special://home/addons/plugin.video.emby/icon.png", sound=False)
|
||||
utils.window('emby_online', value="false")
|
||||
|
||||
xbmcgui.Dialog().notification(
|
||||
heading="Error connecting",
|
||||
message="%s Server is unreachable." % self.addonName,
|
||||
icon="special://home/addons/plugin.video.emby/icon.png",
|
||||
sound=False)
|
||||
|
||||
self.server_online = False
|
||||
|
||||
else:
|
||||
|
@ -235,54 +237,55 @@ class Service():
|
|||
if not self.server_online:
|
||||
# Server was offline when Kodi started.
|
||||
# Wait for server to be fully established.
|
||||
if self.KodiMonitor.waitForAbort(5):
|
||||
if monitor.waitForAbort(5):
|
||||
# Abort was requested while waiting.
|
||||
break
|
||||
# Alert the user that server is online.
|
||||
xbmcgui.Dialog().notification("Emby server", "Welcome %s!" % user.currUser, icon="special://home/addons/plugin.video.emby/icon.png", time=2000, sound=False)
|
||||
xbmcgui.Dialog().notification(
|
||||
heading="Emby server",
|
||||
message="Server is online.",
|
||||
icon="special://home/addons/plugin.video.emby/icon.png",
|
||||
time=2000,
|
||||
sound=False)
|
||||
|
||||
self.server_online = True
|
||||
self.logMsg("Server is online and ready.", 1)
|
||||
utils.window('Server_online', value="true")
|
||||
utils.window('emby_online', value="true")
|
||||
|
||||
# Start the User client
|
||||
if self.newUserClient is None:
|
||||
self.newUserClient = "Started"
|
||||
# Start the userclient thread
|
||||
if not self.userclient_running:
|
||||
self.userclient_running = True
|
||||
user.start()
|
||||
|
||||
break
|
||||
|
||||
if self.KodiMonitor.waitForAbort(1):
|
||||
if monitor.waitForAbort(1):
|
||||
# Abort was requested while waiting.
|
||||
break
|
||||
|
||||
if self.KodiMonitor.waitForAbort(1):
|
||||
if monitor.waitForAbort(1):
|
||||
# Abort was requested while waiting. We should exit
|
||||
break
|
||||
|
||||
##### Emby thread is terminating. #####
|
||||
|
||||
# If music is enabled and direct stream for music is enabled
|
||||
# We use Kodi pathsubstitution to allow for music to play outside network
|
||||
# The setting needs to be set before Kodi starts.
|
||||
if utils.settings('enableMusicSync') == "true" and utils.settings('directstreammusic') == "true":
|
||||
# We need to keep track of the settings
|
||||
alternate = utils.settings('altip') == "true"
|
||||
pathsub = utils.settings('pathsub') == "true"
|
||||
|
||||
if pathsub and not alternate:
|
||||
# Path sub in place, but primary address in use, remove it
|
||||
utils.pathsubstitution(False)
|
||||
elif not pathsub and alternate:
|
||||
# Path sub not in place, but secondary address in use, add it
|
||||
utils.pathsubstitution()
|
||||
|
||||
if (self.newWebSocketThread is not None):
|
||||
ws.stopClient()
|
||||
if self.library_running:
|
||||
library.stopThread()
|
||||
|
||||
if (self.newUserClient is not None):
|
||||
if self.websocket_running:
|
||||
ws.stopClient()
|
||||
|
||||
if self.userclient_running:
|
||||
user.stopClient()
|
||||
|
||||
self.logMsg("======== STOP %s ========" % self.addonName, 0)
|
||||
|
||||
# Start the service
|
||||
Service().ServiceEntryPoint()
|
||||
# Delay option
|
||||
delay = int(utils.settings('startupDelay'))
|
||||
|
||||
xbmc.log("Delaying emby startup by: %s sec..." % delay)
|
||||
if delay and xbmc.Monitor().waitForAbort(delay):
|
||||
# Start the service
|
||||
xbmc.log("Abort requested while waiting. Emby for kodi not started.")
|
||||
else:
|
||||
Service().ServiceEntryPoint()
|
Loading…
Add table
Add a link
Reference in a new issue