2015-07-22 13:16:08 +00:00
# -*- coding: utf-8 -*-
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-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
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-03-13 21:24:59 +00:00
2015-04-06 17:17:32 +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-06-05 10:12:09 +00:00
WINDOW = self . WINDOW
WINDOW . setProperty ( ' getLogLevel ' , str ( self . logLevel ) )
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-05-03 05:27:43 +00:00
self . logMsg ( " Platform: %s " % ( self . clientInfo . getPlatform ( ) ) , 0 )
2015-06-05 06:05:40 +00:00
self . logMsg ( " KODI Version: %s " % xbmc . getInfoLabel ( ' System.BuildVersion ' ) , 0 )
self . logMsg ( " %s Version: %s " % ( addonName , self . clientInfo . getVersion ( ) ) , 0 )
2015-06-16 01:23:19 +00:00
self . logMsg ( " Log Level: %s " % self . logLevel , 1 )
2015-06-05 06:05:40 +00:00
# Reset window props for profile switch
WINDOW . clearProperty ( ' Server_online ' )
WINDOW . clearProperty ( ' Server_status ' )
WINDOW . clearProperty ( ' startup ' )
2015-06-16 05:53:01 +00:00
WINDOW . clearProperty ( ' OnWakeSync ' )
2015-06-05 06:05:40 +00:00
embyProperty = WINDOW . getProperty ( ' Emby.nodes.total ' )
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-06-05 06:05:40 +00:00
WINDOW . clearProperty ( ' Emby.nodes. %s . %s ' % ( str ( i ) , prop ) )
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-05-03 05:27:43 +00:00
WINDOW = self . WINDOW
2015-05-12 00:10:33 +00:00
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-05-03 05:27:43 +00:00
if WINDOW . getProperty ( ' 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 ( )
currentFile = xbmc . Player ( ) . getPlayingFile ( )
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-05-12 07:34:03 +00:00
player . played_information [ currentFile ] [ " currentPosition " ] = playTime
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-05-16 08:00:46 +00:00
elif WINDOW . getProperty ( ' commandUpdate ' ) == " true " :
2015-06-05 06:05:40 +00:00
# Received a remote control command that
# requires updating immediately
2015-07-22 13:16:08 +00:00
WINDOW . clearProperty ( ' commandUpdate ' )
player . reportPlayback ( )
2015-05-16 08:00:46 +00:00
lastProgressUpdate = datetime . 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-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-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-05-14 04:48:35 +00:00
if WINDOW . getProperty ( ' Server_online ' ) != " true " :
# 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-06-05 06:05:40 +00:00
WINDOW . setProperty ( ' Server_online ' , " 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-06-05 06:05:40 +00:00
WINDOW . setProperty ( ' Server_online ' , " 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-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-04-26 23:15:40 +00:00
#start the service
2015-06-05 06:05:40 +00:00
Service ( ) . ServiceEntryPoint ( )