From 354f0905f6107c73bb7fc07d05af3e302cd63be0 Mon Sep 17 00:00:00 2001
From: angelblue05 <tamara.angel05@gmail.com>
Date: Tue, 12 May 2015 02:34:03 -0500
Subject: [PATCH] Support Parental control - access schedule

I had to reorganize the service.py loop a bit for this to work.
Logically the top level inside the while loop should be if the user is
authenticated.
---
 resources/lib/DownloadUtils.py | 10 +++-
 resources/lib/UserClient.py    | 28 +++++++++-
 service.py                     | 93 +++++++++++++++++-----------------
 3 files changed, 83 insertions(+), 48 deletions(-)

diff --git a/resources/lib/DownloadUtils.py b/resources/lib/DownloadUtils.py
index d18d2b8a..c6a6fc32 100644
--- a/resources/lib/DownloadUtils.py
+++ b/resources/lib/DownloadUtils.py
@@ -265,8 +265,16 @@ class DownloadUtils():
             if r.status_code == 401:
                 # Unauthorized
                 status = WINDOW.getProperty("Server_status")
-                if (status == "401") or (status == "Auth"):
+
+                if r.headers['X-Application-Error-Code'] == "ParentalControl":
+                    # Parental control - access restricted
+                    WINDOW.setProperty("Server_status", "restricted")
+                    xbmcgui.Dialog().notification("Emby server", "Access restricted.", xbmcgui.NOTIFICATION_ERROR)
+                    return False
+
+                elif (status == "401") or (status == "Auth"):
                     pass
+
                 else:
                     # Tell UserClient token has been revoked.
                     WINDOW.setProperty("Server_status", "401")
diff --git a/resources/lib/UserClient.py b/resources/lib/UserClient.py
index f801627b..bb0f166a 100644
--- a/resources/lib/UserClient.py
+++ b/resources/lib/UserClient.py
@@ -40,6 +40,7 @@ class UserClient(threading.Thread):
     currUserId = None
     currServer = None
     currToken = None
+    HasAccess = True
     AdditionalUser = []
 
     def __init__(self, *args):
@@ -167,6 +168,24 @@ class UserClient(threading.Thread):
 
         return users
 
+    def hasAccess(self):
+
+        url = "{server}/mediabrowser/Users"
+        result = self.doUtils.downloadUrl(url)
+        
+        if result is False:
+            # Access is restricted
+            self.logMsg("Access is restricted.")
+            self.HasAccess = False
+            return
+
+        if self.WINDOW.getProperty("Server_status") == "restricted":
+            self.logMsg("Access is granted.")
+            self.HasAccess = True
+            self.WINDOW.setProperty("Server_status", "")
+            xbmcgui.Dialog().notification("Emby server", "Access is enabled.")
+        return
+
     def loadCurrUser(self):
 
         WINDOW = self.WINDOW
@@ -224,6 +243,8 @@ class UserClient(threading.Thread):
             self.logMsg("Current user: %s" % self.currUser, 0)
             self.logMsg("Current userId: %s" % self.currUserId, 0)
             self.logMsg("Current accessToken: %s" % self.currToken, 0)
+            # parental control - let's verify if access is restricted
+            self.hasAccess()
             return
         
         users = self.getPublicUsers()
@@ -320,7 +341,12 @@ class UserClient(threading.Thread):
 
             if (self.WINDOW.getProperty("Server_status") != ""):
                 status = self.WINDOW.getProperty("Server_status")
-                if status == "401":
+                
+                if status == "restricted":
+                    # Parental control is restricting access
+                    self.HasAccess = False
+
+                elif status == "401":
                     self.WINDOW.setProperty("Server_status", "Auth")
                     # Revoked token
                     self.resetClient()
diff --git a/service.py b/service.py
index 664a354c..d62284af 100644
--- a/service.py
+++ b/service.py
@@ -88,48 +88,48 @@ class Service():
 
             if WINDOW.getProperty('Server_online') == "true":
                 # Server is online
