diff --git a/jellyfin_kodi/connect.py b/jellyfin_kodi/connect.py index e05b5f9d..9fa86f4b 100644 --- a/jellyfin_kodi/connect.py +++ b/jellyfin_kodi/connect.py @@ -147,8 +147,7 @@ class Connect(object): settings('username', self.user['Name']) if 'PrimaryImageTag' in self.user: - server_data = client.auth.get_server_info(client.auth.server_id) - server_address = client.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = client.auth.get_server_info(client.auth.server_id)['address'] window('JellyfinUserImage', api.API(self.user, server_address).get_user_artwork(self.user['Id'])) def select_servers(self, state=None): @@ -212,8 +211,7 @@ class Connect(object): def login(self): users = self.connect_manager.get_public_users() - server_data = self.connect_manager.get_server_info(self.connect_manager.server_id) - server = self.connect_manager.get_server_address(server_data, server_data['LastConnectionMode']) + server = self.connect_manager.get_server_info(self.connect_manager.server_id)['address'] if not users: try: diff --git a/jellyfin_kodi/dialogs/loginmanual.py b/jellyfin_kodi/dialogs/loginmanual.py index 4b9d3fcd..9395aaa8 100644 --- a/jellyfin_kodi/dialogs/loginmanual.py +++ b/jellyfin_kodi/dialogs/loginmanual.py @@ -117,8 +117,7 @@ class LoginManual(xbmcgui.WindowXMLDialog): def _login(self, username, password): - server_data = self.connect_manager.get_server_info(self.connect_manager.server_id) - server = self.connect_manager.get_server_address(server_data, server_data['LastConnectionMode']) + server = self.connect_manager.get_server_info(self.connect_manager.server_id)['address'] result = self.connect_manager.login(server, username, password) if not result: diff --git a/jellyfin_kodi/jellyfin/connection_manager.py b/jellyfin_kodi/jellyfin/connection_manager.py index d3f38713..971252da 100644 --- a/jellyfin_kodi/jellyfin/connection_manager.py +++ b/jellyfin_kodi/jellyfin/connection_manager.py @@ -21,26 +21,11 @@ CONNECTION_STATE = { 'Unavailable': 0, 'ServerSelection': 1, 'ServerSignIn': 2, - 'SignedIn': 3, - 'ServerUpdateNeeded': 5 -} -CONNECTION_MODE = { - 'Local': 0, - 'Manual': 2 + 'SignedIn': 3 } ################################################################################################# - -def get_server_address(server, mode): - - modes = { - CONNECTION_MODE['Local']: server.get('LocalAddress'), - CONNECTION_MODE['Manual']: server.get('ManualAddress') - } - return modes.get(mode) or server.get('ManualAddress', server.get('LocalAddress')) - - class ConnectionManager(object): min_server_version = "10.1.0" @@ -138,55 +123,41 @@ class ConnectionManager(object): address = self._normalize_address(address) - def _on_fail(): - LOG.error("connectToAddress %s failed", address) - return self._resolve_failure() - try: public_info = self._try_connect(address, options=options) - except Exception as error: - LOG.exception(error) - return _on_fail() - else: LOG.info("connectToAddress %s succeeded", address) server = { - 'ManualAddress': address, - 'LastConnectionMode': CONNECTION_MODE['Manual'] + 'address': address, } self._update_server_info(server, public_info) server = self.connect_to_server(server, options) if server is False: - return _on_fail() + LOG.error("connectToAddress %s failed", address) + return { 'State': CONNECTION_STATE['Unavailable'] } return server + except Exception as error: + LOG.exception(error) + LOG.error("connectToAddress %s failed", address) + return { 'State': CONNECTION_STATE['Unavailable'] } + def connect_to_server(self, server, options={}): LOG.info("begin connectToServer") + timeout = self.timeout - tests = [] + try: + result = self._try_connect(server['address'], timeout, options) + LOG.info("calling onSuccessfulConnection with server %s", server.get('Name')) + credentials = self.credentials.get_credentials() + return self._after_connect_validated(server, credentials, result, True, options) - if server.get('LastConnectionMode') is not None and server.get('AccessToken'): - tests.append(server['LastConnectionMode']) - - if CONNECTION_MODE['Manual'] not in tests: - tests.append(CONNECTION_MODE['Manual']) - if CONNECTION_MODE['Local'] not in tests: - tests.append(CONNECTION_MODE['Local']) - - LOG.info("beginning connection tests") - return self._test_next_connection_mode(tests, 0, server, options) - - def get_server_address(self, server, mode): # TODO: De-duplicated (Duplicated from above when getting rid of shortcuts) - - modes = { - CONNECTION_MODE['Local']: server.get('LocalAddress'), - CONNECTION_MODE['Manual']: server.get('ManualAddress') - } - return modes.get(mode) or server.get('ManualAddress', server.get('LocalAddress')) + except Exception as e: + LOG.info("Failing server connection. ERROR msg: {}".format(e)) + return { 'State': CONNECTION_STATE['Unavailable'] } def connect(self, options={}): - LOG.info("Begin connect") return self._connect_to_servers(self.get_available_servers(), options) @@ -284,91 +255,6 @@ class ConnectionManager(object): 'retry': False }) - def _test_next_connection_mode(self, tests, index, server, options): - - if index >= len(tests): - LOG.info("Tested all connection modes. Failing server connection.") - return self._resolve_failure() - - mode = tests[index] - address = get_server_address(server, mode) - enable_retry = False - skip_test = False - timeout = self.timeout - - LOG.info("testing connection mode %s with server %s", mode, server.get('Name')) - - if mode == CONNECTION_MODE['Local']: - enable_retry = True - timeout = 8 - - if self._string_equals_ignore_case(address, server.get('ManualAddress')): - LOG.info("skipping LocalAddress test because it is the same as ManualAddress") - skip_test = True - - elif mode == CONNECTION_MODE['Manual']: - if self._string_equals_ignore_case(address, server.get('LocalAddress')): - enable_retry = True - timeout = 8 - - if skip_test or not address: - LOG.info("skipping test at index: %s", index) - return self._test_next_connection_mode(tests, index + 1, server, options) - - try: - result = self._try_connect(address, timeout, options) - - except Exception: - LOG.exception("test failed for connection mode %s with server %s", mode, server.get('Name')) - return self._test_next_connection_mode(tests, index + 1, server, options) - else: - if self._compare_versions(self._get_min_server_version(), result['Version']) == 1: - LOG.warning("minServerVersion requirement not met. Server version: %s", result['Version']) - return { - 'State': CONNECTION_STATE['ServerUpdateNeeded'], - 'Servers': [server] - } - else: - LOG.info("calling onSuccessfulConnection with connection mode %s with server %s", mode, server.get('Name')) - return self._on_successful_connection(server, result, mode, options) - - def _on_successful_connection(self, server, system_info, connection_mode, options): - - credentials = self.credentials.get_credentials() - return self._after_connect_validated(server, credentials, system_info, connection_mode, True, options) - - def _resolve_failure(self): - return { - 'State': CONNECTION_STATE['Unavailable'] - } - - def _get_min_server_version(self, val=None): - - if val is not None: - self.min_server_version = val - - return self.min_server_version - - def _compare_versions(self, a, b): - - ''' -1 a is smaller - 1 a is larger - 0 equal - ''' - a = LooseVersion(a) - b = LooseVersion(b) - - if a < b: - return -1 - - if a > b: - return 1 - - return 0 - - def _string_equals_ignore_case(self, str1, str2): - return (str1 or "").lower() == (str2 or "").lower() - def _server_discovery(self): MULTI_GROUP = ("", 7359) @@ -440,10 +326,9 @@ class ConnectionManager(object): info = { 'Id': found_server['Id'], - 'LocalAddress': server or found_server['Address'], + 'address': server or found_server['Address'], 'Name': found_server['Name'] - } # TODO - info['LastConnectionMode'] = CONNECTION_MODE['Manual'] if info.get('ManualAddress') else CONNECTION_MODE['Local'] + } servers.append(info) else: @@ -495,26 +380,23 @@ class ConnectionManager(object): } self.credentials.add_update_user(server, info) - def _after_connect_validated(self, server, credentials, system_info, connection_mode, verify_authentication, options): - + def _after_connect_validated(self, server, credentials, system_info, verify_authentication, options): if options.get('enableAutoLogin') is False: self.config.data['auth.user_id'] = server.pop('UserId', None) self.config.data['auth.token'] = server.pop('AccessToken', None) elif verify_authentication and server.get('AccessToken'): - - if self._validate_authentication(server, connection_mode, options) is not False: + if self._validate_authentication(server, options) is not False: self.config.data['auth.user_id'] = server['UserId'] self.config.data['auth.token'] = server['AccessToken'] - return self._after_connect_validated(server, credentials, system_info, connection_mode, False, options) + return self._after_connect_validated(server, credentials, system_info, False, options) - return self._resolve_failure() + return { 'State': CONNECTION_STATE['Unavailable'] } self._update_server_info(server, system_info) self.server_version = system_info['Version'] - server['LastConnectionMode'] = connection_mode if options.get('updateDateLastAccessed') is not False: server['DateLastAccessed'] = datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ') @@ -524,7 +406,7 @@ class ConnectionManager(object): self.server_id = server['Id'] # Update configs - self.config.data['auth.server'] = get_server_address(server, connection_mode) + self.config.data['auth.server'] = server['address'] self.config.data['auth.server-name'] = server['Name'] self.config.data['auth.server=id'] = server['Id'] self.config.data['auth.ssl'] = options.get('ssl', self.config.data['auth.ssl']) @@ -537,12 +419,12 @@ class ConnectionManager(object): # Connected return result - def _validate_authentication(self, server, connection_mode, options={}): + def _validate_authentication(self, server, options={}): try: system_info = self._request_url({ 'type': "GET", - 'url': self.get_jellyfin_url(get_server_address(server, connection_mode), "System/Info"), + 'url': self.get_jellyfin_url(server['address'], "System/Info"), 'verify': options.get('ssl'), 'dataType': "json", 'headers': { @@ -566,8 +448,10 @@ class ConnectionManager(object): server['Name'] = system_info['ServerName'] server['Id'] = system_info['Id'] - if system_info.get('LocalAddress'): - server['LocalAddress'] = system_info['LocalAddress'] + if system_info.get('address'): + server['address'] = system_info['address'] + + ## Finish updating server info def _on_authenticated(self, result, options={}): diff --git a/jellyfin_kodi/monitor.py b/jellyfin_kodi/monitor.py index 04a1bf9b..b25b21cf 100644 --- a/jellyfin_kodi/monitor.py +++ b/jellyfin_kodi/monitor.py @@ -144,9 +144,8 @@ class Monitor(xbmc.Monitor): self.void_responder(data, item) elif method == 'GetServerAddress': - - server_data = server.auth.get_server_info(server.auth.server_id) - server_address = server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + + server_address = server.auth.get_server_info(server.auth.server_id)['address'] self.void_responder(data, server_address) elif method == 'GetPlaybackInfo': diff --git a/jellyfin_kodi/objects/movies.py b/jellyfin_kodi/objects/movies.py index 76dd7fd4..8c58bcdf 100644 --- a/jellyfin_kodi/objects/movies.py +++ b/jellyfin_kodi/objects/movies.py @@ -41,8 +41,7 @@ class Movies(KodiDb): ''' If item does not exist, entry will be added. If item exists, entry will be updated. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Movie') update = True @@ -195,8 +194,7 @@ class Movies(KodiDb): Process movies inside boxset. Process removals from boxset. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Boxset') @@ -274,8 +272,7 @@ class Movies(KodiDb): ''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks Poster with progress bar ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'MovieUserData') diff --git a/jellyfin_kodi/objects/music.py b/jellyfin_kodi/objects/music.py index ae65495e..a7c5fb55 100644 --- a/jellyfin_kodi/objects/music.py +++ b/jellyfin_kodi/objects/music.py @@ -40,8 +40,7 @@ class Music(KodiDb): ''' If item does not exist, entry will be added. If item exists, entry will be updated. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Artist') update = True @@ -107,8 +106,7 @@ class Music(KodiDb): ''' Update object to kodi. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Album') update = True @@ -214,8 +212,7 @@ class Music(KodiDb): ''' Update object to kodi. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Song') update = True @@ -331,8 +328,7 @@ class Music(KodiDb): obj['Path'] = obj['Path'].replace(obj['Filename'], "") else: - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] obj['Path'] = "%s/emby/Audio/%s/" % (server_address, obj['Id']) obj['Filename'] = "stream.%s?static=true" % obj['Container'] @@ -409,8 +405,7 @@ class Music(KodiDb): ''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks Poster with progress bar ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'SongUserData') diff --git a/jellyfin_kodi/objects/musicvideos.py b/jellyfin_kodi/objects/musicvideos.py index f717100a..a819e97b 100644 --- a/jellyfin_kodi/objects/musicvideos.py +++ b/jellyfin_kodi/objects/musicvideos.py @@ -45,8 +45,7 @@ class MusicVideos(KodiDb): If we don't get the track number from Jellyfin, see if we can infer it from the sortname attribute. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'MusicVideo') update = True @@ -180,8 +179,7 @@ class MusicVideos(KodiDb): ''' This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks Poster with progress bar ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'MusicVideoUserData') diff --git a/jellyfin_kodi/objects/tvshows.py b/jellyfin_kodi/objects/tvshows.py index 42c56f9c..c849c48a 100644 --- a/jellyfin_kodi/objects/tvshows.py +++ b/jellyfin_kodi/objects/tvshows.py @@ -48,8 +48,7 @@ class TVShows(KodiDb): Process seasons. Apply series pooling. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Series') update = True @@ -205,8 +204,7 @@ class TVShows(KodiDb): If the show is empty, try to remove it. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Season') @@ -241,8 +239,7 @@ class TVShows(KodiDb): Create additional entry for widgets. This is only required for plugin/episode. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'Episode') update = True @@ -431,8 +428,7 @@ class TVShows(KodiDb): Make sure there's no other bookmarks created by widget. Create additional entry for widgets. This is only required for plugin/episode. ''' - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] API = api.API(item, server_address) obj = self.objects.map(item, 'EpisodeUserData') diff --git a/jellyfin_kodi/player.py b/jellyfin_kodi/player.py index 80e261e6..de2776d9 100644 --- a/jellyfin_kodi/player.py +++ b/jellyfin_kodi/player.py @@ -251,8 +251,7 @@ class Player(xbmc.Player): return break - server_data = item['Server'].auth.get_server_info(item['Server'].auth.server_id) - server_address = item['Server'].auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = item['Server'].auth.get_server_info(item['Server'].auth.server_id)['address'] API = api.API(next_item, server_address) data = objects.map(next_item, "UpNext") artwork = API.get_all_artwork(objects.map(next_item, 'ArtworkParent'), True) diff --git a/jellyfin_kodi/views.py b/jellyfin_kodi/views.py index dbca073c..fbd1f5a0 100644 --- a/jellyfin_kodi/views.py +++ b/jellyfin_kodi/views.py @@ -860,8 +860,7 @@ class Views(object): for library in self.media_folders: if library['Id'] == view_id and 'Primary' in library.get('ImageTags', {}): - server_data = self.server.auth.get_server_info(self.server.auth.server_id) - server_address = self.server.auth.get_server_address(server_data, server_data['LastConnectionMode']) + server_address = self.server.auth.get_server_info(self.server.auth.server_id)['address'] artwork = api.API(None, server_address).get_artwork(view_id, 'Primary') window('%s.artwork' % prop, artwork)