diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 5522b356b..51f05e3c1 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -4,3 +4,5 @@ be8333a80c2650c75444281a9b720da438b2b6d0 # Change indentation of XML and JSON files 7c0e986bd283c764cc16f0c756a03a04e4073ad0 +# Tool: black +df4994bef23a1f7175d47ff4632084e153d6077f diff --git a/jellyfin_kodi/entrypoint/default.py b/jellyfin_kodi/entrypoint/default.py index e2868bb3d..91a354e11 100644 --- a/jellyfin_kodi/entrypoint/default.py +++ b/jellyfin_kodi/entrypoint/default.py @@ -27,7 +27,12 @@ JSONRPC, LazyLogger, ) -from ..helper.utils import JsonDebugPrinter, translate_path, kodi_version +from ..helper.utils import ( + JsonDebugPrinter, + translate_path, + kodi_version, + path_replacements, +) from ..jellyfin import Jellyfin ################################################################################################# @@ -167,6 +172,8 @@ def __init__(self): get_themes(api_client) elif mode == "managelibs": manage_libraries() + elif mode == "managepaths": + path_replacements() elif mode == "backup": backup() elif mode == "restartservice": @@ -278,6 +285,9 @@ def listing(): ) directory(translate(33194), "plugin://plugin.video.jellyfin/?mode=managelibs", True) + directory( + translate(33203), "plugin://plugin.video.jellyfin/?mode=managepaths", True + ) directory(translate(33134), "plugin://plugin.video.jellyfin/?mode=addserver", False) directory(translate(33054), "plugin://plugin.video.jellyfin/?mode=adduser", False) directory(translate(5), "plugin://plugin.video.jellyfin/?mode=settings", False) diff --git a/jellyfin_kodi/helper/api.py b/jellyfin_kodi/helper/api.py index 0174c3edb..5ec3736cb 100644 --- a/jellyfin_kodi/helper/api.py +++ b/jellyfin_kodi/helper/api.py @@ -4,6 +4,8 @@ ################################################################################################## from . import settings, LazyLogger +from .utils import translate_path +import json ################################################################################################## @@ -20,6 +22,16 @@ def __init__(self, item, server=None): self.item = item self.server = server + addon_data = translate_path( + "special://profile/addon_data/plugin.video.jellyfin/data.json" + ) + try: + with open(addon_data, "rb") as infile: + data = json.load(infile) + self.path_data = data["Servers"][0].get("paths", {}) + except Exception as e: + LOG.warning("Addon appears to not be configured yet: {}".format(e)) + def get_playcount(self, played, playcount): """Convert Jellyfin played/playcount into the Kodi equivalent. The playcount is tied to the watch status. @@ -229,6 +241,11 @@ def get_file_path(self, path=None): protocol = path.split("://")[0] path = path.replace(protocol, protocol.lower()) + # Loop through configured path replacements searching for a match + for local_path in self.path_data.keys(): + if local_path in path: + path = path.replace(local_path, self.path_data[local_path]) + return path def get_user_artwork(self, user_id): diff --git a/jellyfin_kodi/helper/utils.py b/jellyfin_kodi/helper/utils.py index c745cb320..4a7857b9f 100644 --- a/jellyfin_kodi/helper/utils.py +++ b/jellyfin_kodi/helper/utils.py @@ -482,10 +482,52 @@ def set_addon_mode(): if value: dialog("ok", "{jellyfin}", translate(33145)) + path_replacements() LOG.info("Add-on playback: %s", settings("useDirectPaths") == "0") +def path_replacements(): + # UI to display and manage path replacements for native mode + from ..database import get_credentials, save_credentials + + # Retrieve existing stored paths + credentials = get_credentials() + if credentials["Servers"]: + paths = credentials["Servers"][0].get("paths", {}) + else: + paths = {} + selected_path = 1 + + # 0 is Finish, -1 is Cancel + while selected_path not in [0, -1]: + replace_paths = [f"{x} : {paths[x]}" for x in paths.keys()] + # Insert a "Finish" entry first, and an "Add" entry second + replace_paths.insert(0, translate(33204)) + replace_paths.insert(1, translate(33205)) + selected_path = dialog("select", translate(33203), replace_paths) + if selected_path == 1: + # Add a new path replacement + remote_path = dialog("input", translate(33206)) + local_path = dialog("input", translate(33207)) + if remote_path and local_path: + paths[remote_path] = local_path + elif selected_path > 1: + # Edit an existing path replacement + edit_remote_path = list(paths.keys())[selected_path - 2] + edit_local_path = paths[edit_remote_path] + # Deleting the existing path + del paths[edit_remote_path] + # Prepopulate the text box with the existing value + remote_path = dialog("input", translate(33206), defaultt=edit_remote_path) + local_path = dialog("input", translate(33207), defaultt=edit_local_path) + if remote_path and local_path: + paths[remote_path] = local_path + + credentials["Servers"][0]["paths"] = paths + save_credentials(credentials) + + class JsonDebugPrinter(object): """Helper class to defer converting data to JSON until it is needed. See: https://github.com/jellyfin/jellyfin-kodi/pull/193 diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index d44a37b1e..57e92fd95 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -996,3 +996,23 @@ msgstr "Max artwork resolution" msgctxt "#33202" msgid "Transcode H265/HEVC RExt" msgstr "Transcode H265/HEVC RExt" + +msgctxt "#33203" +msgid "Manage path replacements" +msgstr "Manage path replacements" + +msgctxt "#33204" +msgid "Finish" +msgstr "Finish" + +msgctxt "#33205" +msgid "New Path Replacement" +msgstr "New Path Replacement" + +msgctxt "#33206" +msgid "Remote Path" +msgstr "Remote Path" + +msgctxt "#33207" +msgid "Local Path" +msgstr "Local Path" diff --git a/resources/language/resource.language.en_us/strings.po b/resources/language/resource.language.en_us/strings.po index 736290a62..fe9812542 100644 --- a/resources/language/resource.language.en_us/strings.po +++ b/resources/language/resource.language.en_us/strings.po @@ -1004,3 +1004,23 @@ msgstr "Max stream bitrate" msgctxt "#33202" msgid "Transcode H265/HEVC RExt" msgstr "Transcode H265/HEVC RExt" + +msgctxt "#33203" +msgid "Manage path replacements" +msgstr "Manage path replacements" + +msgctxt "#33204" +msgid "Finish" +msgstr "Finish" + +msgctxt "#33205" +msgid "New Path Replacement" +msgstr "New Path Replacement" + +msgctxt "#33206" +msgid "Remote Path" +msgstr "Remote Path" + +msgctxt "#33207" +msgid "Local Path" +msgstr "Local Path"