From d2b6eaabb3ef626f0dc66d9bb5bcc6802cfaa6d9 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Thu, 6 Oct 2016 23:15:23 -0500 Subject: [PATCH] Pylint (#65) websocket, artwork, api, service_entry, downloadutils, contextmenu --- resources/lib/context_entry.py | 4 +- resources/lib/downloadutils.py | 49 ++++----- resources/lib/player.py | 1 + resources/lib/service_entry.py | 184 +++++++++++++++++---------------- service.py | 9 +- 5 files changed, 124 insertions(+), 123 deletions(-) diff --git a/resources/lib/context_entry.py b/resources/lib/context_entry.py index 8c4006e3..882b0489 100644 --- a/resources/lib/context_entry.py +++ b/resources/lib/context_entry.py @@ -127,8 +127,8 @@ class ContextMenu(object): options.append(OPTIONS['Addon']) addon = xbmcaddon.Addon('plugin.video.emby') - xml_path = (addon.getAddonInfo('path'), "default", "1080i") - context_menu = context.ContextMenu("script-emby-context.xml", *xml_path) + context_menu = context.ContextMenu("script-emby-context.xml", addon.getAddonInfo('path'), + "default", "1080i") context_menu.set_options(options) context_menu.doModal() diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py index 9b182b20..32397902 100644 --- a/resources/lib/downloadutils.py +++ b/resources/lib/downloadutils.py @@ -3,8 +3,8 @@ ################################################################################################## import json -import requests import logging +import requests import xbmcgui @@ -62,9 +62,9 @@ class DownloadUtils(object): 'Token': server['AccessToken'], 'SSL': ssl } - for s in self.servers: - if s == server_id: - s.update(info) + for server_info in self.servers: + if server_info == server_id: + server_info.update(info) # Set window prop self._set_server_properties(server_id, server['Name'], info) log.info("updating %s to available servers: %s", server_id, self.servers) @@ -89,7 +89,6 @@ class DownloadUtils(object): window('emby_server%s.name' % server_id, value=name) def post_capabilities(self, device_id): - # Post settings to session url = "{server}/emby/Sessions/Capabilities/Full?format=json" data = { @@ -110,9 +109,6 @@ class DownloadUtils(object): ) } - log.debug("capabilities URL: %s" % url) - log.debug("Postdata: %s" % data) - self.downloadUrl(url, postBody=data, action_type="POST") log.debug("Posted capabilities to %s" % self.session['Server']) @@ -120,46 +116,42 @@ class DownloadUtils(object): url = "{server}/emby/Sessions?DeviceId=%s&format=json" % device_id result = self.downloadUrl(url) try: - sessionId = result[0]['Id'] + session_id = result[0]['Id'] except (KeyError, TypeError): - log.info("Failed to retrieve sessionId.") + log.error("Failed to retrieve the session id.") else: - log.debug("Session: %s" % result) - log.info("SessionId: %s" % sessionId) - window('emby_sessionId', value=sessionId) + log.info("SessionId: %s", session_id) + window('emby_sessionId', value=session_id) # Post any permanent additional users - additionalUsers = settings('additionalUsers') - if additionalUsers: + additional_users = settings('additionalUsers') + if additional_users: - additionalUsers = additionalUsers.split(',') - log.info("List of permanent users added to the session: %s" % additionalUsers) + additional_users = additional_users.split(',') + log.info("List of permanent users added to the session: %s", additional_users) # Get the user list from server to get the userId url = "{server}/emby/Users?format=json" result = self.downloadUrl(url) - for additional in additionalUsers: - addUser = additional.decode('utf-8').lower() + for additional in additional_users: + add_user = additional.decode('utf-8').lower() # Compare to server users to list of permanent additional users for user in result: username = user['Name'].lower() - if username in addUser: - userId = user['Id'] - url = ( - "{server}/emby/Sessions/%s/Users/%s?format=json" - % (sessionId, userId) - ) + if username in add_user: + user_id = user['Id'] + url = ("{server}/emby/Sessions/%s/Users/%s?format=json" + % (session_id, user_id)) self.downloadUrl(url, postBody={}, action_type="POST") def start_session(self): # User is identified from this point # Attach authenticated header to the session - # Start session session = requests.Session() session.headers = self.get_header() session.verify = self.session['SSL'] @@ -216,7 +208,6 @@ class DownloadUtils(object): log.debug("===== ENTER downloadUrl =====") - session = requests kwargs = {} default_link = "" @@ -228,6 +219,7 @@ class DownloadUtils(object): if server_id is None and self.session_requests is not None: # Main server session = self.session_requests else: + session = requests kwargs.update({ 'verify': server['SSL'], 'headers': self.get_header(server_id, authenticate) @@ -308,7 +300,8 @@ class DownloadUtils(object): window('emby_serverStatus', value="restricted") raise Warning('restricted') - elif response.headers['X-Application-Error-Code'] == "UnauthorizedAccessException": + elif (response.headers['X-Application-Error-Code'] == + "UnauthorizedAccessException"): # User tried to do something his emby account doesn't allow pass diff --git a/resources/lib/player.py b/resources/lib/player.py index 3291d40e..5ab8602e 100644 --- a/resources/lib/player.py +++ b/resources/lib/player.py @@ -42,6 +42,7 @@ class Player(xbmc.Player): self.xbmcplayer = xbmc.Player() log.debug("Starting playback monitor.") + xbmc.Player.__init__(self) def GetPlayStats(self): diff --git a/resources/lib/service_entry.py b/resources/lib/service_entry.py index 21819550..d991faf9 100644 --- a/resources/lib/service_entry.py +++ b/resources/lib/service_entry.py @@ -28,20 +28,18 @@ log = logging.getLogger("EMBY."+__name__) class Service(object): - welcome_msg = True + startup = False server_online = True warn_auth = True userclient_running = False userclient_thread = None - websocket_running = False websocket_thread = None - library_running = False library_thread = None - monitor = False + last_progress = datetime.today() def __init__(self): @@ -83,30 +81,29 @@ class Service(object): def service_entry_point(self): - # Important: Threads depending on abortRequest will not trigger # if profile switch happens more than once. self.monitor = kodimonitor.KodiMonitor() - kodiProfile = xbmc.translatePath('special://profile') + self.kodi_player = player.Player() + kodi_profile = xbmc.translatePath('special://profile') # Server auto-detect initialsetup.InitialSetup().setup() # Initialize important threads self.userclient_thread = userclient.UserClient() + user_client = self.userclient_thread self.websocket_thread = wsc.WebSocketClient() self.library_thread = librarysync.LibrarySync() - kplayer = player.Player() - # Sync and progress report - lastProgressUpdate = datetime.today() + while not self.monitor.abortRequested(): - if window('emby_kodiProfile') != kodiProfile: + if window('emby_kodiProfile') != kodi_profile: # Profile change happened, terminate this thread and others log.info("Kodi profile was: %s and changed to: %s. Terminating old Emby thread.", - kodiProfile, window('emby_kodiProfile')) - break + kodi_profile, window('emby_kodiProfile')) + raise RuntimeError("Kodi profile changed detected") # Before proceeding, need to make sure: # 1. Server is online @@ -117,69 +114,17 @@ class Service(object): # Emby server is online # Verify if user is set and has access to the server - if self.userclient_thread.get_user() is not None and self.userclient_thread.get_access(): + if user_client.get_user() is not None and user_client.get_access(): - # If an item is playing - if xbmc.Player().isPlaying(): - try: - # Update and report progress - playtime = xbmc.Player().getTime() - totalTime = xbmc.Player().getTotalTime() - currentFile = kplayer.currentFile + # If an item is playing + if self.kodi_player.isPlaying(): + self._report_progress() - # Update positionticks - 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): - kplayer.reportPlayback() - lastProgressUpdate = datetime.today() - - elif window('emby_command') == "true": - # Received a remote control command that - # requires updating immediately - window('emby_command', clear=True) - kplayer.reportPlayback() - lastProgressUpdate = datetime.today() - - except Exception: - log.exception("Exception in Playback Monitor Service") - else: - # Start up events - self.warn_auth = True - if settings('connectMsg') == "true" and self.welcome_msg: - # Reset authentication warnings - self.welcome_msg = False - # Get additional users - additionalUsers = settings('additionalUsers') - if additionalUsers: - add = ", %s" % ", ".join(additionalUsers.split(',')) - else: - add = "" - dialog(type_="notification", - heading="{emby}", - message=("%s %s%s!" - % (lang(33000), self.userclient_thread.get_username().decode('utf-8'), - add.decode('utf-8'))), - icon="{emby}", - time=2000, - sound=False) - - # Start the Websocket Client - if not self.websocket_running: - self.websocket_running = True - self.websocket_thread.start() - # Start the syncing thread - if not self.library_running: - self.library_running = True - self.library_thread.start() + elif not self.startup: + self.startup = self._startup() else: - - if (self.userclient_thread.get_user() is None) and self.warn_auth: + + if (user_client.get_user() is None) and self.warn_auth: # Alert user is not authenticated and suppress future warning self.warn_auth = False log.info("Not authenticated yet.") @@ -187,16 +132,7 @@ class Service(object): # User access is restricted. # Keep verifying until access is granted # unless server goes offline or Kodi is shut down. - while not self.userclient_thread.get_access(): - # Verify access with an API call - - if window('emby_online') != "true": - # Server went offline - break - - if self.monitor.waitForAbort(5): - # Abort was requested while waiting. We should exit - break + self._access_check() else: # Wait until Emby server is online # or Kodi is shut down. @@ -208,18 +144,44 @@ class Service(object): break ##### Emby thread is terminating. ##### - self._shutdown() + self.shutdown() + + def _startup(self): + # Start up events + self.warn_auth = True + + if settings('connectMsg') == "true": + # Get additional users + add_users = ", ".join(settings('additionalUsers').split(',')) + + dialog(type_="notification", + heading="{emby}", + message=("%s %s%s!" + % (lang(33000), self.userclient_thread.get_username().decode('utf-8'), + add_users.decode('utf-8'))), + icon="{emby}", + time=2000, + sound=False) + + # Start the Websocket Client + self.websocket_running = True + self.websocket_thread.start() + # Start the syncing thread + self.library_running = True + self.library_thread.start() + + return True def _server_online_check(self): # Set emby_online true/false property - user = self.userclient_thread + user_client = self.userclient_thread while not self.monitor.abortRequested(): - - if user.get_server() is None: + + if user_client.get_server() is None: # No server info set in add-on settings pass - - elif not user.verify_server(): + + elif not user_client.verify_server(): # Server is offline. # Alert the user and suppress future warning if self.server_online: @@ -270,7 +232,7 @@ class Service(object): # Start the userclient thread if not self.userclient_running: self.userclient_running = True - user.start() + user_client.start() break @@ -278,7 +240,49 @@ class Service(object): # Abort was requested while waiting. break - def _shutdown(self): + def _access_check(self): + # Keep verifying until access is granted + # unless server goes offline or Kodi is shut down. + while not self.userclient_thread.get_access(): + + if window('emby_online') != "true": + # Server went offline + break + + if self.monitor.waitForAbort(5): + # Abort was requested while waiting. We should exit + break + + def _report_progress(self): + # Update and report playback progress + kodi_player = self.kodi_player + try: + play_time = kodi_player.getTime() + filename = kodi_player.currentFile + + # Update positionticks + if filename in kodi_player.played_info: + kodi_player.played_info[filename]['currentPosition'] = play_time + + difference = datetime.today() - self.last_progress + difference_seconds = difference.seconds + + # Report progress to Emby server + if difference_seconds > 3: + kodi_player.reportPlayback() + self.last_progress = datetime.today() + + elif window('emby_command') == "true": + # Received a remote control command that + # requires updating immediately + window('emby_command', clear=True) + kodi_player.reportPlayback() + self.last_progress = datetime.today() + + except Exception as error: + log.exception(error) + + def shutdown(self): if self.userclient_running: self.userclient_thread.stop_client() diff --git a/service.py b/service.py index 47b852ee..b9ace1c0 100644 --- a/service.py +++ b/service.py @@ -26,18 +26,21 @@ from utils import settings loghandler.config() log = logging.getLogger("EMBY.service") -DELAY = settings('startupDelay') or 0 +DELAY = int(settings('startupDelay') or 0) ################################################################################################# if __name__ == "__main__": log.warn("Delaying emby startup by: %s sec...", DELAY) + service = Service() try: - if int(DELAY) and xbmc.Monitor().waitForAbort(int(DELAY)): + if DELAY and xbmc.Monitor().waitForAbort(DELAY): raise RuntimeError("Abort event while waiting to start Emby for kodi") # Start the service - Service().service_entry_point() + service.service_entry_point() except Exception as error: log.exception(error) + log.info("Forcing shutdown") + service.shutdown()