diff --git a/resources/lib/action_menu.py b/resources/lib/action_menu.py index 0698d62..7d4958b 100644 --- a/resources/lib/action_menu.py +++ b/resources/lib/action_menu.py @@ -26,7 +26,7 @@ class ActionAutoClose(threading.Thread): def run(self): log.debug("ActionAutoClose Running") - while not xbmc.abortRequested and not self.stop_thread: + while not xbmc.Monitor().abortRequested() and not self.stop_thread: time_since_last = time.time() - self.last_interaction log.debug("ActionAutoClose time_since_last : {0}".format(time_since_last)) diff --git a/resources/lib/cache_images.py b/resources/lib/cache_images.py index c033dfe..5c09a6c 100644 --- a/resources/lib/cache_images.py +++ b/resources/lib/cache_images.py @@ -2,7 +2,7 @@ # Gnu General Public License - see LICENSE.TXT from __future__ import division, absolute_import, print_function, unicode_literals -import urllib +from six.moves.urllib.parse import unquote import requests import base64 import sys @@ -150,7 +150,7 @@ class CacheArtwork(threading.Thread): unused_texture_ids = set() for texture in textures: url = texture.get("url") - url = urllib.unquote(url) + url = unquote(url) url = url.replace("image://", "") url = url[0:-1] if url.find("/") > -1 and url not in jellyfin_texture_urls or url.find("localhost:24276") > -1: @@ -285,7 +285,7 @@ class CacheArtwork(threading.Thread): texture_urls = set() for texture in textures: url = texture.get("url") - url = urllib.unquote(url) + url = unquote(url) url = url.replace("image://", "") url = url[0:-1] texture_urls.add(url) diff --git a/resources/lib/clientinfo.py b/resources/lib/clientinfo.py index 1187fd5..23f8a68 100644 --- a/resources/lib/clientinfo.py +++ b/resources/lib/clientinfo.py @@ -1,7 +1,8 @@ # Gnu General Public License - see LICENSE.TXT from __future__ import division, absolute_import, print_function, unicode_literals -from uuid import uuid4 as uuid4 +from uuid import uuid4 +from kodi_six.utils import py2_decode import xbmcaddon import xbmc import xbmcvfs @@ -23,14 +24,15 @@ class ClientInformation: if client_id: return client_id - jellyfin_guid_path = xbmc.translatePath("special://temp/jellycon_guid").decode('utf-8') + jellyfin_guid_path = py2_decode(xbmc.translatePath("special://temp/jellycon_guid")) log.debug("jellyfin_guid_path: {0}".format(jellyfin_guid_path)) guid = xbmcvfs.File(jellyfin_guid_path) client_id = guid.read() guid.close() if not client_id: - client_id = str("%012X" % uuid4()) + # Needs to be captilized for backwards compat + client_id = uuid4().hex.upper() log.debug("Generating a new guid: {0}".format(client_id)) guid = xbmcvfs.File(jellyfin_guid_path, 'w') guid.write(client_id) diff --git a/resources/lib/context_monitor.py b/resources/lib/context_monitor.py index aa77267..ee02adb 100644 --- a/resources/lib/context_monitor.py +++ b/resources/lib/context_monitor.py @@ -16,7 +16,7 @@ class ContextMonitor(threading.Thread): item_id = None log.debug("ContextMonitor Thread Started") - while not xbmc.abortRequested and not self.stop_thread: + while not xbmc.Monitor().abortRequested() and not self.stop_thread: if xbmc.getCondVisibility("Window.IsActive(fullscreenvideo) | Window.IsActive(visualisation)"): xbmc.sleep(1000) diff --git a/resources/lib/datamanager.py b/resources/lib/datamanager.py index b4620d0..eeff03d 100644 --- a/resources/lib/datamanager.py +++ b/resources/lib/datamanager.py @@ -62,7 +62,7 @@ class DataManager: server = download_utils.get_server() m = hashlib.md5() - m.update(user_id + "|" + str(server) + "|" + url) + m.update('{}|{}|{}'.format(user_id, server, url).encode()) url_hash = m.hexdigest() cache_file = os.path.join(self.addon_dir, "cache_" + url_hash + ".pickle") diff --git a/resources/lib/dir_functions.py b/resources/lib/dir_functions.py index 634b32d..1e2b263 100644 --- a/resources/lib/dir_functions.py +++ b/resources/lib/dir_functions.py @@ -5,7 +5,7 @@ import xbmcaddon import xbmcplugin import xbmcgui -import urllib +from six.moves.urllib.parse import quote, unquote import sys import re @@ -126,7 +126,7 @@ def get_content(url, params): if url_prev: list_item = xbmcgui.ListItem("Prev Page (" + str(start_index - page_limit + 1) + "-" + str(start_index) + " of " + str(total_records) + ")") - u = sys.argv[0] + "?url=" + urllib.quote(url_prev) + "&mode=GET_CONTENT&media_type=movies" + u = sys.argv[0] + "?url=" + quote(url_prev) + "&mode=GET_CONTENT&media_type=movies" log.debug("ADDING PREV ListItem: {0} - {1}".format(u, list_item)) dir_items.insert(0, (u, list_item, True)) @@ -136,7 +136,7 @@ def get_content(url, params): upper_count = total_records list_item = xbmcgui.ListItem("Next Page (" + str(start_index + page_limit + 1) + "-" + str(upper_count) + " of " + str(total_records) + ")") - u = sys.argv[0] + "?url=" + urllib.quote(url_next) + "&mode=GET_CONTENT&media_type=movies" + u = sys.argv[0] + "?url=" + quote(url_next) + "&mode=GET_CONTENT&media_type=movies" log.debug("ADDING NEXT ListItem: {0} - {1}".format(u, list_item)) dir_items.append((u, list_item, True)) @@ -238,7 +238,7 @@ def process_directory(url, progress, params, use_cache_data=False): name_format = params.get("name_format", None) name_format_type = None if name_format is not None: - name_format = urllib.unquote(name_format) + name_format = unquote(name_format) tokens = name_format.split("|") if len(tokens) == 2: name_format_type = tokens[0] diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py index 7ef3edc..a8a121c 100644 --- a/resources/lib/downloadutils.py +++ b/resources/lib/downloadutils.py @@ -598,7 +598,7 @@ class DownloadUtils: settings = xbmcaddon.Addon() device_name = settings.getSetting('deviceName') # remove none ascii chars - device_name = device_name.decode("ascii", errors='ignore') + device_name = py2_decode(device_name) # remove some chars not valid for names device_name = device_name.replace("\"", "_") if len(device_name) == 0: diff --git a/resources/lib/functions.py b/resources/lib/functions.py index 0f81ad0..ed25426 100644 --- a/resources/lib/functions.py +++ b/resources/lib/functions.py @@ -1,7 +1,7 @@ # Gnu General Public License - see LICENSE.TXT from __future__ import division, absolute_import, print_function, unicode_literals -import urllib +from six.moves.urllib.parse import quote, unquote import sys import os import time @@ -34,6 +34,7 @@ from .cache_images import CacheArtwork from .dir_functions import get_content, process_directory from .tracking import timer from .skin_cloner import clone_default_skin +from .play_utils import play_file __addon__ = xbmcaddon.Addon() __addondir__ = xbmc.translatePath(__addon__.getAddonInfo('profile')) @@ -74,7 +75,7 @@ def main_entry_point(): param_url = params.get('url', None) if param_url: - param_url = urllib.unquote(param_url) + param_url = unquote(param_url) mode = params.get("mode", None) @@ -632,7 +633,7 @@ def show_menu(params): elif selected_action == "show_extras": # "http://localhost:8096/Users/3138bed521e5465b9be26d2c63be94af/Items/78/SpecialFeatures" u = "{server}/Users/{userid}/Items/" + item_id + "/SpecialFeatures" - action_url = ("plugin://plugin.video.jellycon/?url=" + urllib.quote(u) + "&mode=GET_CONTENT&media_type=Videos") + action_url = ("plugin://plugin.video.jellycon/?url=" + quote(u) + "&mode=GET_CONTENT&media_type=Videos") built_in_command = 'ActivateWindow(Videos, ' + action_url + ', return)' xbmc.executebuiltin(built_in_command) @@ -648,7 +649,7 @@ def show_menu(params): '&IsMissing=false' + '&Fields=SpecialEpisodeNumbers,{field_filters}' + '&format=json') - action_url = ("plugin://plugin.video.jellycon/?url=" + urllib.quote(u) + "&mode=GET_CONTENT&media_type=Season") + action_url = ("plugin://plugin.video.jellycon/?url=" + quote(u) + "&mode=GET_CONTENT&media_type=Season") built_in_command = 'ActivateWindow(Videos, ' + action_url + ', return)' xbmc.executebuiltin(built_in_command) @@ -665,7 +666,7 @@ def show_menu(params): '&Fields={field_filters}' + '&format=json') - action_url = ("plugin://plugin.video.jellycon/?url=" + urllib.quote(u) + "&mode=GET_CONTENT&media_type=Series") + action_url = ("plugin://plugin.video.jellycon/?url=" + quote(u) + "&mode=GET_CONTENT&media_type=Series") if xbmc.getCondVisibility("Window.IsActive(home)"): built_in_command = 'ActivateWindow(Videos, ' + action_url + ', return)' @@ -794,7 +795,7 @@ def search_results(params): query_string = params.get('query') if query_string: log.debug("query_string : {0}".format(query_string)) - query_string = urllib.unquote(query_string) + query_string = unquote(query_string) log.debug("query_string : {0}".format(query_string)) item_type = item_type.lower() @@ -841,7 +842,7 @@ def search_results(params): else: query = query_string - query = urllib.quote(query) + query = quote(query) log.debug("query : {0}".format(query)) if (not item_type) or (not query): @@ -977,7 +978,8 @@ def play_action(params): play_info["subtitle_stream_index"] = subtitle_stream_index play_info["audio_stream_index"] = audio_stream_index log.info("Sending jellycon_play_action : {0}".format(play_info)) - send_event_notification("jellycon_play_action", play_info) + play_file(play_info) + #send_event_notification("jellycon_play_action", play_info) def play_item_trailer(item_id): diff --git a/resources/lib/item_functions.py b/resources/lib/item_functions.py index 9c0a4e3..dbd3457 100644 --- a/resources/lib/item_functions.py +++ b/resources/lib/item_functions.py @@ -2,7 +2,7 @@ from __future__ import division, absolute_import, print_function, unicode_litera import sys import os -import urllib +from six.moves.urllib.parse import quote from datetime import datetime @@ -318,7 +318,7 @@ def extract_item_info(item, gui_options): runtime = item.get("RunTimeTicks") if item_details.is_folder is False and runtime: - item_details.duration = long(runtime) / 10000000 + item_details.duration = runtime / 10000000 child_count = item.get("ChildCount") if child_count: @@ -370,9 +370,9 @@ def add_gui_item(url, item_details, display_options, folder=True, default_sort=F # Create the URL to pass to the item if folder: - u = sys.argv[0] + "?url=" + urllib.quote(url) + mode + "&media_type=" + item_details.item_type + u = sys.argv[0] + "?url=" + quote(url) + mode + "&media_type=" + item_details.item_type if item_details.name_format: - u += '&name_format=' + urllib.quote(item_details.name_format) + u += '&name_format=' + quote(item_details.name_format) if default_sort: u += '&sort=none' else: @@ -499,8 +499,8 @@ def add_gui_item(url, item_details, display_options, folder=True, default_sort=F if item_details.genres: genres_list = [] for genre in item_details.genres: - genres_list.append(urllib.quote(genre.encode('utf8'))) - item_properties["genres"] = urllib.quote("|".join(genres_list)) + genres_list.append(quote(genre.encode('utf8'))) + item_properties["genres"] = quote("|".join(genres_list)) info_labels["genre"] = " / ".join(item_details.genres) diff --git a/resources/lib/menu_functions.py b/resources/lib/menu_functions.py index 7e724cf..2ff1c23 100644 --- a/resources/lib/menu_functions.py +++ b/resources/lib/menu_functions.py @@ -3,7 +3,7 @@ from __future__ import division, absolute_import, print_function, unicode_literals import sys -import urllib +from six.moves.urllib.parse import quote import base64 import string @@ -76,7 +76,7 @@ def show_movie_tags(menu_params): art = {"thumb": "http://localhost:24276/" + base64.b64encode(item_url)} - content_url = urllib.quote(item_url) + content_url = quote(item_url) url = sys.argv[0] + ("?url=" + content_url + "&mode=GET_CONTENT" + @@ -162,7 +162,7 @@ def show_movie_years(menu_params): art = {"thumb": "http://localhost:24276/" + base64.b64encode(item_url)} - content_url = urllib.quote(item_url) + content_url = quote(item_url) url = sys.argv[0] + ("?url=" + content_url + "&mode=GET_CONTENT" + @@ -247,7 +247,7 @@ def show_movie_pages(menu_params): start_index = start_index + page_limit for collection in collections: - content_url = urllib.quote(collection['path']) + content_url = quote(collection['path']) url = sys.argv[0] + ("?url=" + content_url + "&mode=GET_CONTENT" + "&media_type=" + collection["media_type"]) @@ -329,7 +329,7 @@ def show_genre_list(menu_params): collections.append(item_data) for collection in collections: - url = sys.argv[0] + ("?url=" + urllib.quote(collection['path']) + + url = sys.argv[0] + ("?url=" + quote(collection['path']) + "&mode=GET_CONTENT" + "&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} - {1} - {2}".format(collection.get('title'), url, collection.get("art"))) @@ -396,7 +396,7 @@ def show_movie_alpha_list(menu_params): collections.append(item_data) for collection in collections: - url = (sys.argv[0] + "?url=" + urllib.quote(collection['path']) + + url = (sys.argv[0] + "?url=" + quote(collection['path']) + "&mode=GET_CONTENT&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} ({1})".format(collection.get('title'), url)) add_menu_directory_item(collection.get('title', string_load(30250)), url, art=collection.get("art")) @@ -457,7 +457,7 @@ def show_tvshow_alpha_list(menu_params): collections.append(item_data) for collection in collections: - url = (sys.argv[0] + "?url=" + urllib.quote(collection['path']) + + url = (sys.argv[0] + "?url=" + quote(collection['path']) + "&mode=GET_CONTENT&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} ({1})".format(collection.get('title'), url)) add_menu_directory_item(collection.get('title', string_load(30250)), url, art=collection.get("art")) @@ -529,7 +529,7 @@ def display_homevideos_type(menu_params, view): base_params["Fields"] = "{field_filters}" base_params["ImageTypeLimit"] = 1 path = get_jellyfin_url("{server}/Users/{userid}/Items", base_params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=homevideos" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos" add_menu_directory_item(view_name + string_load(30405), url) # In progress home movies @@ -539,7 +539,7 @@ def display_homevideos_type(menu_params, view): params["Recursive"] = True params["Limit"] = "{ItemLimit}" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=homevideos" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos" add_menu_directory_item(view_name + string_load(30267) + " (" + show_x_filtered_items + ")", url) # Recently added @@ -553,7 +553,7 @@ def display_homevideos_type(menu_params, view): params["IsPlayed"] = False params["Limit"] = "{ItemLimit}" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=homevideos" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos" add_menu_directory_item(view_name + string_load(30268) + " (" + show_x_filtered_items + ")", url) xbmcplugin.endOfDirectory(handle) @@ -595,7 +595,7 @@ def display_tvshow_type(menu_params, view): base_params["IncludeItemTypes"] = "Series" base_params["Recursive"] = True path = get_jellyfin_url("{server}/Users/{userid}/Items", base_params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=tvshows" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows" add_menu_directory_item(view_name + string_load(30405), url) # Favorite TV Shows @@ -603,7 +603,7 @@ def display_tvshow_type(menu_params, view): params.update(base_params) params["Filters"] = "IsFavorite" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=tvshows" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows" add_menu_directory_item(view_name + string_load(30414), url) # Tv Shows with unplayed @@ -611,7 +611,7 @@ def display_tvshow_type(menu_params, view): params.update(base_params) params["IsPlayed"] = False path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=tvshows" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows" add_menu_directory_item(view_name + string_load(30285), url) # In progress episodes @@ -623,8 +623,8 @@ def display_tvshow_type(menu_params, view): params["Filters"] = "IsResumable" params["IncludeItemTypes"] = "Episode" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none" - url += "&name_format=" + urllib.quote('Episode|episode_name_format') + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none" + url += "&name_format=" + quote('Episode|episode_name_format') add_menu_directory_item(view_name + string_load(30267) + " (" + show_x_filtered_items + ")", url) # Latest Episodes @@ -635,7 +635,7 @@ def display_tvshow_type(menu_params, view): params["SortOrder"] = "Descending" params["IncludeItemTypes"] = "Episode" path = get_jellyfin_url("{server}/Users/{userid}/Items/Latest", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=tvshows&sort=none" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows&sort=none" add_menu_directory_item(view_name + string_load(30288) + " (" + show_x_filtered_items + ")", url) # Recently Added @@ -647,8 +647,8 @@ def display_tvshow_type(menu_params, view): params["Filters"] = "IsNotFolder" params["IncludeItemTypes"] = "Episode" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none" - url += "&name_format=" + urllib.quote('Episode|episode_name_format') + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none" + url += "&name_format=" + quote('Episode|episode_name_format') add_menu_directory_item(view_name + string_load(30268) + " (" + show_x_filtered_items + ")", url) # Next Up Episodes @@ -661,8 +661,8 @@ def display_tvshow_type(menu_params, view): params["Filters"] = "IsNotFolder" params["IncludeItemTypes"] = "Episode" path = get_jellyfin_url("{server}/Shows/NextUp", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none" - url += "&name_format=" + urllib.quote('Episode|episode_name_format') + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none" + url += "&name_format=" + quote('Episode|episode_name_format') add_menu_directory_item(view_name + string_load(30278) + " (" + show_x_filtered_items + ")", url) # TV Show Genres @@ -694,7 +694,7 @@ def display_music_type(menu_params, view): params["ImageTypeLimit"] = 1 params["IncludeItemTypes"] = "MusicAlbum" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums" add_menu_directory_item(view_name + string_load(30320), url) # recently added @@ -704,7 +704,7 @@ def display_music_type(menu_params, view): params["IncludeItemTypes"] = "Audio" params["Limit"] = "{ItemLimit}" path = get_jellyfin_url("{server}/Users/{userid}/Items/Latest", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums" add_menu_directory_item(view_name + string_load(30268) + " (" + show_x_filtered_items + ")", url) # recently played @@ -718,7 +718,7 @@ def display_music_type(menu_params, view): params["SortBy"] = "DatePlayed" params["SortOrder"] = "Descending" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum" add_menu_directory_item(view_name + string_load(30349) + " (" + show_x_filtered_items + ")", url) # most played @@ -732,7 +732,7 @@ def display_music_type(menu_params, view): params["SortBy"] = "PlayCount" params["SortOrder"] = "Descending" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum" add_menu_directory_item(view_name + string_load(30353) + " (" + show_x_filtered_items + ")", url) # artists @@ -741,7 +741,7 @@ def display_music_type(menu_params, view): params["Recursive"] = True params["ImageTypeLimit"] = 1 path = get_jellyfin_url("{server}/Artists/AlbumArtists", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=MusicArtists" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicArtists" add_menu_directory_item(view_name + string_load(30321), url) xbmcplugin.endOfDirectory(handle) @@ -761,7 +761,7 @@ def display_musicvideos_type(params, view): params["IsMissing"] = False params["Fields"] = "{field_filters}" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=musicvideos" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=musicvideos" add_menu_directory_item(view_name + string_load(30405), url) xbmcplugin.endOfDirectory(handle) @@ -780,7 +780,7 @@ def display_livetv_type(menu_params, view): params["ImageTypeLimit"] = 1 params["Fields"] = "{field_filters}" path = get_jellyfin_url("{server}/LiveTv/Channels", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=livetv" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=livetv" add_menu_directory_item(view_name + string_load(30360), url) # programs @@ -791,7 +791,7 @@ def display_livetv_type(menu_params, view): params["Fields"] = "ChannelInfo,{field_filters}" params["EnableTotalRecordCount"] = False path = get_jellyfin_url("{server}/LiveTv/Programs/Recommended", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=livetv" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=livetv" add_menu_directory_item(view_name + string_load(30361), url) # recordings @@ -802,7 +802,7 @@ def display_livetv_type(menu_params, view): params["Fields"] = "{field_filters}" params["EnableTotalRecordCount"] = False path = get_jellyfin_url("{server}/LiveTv/Recordings", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=livetv" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=livetv" add_menu_directory_item(view_name + string_load(30362), url) xbmcplugin.endOfDirectory(handle) @@ -834,8 +834,8 @@ def display_movies_type(menu_params, view): # All Movies path = get_jellyfin_url("{server}/Users/{userid}/Items", base_params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=movies" - add_menu_directory_item(view_name + string_load(30405), url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies" + add_menu_directory_item('{}{}'.format(view_name, string_load(30405)), url) # Favorite Movies params = {} @@ -844,8 +844,8 @@ def display_movies_type(menu_params, view): params["GroupItemsIntoCollections"] = False params["Filters"] = "IsFavorite" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=movies" - add_menu_directory_item(view_name + string_load(30414), url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies" + add_menu_directory_item('{}{}'.format(view_name, string_load(30414)), url) # Unwatched Movies params = {} @@ -854,8 +854,8 @@ def display_movies_type(menu_params, view): params["GroupItemsIntoCollections"] = False params["IsPlayed"] = False path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=movies" - add_menu_directory_item(view_name + string_load(30285), url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies" + add_menu_directory_item('{}{}'.format(view_name, string_load(30285)), url) # Recently Watched Movies params = {} @@ -867,8 +867,8 @@ def display_movies_type(menu_params, view): params["GroupItemsIntoCollections"] = False params["Limit"] = "{ItemLimit}" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none" - add_menu_directory_item(view_name + string_load(30349) + " (" + show_x_filtered_items + ")", url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none" + add_menu_directory_item('{}{} ({})'.format(view_name, string_load(30349), show_x_filtered_items), url) # Resumable Movies params = {} @@ -878,8 +878,8 @@ def display_movies_type(menu_params, view): params["SortOrder"] = "Descending" params["Limit"] = "{ItemLimit}" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none" - add_menu_directory_item(view_name + string_load(30267) + " (" + show_x_filtered_items + ")", url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none" + add_menu_directory_item('{}{} ({})'.format(view_name, string_load(30267), show_x_filtered_items), url) # Recently Added Movies params = {} @@ -890,8 +890,8 @@ def display_movies_type(menu_params, view): params["SortOrder"] = "Descending" params["Filters"] = "IsNotFolder" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none" - add_menu_directory_item(view_name + string_load(30268) + " (" + show_x_filtered_items + ")", url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none" + add_menu_directory_item('{}{} ({})'.format(view_name, string_load(30268), show_x_filtered_items), url) # Collections params = {} @@ -902,50 +902,50 @@ def display_movies_type(menu_params, view): params["IncludeItemTypes"] = "Boxset" params["Recursive"] = True path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=boxsets" - add_menu_directory_item(view_name + string_load(30410), url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets" + add_menu_directory_item('{}{}'.format(view_name, string_load(30410)), url) # Favorite Collections params["Filters"] = "IsFavorite" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=boxsets" - add_menu_directory_item(view_name + string_load(30415), url) + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets" + add_menu_directory_item('{}{}'.format(view_name, string_load(30415)), url) # Genres path = "plugin://plugin.video.jellycon/?mode=GENRES&item_type=movie" if view is not None: path += "&parent_id=" + view.get("Id") - add_menu_directory_item(view_name + string_load(30325), path) + add_menu_directory_item('{}{}'.format(view_name, string_load(30325)), path) # Pages path = "plugin://plugin.video.jellycon/?mode=MOVIE_PAGES" if view is not None: path += "&parent_id=" + view.get("Id") - add_menu_directory_item(view_name + string_load(30397), path) + add_menu_directory_item('{}{}'.format(view_name, string_load(30397)), path) # Alpha Picker path = "plugin://plugin.video.jellycon/?mode=MOVIE_ALPHA" if view is not None: path += "&parent_id=" + view.get("Id") - add_menu_directory_item(view_name + string_load(30404), path) + add_menu_directory_item('{}{}'.format(view_name, string_load(30404)), path) # Years path = "plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_movie_years" if view is not None: path += "&parent_id=" + view.get("Id") - add_menu_directory_item(view_name + string_load(30411), path) + add_menu_directory_item('{}{}'.format(view_name, string_load(30411)), path) # Decades path = "plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_movie_years&group=true" if view is not None: path += "&parent_id=" + view.get("Id") - add_menu_directory_item(view_name + string_load(30412), path) + add_menu_directory_item('{}{}'.format(view_name, string_load(30412)), path) # Tags path = "plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=show_movie_tags" if view is not None: path += "&parent_id=" + view.get("Id") - add_menu_directory_item(view_name + string_load(30413), path) + add_menu_directory_item('{}{}'.format(view_name, string_load(30413)), path) xbmcplugin.endOfDirectory(handle) @@ -996,7 +996,7 @@ def get_playlist_path(view_info): params["ImageTypeLimit"] = 1 path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=playlists" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=playlists" return url @@ -1012,7 +1012,7 @@ def get_collection_path(view_info): params["IsMissing"] = False path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=boxsets" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets" return url @@ -1024,7 +1024,7 @@ def get_channel_path(view): params["Fields"] = "{field_filters}" path = get_jellyfin_url("{server}/Users/{userid}/Items", params) - url = sys.argv[0] + "?url=" + urllib.quote(path) + "&mode=GET_CONTENT&media_type=files" + url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=files" return url diff --git a/resources/lib/server_detect.py b/resources/lib/server_detect.py index 8c62ce2..58c27dc 100644 --- a/resources/lib/server_detect.py +++ b/resources/lib/server_detect.py @@ -231,17 +231,17 @@ def check_server(force=False, change_user=False, notify=False): log.debug("Testing_Url: {0}".format(public_lookup_url)) progress = xbmcgui.DialogProgress() - progress.create(__addon_name__ + " : " + string_load(30376)) + progress.create('{} : {}'.format(__addon_name__, string_load(30376))) progress.update(0, string_load(30377)) result = du.download_url(public_lookup_url, authenticate=False) progress.close() if result: - xbmcgui.Dialog().ok(__addon_name__ + " : " + string_load(30167), + xbmcgui.Dialog().ok('{} : {}'.format(__addon_name__, string_load(30167)), server_url) break else: - return_index = xbmcgui.Dialog().yesno(__addon_name__ + " : " + string_load(30135), + return_index = xbmcgui.Dialog().yesno('{} : {}'.format(__addon_name__, string_load(30135)), server_url, string_load(30371)) if not return_index: @@ -255,7 +255,7 @@ def check_server(force=False, change_user=False, notify=False): # do we need to change the user user_details = load_user_details(settings) current_username = user_details.get("username", "") - current_username = unicode(current_username, "utf-8") + current_username = py2_decode(current_username) # if asked or we have no current user then show user selection screen if something_changed or change_user or len(current_username) == 0: @@ -384,7 +384,7 @@ def check_server(force=False, change_user=False, notify=False): if secured: # we need a password, check the settings first m = hashlib.md5() - m.update(selected_user_name) + m.update(selected_user_name.encode()) hashed_username = m.hexdigest() saved_password = settings.getSetting("saved_user_password_" + hashed_username) allow_password_saving = settings.getSetting("allow_password_saving") == "true" diff --git a/resources/lib/trakttokodi.py b/resources/lib/trakttokodi.py index 6938335..0e5a6d0 100644 --- a/resources/lib/trakttokodi.py +++ b/resources/lib/trakttokodi.py @@ -1,7 +1,7 @@ # Gnu General Public License - see LICENSE.TXT from __future__ import division, absolute_import, print_function, unicode_literals -import urllib +from six.moves.urllib.parse import quote, unquote import encodings import xbmc @@ -106,7 +106,7 @@ def get_episode_id(parent_id, episode): def get_match(item_type, title, year, imdb_id): - query = urllib.quote(title) + query = quote(title) results = search(item_type, query=query) results = results.get('SearchHints') @@ -138,7 +138,7 @@ def entry_point(parameters): action = parameters.get('action', None) video_type = parameters.get('video_type', None) - title = urllib.unquote(parameters.get('title', '')) + title = unquote(parameters.get('title', '')) year = parameters.get('year', '') episode = parameters.get('episode', '') @@ -246,4 +246,4 @@ def entry_point(parameters): not_found('{title} ({year}) - S{season}'.format(title=title, year=year, season=str_season)) if url and media_type: - xbmc.executebuiltin('ActivateWindow(Videos, plugin://plugin.video.jellycon/?mode=GET_CONTENT&url={url}&media_type={media_type})'.format(url=urllib.quote(url), media_type=media_type)) + xbmc.executebuiltin('ActivateWindow(Videos, plugin://plugin.video.jellycon/?mode=GET_CONTENT&url={url}&media_type={media_type})'.format(url=quote(url), media_type=media_type)) diff --git a/resources/lib/translation.py b/resources/lib/translation.py index 27f029e..de2a4f3 100644 --- a/resources/lib/translation.py +++ b/resources/lib/translation.py @@ -2,6 +2,7 @@ from __future__ import division, absolute_import, print_function, unicode_litera import xbmcaddon from .loghandler import LazyLogger +from kodi_six.utils import py2_encode log = LazyLogger(__name__) addon = xbmcaddon.Addon() @@ -9,7 +10,7 @@ addon = xbmcaddon.Addon() def string_load(string_id): try: - return addon.getLocalizedString(string_id).encode('utf-8', 'ignore') + return py2_encode(addon.getLocalizedString(string_id)) except Exception as e: log.error('Failed String Load: {0} ({1})', string_id, e) return str(string_id) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 8f5e440..4b9b5c7 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -300,7 +300,7 @@ def single_urlencode(text): def send_event_notification(method, data): message_data = json.dumps(data) source_id = "jellycon" - base64_data = base64.b64encode(message_data) + base64_data = base64.b64encode(message_data.encode()) escaped_data = '\\"[\\"{0}\\"]\\"'.format(base64_data) command = 'XBMC.NotifyAll({0}.SIGNAL,{1},{2})'.format(source_id, method, escaped_data) log.debug("Sending notification event data: {0}".format(command)) diff --git a/resources/lib/widgets.py b/resources/lib/widgets.py index e51a07f..59ea58e 100644 --- a/resources/lib/widgets.py +++ b/resources/lib/widgets.py @@ -55,7 +55,7 @@ def set_random_movies(): movies_list_string = ",".join(randon_movies_list) home_window = HomeWindow() m = hashlib.md5() - m.update(movies_list_string) + m.update(movies_list_string.encode()) new_widget_hash = m.hexdigest() log.debug("set_random_movies : {0}".format(movies_list_string))