-                if xbmc.Player().isPlaying():
-                    try:
-                        playTime = xbmc.Player().getTime()
-                        totalTime = xbmc.Player().getTotalTime()
-                        currentFile = xbmc.Player().getPlayingFile()
+                if (user.currUser != None) and (user.HasAccess == True):
+                    self.warn_auth = True
 
-                        if(player.played_information.get(currentFile) != None):
-                            player.played_information[currentFile]["currentPosition"] = playTime
-                        
-                        # send update
-                        td = datetime.today() - lastProgressUpdate
-                        secDiff = td.seconds
-                        if(secDiff > 3):
-                            try:
-                                player.reportPlayback()
-                            except Exception, msg:
-                                self.logMsg("Exception reporting progress: %s" % msg)
-                                pass
-                            lastProgressUpdate = datetime.today()
-                        # only try autoplay when there's 20 seconds or less remaining and only once!
-                        addonSettings = xbmcaddon.Addon(id='plugin.video.emby')
-                      
-                        # if its an episode see if autoplay is enabled
-                        if addonSettings.getSetting("autoPlaySeason")=="true":
-                            notificationtime = addonSettings.getSetting("autoPlaySeasonTime")
-                            if (totalTime - playTime <= int(notificationtime) and (lastFile==None or lastFile!=currentFile)):
-                                lastFile = currentFile
-                                player.autoPlayPlayback()
-                        
-                    except Exception, e:
-                        self.logMsg("Exception in Playback Monitor Service: %s" % e)
-                        pass
-                else:
-                    # background worker for database sync
-                    if (user.currUser != None):
-                        self.warn_auth = True
-                        
-                        # Correctly launch the websocket, if user manually launches the add-on
-                        if (self.newWebSocketThread == None):
-                            self.newWebSocketThread = "Started"
-                            ws.start()
-                
+                    # Correctly launch the websocket, if user manually launches the add-on
+                    if (self.newWebSocketThread == None):
+                        self.newWebSocketThread = "Started"
+                        ws.start()
+
+                    if xbmc.Player().isPlaying():
+                        try:
+                            playTime = xbmc.Player().getTime()
+                            totalTime = xbmc.Player().getTotalTime()
+                            currentFile = xbmc.Player().getPlayingFile()
+
+                            if(player.played_information.get(currentFile) != None):
+                                player.played_information[currentFile]["currentPosition"] = playTime
+                            
+                            # send update
+                            td = datetime.today() - lastProgressUpdate
+                            secDiff = td.seconds
+                            if(secDiff > 3):
+                                try:
+                                    player.reportPlayback()
+                                except Exception, msg:
+                                    self.logMsg("Exception reporting progress: %s" % msg)
+                                    pass
+                                lastProgressUpdate = datetime.today()
+                            # only try autoplay when there's 20 seconds or less remaining and only once!
+                            addonSettings = xbmcaddon.Addon(id='plugin.video.emby')
+                          
+                            # if its an episode see if autoplay is enabled
+                            if addonSettings.getSetting("autoPlaySeason")=="true":
+                                notificationtime = addonSettings.getSetting("autoPlaySeasonTime")
+                                if (totalTime - playTime <= int(notificationtime) and (lastFile==None or lastFile!=currentFile)):
+                                    lastFile = currentFile
+                                    player.autoPlayPlayback()
+                            
+                        except Exception, e:
+                            self.logMsg("Exception in Playback Monitor Service: %s" % e)
+                            pass
+
+                    else:
                         #full sync
                         if (startupComplete == False):
                             self.logMsg("Doing_Db_Sync: syncDatabase (Started)")
@@ -143,11 +143,12 @@ class Service():
                                 # Abort was requested while waiting. We should exit
                                 break    
                             #WebSocketThread().processPendingActions()
-                        
-                    else:
-                        if self.warn_auth:
-                            self.logMsg("Not authenticated yet.", 1)
-                            self.warn_auth = False
+                else:
+                    user.hasAccess()
+                    if self.warn_auth:
+                        self.logMsg("Not authenticated yet.", 1)
+                        self.warn_auth = False
+
             else:
                 # Wait until server becomes online or shut down is requested
                 while not self.KodiMonitor.abortRequested():