2015-07-22 13:16:08 +00:00
# -*- coding: utf-8 -*-
2015-06-05 06:05:40 +00:00
2015-09-24 11:59:26 +00:00
#################################################################################################
2015-06-05 06:05:40 +00:00
import os
import sys
import time
from datetime import datetime
2015-03-13 21:24:59 +00:00
import xbmcaddon
import xbmc
import xbmcgui
2015-07-22 13:16:08 +00:00
import xbmcvfs
2015-03-13 21:24:59 +00:00
2015-09-24 11:59:26 +00:00
#################################################################################################
2015-08-14 09:03:12 +00:00
_addon = xbmcaddon . Addon ( id = ' plugin.video.emby ' )
addon_path = _addon . getAddonInfo ( ' path ' ) . decode ( ' utf-8 ' )
2015-06-05 06:05:40 +00:00
base_resource_path = xbmc . translatePath ( os . path . join ( addon_path , ' resources ' , ' lib ' ) ) . decode ( ' utf-8 ' )
sys . path . append ( base_resource_path )
2015-03-13 21:24:59 +00:00
2015-09-24 11:59:26 +00:00
#################################################################################################
2015-03-13 21:24:59 +00:00
import KodiMonitor
import Utils as utils
2015-04-03 10:13:01 +00:00
from ClientInformation import ClientInformation
2015-06-05 06:05:40 +00:00
from ConnectionManager import ConnectionManager
2015-04-03 10:13:01 +00:00
from UserClient import UserClient
2015-06-05 06:05:40 +00:00
from Player import Player
from WebSocketClient import WebSocketThread
from LibrarySync import LibrarySync
2015-04-06 17:17:32 +00:00
2015-09-24 11:59:26 +00:00
#################################################################################################
2015-03-13 21:24:59 +00:00
class Service ( ) :
2015-04-03 10:13:01 +00:00
2015-05-17 12:11:50 +00:00
KodiMonitor = KodiMonitor . Kodi_Monitor ( )
2015-06-05 06:05:40 +00:00
clientInfo = ClientInformation ( )
2015-04-06 17:17:32 +00:00
addonName = clientInfo . getAddonName ( )
2015-06-05 10:12:09 +00:00
logLevel = UserClient ( ) . getLogLevel ( )
2015-05-03 05:27:43 +00:00
WINDOW = xbmcgui . Window ( 10000 )
2015-06-05 06:05:40 +00:00
newWebSocketThread = None
newUserClient = None
2015-06-16 05:53:01 +00:00
newLibraryThread = None
2015-05-03 05:27:43 +00:00
warn_auth = True
2015-06-04 10:10:49 +00:00
welcome_msg = True
2015-05-03 05:27:43 +00:00
server_online = True
2015-06-05 06:05:40 +00:00
def __init__ ( self , * args ) :
2015-04-26 20:41:39 +00:00
addonName = self . addonName
2015-09-24 11:59:26 +00:00
clientInfo = self . clientInfo
logLevel = self . logLevel
utils . window ( ' getLogLevel ' , value = str ( logLevel ) )
utils . window ( ' kodiProfile_emby ' , value = xbmc . translatePath ( " special://profile " ) )
2015-03-13 21:24:59 +00:00
2015-06-05 06:05:40 +00:00
# Initial logging
2015-04-06 17:17:32 +00:00
self . logMsg ( " Starting Monitor " , 0 )
self . logMsg ( " ======== START %s ======== " % addonName , 0 )
2015-09-24 11:59:26 +00:00
self . logMsg ( " Platform: %s " % ( clientInfo . getPlatform ( ) ) , 0 )
2015-06-05 06:05:40 +00:00
self . logMsg ( " KODI Version: %s " % xbmc . getInfoLabel ( ' System.BuildVersion ' ) , 0 )
2015-09-24 11:59:26 +00:00
self . logMsg ( " %s Version: %s " % ( addonName , clientInfo . getVersion ( ) ) , 0 )
self . logMsg ( " Log Level: %s " % logLevel , 0 )
2015-06-05 06:05:40 +00:00
# Reset window props for profile switch
2015-09-24 11:59:26 +00:00
utils . window ( ' Server_online ' , clear = True )
utils . window ( ' Server_status ' , clear = True )
utils . window ( ' startup ' , clear = True )
utils . window ( ' OnWakeSync ' , clear = True )
2015-11-08 11:42:53 +00:00
utils . window ( ' kodiScan ' , clear = True )
2015-09-24 11:59:26 +00:00
utils . window ( ' minDBVersionCheck ' , clear = True )
2015-09-06 17:28:00 +00:00
2015-09-07 09:12:28 +00:00
# Set min DB version
2015-10-20 10:22:23 +00:00
utils . window ( ' minDBVersion ' , value = " 1.1.52 " )
2015-06-05 06:05:40 +00:00
2015-09-24 11:59:26 +00:00
embyProperty = utils . window ( ' Emby.nodes.total ' )
2015-06-05 06:05:40 +00:00
propNames = [
2015-05-07 08:32:30 +00:00
2015-06-05 06:05:40 +00:00
" 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 "
]
2015-05-07 08:32:30 +00:00
if embyProperty :
totalNodes = int ( embyProperty )
for i in range ( totalNodes ) :
for prop in propNames :
2015-09-24 11:59:26 +00:00
utils . window ( ' Emby.nodes. %s . %s ' % ( str ( i ) , prop ) , clear = True )
2015-04-06 17:17:32 +00:00
def logMsg ( self , msg , lvl = 1 ) :
2015-06-05 06:05:40 +00:00
2015-05-03 05:27:43 +00:00
className = self . __class__ . __name__
2015-06-05 06:05:40 +00:00
utils . logMsg ( " %s %s " % ( self . addonName , className ) , msg , int ( lvl ) )
2015-03-13 21:24:59 +00:00
def ServiceEntryPoint ( self ) :
2015-09-24 11:59:26 +00:00
kodiProfile = xbmc . translatePath ( " special://profile " )
2015-06-05 06:05:40 +00:00
# Server auto-detect
2015-03-14 02:37:03 +00:00
ConnectionManager ( ) . checkServer ( )
2015-06-05 06:05:40 +00:00
# Initialize important threads
2015-04-03 10:13:01 +00:00
user = UserClient ( )
player = Player ( )
2015-04-01 19:07:29 +00:00
ws = WebSocketThread ( )
2015-06-16 05:53:01 +00:00
library = LibrarySync ( )
2015-06-05 06:05:40 +00:00
# Sync and progress report
lastProgressUpdate = datetime . today ( )
2015-04-01 19:07:29 +00:00
while not self . KodiMonitor . abortRequested ( ) :
2015-05-03 05:27:43 +00:00
2015-06-05 06:05:40 +00:00
# Before proceeding, need to make sure:
# 1. Server is online
# 2. User is set
# 3. User has access to the server
2015-09-24 11:59:26 +00:00
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
2015-06-05 06:05:40 +00:00
2015-09-24 11:59:26 +00:00
if utils . window ( ' Server_online ' ) == " true " :
2015-06-05 06:05:40 +00:00
# Emby server is online
# Verify if user is set and has access to the server
2015-07-22 13:16:08 +00:00
if ( user . currUser is not None ) and user . HasAccess :
2015-06-16 05:53:01 +00:00
2015-06-05 06:05:40 +00:00
# If an item is playing
2015-05-12 07:34:03 +00:00
if xbmc . Player ( ) . isPlaying ( ) :
try :
2015-06-05 06:05:40 +00:00
# Update and report progress
2015-05-12 07:34:03 +00:00
playTime = xbmc . Player ( ) . getTime ( )
totalTime = xbmc . Player ( ) . getTotalTime ( )
2015-10-01 13:08:34 +00:00
currentFile = player . currentFile
2015-05-12 07:34:03 +00:00
2015-06-05 06:05:40 +00:00
# Update positionticks
2015-07-22 13:16:08 +00:00
if player . played_information . get ( currentFile ) is not None :
2015-09-24 11:59:26 +00:00
player . played_information [ currentFile ] [ ' currentPosition ' ] = playTime
2015-05-12 07:34:03 +00:00
td = datetime . today ( ) - lastProgressUpdate
secDiff = td . seconds
2015-06-05 06:05:40 +00:00
# Report progress to Emby server
if ( secDiff > 3 ) :
2015-07-22 13:16:08 +00:00
player . reportPlayback ( )
2015-05-12 07:34:03 +00:00
lastProgressUpdate = datetime . today ( )
2015-06-05 06:05:40 +00:00
2015-09-24 11:59:26 +00:00
elif utils . window ( ' commandUpdate ' ) == " true " :
2015-06-05 06:05:40 +00:00
# Received a remote control command that
# requires updating immediately
2015-09-24 11:59:26 +00:00
utils . window ( ' commandUpdate ' , clear = True )
2015-07-22 13:16:08 +00:00
player . reportPlayback ( )
2015-09-24 11:59:26 +00:00
lastProgressUpdate = da4tetime . today ( )
2015-05-12 07:34:03 +00:00
2015-06-05 06:05:40 +00:00
except Exception as e :
2015-07-22 13:16:08 +00:00
self . logMsg ( " Exception in Playback Monitor Service: %s " % e , 1 )
2015-05-12 07:34:03 +00:00
pass
2015-06-16 07:11:38 +00:00
else :
# Start up events
self . warn_auth = True
2015-08-14 09:03:12 +00:00
if utils . settings ( ' supressConnectMsg ' ) == " false " :
2015-06-16 07:11:38 +00:00
if self . welcome_msg :
# Reset authentication warnings
self . welcome_msg = False
2015-08-15 05:20:06 +00:00
# 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 )
2015-06-16 07:11:38 +00:00
# Start the Websocket Client
2015-07-22 13:16:08 +00:00
if ( self . newWebSocketThread is None ) :
2015-06-16 07:11:38 +00:00
self . newWebSocketThread = " Started "
ws . start ( )
2015-06-16 08:25:12 +00:00
# Start the Library Sync Thread
2015-07-22 13:16:08 +00:00
if ( self . newLibraryThread is None ) :
2015-06-16 07:11:38 +00:00
self . newLibraryThread = " Started "
library . start ( )
2015-06-16 05:53:01 +00:00
2015-05-12 07:34:03 +00:00
else :
2015-05-12 08:16:34 +00:00
2015-07-22 13:16:08 +00:00
if ( user . currUser is None ) and self . warn_auth :
2015-06-05 06:05:40 +00:00
# Alert user is not authenticated and suppress future warning
2015-05-12 07:34:03 +00:00
self . warn_auth = False
2015-06-05 06:05:40 +00:00
self . logMsg ( " Not authenticated yet. " , 1 )
2015-05-12 07:34:03 +00:00
2015-06-05 06:05:40 +00:00
# User access is restricted.
# Keep verifying until access is granted
# unless server goes offline or Kodi is shut down.
2015-05-12 08:16:34 +00:00
while user . HasAccess == False :
2015-06-05 06:05:40 +00:00
# Verify access with an API call
2015-05-12 08:16:34 +00:00
user . hasAccess ( )
2015-05-12 22:08:39 +00:00
2015-09-24 11:59:26 +00:00
if utils . window ( ' Server_online ' ) != " true " :
2015-05-14 04:48:35 +00:00
# Server went offline
break
2015-05-12 08:16:34 +00:00
if self . KodiMonitor . waitForAbort ( 5 ) :
# Abort was requested while waiting. We should exit
break
2015-04-01 19:07:29 +00:00
else :
2015-06-05 06:05:40 +00:00
# Wait until Emby server is online
# or Kodi is shut down.
2015-05-03 05:27:43 +00:00
while not self . KodiMonitor . abortRequested ( ) :
2015-04-26 23:15:40 +00:00
2015-05-03 05:27:43 +00:00
if user . getServer ( ) == " " :
2015-06-05 06:05:40 +00:00
# No server info set in add-on settings
2015-05-03 05:27:43 +00:00
pass
2015-06-05 06:05:40 +00:00
2015-05-06 22:58:31 +00:00
elif user . getPublicUsers ( ) == False :
2015-06-05 06:05:40 +00:00
# Server is offline.
# Alert the user and suppress future warning
2015-05-03 05:27:43 +00:00
if self . server_online :
self . logMsg ( " Server is offline. " , 1 )
2015-09-24 11:59:26 +00:00
utils . window ( ' Server_online ' , value = " false " )
2015-07-22 13:16:08 +00:00
xbmcgui . Dialog ( ) . notification ( " Error connecting " , " %s Server is unreachable. " % self . addonName , icon = " special://home/addons/plugin.video.emby/icon.png " , sound = False )
2015-05-03 05:27:43 +00:00
self . server_online = False
2015-06-05 06:05:40 +00:00
2015-03-13 21:24:59 +00:00
else :
2015-05-03 05:27:43 +00:00
# Server is online
if not self . server_online :
2015-06-05 06:05:40 +00:00
# Server was offline when Kodi started.
2015-05-03 05:27:43 +00:00
# Wait for server to be fully established.
if self . KodiMonitor . waitForAbort ( 5 ) :
# Abort was requested while waiting.
break
2015-06-05 06:05:40 +00:00
# Alert the user that server is online.
2015-07-22 13:16:08 +00:00
xbmcgui . Dialog ( ) . notification ( " Emby server " , " Welcome %s ! " % user . currUser , icon = " special://home/addons/plugin.video.emby/icon.png " , time = 2000 , sound = False )
2015-06-05 06:05:40 +00:00
2015-05-03 05:27:43 +00:00
self . server_online = True
self . logMsg ( " Server is online and ready. " , 1 )
2015-09-24 11:59:26 +00:00
utils . window ( ' Server_online ' , value = " true " )
2015-05-03 05:27:43 +00:00
2015-06-05 06:05:40 +00:00
# Start the User client
2015-07-22 13:16:08 +00:00
if self . newUserClient is None :
2015-05-03 05:27:43 +00:00
self . newUserClient = " Started "
user . start ( )
break
if self . KodiMonitor . waitForAbort ( 1 ) :
# Abort was requested while waiting.
break
2015-04-12 09:49:02 +00:00
2015-06-05 06:05:40 +00:00
if self . KodiMonitor . waitForAbort ( 1 ) :
# Abort was requested while waiting. We should exit
break
2015-08-22 16:17:54 +00:00
2015-09-24 11:59:26 +00:00
##### Emby thread is terminating. #####
# If music is enabled and direct stream for music is enabled
2015-08-22 16:17:54 +00:00
# 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 ( )
2015-04-01 19:07:29 +00:00
2015-07-22 13:16:08 +00:00
if ( self . newWebSocketThread is not None ) :
2015-04-03 10:13:01 +00:00
ws . stopClient ( )
2015-07-22 13:16:08 +00:00
if ( self . newUserClient is not None ) :
2015-05-03 05:27:43 +00:00
user . stopClient ( )
self . logMsg ( " ======== STOP %s ======== " % self . addonName , 0 )
2015-05-17 12:11:50 +00:00
2015-09-24 11:59:26 +00:00
# Start the service
2015-06-05 06:05:40 +00:00
Service ( ) . ServiceEntryPoint ( )