diff --git a/src/ytdl_sub/downloaders/info_json/info_json_downloader.py b/src/ytdl_sub/downloaders/info_json/info_json_downloader.py index 4c95e71e..f1b29aa4 100644 --- a/src/ytdl_sub/downloaders/info_json/info_json_downloader.py +++ b/src/ytdl_sub/downloaders/info_json/info_json_downloader.py @@ -10,7 +10,6 @@ from ytdl_sub.config.overrides import Overrides from ytdl_sub.config.validators.options import OptionsDictValidator from ytdl_sub.downloaders.source_plugin import SourcePlugin from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder -from ytdl_sub.entries.entry import YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.entries.script.variable_definitions import VariableDefinitions @@ -107,10 +106,7 @@ class InfoJsonDownloader(SourcePlugin[InfoJsonDownloaderOptions]): # See if prior variables exist. If so, delete them from metadata # to avoid saving them recursively on multiple updates - prior_variables = {} - if entry.kwargs_contains(YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY): - prior_variables = entry.kwargs(YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY) - del entry._kwargs[YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY] + prior_variables = entry.maybe_get_prior_variables() entry.initialize_script(self.overrides).add( { diff --git a/src/ytdl_sub/entries/base_entry.py b/src/ytdl_sub/entries/base_entry.py index 7c7f79a3..b3ab6c6b 100644 --- a/src/ytdl_sub/entries/base_entry.py +++ b/src/ytdl_sub/entries/base_entry.py @@ -80,26 +80,17 @@ class BaseEntry(ABC): """ return self.kwargs_get(v.uploader_id.metadata_key, self.uid) - def kwargs_contains(self, key: str) -> bool: - """Returns whether internal kwargs contains the specified key""" - return key in self._kwargs - def kwargs(self, key) -> Any: """Returns an internal kwarg value supplied from ytdl""" - if not self.kwargs_contains(key): + if key not in self._kwargs: raise KeyError(f"Expected '{key}' in {self.__class__.__name__} but does not exist.") - output = self._kwargs[key] - - # Replace curly braces with unicode version to avoid variable shenanigans - if isinstance(output, str): - return output.replace("{", "{").replace("}", "}") - return output + return self._kwargs[key] def kwargs_get(self, key: str, default: Optional[Any] = None) -> Any: """ Dict get on kwargs """ - if not self.kwargs_contains(key) or self.kwargs(key) is None: + if key not in self._kwargs or self.kwargs(key) is None: return default return self.kwargs(key) diff --git a/src/ytdl_sub/entries/entry.py b/src/ytdl_sub/entries/entry.py index cfd0546f..90452a23 100644 --- a/src/ytdl_sub/entries/entry.py +++ b/src/ytdl_sub/entries/entry.py @@ -2,6 +2,7 @@ import copy import json import os from pathlib import Path +from typing import Any from typing import Dict from typing import Optional from typing import Type @@ -20,7 +21,7 @@ from ytdl_sub.validators.audo_codec_validator import VIDEO_CODEC_EXTS v: VariableDefinitions = VARIABLES -YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY: str = "ytdl_sub_entry_variables" +_YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY: str = "ytdl_sub_entry_variables" TypeT = TypeVar("TypeT") @@ -131,7 +132,7 @@ class Entry(BaseEntry, Scriptable): Write the entry's _kwargs back into the info.json file as well as its source variables """ kwargs_dict = copy.deepcopy(self._kwargs) - kwargs_dict["ytdl_sub_entry_variables"] = self.to_dict() + kwargs_dict[_YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY] = self.to_dict() kwargs_json = json.dumps(kwargs_dict, ensure_ascii=False, sort_keys=True, indent=2) with open(self.get_download_info_json_path(), "w", encoding="utf-8") as file: @@ -174,6 +175,18 @@ class Entry(BaseEntry, Scriptable): return file_exists + def maybe_get_prior_variables(self) -> Dict[str, Any]: + """ + If variables exist in the .info.json from a prior run, delete them + from kwargs (to prevent nested writes) and return them + """ + maybe_prior_variables: Dict[str, Any] = {} + if _YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY in self._kwargs: + maybe_prior_variables = self._kwargs[_YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY] + del self._kwargs[_YTDL_SUB_ENTRY_VARIABLES_KWARG_KEY] + + return maybe_prior_variables + @final def to_dict(self) -> Dict[str, str]: """ diff --git a/src/ytdl_sub/entries/script/variable_scripts.py b/src/ytdl_sub/entries/script/variable_scripts.py index ef4e4a08..90808c37 100644 --- a/src/ytdl_sub/entries/script/variable_scripts.py +++ b/src/ytdl_sub/entries/script/variable_scripts.py @@ -163,7 +163,9 @@ ENTRY_DERIVED_VARIABLES: Dict[Variable, str] = { v.upload_date_index_padded: _pad_int(v.upload_date_index, 2), v.upload_date_index_reversed: f"{{%sub(100, {v.upload_date_index.variable_name})}}", v.upload_date_index_reversed_padded: _pad_int(v.upload_date_index_reversed, 2), - v.playlist_index_reversed: f"{{%sub({v.playlist_count.variable_name}, {v.playlist_index.variable_name}, -1)}}", + v.playlist_index_reversed: ( + f"{{%sub({v.playlist_count.variable_name}, {v.playlist_index.variable_name}, -1)}}" + ), v.playlist_index_padded: _pad_int(v.playlist_index, 2), v.playlist_index_reversed_padded: _pad_int(v.playlist_index_reversed, 2), v.playlist_index_padded6: _pad_int(v.playlist_index, 6), diff --git a/tests/unit/entries/test_entry.py b/tests/unit/entries/test_entry.py index 01ee6ed5..df712c4d 100644 --- a/tests/unit/entries/test_entry.py +++ b/tests/unit/entries/test_entry.py @@ -19,7 +19,6 @@ class TestEntry(object): key = "dne" expected_error_msg = f"Expected '{key}' in Entry but does not exist." - assert mock_entry.kwargs_contains(key) is False with pytest.raises(KeyError, match=expected_error_msg): mock_entry.kwargs(key)