all-in on partial resolution
This commit is contained in:
parent
6ecd04619e
commit
71f43e37b7
8 changed files with 810 additions and 700 deletions
|
|
@ -16,36 +16,28 @@ from ytdl_sub.validators.string_formatter_validators import validate_formatters
|
||||||
|
|
||||||
class ResolutionLevel:
|
class ResolutionLevel:
|
||||||
ORIGINAL = 0
|
ORIGINAL = 0
|
||||||
FILL = 1
|
RESOLVE = 1
|
||||||
RESOLVE = 2
|
INTERNAL = 2
|
||||||
INTERNAL = 3
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def name_of(cls, resolution_level: int) -> str:
|
def name_of(cls, resolution_level: int) -> str:
|
||||||
if resolution_level == cls.ORIGINAL:
|
if resolution_level == cls.ORIGINAL:
|
||||||
return "original"
|
return "original"
|
||||||
if resolution_level == cls.FILL:
|
|
||||||
return "fill"
|
|
||||||
if resolution_level == cls.RESOLVE:
|
if resolution_level == cls.RESOLVE:
|
||||||
return "resolve"
|
return "resolve"
|
||||||
if resolution_level == cls.INTERNAL:
|
if resolution_level == cls.INTERNAL:
|
||||||
return "internal"
|
return "internal"
|
||||||
|
raise ValueError("Invalid resolution level")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def all(cls) -> List[int]:
|
def all(cls) -> List[int]:
|
||||||
return [cls.ORIGINAL, cls.FILL, cls.RESOLVE, cls.INTERNAL]
|
return [cls.ORIGINAL, cls.RESOLVE, cls.INTERNAL]
|
||||||
|
|
||||||
raise ValueError("Invalid resolution level")
|
|
||||||
|
|
||||||
|
|
||||||
class VariableValidation:
|
class VariableValidation:
|
||||||
|
|
||||||
def _apply_resolution_level(self) -> None:
|
def _apply_resolution_level(self) -> None:
|
||||||
if self._resolution_level == ResolutionLevel.FILL:
|
if self._resolution_level == ResolutionLevel.RESOLVE:
|
||||||
# If anything is resolvable, 'fill' it with the resolved value.
|
|
||||||
# This will happen automatically when validating
|
|
||||||
pass
|
|
||||||
elif self._resolution_level == ResolutionLevel.RESOLVE:
|
|
||||||
# Partial resolve everything, but not including internal variables
|
# Partial resolve everything, but not including internal variables
|
||||||
self.unresolved_variables |= VARIABLES.variable_names(include_sanitized=True)
|
self.unresolved_variables |= VARIABLES.variable_names(include_sanitized=True)
|
||||||
self.script = self.script.resolve_partial(unresolvable=self.unresolved_variables)
|
self.script = self.script.resolve_partial(unresolvable=self.unresolved_variables)
|
||||||
|
|
@ -61,7 +53,7 @@ class VariableValidation:
|
||||||
downloader_options: MultiUrlValidator,
|
downloader_options: MultiUrlValidator,
|
||||||
output_options: OutputOptions,
|
output_options: OutputOptions,
|
||||||
plugins: PresetPlugins,
|
plugins: PresetPlugins,
|
||||||
resolution_level: int = ResolutionLevel.FILL,
|
resolution_level: int = ResolutionLevel.RESOLVE,
|
||||||
):
|
):
|
||||||
self.overrides = overrides
|
self.overrides = overrides
|
||||||
self.downloader_options = downloader_options
|
self.downloader_options = downloader_options
|
||||||
|
|
|
||||||
|
|
@ -281,10 +281,10 @@ class Script:
|
||||||
self._variables[variable_name] = ResolvedSyntaxTree(ast=[resolved])
|
self._variables[variable_name] = ResolvedSyntaxTree(ast=[resolved])
|
||||||
|
|
||||||
def _recursive_get_unresolved_output_filter_variables(
|
def _recursive_get_unresolved_output_filter_variables(
|
||||||
self, current_var: SyntaxTree, subset_to_resolve: Set[str], unresolvable: Set[Variable]
|
self, current_var: SyntaxTree, subset_to_resolve: Set[str], unresolvable: Set[Variable], allow_partial_resolve: bool = False
|
||||||
) -> Set[str]:
|
) -> Set[str]:
|
||||||
for var_dep in current_var.variables:
|
for var_dep in current_var.variables:
|
||||||
if var_dep in unresolvable:
|
if var_dep in unresolvable and not allow_partial_resolve:
|
||||||
raise ScriptVariableNotResolved(
|
raise ScriptVariableNotResolved(
|
||||||
f"Output filter variable contains the variable {var_dep} "
|
f"Output filter variable contains the variable {var_dep} "
|
||||||
f"which is set as unresolvable"
|
f"which is set as unresolvable"
|
||||||
|
|
@ -299,12 +299,14 @@ class Script:
|
||||||
current_var=self._variables[var_dep.name],
|
current_var=self._variables[var_dep.name],
|
||||||
subset_to_resolve=subset_to_resolve,
|
subset_to_resolve=subset_to_resolve,
|
||||||
unresolvable=unresolvable,
|
unresolvable=unresolvable,
|
||||||
|
allow_partial_resolve=allow_partial_resolve,
|
||||||
)
|
)
|
||||||
for custom_func_dep in current_var.custom_functions:
|
for custom_func_dep in current_var.custom_functions:
|
||||||
subset_to_resolve |= self._recursive_get_unresolved_output_filter_variables(
|
subset_to_resolve |= self._recursive_get_unresolved_output_filter_variables(
|
||||||
current_var=self._functions[custom_func_dep.name],
|
current_var=self._functions[custom_func_dep.name],
|
||||||
subset_to_resolve=subset_to_resolve,
|
subset_to_resolve=subset_to_resolve,
|
||||||
unresolvable=unresolvable,
|
unresolvable=unresolvable,
|
||||||
|
allow_partial_resolve=allow_partial_resolve,
|
||||||
)
|
)
|
||||||
|
|
||||||
for lambda_func in current_var.lambdas:
|
for lambda_func in current_var.lambdas:
|
||||||
|
|
@ -313,6 +315,7 @@ class Script:
|
||||||
current_var=self._functions[lambda_func.value],
|
current_var=self._functions[lambda_func.value],
|
||||||
subset_to_resolve=subset_to_resolve,
|
subset_to_resolve=subset_to_resolve,
|
||||||
unresolvable=unresolvable,
|
unresolvable=unresolvable,
|
||||||
|
allow_partial_resolve=allow_partial_resolve,
|
||||||
)
|
)
|
||||||
|
|
||||||
return subset_to_resolve
|
return subset_to_resolve
|
||||||
|
|
@ -321,6 +324,7 @@ class Script:
|
||||||
self,
|
self,
|
||||||
output_filter: Set[str],
|
output_filter: Set[str],
|
||||||
unresolvable: Set[Variable],
|
unresolvable: Set[Variable],
|
||||||
|
allow_partial_resolvable: bool = False,
|
||||||
) -> Set[str]:
|
) -> Set[str]:
|
||||||
"""
|
"""
|
||||||
When an output filter is applied, only a subset of variables that the filter
|
When an output filter is applied, only a subset of variables that the filter
|
||||||
|
|
@ -340,6 +344,7 @@ class Script:
|
||||||
current_var=self._variables[output_filter_variable],
|
current_var=self._variables[output_filter_variable],
|
||||||
subset_to_resolve=subset_to_resolve,
|
subset_to_resolve=subset_to_resolve,
|
||||||
unresolvable=unresolvable,
|
unresolvable=unresolvable,
|
||||||
|
allow_partial_resolve=allow_partial_resolvable,
|
||||||
)
|
)
|
||||||
|
|
||||||
return subset_to_resolve
|
return subset_to_resolve
|
||||||
|
|
@ -706,10 +711,11 @@ class Script:
|
||||||
"""
|
"""
|
||||||
return set(to_function_definition_name(name) for name in self._functions.keys())
|
return set(to_function_definition_name(name) for name in self._functions.keys())
|
||||||
|
|
||||||
def resolve_partial(
|
def _resolve_partial(
|
||||||
self,
|
self,
|
||||||
unresolvable: Optional[Set[str]] = None,
|
unresolvable: Optional[Set[str]] = None,
|
||||||
) -> "Script":
|
output_filter: Optional[Set[str]] = None,
|
||||||
|
) -> Dict[str, SyntaxTree]:
|
||||||
"""
|
"""
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
|
|
@ -724,12 +730,14 @@ class Script:
|
||||||
if name not in unresolvable
|
if name not in unresolvable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
to_partially_resolve: Set[Variable] = {Variable(name) for name in output_filter} if output_filter else set(unresolved.keys())
|
||||||
|
|
||||||
partially_resolved = True
|
partially_resolved = True
|
||||||
while partially_resolved:
|
while partially_resolved:
|
||||||
|
|
||||||
partially_resolved = False
|
partially_resolved = False
|
||||||
|
|
||||||
for variable in list(unresolved.keys()):
|
for variable in list(to_partially_resolve):
|
||||||
definition = unresolved[variable]
|
definition = unresolved[variable]
|
||||||
|
|
||||||
maybe_resolved = definition
|
maybe_resolved = definition
|
||||||
|
|
@ -750,6 +758,7 @@ class Script:
|
||||||
if isinstance(maybe_resolved, Resolvable):
|
if isinstance(maybe_resolved, Resolvable):
|
||||||
resolved[variable] = maybe_resolved
|
resolved[variable] = maybe_resolved
|
||||||
del unresolved[variable]
|
del unresolved[variable]
|
||||||
|
to_partially_resolve.remove(variable)
|
||||||
partially_resolved = True
|
partially_resolved = True
|
||||||
else:
|
else:
|
||||||
unresolved[variable] = maybe_resolved
|
unresolved[variable] = maybe_resolved
|
||||||
|
|
@ -758,11 +767,34 @@ class Script:
|
||||||
# which means we can iterate again
|
# which means we can iterate again
|
||||||
partially_resolved |= definition != maybe_resolved
|
partially_resolved |= definition != maybe_resolved
|
||||||
|
|
||||||
return copy.deepcopy(self).add_parsed(
|
return {
|
||||||
{var_name: self._variables[var_name] for var_name in unresolvable}
|
|
||||||
| {
|
|
||||||
var.name: ResolvedSyntaxTree(ast=[definition])
|
var.name: ResolvedSyntaxTree(ast=[definition])
|
||||||
for var, definition in resolved.items()
|
for var, definition in resolved.items()
|
||||||
}
|
} | {var.name: SyntaxTree(ast=[definition]) for var, definition in unresolved.items()}
|
||||||
| {var.name: SyntaxTree(ast=[definition]) for var, definition in unresolved.items()}
|
|
||||||
)
|
|
||||||
|
def resolve_partial(
|
||||||
|
self,
|
||||||
|
unresolvable: Optional[Set[str]] = None,
|
||||||
|
) -> "Script":
|
||||||
|
out = self._resolve_partial(unresolvable=unresolvable)
|
||||||
|
|
||||||
|
return copy.deepcopy(self).add_parsed(
|
||||||
|
{var_name: self._variables[var_name] for var_name in unresolvable}
|
||||||
|
| out
|
||||||
|
)
|
||||||
|
|
||||||
|
def resolve_partial_once(
|
||||||
|
self,
|
||||||
|
variable_definitions: Dict[str, SyntaxTree],
|
||||||
|
unresolvable: Optional[Set[str]] = None
|
||||||
|
) -> Dict[str, SyntaxTree]:
|
||||||
|
try:
|
||||||
|
self.add_parsed(variable_definitions)
|
||||||
|
return self._resolve_partial(
|
||||||
|
unresolvable=unresolvable,
|
||||||
|
output_filter=set(list(variable_definitions.keys())),
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
for name in variable_definitions.keys():
|
||||||
|
self._variables.pop(name, None)
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ class BaseSubscription(ABC):
|
||||||
"""
|
"""
|
||||||
return self._preset_options.yaml
|
return self._preset_options.yaml
|
||||||
|
|
||||||
def resolved_yaml(self, resolution_level: int = ResolutionLevel.FILL) -> str:
|
def resolved_yaml(self, resolution_level: int = ResolutionLevel.RESOLVE) -> str:
|
||||||
"""
|
"""
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
|
|
|
||||||
|
|
@ -253,10 +253,12 @@ def _validate_formatter(
|
||||||
|
|
||||||
if resolve_partial and not is_static_formatter:
|
if resolve_partial and not is_static_formatter:
|
||||||
formatter_hash = get_md5_hash(formatter_validator.format_string)
|
formatter_hash = get_md5_hash(formatter_validator.format_string)
|
||||||
|
|
||||||
parsed = (
|
parsed = (
|
||||||
mock_script.add_parsed({formatter_hash: formatter_validator.parsed})
|
mock_script.resolve_partial_once(
|
||||||
.resolve_partial(unresolvable=unresolved_variables)
|
variable_definitions={formatter_hash: formatter_validator.parsed},
|
||||||
.definition_of(formatter_hash)
|
unresolvable=unresolved_variables
|
||||||
|
)[formatter_hash]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add lambda functions to custom function names, if it's custom
|
# Add lambda functions to custom function names, if it's custom
|
||||||
|
|
|
||||||
248
tests/resources/expected_json/tv_show/inspect_sub_internal.json
Normal file
248
tests/resources/expected_json/tv_show/inspect_sub_internal.json
Normal file
|
|
@ -0,0 +1,248 @@
|
||||||
|
{
|
||||||
|
"chapters": {
|
||||||
|
"allow_chapters_from_comments": false,
|
||||||
|
"embed_chapters": true,
|
||||||
|
"enable": "True",
|
||||||
|
"force_key_frames": false
|
||||||
|
},
|
||||||
|
"date_range": {
|
||||||
|
"breaks": "True",
|
||||||
|
"enable": "True",
|
||||||
|
"type": "upload_date"
|
||||||
|
},
|
||||||
|
"download": [
|
||||||
|
{
|
||||||
|
"download_reverse": "True",
|
||||||
|
"include_sibling_metadata": false,
|
||||||
|
"playlist_thumbnails": [
|
||||||
|
{
|
||||||
|
"name": "poster.jpg",
|
||||||
|
"uid": "avatar_uncropped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fanart.jpg",
|
||||||
|
"uid": "banner_uncropped"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source_thumbnails": [
|
||||||
|
{
|
||||||
|
"name": "poster.jpg",
|
||||||
|
"uid": "avatar_uncropped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fanart.jpg",
|
||||||
|
"uid": "banner_uncropped"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "https://www.youtube.com/@novapbs",
|
||||||
|
"variables": {},
|
||||||
|
"webpage_url": "{ %map_get( entry_metadata, \"webpage_url\" ) }",
|
||||||
|
"ytdl_options": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"file_convert": {
|
||||||
|
"convert_to": "mp4",
|
||||||
|
"convert_with": "yt-dlp",
|
||||||
|
"enable": "True"
|
||||||
|
},
|
||||||
|
"format": "(bv*[ext=mp4][vcodec~='^((he|a)vc|h26[45])']+ba[ext=m4a]) / (bv[ext=mp4]*+ba[ext=m4a]/b)",
|
||||||
|
"output_options": {
|
||||||
|
"download_archive_name": ".ytdl-sub-NOVA PBS-download-archive.json",
|
||||||
|
"file_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ), \".e\", %string( %pad_zero( %int( %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), \"01\" ) ), 6 ) ), \" - \", %string( %sanitize_plex_episode( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) ) ) ) ) ) ) }.{ ext }",
|
||||||
|
"info_json_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ), \".e\", %string( %pad_zero( %int( %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), \"01\" ) ), 6 ) ), \" - \", %string( %sanitize_plex_episode( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) ) ) ) ) ) ) }.info.json",
|
||||||
|
"keep_files_date_eval": "{ %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"date_standardized\" ) ) }",
|
||||||
|
"maintain_download_archive": true,
|
||||||
|
"output_directory": "/var/folders/rw/hl1xmkmj68zdl2kjx3l0dwzc0000gn/T/tmp5_pbxsle/NOVA PBS",
|
||||||
|
"preserve_mtime": false,
|
||||||
|
"thumbnail_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ), \".e\", %string( %pad_zero( %int( %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), \"01\" ) ), 6 ) ), \" - \", %string( %sanitize_plex_episode( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) ) ) ) ) ) ) }-thumb.jpg"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"%bilateral_url": "{ %if( %and( enable_bilateral_scraping, subscription_has_download_archive, %is_bilateral_url( $0 ) ), $0, '' ) }",
|
||||||
|
"%episode_ordering_": "{ %eq( %lower( tv_show_by_date_episode_ordering ), $0 ) }",
|
||||||
|
"%is_bilateral_url": "{ %contains( $0, \"youtube.com/playlist\" ) }",
|
||||||
|
"%ordering_pair_eq": "{ %eq( [ tv_show_by_date_season_ordering, tv_show_by_date_episode_ordering ], [ $0, $1 ] ) }",
|
||||||
|
"%season_ordering_": "{ %eq( %lower( tv_show_by_date_season_ordering ), $0 ) }",
|
||||||
|
"assert_not_collection": true,
|
||||||
|
"avatar_uncropped_thumbnail_file_name": "poster.jpg",
|
||||||
|
"banner_uncropped_thumbnail_file_name": "fanart.jpg",
|
||||||
|
"enable_bilateral_scraping": true,
|
||||||
|
"enable_resolution_assert": true,
|
||||||
|
"enable_throttle_protection": true,
|
||||||
|
"episode_content_rating": "TV-14",
|
||||||
|
"episode_date_standardized": "{ %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"date_standardized\" ) ) }",
|
||||||
|
"episode_file_name": "s{ %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) }.e{ %pad_zero( %int( %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), upload_date_index_padded ) ), 6 ) } - { %sanitize_plex_episode( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) ) }",
|
||||||
|
"episode_file_path": "{ %sanitize( %concat( \"Season \", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ) ) ) }/{ %sanitize( %concat( \"s\", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ), \".e\", %string( %pad_zero( %int( %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), upload_date_index_padded ) ), 6 ) ), \" - \", %string( %sanitize_plex_episode( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) ) ) ) ) }",
|
||||||
|
"episode_number": "{ %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ) }{ %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) }{ upload_date_index_padded }",
|
||||||
|
"episode_number_and_padded_": "{ [ %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), upload_date_index_padded ), 6 ] }",
|
||||||
|
"episode_number_padded": "{ %pad_zero( %int( %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), upload_date_index_padded ) ), 6 ) }",
|
||||||
|
"episode_plot": "{ %map_get( entry_metadata, \"webpage_url\" ) }\n\n{ %map_get_non_empty( entry_metadata, \"description\", '' ) }",
|
||||||
|
"episode_title": "{ %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"date_standardized\" ) ) } - { %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) }",
|
||||||
|
"episode_year": "{ %slice( %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"date_standardized\" ) ), 0, 4 ) }",
|
||||||
|
"file_title": "{ %sanitize_plex_episode( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) ) }",
|
||||||
|
"file_uid": "{ %sanitize_plex_episode( %map_get( entry_metadata, \"id\" ) ) }",
|
||||||
|
"include_sibling_metadata": false,
|
||||||
|
"modified_webpage_url": "{ %map_get( entry_metadata, \"webpage_url\" ) }",
|
||||||
|
"only_recent_date_range": "2months",
|
||||||
|
"only_recent_max_files": 30,
|
||||||
|
"resolution_assert": "{ %if( %and( enable_resolution_assert, %ne( height, 0 ), %not( resolution_assert_is_ignored ) ), %assert( %gte( height, resolution_assert_height_gte ), %concat( \"Entry \", title, \" downloaded at a low resolution (\", resolution_readable, \"), you've probably been throttled. \", \"Stopping further downloads, wait a few hours and try again. \", \"Disable using the override variable `enable_resolution_assert: False`.\" ) ), \"false is no-op\" ) }",
|
||||||
|
"resolution_assert_height_gte": 361,
|
||||||
|
"resolution_assert_ignore_titles": "{ [ ] }",
|
||||||
|
"resolution_assert_is_ignored": "{ %print_if_true( %concat( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ), \" has a match in resolution_assert_ignore_titles, skipping resolution assert.\" ), %contains_any( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ), [ ] ) ) }",
|
||||||
|
"resolution_assert_print": true,
|
||||||
|
"resolution_readable": "{ %map_get_non_empty( entry_metadata, \"width\", 0 ) }x{ %map_get_non_empty( entry_metadata, \"height\", 0 ) }",
|
||||||
|
"s01_name": "",
|
||||||
|
"s01_url": "",
|
||||||
|
"season_directory_name": "Season { %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) }",
|
||||||
|
"season_number": "{ %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) }",
|
||||||
|
"season_number_padded": "{ %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) }",
|
||||||
|
"season_poster_file_name": "{ %sanitize( %concat( \"Season \", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ) ) ) }/Season{ %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) }.jpg",
|
||||||
|
"subscription_array": [
|
||||||
|
"https://www.youtube.com/@novapbs"
|
||||||
|
],
|
||||||
|
"subscription_indent_1": "Documentaries",
|
||||||
|
"subscription_indent_2": "TV-14",
|
||||||
|
"subscription_value": "https://www.youtube.com/@novapbs",
|
||||||
|
"subscription_value_1": "https://www.youtube.com/@novapbs",
|
||||||
|
"thumbnail_file_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"year\" ) ) ), \".e\", %string( %pad_zero( %int( %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), upload_date_index_padded ) ), 6 ) ), \" - \", %string( %sanitize_plex_episode( %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) ) ) ) ) ) ) }-thumb.jpg",
|
||||||
|
"tv_show_by_date_episode_ordering": "upload-month-day",
|
||||||
|
"tv_show_by_date_ordering_pair_validation_": "{ [ %concat( %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ), %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) ), upload_date_index_padded ), 6 ] }",
|
||||||
|
"tv_show_by_date_season_ordering": "upload-year",
|
||||||
|
"tv_show_content_rating": "TV-14",
|
||||||
|
"tv_show_content_rating_default": "TV-14",
|
||||||
|
"tv_show_date_range_type": "upload_date",
|
||||||
|
"tv_show_directory": "/var/folders/rw/hl1xmkmj68zdl2kjx3l0dwzc0000gn/T/tmp5_pbxsle",
|
||||||
|
"tv_show_fanart_file_name": "fanart.jpg",
|
||||||
|
"tv_show_genre": "Documentaries",
|
||||||
|
"tv_show_genre_default": "ytdl-sub",
|
||||||
|
"tv_show_name": "NOVA PBS",
|
||||||
|
"tv_show_poster_file_name": "poster.jpg",
|
||||||
|
"url": "https://www.youtube.com/@novapbs",
|
||||||
|
"url10": "",
|
||||||
|
"url100": "",
|
||||||
|
"url11": "",
|
||||||
|
"url12": "",
|
||||||
|
"url13": "",
|
||||||
|
"url14": "",
|
||||||
|
"url15": "",
|
||||||
|
"url16": "",
|
||||||
|
"url17": "",
|
||||||
|
"url18": "",
|
||||||
|
"url19": "",
|
||||||
|
"url2": "",
|
||||||
|
"url20": "",
|
||||||
|
"url21": "",
|
||||||
|
"url22": "",
|
||||||
|
"url23": "",
|
||||||
|
"url24": "",
|
||||||
|
"url25": "",
|
||||||
|
"url26": "",
|
||||||
|
"url27": "",
|
||||||
|
"url28": "",
|
||||||
|
"url29": "",
|
||||||
|
"url3": "",
|
||||||
|
"url30": "",
|
||||||
|
"url31": "",
|
||||||
|
"url32": "",
|
||||||
|
"url33": "",
|
||||||
|
"url34": "",
|
||||||
|
"url35": "",
|
||||||
|
"url36": "",
|
||||||
|
"url37": "",
|
||||||
|
"url38": "",
|
||||||
|
"url39": "",
|
||||||
|
"url4": "",
|
||||||
|
"url40": "",
|
||||||
|
"url41": "",
|
||||||
|
"url42": "",
|
||||||
|
"url43": "",
|
||||||
|
"url44": "",
|
||||||
|
"url45": "",
|
||||||
|
"url46": "",
|
||||||
|
"url47": "",
|
||||||
|
"url48": "",
|
||||||
|
"url49": "",
|
||||||
|
"url5": "",
|
||||||
|
"url50": "",
|
||||||
|
"url51": "",
|
||||||
|
"url52": "",
|
||||||
|
"url53": "",
|
||||||
|
"url54": "",
|
||||||
|
"url55": "",
|
||||||
|
"url56": "",
|
||||||
|
"url57": "",
|
||||||
|
"url58": "",
|
||||||
|
"url59": "",
|
||||||
|
"url6": "",
|
||||||
|
"url60": "",
|
||||||
|
"url61": "",
|
||||||
|
"url62": "",
|
||||||
|
"url63": "",
|
||||||
|
"url64": "",
|
||||||
|
"url65": "",
|
||||||
|
"url66": "",
|
||||||
|
"url67": "",
|
||||||
|
"url68": "",
|
||||||
|
"url69": "",
|
||||||
|
"url7": "",
|
||||||
|
"url70": "",
|
||||||
|
"url71": "",
|
||||||
|
"url72": "",
|
||||||
|
"url73": "",
|
||||||
|
"url74": "",
|
||||||
|
"url75": "",
|
||||||
|
"url76": "",
|
||||||
|
"url77": "",
|
||||||
|
"url78": "",
|
||||||
|
"url79": "",
|
||||||
|
"url8": "",
|
||||||
|
"url80": "",
|
||||||
|
"url81": "",
|
||||||
|
"url82": "",
|
||||||
|
"url83": "",
|
||||||
|
"url84": "",
|
||||||
|
"url85": "",
|
||||||
|
"url86": "",
|
||||||
|
"url87": "",
|
||||||
|
"url88": "",
|
||||||
|
"url89": "",
|
||||||
|
"url9": "",
|
||||||
|
"url90": "",
|
||||||
|
"url91": "",
|
||||||
|
"url92": "",
|
||||||
|
"url93": "",
|
||||||
|
"url94": "",
|
||||||
|
"url95": "",
|
||||||
|
"url96": "",
|
||||||
|
"url97": "",
|
||||||
|
"url98": "",
|
||||||
|
"url99": "",
|
||||||
|
"urls": [
|
||||||
|
"https://www.youtube.com/@novapbs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"throttle_protection": {
|
||||||
|
"enable": true,
|
||||||
|
"sleep_per_download_s": {
|
||||||
|
"max": "28.4",
|
||||||
|
"min": "13.8"
|
||||||
|
},
|
||||||
|
"sleep_per_request_s": {
|
||||||
|
"max": "0.75",
|
||||||
|
"min": "0.0"
|
||||||
|
},
|
||||||
|
"sleep_per_subscription_s": {
|
||||||
|
"max": "26.1",
|
||||||
|
"min": "16.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"video_tags": {
|
||||||
|
"contentRating": "TV-14",
|
||||||
|
"date": "{ %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"date_standardized\" ) ) }",
|
||||||
|
"episode_id": "{ %int( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"month\" ) ) }{ %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"day_padded\" ) }01",
|
||||||
|
"genre": "Documentaries",
|
||||||
|
"show": "NOVA PBS",
|
||||||
|
"synopsis": "{ %map_get( entry_metadata, \"webpage_url\" ) }\n\n{ %map_get_non_empty( entry_metadata, \"description\", '' ) }",
|
||||||
|
"title": "{ %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"date_standardized\" ) ) } - { %map_get_non_empty( entry_metadata, \"title\", %map_get( entry_metadata, \"id\" ) ) }",
|
||||||
|
"year": "{ %slice( %string( %map_get( %to_date_metadata( %map_get_non_empty( entry_metadata, \"upload_date\", %datetime_strftime( %map_get( entry_metadata, \"epoch\" ), \"%Y%m%d\" ) ) ), \"date_standardized\" ) ), 0, 4 ) }"
|
||||||
|
}
|
||||||
|
}
|
||||||
259
tests/resources/expected_json/tv_show/inspect_sub_original.json
Normal file
259
tests/resources/expected_json/tv_show/inspect_sub_original.json
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
{
|
||||||
|
"presets": {
|
||||||
|
"NOVA PBS": {
|
||||||
|
"chapters": {
|
||||||
|
"embed_chapters": true
|
||||||
|
},
|
||||||
|
"date_range": {
|
||||||
|
"type": "{tv_show_date_range_type}"
|
||||||
|
},
|
||||||
|
"download": [
|
||||||
|
{
|
||||||
|
"download_reverse": false,
|
||||||
|
"url": "{ %array_apply(urls, %bilateral_url) }",
|
||||||
|
"webpage_url": "{modified_webpage_url}",
|
||||||
|
"ytdl_options": {
|
||||||
|
"playlist_items": "-1:0:-1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include_sibling_metadata": "{include_sibling_metadata}",
|
||||||
|
"playlist_thumbnails": [
|
||||||
|
{
|
||||||
|
"name": "{avatar_uncropped_thumbnail_file_name}",
|
||||||
|
"uid": "avatar_uncropped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "{banner_uncropped_thumbnail_file_name}",
|
||||||
|
"uid": "banner_uncropped"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source_thumbnails": [
|
||||||
|
{
|
||||||
|
"name": "{avatar_uncropped_thumbnail_file_name}",
|
||||||
|
"uid": "avatar_uncropped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "{banner_uncropped_thumbnail_file_name}",
|
||||||
|
"uid": "banner_uncropped"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "{ %array_at(urls, 0) }",
|
||||||
|
"webpage_url": "{modified_webpage_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include_sibling_metadata": "{include_sibling_metadata}",
|
||||||
|
"url": "{ %array_slice(urls, 1) }",
|
||||||
|
"webpage_url": "{modified_webpage_url}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"file_convert": {
|
||||||
|
"convert_to": "mp4"
|
||||||
|
},
|
||||||
|
"format": "(bv*[ext=mp4][vcodec~='^((he|a)vc|h26[45])']+ba[ext=m4a]) / (bv[ext=mp4]*+ba[ext=m4a]/b)",
|
||||||
|
"output_options": {
|
||||||
|
"file_name": "{episode_file_path}.{ext}",
|
||||||
|
"info_json_name": "{episode_file_path}.{info_json_ext}",
|
||||||
|
"keep_files_date_eval": "{episode_date_standardized}",
|
||||||
|
"maintain_download_archive": true,
|
||||||
|
"output_directory": "{tv_show_directory}/{tv_show_name_sanitized}",
|
||||||
|
"thumbnail_name": "{thumbnail_file_name}"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"%bilateral_url": "{ \n %if(\n %and(\n enable_bilateral_scraping,\n subscription_has_download_archive,\n %is_bilateral_url($0)\n ),\n $0,\n \"\"\n )\n}",
|
||||||
|
"%episode_ordering_": "{ %eq( %lower(tv_show_by_date_episode_ordering), $0 ) }",
|
||||||
|
"%is_bilateral_url": "{ %contains( $0, \"youtube.com/playlist\" ) }",
|
||||||
|
"%ordering_pair_eq": "{\n %eq([tv_show_by_date_season_ordering, tv_show_by_date_episode_ordering], [$0, $1])\n}",
|
||||||
|
"%season_ordering_": "{ %eq( %lower(tv_show_by_date_season_ordering), $0 ) }",
|
||||||
|
"assert_not_collection": "{\n %assert(\n %and(\n %not( %bool(s01_url) ),\n %not( %bool(s01_name) )\n ),\n \"Provided `s01_url` or `s01_name` variable to TV Show by Date preset when it expects `url`. Perhaps you meant to use the `TV Show Collection` preset?\"\n )\n}",
|
||||||
|
"avatar_uncropped_thumbnail_file_name": "{tv_show_poster_file_name}",
|
||||||
|
"banner_uncropped_thumbnail_file_name": "{tv_show_fanart_file_name}",
|
||||||
|
"enable_bilateral_scraping": true,
|
||||||
|
"enable_resolution_assert": true,
|
||||||
|
"enable_throttle_protection": true,
|
||||||
|
"episode_content_rating": "{tv_show_content_rating}",
|
||||||
|
"episode_date_standardized": "{\n %if(\n %contains(tv_show_by_date_season_ordering, \"release\"),\n release_date_standardized,\n upload_date_standardized\n )\n}",
|
||||||
|
"episode_file_name": "s{season_number_padded}.e{episode_number_padded} - {file_title}",
|
||||||
|
"episode_file_path": "{season_directory_name_sanitized}/{episode_file_name_sanitized}",
|
||||||
|
"episode_number": "{ %array_at(episode_number_and_padded_, 0) }",
|
||||||
|
"episode_number_and_padded_": "{\n %elif(\n %episode_ordering_( \"upload-day\" ), [ %concat(upload_day, upload_date_index_padded), 4 ],\n %episode_ordering_( \"upload-month-day\" ), [ %concat(upload_month, upload_day_padded, upload_date_index_padded), 6],\n %episode_ordering_( \"upload-month-day-reversed\" ), [ %concat(upload_day_of_year_reversed, upload_date_index_reversed_padded), 5],\n %episode_ordering_( \"release-day\" ), [ %concat(release_day, upload_date_index_padded), 4 ],\n %episode_ordering_( \"release-month-day\" ), [ %concat(release_month, release_day_padded, upload_date_index_padded), 6],\n %episode_ordering_( \"release-month-day-reversed\" ), [ %concat(release_day_of_year_reversed, upload_date_index_reversed_padded), 5],\n %episode_ordering_( \"download-index\" ), [ download_index, 6 ],\n %throw(\n 'tv_show_by_date_episode_ordering must be one of the following: \"upload-day\", \"upload-month-day\", \"upload-month-day-reversed\", \"release-day\", \"release-month-day\", \"release-month-day-reversed\", \"download-index\"'\n )\n )\n}",
|
||||||
|
"episode_number_padded": "{ %pad_zero( %int(episode_number), %int(%array_at(episode_number_and_padded_, 1))) }",
|
||||||
|
"episode_plot": "{webpage_url}\n\n{description}",
|
||||||
|
"episode_title": "{episode_date_standardized} - {title}",
|
||||||
|
"episode_year": "{%slice(episode_date_standardized, 0, 4)}",
|
||||||
|
"file_title": "{title_sanitized_plex}",
|
||||||
|
"file_uid": "{uid_sanitized_plex}",
|
||||||
|
"include_sibling_metadata": false,
|
||||||
|
"modified_webpage_url": "{webpage_url}",
|
||||||
|
"only_recent_date_range": "2months",
|
||||||
|
"only_recent_max_files": 30,
|
||||||
|
"resolution_assert": "{\n %if(\n %and(\n enable_resolution_assert,\n %ne( height, 0 ),\n %not(resolution_assert_is_ignored)\n ),\n %assert(\n %gte( height, resolution_assert_height_gte ),\n %concat(\n \"Entry \",\n title,\n \" downloaded at a low resolution (\",\n resolution_readable,\n \"), you've probably been throttled. \",\n \"Stopping further downloads, wait a few hours and try again. \",\n \"Disable using the override variable `enable_resolution_assert: False`.\"\n )\n ),\n \"false is no-op\"\n )\n}",
|
||||||
|
"resolution_assert_height_gte": 361,
|
||||||
|
"resolution_assert_ignore_titles": "{ [] }",
|
||||||
|
"resolution_assert_is_ignored": "{\n %print_if_true(\n %concat(title, \" has a match in resolution_assert_ignore_titles, skipping resolution assert.\"),\n %contains_any(title, resolution_assert_ignore_titles)\n )\n}",
|
||||||
|
"resolution_assert_print": "{\n %print(\n %if(\n enable_resolution_assert,\n \"Resolution assert is enabled, will fail on low-quality video downloads and presume throttle. Disable using the override variable `enable_resolution_assert: False`\",\n \"Resolution assert is disabled. Use at your own risk!\"\n ),\n enable_resolution_assert,\n -1\n )\n}",
|
||||||
|
"resolution_readable": "{width}x{height}",
|
||||||
|
"s01_name": "",
|
||||||
|
"s01_url": "",
|
||||||
|
"season_directory_name": "Season {season_number_padded}",
|
||||||
|
"season_number": "{\n %elif(\n %season_ordering_( \"upload-year\" ), upload_year,\n %season_ordering_( \"upload-year-month\" ), %concat(upload_year, upload_month_padded),\n %season_ordering_( \"release-year\" ), release_year,\n %season_ordering_( \"release-year-month\" ), %concat(release_year, release_month_padded),\n %throw(\n 'tv_show_by_date_season_ordering must be one of the following: \"upload-year\", \"upload-year-month\", \"release-year\", \"release-year-month\"'\n )\n )\n}",
|
||||||
|
"season_number_padded": "{season_number}",
|
||||||
|
"season_poster_file_name": "{season_directory_name_sanitized}/Season{season_number_padded}.jpg",
|
||||||
|
"subscription_array": "{%from_json('''[\"https://www.youtube.com/@novapbs\"]''')}",
|
||||||
|
"subscription_indent_1": "Documentaries",
|
||||||
|
"subscription_indent_2": "{tv_show_content_rating_default}",
|
||||||
|
"subscription_value": "https://www.youtube.com/@novapbs",
|
||||||
|
"subscription_value_1": "https://www.youtube.com/@novapbs",
|
||||||
|
"thumbnail_file_name": "{episode_file_path}-thumb.jpg",
|
||||||
|
"tv_show_by_date_episode_ordering": "upload-month-day",
|
||||||
|
"tv_show_by_date_ordering_pair_validation_": "{\n %assert_then(\n %or(\n %ordering_pair_eq(\"upload-year\", \"upload-month-day\"),\n %ordering_pair_eq(\"upload-year\", \"upload-month-day-reversed\"),\n %ordering_pair_eq(\"upload-year\", \"download-index\"),\n %ordering_pair_eq(\"upload-year-month\", \"upload-day\"),\n %ordering_pair_eq(\"release-year\", \"release-month-day\"),\n %ordering_pair_eq(\"release-year\", \"release-month-day-reversed\"),\n %ordering_pair_eq(\"release-year\", \"download-index\"),\n %ordering_pair_eq(\"release-year-month\", \"release-day\")\n ),\n episode_number_and_padded_,\n \"Detected incompatibility between tv_show_by_date_season_ordering and tv_show_by_date_episode_ordering. Ensure you are not using both upload and release date, and that the year/month/day are included in the combined season and episode.\"\n )\n}",
|
||||||
|
"tv_show_by_date_season_ordering": "upload-year",
|
||||||
|
"tv_show_content_rating": "{subscription_indent_2}",
|
||||||
|
"tv_show_content_rating_default": "TV-14",
|
||||||
|
"tv_show_date_range_type": "{\n %if(\n %contains(tv_show_by_date_season_ordering, \"release\"),\n \"release_date\",\n \"upload_date\"\n )\n}",
|
||||||
|
"tv_show_directory": "/var/folders/rw/hl1xmkmj68zdl2kjx3l0dwzc0000gn/T/tmpi3yfj1k0",
|
||||||
|
"tv_show_fanart_file_name": "fanart.jpg",
|
||||||
|
"tv_show_genre": "{subscription_indent_1}",
|
||||||
|
"tv_show_genre_default": "ytdl-sub",
|
||||||
|
"tv_show_name": "{subscription_name}",
|
||||||
|
"tv_show_poster_file_name": "poster.jpg",
|
||||||
|
"url": "{subscription_value}",
|
||||||
|
"url10": "",
|
||||||
|
"url100": "",
|
||||||
|
"url11": "",
|
||||||
|
"url12": "",
|
||||||
|
"url13": "",
|
||||||
|
"url14": "",
|
||||||
|
"url15": "",
|
||||||
|
"url16": "",
|
||||||
|
"url17": "",
|
||||||
|
"url18": "",
|
||||||
|
"url19": "",
|
||||||
|
"url2": "",
|
||||||
|
"url20": "",
|
||||||
|
"url21": "",
|
||||||
|
"url22": "",
|
||||||
|
"url23": "",
|
||||||
|
"url24": "",
|
||||||
|
"url25": "",
|
||||||
|
"url26": "",
|
||||||
|
"url27": "",
|
||||||
|
"url28": "",
|
||||||
|
"url29": "",
|
||||||
|
"url3": "",
|
||||||
|
"url30": "",
|
||||||
|
"url31": "",
|
||||||
|
"url32": "",
|
||||||
|
"url33": "",
|
||||||
|
"url34": "",
|
||||||
|
"url35": "",
|
||||||
|
"url36": "",
|
||||||
|
"url37": "",
|
||||||
|
"url38": "",
|
||||||
|
"url39": "",
|
||||||
|
"url4": "",
|
||||||
|
"url40": "",
|
||||||
|
"url41": "",
|
||||||
|
"url42": "",
|
||||||
|
"url43": "",
|
||||||
|
"url44": "",
|
||||||
|
"url45": "",
|
||||||
|
"url46": "",
|
||||||
|
"url47": "",
|
||||||
|
"url48": "",
|
||||||
|
"url49": "",
|
||||||
|
"url5": "",
|
||||||
|
"url50": "",
|
||||||
|
"url51": "",
|
||||||
|
"url52": "",
|
||||||
|
"url53": "",
|
||||||
|
"url54": "",
|
||||||
|
"url55": "",
|
||||||
|
"url56": "",
|
||||||
|
"url57": "",
|
||||||
|
"url58": "",
|
||||||
|
"url59": "",
|
||||||
|
"url6": "",
|
||||||
|
"url60": "",
|
||||||
|
"url61": "",
|
||||||
|
"url62": "",
|
||||||
|
"url63": "",
|
||||||
|
"url64": "",
|
||||||
|
"url65": "",
|
||||||
|
"url66": "",
|
||||||
|
"url67": "",
|
||||||
|
"url68": "",
|
||||||
|
"url69": "",
|
||||||
|
"url7": "",
|
||||||
|
"url70": "",
|
||||||
|
"url71": "",
|
||||||
|
"url72": "",
|
||||||
|
"url73": "",
|
||||||
|
"url74": "",
|
||||||
|
"url75": "",
|
||||||
|
"url76": "",
|
||||||
|
"url77": "",
|
||||||
|
"url78": "",
|
||||||
|
"url79": "",
|
||||||
|
"url8": "",
|
||||||
|
"url80": "",
|
||||||
|
"url81": "",
|
||||||
|
"url82": "",
|
||||||
|
"url83": "",
|
||||||
|
"url84": "",
|
||||||
|
"url85": "",
|
||||||
|
"url86": "",
|
||||||
|
"url87": "",
|
||||||
|
"url88": "",
|
||||||
|
"url89": "",
|
||||||
|
"url9": "",
|
||||||
|
"url90": "",
|
||||||
|
"url91": "",
|
||||||
|
"url92": "",
|
||||||
|
"url93": "",
|
||||||
|
"url94": "",
|
||||||
|
"url95": "",
|
||||||
|
"url96": "",
|
||||||
|
"url97": "",
|
||||||
|
"url98": "",
|
||||||
|
"url99": "",
|
||||||
|
"urls": "{subscription_array}"
|
||||||
|
},
|
||||||
|
"preset": [
|
||||||
|
"_season_by_year",
|
||||||
|
"plex_tv_show_by_date",
|
||||||
|
"season_by_year__episode_by_month_day",
|
||||||
|
"Plex TV Show by Date",
|
||||||
|
"__preset__"
|
||||||
|
],
|
||||||
|
"throttle_protection": {
|
||||||
|
"enable": "{\n %print(\n %if(\n enable_throttle_protection,\n \"Throttle protection is enabled. Disable using the override variable `enable_throttle_protection: False`\",\n \"Throttle protection is disabled. Use at your own risk!\"\n ),\n enable_throttle_protection\n )\n}",
|
||||||
|
"sleep_per_download_s": {
|
||||||
|
"max": 28.4,
|
||||||
|
"min": 13.8
|
||||||
|
},
|
||||||
|
"sleep_per_request_s": {
|
||||||
|
"max": 0.75,
|
||||||
|
"min": 0.0
|
||||||
|
},
|
||||||
|
"sleep_per_subscription_s": {
|
||||||
|
"max": 26.1,
|
||||||
|
"min": 16.3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"video_tags": {
|
||||||
|
"contentRating": "{episode_content_rating}",
|
||||||
|
"date": "{episode_date_standardized}",
|
||||||
|
"episode_id": "{episode_number}",
|
||||||
|
"genre": "{tv_show_genre}",
|
||||||
|
"show": "{tv_show_name}",
|
||||||
|
"synopsis": "{episode_plot}",
|
||||||
|
"title": "{episode_title}",
|
||||||
|
"year": "{episode_year}"
|
||||||
|
},
|
||||||
|
"ytdl_options": {
|
||||||
|
"break_on_existing": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
248
tests/resources/expected_json/tv_show/inspect_sub_resolve.json
Normal file
248
tests/resources/expected_json/tv_show/inspect_sub_resolve.json
Normal file
|
|
@ -0,0 +1,248 @@
|
||||||
|
{
|
||||||
|
"chapters": {
|
||||||
|
"allow_chapters_from_comments": false,
|
||||||
|
"embed_chapters": true,
|
||||||
|
"enable": "True",
|
||||||
|
"force_key_frames": false
|
||||||
|
},
|
||||||
|
"date_range": {
|
||||||
|
"breaks": "True",
|
||||||
|
"enable": "True",
|
||||||
|
"type": "upload_date"
|
||||||
|
},
|
||||||
|
"download": [
|
||||||
|
{
|
||||||
|
"download_reverse": "True",
|
||||||
|
"include_sibling_metadata": false,
|
||||||
|
"playlist_thumbnails": [
|
||||||
|
{
|
||||||
|
"name": "poster.jpg",
|
||||||
|
"uid": "avatar_uncropped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fanart.jpg",
|
||||||
|
"uid": "banner_uncropped"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source_thumbnails": [
|
||||||
|
{
|
||||||
|
"name": "poster.jpg",
|
||||||
|
"uid": "avatar_uncropped"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fanart.jpg",
|
||||||
|
"uid": "banner_uncropped"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "https://www.youtube.com/@novapbs",
|
||||||
|
"variables": {},
|
||||||
|
"webpage_url": "{ webpage_url }",
|
||||||
|
"ytdl_options": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"file_convert": {
|
||||||
|
"convert_to": "mp4",
|
||||||
|
"convert_with": "yt-dlp",
|
||||||
|
"enable": "True"
|
||||||
|
},
|
||||||
|
"format": "(bv*[ext=mp4][vcodec~='^((he|a)vc|h26[45])']+ba[ext=m4a]) / (bv[ext=mp4]*+ba[ext=m4a]/b)",
|
||||||
|
"output_options": {
|
||||||
|
"download_archive_name": ".ytdl-sub-NOVA PBS-download-archive.json",
|
||||||
|
"file_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( upload_year ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( upload_year ), \".e\", %string( %pad_zero( %int( %concat( upload_month, upload_day_padded, upload_date_index_padded ) ), 6 ) ), \" - \", %string( title_sanitized_plex ) ) ) ) ) }.{ ext }",
|
||||||
|
"info_json_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( upload_year ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( upload_year ), \".e\", %string( %pad_zero( %int( %concat( upload_month, upload_day_padded, upload_date_index_padded ) ), 6 ) ), \" - \", %string( title_sanitized_plex ) ) ) ) ) }.{ info_json_ext }",
|
||||||
|
"keep_files_date_eval": "{ upload_date_standardized }",
|
||||||
|
"maintain_download_archive": true,
|
||||||
|
"output_directory": "/var/folders/rw/hl1xmkmj68zdl2kjx3l0dwzc0000gn/T/tmp9xwmie5t/NOVA PBS",
|
||||||
|
"preserve_mtime": false,
|
||||||
|
"thumbnail_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( upload_year ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( upload_year ), \".e\", %string( %pad_zero( %int( %concat( upload_month, upload_day_padded, upload_date_index_padded ) ), 6 ) ), \" - \", %string( title_sanitized_plex ) ) ) ) ) }-thumb.jpg"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"%bilateral_url": "{ %if( %and( enable_bilateral_scraping, subscription_has_download_archive, %is_bilateral_url( $0 ) ), $0, '' ) }",
|
||||||
|
"%episode_ordering_": "{ %eq( %lower( tv_show_by_date_episode_ordering ), $0 ) }",
|
||||||
|
"%is_bilateral_url": "{ %contains( $0, \"youtube.com/playlist\" ) }",
|
||||||
|
"%ordering_pair_eq": "{ %eq( [ tv_show_by_date_season_ordering, tv_show_by_date_episode_ordering ], [ $0, $1 ] ) }",
|
||||||
|
"%season_ordering_": "{ %eq( %lower( tv_show_by_date_season_ordering ), $0 ) }",
|
||||||
|
"assert_not_collection": true,
|
||||||
|
"avatar_uncropped_thumbnail_file_name": "poster.jpg",
|
||||||
|
"banner_uncropped_thumbnail_file_name": "fanart.jpg",
|
||||||
|
"enable_bilateral_scraping": true,
|
||||||
|
"enable_resolution_assert": true,
|
||||||
|
"enable_throttle_protection": true,
|
||||||
|
"episode_content_rating": "TV-14",
|
||||||
|
"episode_date_standardized": "{ upload_date_standardized }",
|
||||||
|
"episode_file_name": "s{ upload_year }.e{ %pad_zero( %int( %concat( upload_month, upload_day_padded, upload_date_index_padded ) ), 6 ) } - { title_sanitized_plex }",
|
||||||
|
"episode_file_path": "{ %sanitize( %concat( \"Season \", %string( upload_year ) ) ) }/{ %sanitize( %concat( \"s\", %string( upload_year ), \".e\", %string( %pad_zero( %int( %concat( upload_month, upload_day_padded, upload_date_index_padded ) ), 6 ) ), \" - \", %string( title_sanitized_plex ) ) ) }",
|
||||||
|
"episode_number": "{ upload_month }{ upload_day_padded }{ upload_date_index_padded }",
|
||||||
|
"episode_number_and_padded_": "{ [ %concat( upload_month, upload_day_padded, upload_date_index_padded ), 6 ] }",
|
||||||
|
"episode_number_padded": "{ %pad_zero( %int( %concat( upload_month, upload_day_padded, upload_date_index_padded ) ), 6 ) }",
|
||||||
|
"episode_plot": "{ webpage_url }\n\n{ description }",
|
||||||
|
"episode_title": "{ upload_date_standardized } - { title }",
|
||||||
|
"episode_year": "{ %slice( upload_date_standardized, 0, 4 ) }",
|
||||||
|
"file_title": "{ title_sanitized_plex }",
|
||||||
|
"file_uid": "{ uid_sanitized_plex }",
|
||||||
|
"include_sibling_metadata": false,
|
||||||
|
"modified_webpage_url": "{ webpage_url }",
|
||||||
|
"only_recent_date_range": "2months",
|
||||||
|
"only_recent_max_files": 30,
|
||||||
|
"resolution_assert": "{ %if( %and( enable_resolution_assert, %ne( height, 0 ), %not( resolution_assert_is_ignored ) ), %assert( %gte( height, resolution_assert_height_gte ), %concat( \"Entry \", title, \" downloaded at a low resolution (\", resolution_readable, \"), you've probably been throttled. \", \"Stopping further downloads, wait a few hours and try again. \", \"Disable using the override variable `enable_resolution_assert: False`.\" ) ), \"false is no-op\" ) }",
|
||||||
|
"resolution_assert_height_gte": 361,
|
||||||
|
"resolution_assert_ignore_titles": "{ [ ] }",
|
||||||
|
"resolution_assert_is_ignored": "{ %print_if_true( %concat( title, \" has a match in resolution_assert_ignore_titles, skipping resolution assert.\" ), %contains_any( title, [ ] ) ) }",
|
||||||
|
"resolution_assert_print": true,
|
||||||
|
"resolution_readable": "{ width }x{ height }",
|
||||||
|
"s01_name": "",
|
||||||
|
"s01_url": "",
|
||||||
|
"season_directory_name": "Season { upload_year }",
|
||||||
|
"season_number": "{ upload_year }",
|
||||||
|
"season_number_padded": "{ upload_year }",
|
||||||
|
"season_poster_file_name": "{ %sanitize( %concat( \"Season \", %string( upload_year ) ) ) }/Season{ upload_year }.jpg",
|
||||||
|
"subscription_array": [
|
||||||
|
"https://www.youtube.com/@novapbs"
|
||||||
|
],
|
||||||
|
"subscription_indent_1": "Documentaries",
|
||||||
|
"subscription_indent_2": "TV-14",
|
||||||
|
"subscription_value": "https://www.youtube.com/@novapbs",
|
||||||
|
"subscription_value_1": "https://www.youtube.com/@novapbs",
|
||||||
|
"thumbnail_file_name": "{ %concat( %string( %sanitize( %concat( \"Season \", %string( upload_year ) ) ) ), \"/\", %string( %sanitize( %concat( \"s\", %string( upload_year ), \".e\", %string( %pad_zero( %int( %concat( upload_month, upload_day_padded, upload_date_index_padded ) ), 6 ) ), \" - \", %string( title_sanitized_plex ) ) ) ) ) }-thumb.jpg",
|
||||||
|
"tv_show_by_date_episode_ordering": "upload-month-day",
|
||||||
|
"tv_show_by_date_ordering_pair_validation_": "{ [ %concat( upload_month, upload_day_padded, upload_date_index_padded ), 6 ] }",
|
||||||
|
"tv_show_by_date_season_ordering": "upload-year",
|
||||||
|
"tv_show_content_rating": "TV-14",
|
||||||
|
"tv_show_content_rating_default": "TV-14",
|
||||||
|
"tv_show_date_range_type": "upload_date",
|
||||||
|
"tv_show_directory": "/var/folders/rw/hl1xmkmj68zdl2kjx3l0dwzc0000gn/T/tmp9xwmie5t",
|
||||||
|
"tv_show_fanart_file_name": "fanart.jpg",
|
||||||
|
"tv_show_genre": "Documentaries",
|
||||||
|
"tv_show_genre_default": "ytdl-sub",
|
||||||
|
"tv_show_name": "NOVA PBS",
|
||||||
|
"tv_show_poster_file_name": "poster.jpg",
|
||||||
|
"url": "https://www.youtube.com/@novapbs",
|
||||||
|
"url10": "",
|
||||||
|
"url100": "",
|
||||||
|
"url11": "",
|
||||||
|
"url12": "",
|
||||||
|
"url13": "",
|
||||||
|
"url14": "",
|
||||||
|
"url15": "",
|
||||||
|
"url16": "",
|
||||||
|
"url17": "",
|
||||||
|
"url18": "",
|
||||||
|
"url19": "",
|
||||||
|
"url2": "",
|
||||||
|
"url20": "",
|
||||||
|
"url21": "",
|
||||||
|
"url22": "",
|
||||||
|
"url23": "",
|
||||||
|
"url24": "",
|
||||||
|
"url25": "",
|
||||||
|
"url26": "",
|
||||||
|
"url27": "",
|
||||||
|
"url28": "",
|
||||||
|
"url29": "",
|
||||||
|
"url3": "",
|
||||||
|
"url30": "",
|
||||||
|
"url31": "",
|
||||||
|
"url32": "",
|
||||||
|
"url33": "",
|
||||||
|
"url34": "",
|
||||||
|
"url35": "",
|
||||||
|
"url36": "",
|
||||||
|
"url37": "",
|
||||||
|
"url38": "",
|
||||||
|
"url39": "",
|
||||||
|
"url4": "",
|
||||||
|
"url40": "",
|
||||||
|
"url41": "",
|
||||||
|
"url42": "",
|
||||||
|
"url43": "",
|
||||||
|
"url44": "",
|
||||||
|
"url45": "",
|
||||||
|
"url46": "",
|
||||||
|
"url47": "",
|
||||||
|
"url48": "",
|
||||||
|
"url49": "",
|
||||||
|
"url5": "",
|
||||||
|
"url50": "",
|
||||||
|
"url51": "",
|
||||||
|
"url52": "",
|
||||||
|
"url53": "",
|
||||||
|
"url54": "",
|
||||||
|
"url55": "",
|
||||||
|
"url56": "",
|
||||||
|
"url57": "",
|
||||||
|
"url58": "",
|
||||||
|
"url59": "",
|
||||||
|
"url6": "",
|
||||||
|
"url60": "",
|
||||||
|
"url61": "",
|
||||||
|
"url62": "",
|
||||||
|
"url63": "",
|
||||||
|
"url64": "",
|
||||||
|
"url65": "",
|
||||||
|
"url66": "",
|
||||||
|
"url67": "",
|
||||||
|
"url68": "",
|
||||||
|
"url69": "",
|
||||||
|
"url7": "",
|
||||||
|
"url70": "",
|
||||||
|
"url71": "",
|
||||||
|
"url72": "",
|
||||||
|
"url73": "",
|
||||||
|
"url74": "",
|
||||||
|
"url75": "",
|
||||||
|
"url76": "",
|
||||||
|
"url77": "",
|
||||||
|
"url78": "",
|
||||||
|
"url79": "",
|
||||||
|
"url8": "",
|
||||||
|
"url80": "",
|
||||||
|
"url81": "",
|
||||||
|
"url82": "",
|
||||||
|
"url83": "",
|
||||||
|
"url84": "",
|
||||||
|
"url85": "",
|
||||||
|
"url86": "",
|
||||||
|
"url87": "",
|
||||||
|
"url88": "",
|
||||||
|
"url89": "",
|
||||||
|
"url9": "",
|
||||||
|
"url90": "",
|
||||||
|
"url91": "",
|
||||||
|
"url92": "",
|
||||||
|
"url93": "",
|
||||||
|
"url94": "",
|
||||||
|
"url95": "",
|
||||||
|
"url96": "",
|
||||||
|
"url97": "",
|
||||||
|
"url98": "",
|
||||||
|
"url99": "",
|
||||||
|
"urls": [
|
||||||
|
"https://www.youtube.com/@novapbs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"throttle_protection": {
|
||||||
|
"enable": true,
|
||||||
|
"sleep_per_download_s": {
|
||||||
|
"max": "28.4",
|
||||||
|
"min": "13.8"
|
||||||
|
},
|
||||||
|
"sleep_per_request_s": {
|
||||||
|
"max": "0.75",
|
||||||
|
"min": "0.0"
|
||||||
|
},
|
||||||
|
"sleep_per_subscription_s": {
|
||||||
|
"max": "26.1",
|
||||||
|
"min": "16.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"video_tags": {
|
||||||
|
"contentRating": "TV-14",
|
||||||
|
"date": "{ upload_date_standardized }",
|
||||||
|
"episode_id": "{ upload_month }{ upload_day_padded }{ upload_date_index_padded }",
|
||||||
|
"genre": "Documentaries",
|
||||||
|
"show": "NOVA PBS",
|
||||||
|
"synopsis": "{ webpage_url }\n\n{ description }",
|
||||||
|
"title": "{ upload_date_standardized } - { title }",
|
||||||
|
"year": "{ %slice( upload_date_standardized, 0, 4 ) }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -535,674 +535,3 @@ def test_music_video_subscriptions(default_config: ConfigFile, music_video_subsc
|
||||||
assert gnr_urls[0] == "https://www.youtube.com/playlist?list=PLOTK54q5K4INNXaHKtmXYr6J7CajWjqeJ"
|
assert gnr_urls[0] == "https://www.youtube.com/playlist?list=PLOTK54q5K4INNXaHKtmXYr6J7CajWjqeJ"
|
||||||
assert gnr.get("subscription_indent_1").native == "Rock"
|
assert gnr.get("subscription_indent_1").native == "Rock"
|
||||||
assert gnr_urls[1] == "https://www.youtube.com/watch?v=OldpIhHPsbs"
|
assert gnr_urls[1] == "https://www.youtube.com/watch?v=OldpIhHPsbs"
|
||||||
|
|
||||||
|
|
||||||
def test_default_docker_config_and_subscriptions(
|
|
||||||
docker_default_subscription_path: Path, output_directory: str
|
|
||||||
):
|
|
||||||
default_config = ConfigFile.from_file_path("docker/root/defaults/config.yaml")
|
|
||||||
default_subs = Subscription.from_file_path(
|
|
||||||
config=default_config, subscription_path=docker_default_subscription_path
|
|
||||||
)
|
|
||||||
assert len(default_subs) == 1
|
|
||||||
|
|
||||||
resolved_yaml_as_json = yaml.safe_load(default_subs[0].resolved_yaml())
|
|
||||||
|
|
||||||
assert resolved_yaml_as_json == {
|
|
||||||
"chapters": {
|
|
||||||
"allow_chapters_from_comments": False,
|
|
||||||
"embed_chapters": True,
|
|
||||||
"enable": "True",
|
|
||||||
"force_key_frames": False,
|
|
||||||
},
|
|
||||||
"date_range": {"breaks": "True", "enable": "True", "type": "upload_date"},
|
|
||||||
"download": [
|
|
||||||
{
|
|
||||||
"download_reverse": "True",
|
|
||||||
"include_sibling_metadata": False,
|
|
||||||
"playlist_thumbnails": [
|
|
||||||
{"name": "{avatar_uncropped_thumbnail_file_name}", "uid": "avatar_uncropped"},
|
|
||||||
{"name": "{banner_uncropped_thumbnail_file_name}", "uid": "banner_uncropped"},
|
|
||||||
],
|
|
||||||
"source_thumbnails": [
|
|
||||||
{"name": "{avatar_uncropped_thumbnail_file_name}", "uid": "avatar_uncropped"},
|
|
||||||
{"name": "{banner_uncropped_thumbnail_file_name}", "uid": "banner_uncropped"},
|
|
||||||
],
|
|
||||||
"url": "https://www.youtube.com/@novapbs",
|
|
||||||
"variables": {},
|
|
||||||
"webpage_url": "{modified_webpage_url}",
|
|
||||||
"ytdl_options": {},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"file_convert": {"convert_to": "mp4", "convert_with": "yt-dlp", "enable": "True"},
|
|
||||||
"format": "(bv*[ext=mp4][vcodec~='^((he|a)vc|h26[45])']+ba[ext=m4a]) / (bv[ext=mp4]*+ba[ext=m4a]/b)",
|
|
||||||
"output_options": {
|
|
||||||
"download_archive_name": ".ytdl-sub-NOVA PBS-download-archive.json",
|
|
||||||
"file_name": "{episode_file_path}.{ext}",
|
|
||||||
"info_json_name": "{episode_file_path}.{info_json_ext}",
|
|
||||||
"keep_files_date_eval": "{episode_date_standardized}",
|
|
||||||
"maintain_download_archive": True,
|
|
||||||
"output_directory": f"{output_directory}/NOVA PBS",
|
|
||||||
"preserve_mtime": False,
|
|
||||||
"thumbnail_name": "{thumbnail_file_name}",
|
|
||||||
},
|
|
||||||
"overrides": {
|
|
||||||
"%bilateral_url": "{ %if( %and( enable_bilateral_scraping, "
|
|
||||||
"subscription_has_download_archive, "
|
|
||||||
"%is_bilateral_url( $0 ) ), $0, '' ) }",
|
|
||||||
"%episode_ordering_": "{ %eq( %lower( " "tv_show_by_date_episode_ordering ), $0 ) " "}",
|
|
||||||
"%is_bilateral_url": '{ %contains( $0, "youtube.com/playlist" ) ' "}",
|
|
||||||
"%ordering_pair_eq": "{ %eq( [ tv_show_by_date_season_ordering, "
|
|
||||||
"tv_show_by_date_episode_ordering ], [ $0, "
|
|
||||||
"$1 ] ) }",
|
|
||||||
"%season_ordering_": "{ %eq( %lower( " "tv_show_by_date_season_ordering ), $0 ) }",
|
|
||||||
"assert_not_collection": "{ %assert( %and( %not( %bool( s01_url "
|
|
||||||
") ), %not( %bool( s01_name ) ) ), "
|
|
||||||
'"Provided `s01_url` or `s01_name` '
|
|
||||||
"variable to TV Show by Date preset "
|
|
||||||
"when it expects `url`. Perhaps you "
|
|
||||||
"meant to use the `TV Show Collection` "
|
|
||||||
'preset?" ) }',
|
|
||||||
"avatar_uncropped_thumbnail_file_name": "{ " "tv_show_poster_file_name " "}",
|
|
||||||
"banner_uncropped_thumbnail_file_name": "{ " "tv_show_fanart_file_name " "}",
|
|
||||||
"enable_bilateral_scraping": "{ %bool(True) }",
|
|
||||||
"enable_resolution_assert": "{ %bool(True) }",
|
|
||||||
"enable_throttle_protection": "{ %bool(True) }",
|
|
||||||
"episode_content_rating": "{ tv_show_content_rating }",
|
|
||||||
"episode_date_standardized": "{ %if( %contains( "
|
|
||||||
"tv_show_by_date_season_ordering, "
|
|
||||||
'"release" ), '
|
|
||||||
"release_date_standardized, "
|
|
||||||
"upload_date_standardized ) }",
|
|
||||||
"episode_file_name": '{ %concat( %string( "s" ), %string( '
|
|
||||||
'season_number_padded ), %string( ".e" ), '
|
|
||||||
"%string( episode_number_padded ), "
|
|
||||||
'%string( " - " ), %string( file_title ) ) '
|
|
||||||
"}",
|
|
||||||
"episode_file_path": "{ %concat( %string( "
|
|
||||||
"season_directory_name_sanitized ), "
|
|
||||||
'%string( "/" ), %string( '
|
|
||||||
"episode_file_name_sanitized ) ) }",
|
|
||||||
"episode_number": "{ %array_at( episode_number_and_padded_, 0 ) " "}",
|
|
||||||
"episode_number_and_padded_": "{ %elif( %episode_ordering_( "
|
|
||||||
'"upload-day" ), [ %concat( '
|
|
||||||
"upload_day, "
|
|
||||||
"upload_date_index_padded ), 4 ], "
|
|
||||||
"%episode_ordering_( "
|
|
||||||
'"upload-month-day" ), [ %concat( '
|
|
||||||
"upload_month, upload_day_padded, "
|
|
||||||
"upload_date_index_padded ), 6 ], "
|
|
||||||
"%episode_ordering_( "
|
|
||||||
'"upload-month-day-reversed" ), [ '
|
|
||||||
"%concat( "
|
|
||||||
"upload_day_of_year_reversed, "
|
|
||||||
"upload_date_index_reversed_padded "
|
|
||||||
"), 5 ], %episode_ordering_( "
|
|
||||||
'"release-day" ), [ %concat( '
|
|
||||||
"release_day, "
|
|
||||||
"upload_date_index_padded ), 4 ], "
|
|
||||||
"%episode_ordering_( "
|
|
||||||
'"release-month-day" ), [ '
|
|
||||||
"%concat( release_month, "
|
|
||||||
"release_day_padded, "
|
|
||||||
"upload_date_index_padded ), 6 ], "
|
|
||||||
"%episode_ordering_( "
|
|
||||||
'"release-month-day-reversed" ), '
|
|
||||||
"[ %concat( "
|
|
||||||
"release_day_of_year_reversed, "
|
|
||||||
"upload_date_index_reversed_padded "
|
|
||||||
"), 5 ], %episode_ordering_( "
|
|
||||||
'"download-index" ), [ '
|
|
||||||
"download_index, 6 ], %throw( "
|
|
||||||
"'tv_show_by_date_episode_ordering "
|
|
||||||
"must be one of the following: "
|
|
||||||
'"upload-day", '
|
|
||||||
'"upload-month-day", '
|
|
||||||
'"upload-month-day-reversed", '
|
|
||||||
'"release-day", '
|
|
||||||
'"release-month-day", '
|
|
||||||
'"release-month-day-reversed", '
|
|
||||||
'"download-index"\' ) ) }',
|
|
||||||
"episode_number_padded": "{ %pad_zero( %int( episode_number ), "
|
|
||||||
"%int( %array_at( "
|
|
||||||
"episode_number_and_padded_, 1 ) ) ) }",
|
|
||||||
"episode_plot": '{ %concat( %string( webpage_url ), %string( "\n'
|
|
||||||
"\n"
|
|
||||||
'" ), %string( description ) ) }',
|
|
||||||
"episode_title": "{ %concat( %string( episode_date_standardized "
|
|
||||||
'), %string( " - " ), %string( title ) ) }',
|
|
||||||
"episode_year": "{ %slice( episode_date_standardized, 0, 4 ) }",
|
|
||||||
"file_title": "{ title_sanitized_plex }",
|
|
||||||
"file_uid": "{ uid_sanitized_plex }",
|
|
||||||
"include_sibling_metadata": "{ %bool(False) }",
|
|
||||||
"modified_webpage_url": "{ webpage_url }",
|
|
||||||
"music_directory": "/music",
|
|
||||||
"music_video_directory": "/music_videos",
|
|
||||||
"resolution_assert": "{ %if( %and( enable_resolution_assert, "
|
|
||||||
"%ne( height, 0 ), %not( "
|
|
||||||
"resolution_assert_is_ignored ) ), "
|
|
||||||
"%assert( %gte( height, "
|
|
||||||
"resolution_assert_height_gte ), %concat( "
|
|
||||||
'"Entry ", title, " downloaded at a low '
|
|
||||||
'resolution (", resolution_readable, "), '
|
|
||||||
"you've probably been throttled. \", "
|
|
||||||
'"Stopping further downloads, wait a few '
|
|
||||||
'hours and try again. ", "Disable using '
|
|
||||||
"the override variable "
|
|
||||||
'`enable_resolution_assert: False`." ) ), '
|
|
||||||
'"false is no-op" ) }',
|
|
||||||
"resolution_assert_height_gte": "{ %int(361) }",
|
|
||||||
"resolution_assert_ignore_titles": "{ [ ] }",
|
|
||||||
"resolution_assert_is_ignored": "{ %print_if_true( %concat( "
|
|
||||||
'title, " has a match in '
|
|
||||||
"resolution_assert_ignore_titles, "
|
|
||||||
'skipping resolution assert." '
|
|
||||||
"), %contains_any( title, "
|
|
||||||
"resolution_assert_ignore_titles "
|
|
||||||
") ) }",
|
|
||||||
"resolution_assert_print": "{ %print( %if( "
|
|
||||||
"enable_resolution_assert, "
|
|
||||||
'"Resolution assert is enabled, will '
|
|
||||||
"fail on low-quality video downloads "
|
|
||||||
"and presume throttle. Disable using "
|
|
||||||
"the override variable "
|
|
||||||
'`enable_resolution_assert: False`", '
|
|
||||||
'"Resolution assert is disabled. Use '
|
|
||||||
'at your own risk!" ), '
|
|
||||||
"enable_resolution_assert, -1 ) }",
|
|
||||||
"resolution_readable": "{ %concat( %string( width ), %string( "
|
|
||||||
'"x" ), %string( height ) ) }',
|
|
||||||
"s01_name": "",
|
|
||||||
"s01_url": "",
|
|
||||||
"season_directory_name": '{ %concat( %string( "Season " ), '
|
|
||||||
"%string( season_number_padded ) ) }",
|
|
||||||
"season_number": '{ %elif( %season_ordering_( "upload-year" ), '
|
|
||||||
"upload_year, %season_ordering_( "
|
|
||||||
'"upload-year-month" ), %concat( upload_year, '
|
|
||||||
"upload_month_padded ), %season_ordering_( "
|
|
||||||
'"release-year" ), release_year, '
|
|
||||||
'%season_ordering_( "release-year-month" ), '
|
|
||||||
"%concat( release_year, release_month_padded "
|
|
||||||
"), %throw( 'tv_show_by_date_season_ordering "
|
|
||||||
'must be one of the following: "upload-year", '
|
|
||||||
'"upload-year-month", "release-year", '
|
|
||||||
'"release-year-month"\' ) ) }',
|
|
||||||
"season_number_padded": "{ season_number }",
|
|
||||||
"season_poster_file_name": "{ %concat( %string( "
|
|
||||||
"season_directory_name_sanitized ), "
|
|
||||||
'%string( "/Season" ), %string( '
|
|
||||||
"season_number_padded ), %string( "
|
|
||||||
'".jpg" ) ) }',
|
|
||||||
"subscription_array": "{ %from_json( "
|
|
||||||
"'[\"https://www.youtube.com/@novapbs\"]' "
|
|
||||||
") }",
|
|
||||||
"subscription_indent_1": "Documentaries",
|
|
||||||
"subscription_indent_2": "{ tv_show_content_rating_default }",
|
|
||||||
"subscription_value": "https://www.youtube.com/@novapbs",
|
|
||||||
"subscription_value_1": "https://www.youtube.com/@novapbs",
|
|
||||||
"thumbnail_file_name": "{ %concat( %string( episode_file_path "
|
|
||||||
'), %string( "-thumb.jpg" ) ) }',
|
|
||||||
"tv_show_by_date_episode_ordering": "upload-month-day",
|
|
||||||
"tv_show_by_date_ordering_pair_validation_": "{ %assert_then( "
|
|
||||||
"%or( "
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"upload-year", '
|
|
||||||
'"upload-month-day" '
|
|
||||||
"), "
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"upload-year", '
|
|
||||||
'"upload-month-day-reversed" '
|
|
||||||
"), "
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"upload-year", '
|
|
||||||
'"download-index" '
|
|
||||||
"), "
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"upload-year-month", '
|
|
||||||
'"upload-day" ), '
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"release-year", '
|
|
||||||
'"release-month-day" '
|
|
||||||
"), "
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"release-year", '
|
|
||||||
'"release-month-day-reversed" '
|
|
||||||
"), "
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"release-year", '
|
|
||||||
'"download-index" '
|
|
||||||
"), "
|
|
||||||
"%ordering_pair_eq( "
|
|
||||||
'"release-year-month", '
|
|
||||||
'"release-day" ) '
|
|
||||||
"), "
|
|
||||||
"episode_number_and_padded_, "
|
|
||||||
'"Detected '
|
|
||||||
"incompatibility "
|
|
||||||
"between "
|
|
||||||
"tv_show_by_date_season_ordering "
|
|
||||||
"and "
|
|
||||||
"tv_show_by_date_episode_ordering. "
|
|
||||||
"Ensure you are "
|
|
||||||
"not using both "
|
|
||||||
"upload and "
|
|
||||||
"release date, and "
|
|
||||||
"that the "
|
|
||||||
"year/month/day "
|
|
||||||
"are included in "
|
|
||||||
"the combined "
|
|
||||||
"season and "
|
|
||||||
'episode." ) }',
|
|
||||||
"tv_show_by_date_season_ordering": "upload-year",
|
|
||||||
"tv_show_content_rating": "{ subscription_indent_2 }",
|
|
||||||
"tv_show_content_rating_default": "TV-14",
|
|
||||||
"tv_show_date_range_type": "{ %if( %contains( "
|
|
||||||
"tv_show_by_date_season_ordering, "
|
|
||||||
'"release" ), "release_date", '
|
|
||||||
'"upload_date" ) }',
|
|
||||||
"tv_show_directory": output_directory,
|
|
||||||
"tv_show_fanart_file_name": "fanart.jpg",
|
|
||||||
"tv_show_genre": "{ subscription_indent_1 }",
|
|
||||||
"tv_show_genre_default": "ytdl-sub",
|
|
||||||
"tv_show_name": "{ subscription_name }",
|
|
||||||
"tv_show_poster_file_name": "poster.jpg",
|
|
||||||
"url": "{ subscription_value }",
|
|
||||||
"url10": "",
|
|
||||||
"url100": "",
|
|
||||||
"url11": "",
|
|
||||||
"url12": "",
|
|
||||||
"url13": "",
|
|
||||||
"url14": "",
|
|
||||||
"url15": "",
|
|
||||||
"url16": "",
|
|
||||||
"url17": "",
|
|
||||||
"url18": "",
|
|
||||||
"url19": "",
|
|
||||||
"url2": "",
|
|
||||||
"url20": "",
|
|
||||||
"url21": "",
|
|
||||||
"url22": "",
|
|
||||||
"url23": "",
|
|
||||||
"url24": "",
|
|
||||||
"url25": "",
|
|
||||||
"url26": "",
|
|
||||||
"url27": "",
|
|
||||||
"url28": "",
|
|
||||||
"url29": "",
|
|
||||||
"url3": "",
|
|
||||||
"url30": "",
|
|
||||||
"url31": "",
|
|
||||||
"url32": "",
|
|
||||||
"url33": "",
|
|
||||||
"url34": "",
|
|
||||||
"url35": "",
|
|
||||||
"url36": "",
|
|
||||||
"url37": "",
|
|
||||||
"url38": "",
|
|
||||||
"url39": "",
|
|
||||||
"url4": "",
|
|
||||||
"url40": "",
|
|
||||||
"url41": "",
|
|
||||||
"url42": "",
|
|
||||||
"url43": "",
|
|
||||||
"url44": "",
|
|
||||||
"url45": "",
|
|
||||||
"url46": "",
|
|
||||||
"url47": "",
|
|
||||||
"url48": "",
|
|
||||||
"url49": "",
|
|
||||||
"url5": "",
|
|
||||||
"url50": "",
|
|
||||||
"url51": "",
|
|
||||||
"url52": "",
|
|
||||||
"url53": "",
|
|
||||||
"url54": "",
|
|
||||||
"url55": "",
|
|
||||||
"url56": "",
|
|
||||||
"url57": "",
|
|
||||||
"url58": "",
|
|
||||||
"url59": "",
|
|
||||||
"url6": "",
|
|
||||||
"url60": "",
|
|
||||||
"url61": "",
|
|
||||||
"url62": "",
|
|
||||||
"url63": "",
|
|
||||||
"url64": "",
|
|
||||||
"url65": "",
|
|
||||||
"url66": "",
|
|
||||||
"url67": "",
|
|
||||||
"url68": "",
|
|
||||||
"url69": "",
|
|
||||||
"url7": "",
|
|
||||||
"url70": "",
|
|
||||||
"url71": "",
|
|
||||||
"url72": "",
|
|
||||||
"url73": "",
|
|
||||||
"url74": "",
|
|
||||||
"url75": "",
|
|
||||||
"url76": "",
|
|
||||||
"url77": "",
|
|
||||||
"url78": "",
|
|
||||||
"url79": "",
|
|
||||||
"url8": "",
|
|
||||||
"url80": "",
|
|
||||||
"url81": "",
|
|
||||||
"url82": "",
|
|
||||||
"url83": "",
|
|
||||||
"url84": "",
|
|
||||||
"url85": "",
|
|
||||||
"url86": "",
|
|
||||||
"url87": "",
|
|
||||||
"url88": "",
|
|
||||||
"url89": "",
|
|
||||||
"url9": "",
|
|
||||||
"url90": "",
|
|
||||||
"url91": "",
|
|
||||||
"url92": "",
|
|
||||||
"url93": "",
|
|
||||||
"url94": "",
|
|
||||||
"url95": "",
|
|
||||||
"url96": "",
|
|
||||||
"url97": "",
|
|
||||||
"url98": "",
|
|
||||||
"url99": "",
|
|
||||||
"urls": "{ subscription_array }",
|
|
||||||
},
|
|
||||||
"throttle_protection": {
|
|
||||||
"enable": True,
|
|
||||||
"sleep_per_download_s": {"max": "28.4", "min": "13.8"},
|
|
||||||
"sleep_per_request_s": {"max": "0.75", "min": "0.0"},
|
|
||||||
"sleep_per_subscription_s": {"max": "26.1", "min": "16.3"},
|
|
||||||
},
|
|
||||||
"video_tags": {
|
|
||||||
"contentRating": "{episode_content_rating}",
|
|
||||||
"date": "{episode_date_standardized}",
|
|
||||||
"episode_id": "{episode_number}",
|
|
||||||
"genre": "{tv_show_genre}",
|
|
||||||
"show": "{tv_show_name}",
|
|
||||||
"synopsis": "{episode_plot}",
|
|
||||||
"title": "{episode_title}",
|
|
||||||
"year": "{episode_year}",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_default_docker_config_and_subscriptions_resolved_resolution(
|
|
||||||
docker_default_subscription_path: Path, output_directory: str
|
|
||||||
):
|
|
||||||
default_config = ConfigFile.from_file_path("docker/root/defaults/config.yaml")
|
|
||||||
default_subs = Subscription.from_file_path(
|
|
||||||
config=default_config, subscription_path=docker_default_subscription_path
|
|
||||||
)
|
|
||||||
assert len(default_subs) == 1
|
|
||||||
|
|
||||||
resolved_yaml_as_json = yaml.safe_load(
|
|
||||||
default_subs[0].resolved_yaml(resolution_level=ResolutionLevel.RESOLVE)
|
|
||||||
)
|
|
||||||
|
|
||||||
assert resolved_yaml_as_json == {
|
|
||||||
"chapters": {
|
|
||||||
"allow_chapters_from_comments": False,
|
|
||||||
"embed_chapters": True,
|
|
||||||
"enable": "True",
|
|
||||||
"force_key_frames": False,
|
|
||||||
},
|
|
||||||
"date_range": {"breaks": "True", "enable": "True", "type": "upload_date"},
|
|
||||||
"download": [
|
|
||||||
{
|
|
||||||
"download_reverse": "True",
|
|
||||||
"include_sibling_metadata": False,
|
|
||||||
"playlist_thumbnails": [
|
|
||||||
{"name": "{avatar_uncropped_thumbnail_file_name}", "uid": "avatar_uncropped"},
|
|
||||||
{"name": "{banner_uncropped_thumbnail_file_name}", "uid": "banner_uncropped"},
|
|
||||||
],
|
|
||||||
"source_thumbnails": [
|
|
||||||
{"name": "{avatar_uncropped_thumbnail_file_name}", "uid": "avatar_uncropped"},
|
|
||||||
{"name": "{banner_uncropped_thumbnail_file_name}", "uid": "banner_uncropped"},
|
|
||||||
],
|
|
||||||
"url": "https://www.youtube.com/@novapbs",
|
|
||||||
"variables": {},
|
|
||||||
"webpage_url": "{modified_webpage_url}",
|
|
||||||
"ytdl_options": {},
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"file_convert": {"convert_to": "mp4", "convert_with": "yt-dlp", "enable": "True"},
|
|
||||||
"format": "(bv*[ext=mp4][vcodec~='^((he|a)vc|h26[45])']+ba[ext=m4a]) / (bv[ext=mp4]*+ba[ext=m4a]/b)",
|
|
||||||
"output_options": {
|
|
||||||
"download_archive_name": ".ytdl-sub-NOVA PBS-download-archive.json",
|
|
||||||
"file_name": "{episode_file_path}.{ext}",
|
|
||||||
"info_json_name": "{episode_file_path}.{info_json_ext}",
|
|
||||||
"keep_files_date_eval": "{episode_date_standardized}",
|
|
||||||
"maintain_download_archive": True,
|
|
||||||
"output_directory": f"{output_directory}/NOVA PBS",
|
|
||||||
"preserve_mtime": False,
|
|
||||||
"thumbnail_name": "{thumbnail_file_name}",
|
|
||||||
},
|
|
||||||
"overrides": {
|
|
||||||
"%bilateral_url": "{ %if( %and( enable_bilateral_scraping, "
|
|
||||||
"subscription_has_download_archive, "
|
|
||||||
"%is_bilateral_url( $0 ) ), $0, '' ) }",
|
|
||||||
"%episode_ordering_": "{ %eq( %lower( " "tv_show_by_date_episode_ordering ), $0 ) " "}",
|
|
||||||
"%is_bilateral_url": '{ %contains( $0, "youtube.com/playlist" ) ' "}",
|
|
||||||
"%ordering_pair_eq": "{ %eq( [ tv_show_by_date_season_ordering, "
|
|
||||||
"tv_show_by_date_episode_ordering ], [ $0, "
|
|
||||||
"$1 ] ) }",
|
|
||||||
"%season_ordering_": "{ %eq( %lower( " "tv_show_by_date_season_ordering ), $0 ) }",
|
|
||||||
"assert_not_collection": True,
|
|
||||||
"avatar_uncropped_thumbnail_file_name": "poster.jpg",
|
|
||||||
"banner_uncropped_thumbnail_file_name": "fanart.jpg",
|
|
||||||
"enable_bilateral_scraping": True,
|
|
||||||
"enable_resolution_assert": True,
|
|
||||||
"enable_throttle_protection": True,
|
|
||||||
"episode_content_rating": "TV-14",
|
|
||||||
"episode_date_standardized": "{ upload_date_standardized }",
|
|
||||||
"episode_file_name": "s{ upload_year }.e{ %pad_zero( %int( "
|
|
||||||
"%concat( upload_month, upload_day_padded, "
|
|
||||||
"upload_date_index_padded ) ), 6 ) } - { "
|
|
||||||
"title_sanitized_plex }",
|
|
||||||
"episode_file_path": '{ %sanitize( %concat( "Season ", %string( '
|
|
||||||
"upload_year ) ) ) }/{ %sanitize( %concat( "
|
|
||||||
'"s", %string( upload_year ), ".e", '
|
|
||||||
"%string( %pad_zero( %int( %concat( "
|
|
||||||
"upload_month, upload_day_padded, "
|
|
||||||
'upload_date_index_padded ) ), 6 ) ), " - '
|
|
||||||
'", %string( title_sanitized_plex ) ) ) }',
|
|
||||||
"episode_number": "{ upload_month }{ upload_day_padded }{ "
|
|
||||||
"upload_date_index_padded }",
|
|
||||||
"episode_number_and_padded_": "{ [ %concat( upload_month, "
|
|
||||||
"upload_day_padded, "
|
|
||||||
"upload_date_index_padded ), 6 ] "
|
|
||||||
"}",
|
|
||||||
"episode_number_padded": "{ %pad_zero( %int( %concat( "
|
|
||||||
"upload_month, upload_day_padded, "
|
|
||||||
"upload_date_index_padded ) ), 6 ) }",
|
|
||||||
"episode_plot": "{ webpage_url }\n\n{ description }",
|
|
||||||
"episode_title": "{ upload_date_standardized } - { title }",
|
|
||||||
"episode_year": "{ %slice( upload_date_standardized, 0, 4 ) }",
|
|
||||||
"file_title": "{ title_sanitized_plex }",
|
|
||||||
"file_uid": "{ uid_sanitized_plex }",
|
|
||||||
"include_sibling_metadata": False,
|
|
||||||
"modified_webpage_url": "{ webpage_url }",
|
|
||||||
"music_directory": "/music",
|
|
||||||
"music_video_directory": "/music_videos",
|
|
||||||
"resolution_assert": "{ %if( %and( enable_resolution_assert, "
|
|
||||||
"%ne( height, 0 ), %not( "
|
|
||||||
"resolution_assert_is_ignored ) ), "
|
|
||||||
"%assert( %gte( height, "
|
|
||||||
"resolution_assert_height_gte ), %concat( "
|
|
||||||
'"Entry ", title, " downloaded at a low '
|
|
||||||
'resolution (", resolution_readable, "), '
|
|
||||||
"you've probably been throttled. \", "
|
|
||||||
'"Stopping further downloads, wait a few '
|
|
||||||
'hours and try again. ", "Disable using '
|
|
||||||
"the override variable "
|
|
||||||
'`enable_resolution_assert: False`." ) ), '
|
|
||||||
'"false is no-op" ) }',
|
|
||||||
"resolution_assert_height_gte": 361,
|
|
||||||
"resolution_assert_ignore_titles": "{ [ ] }",
|
|
||||||
"resolution_assert_is_ignored": "{ %print_if_true( %concat( "
|
|
||||||
'title, " has a match in '
|
|
||||||
"resolution_assert_ignore_titles, "
|
|
||||||
'skipping resolution assert." '
|
|
||||||
"), %contains_any( title, "
|
|
||||||
"resolution_assert_ignore_titles "
|
|
||||||
") ) }",
|
|
||||||
"resolution_assert_print": True,
|
|
||||||
"resolution_readable": "{ width }x{ height }",
|
|
||||||
"s01_name": "",
|
|
||||||
"s01_url": "",
|
|
||||||
"season_directory_name": "Season { upload_year }",
|
|
||||||
"season_number": "{ upload_year }",
|
|
||||||
"season_number_padded": "{ upload_year }",
|
|
||||||
"season_poster_file_name": '{ %sanitize( %concat( "Season ", '
|
|
||||||
"%string( upload_year ) ) ) "
|
|
||||||
"}/Season{ upload_year }.jpg",
|
|
||||||
"subscription_array": ["https://www.youtube.com/@novapbs"],
|
|
||||||
"subscription_indent_1": "Documentaries",
|
|
||||||
"subscription_indent_2": "TV-14",
|
|
||||||
"subscription_value": "https://www.youtube.com/@novapbs",
|
|
||||||
"subscription_value_1": "https://www.youtube.com/@novapbs",
|
|
||||||
"thumbnail_file_name": "{ %concat( %string( %sanitize( %concat( "
|
|
||||||
'"Season ", %string( upload_year ) ) ) '
|
|
||||||
'), "/", %string( %sanitize( %concat( '
|
|
||||||
'"s", %string( upload_year ), ".e", '
|
|
||||||
"%string( %pad_zero( %int( %concat( "
|
|
||||||
"upload_month, upload_day_padded, "
|
|
||||||
'upload_date_index_padded ) ), 6 ) ), " '
|
|
||||||
'- ", %string( title_sanitized_plex ) ) '
|
|
||||||
") ) ) }-thumb.jpg",
|
|
||||||
"tv_show_by_date_episode_ordering": "upload-month-day",
|
|
||||||
"tv_show_by_date_ordering_pair_validation_": "{ [ %concat( "
|
|
||||||
"upload_month, "
|
|
||||||
"upload_day_padded, "
|
|
||||||
"upload_date_index_padded "
|
|
||||||
"), 6 ] }",
|
|
||||||
"tv_show_by_date_season_ordering": "upload-year",
|
|
||||||
"tv_show_content_rating": "TV-14",
|
|
||||||
"tv_show_content_rating_default": "TV-14",
|
|
||||||
"tv_show_date_range_type": "upload_date",
|
|
||||||
"tv_show_directory": output_directory,
|
|
||||||
"tv_show_fanart_file_name": "fanart.jpg",
|
|
||||||
"tv_show_genre": "Documentaries",
|
|
||||||
"tv_show_genre_default": "ytdl-sub",
|
|
||||||
"tv_show_name": "NOVA PBS",
|
|
||||||
"tv_show_poster_file_name": "poster.jpg",
|
|
||||||
"url": "https://www.youtube.com/@novapbs",
|
|
||||||
"url10": "",
|
|
||||||
"url100": "",
|
|
||||||
"url11": "",
|
|
||||||
"url12": "",
|
|
||||||
"url13": "",
|
|
||||||
"url14": "",
|
|
||||||
"url15": "",
|
|
||||||
"url16": "",
|
|
||||||
"url17": "",
|
|
||||||
"url18": "",
|
|
||||||
"url19": "",
|
|
||||||
"url2": "",
|
|
||||||
"url20": "",
|
|
||||||
"url21": "",
|
|
||||||
"url22": "",
|
|
||||||
"url23": "",
|
|
||||||
"url24": "",
|
|
||||||
"url25": "",
|
|
||||||
"url26": "",
|
|
||||||
"url27": "",
|
|
||||||
"url28": "",
|
|
||||||
"url29": "",
|
|
||||||
"url3": "",
|
|
||||||
"url30": "",
|
|
||||||
"url31": "",
|
|
||||||
"url32": "",
|
|
||||||
"url33": "",
|
|
||||||
"url34": "",
|
|
||||||
"url35": "",
|
|
||||||
"url36": "",
|
|
||||||
"url37": "",
|
|
||||||
"url38": "",
|
|
||||||
"url39": "",
|
|
||||||
"url4": "",
|
|
||||||
"url40": "",
|
|
||||||
"url41": "",
|
|
||||||
"url42": "",
|
|
||||||
"url43": "",
|
|
||||||
"url44": "",
|
|
||||||
"url45": "",
|
|
||||||
"url46": "",
|
|
||||||
"url47": "",
|
|
||||||
"url48": "",
|
|
||||||
"url49": "",
|
|
||||||
"url5": "",
|
|
||||||
"url50": "",
|
|
||||||
"url51": "",
|
|
||||||
"url52": "",
|
|
||||||
"url53": "",
|
|
||||||
"url54": "",
|
|
||||||
"url55": "",
|
|
||||||
"url56": "",
|
|
||||||
"url57": "",
|
|
||||||
"url58": "",
|
|
||||||
"url59": "",
|
|
||||||
"url6": "",
|
|
||||||
"url60": "",
|
|
||||||
"url61": "",
|
|
||||||
"url62": "",
|
|
||||||
"url63": "",
|
|
||||||
"url64": "",
|
|
||||||
"url65": "",
|
|
||||||
"url66": "",
|
|
||||||
"url67": "",
|
|
||||||
"url68": "",
|
|
||||||
"url69": "",
|
|
||||||
"url7": "",
|
|
||||||
"url70": "",
|
|
||||||
"url71": "",
|
|
||||||
"url72": "",
|
|
||||||
"url73": "",
|
|
||||||
"url74": "",
|
|
||||||
"url75": "",
|
|
||||||
"url76": "",
|
|
||||||
"url77": "",
|
|
||||||
"url78": "",
|
|
||||||
"url79": "",
|
|
||||||
"url8": "",
|
|
||||||
"url80": "",
|
|
||||||
"url81": "",
|
|
||||||
"url82": "",
|
|
||||||
"url83": "",
|
|
||||||
"url84": "",
|
|
||||||
"url85": "",
|
|
||||||
"url86": "",
|
|
||||||
"url87": "",
|
|
||||||
"url88": "",
|
|
||||||
"url89": "",
|
|
||||||
"url9": "",
|
|
||||||
"url90": "",
|
|
||||||
"url91": "",
|
|
||||||
"url92": "",
|
|
||||||
"url93": "",
|
|
||||||
"url94": "",
|
|
||||||
"url95": "",
|
|
||||||
"url96": "",
|
|
||||||
"url97": "",
|
|
||||||
"url98": "",
|
|
||||||
"url99": "",
|
|
||||||
"urls": ["https://www.youtube.com/@novapbs"],
|
|
||||||
},
|
|
||||||
"throttle_protection": {
|
|
||||||
"enable": True,
|
|
||||||
"sleep_per_download_s": {"max": "28.4", "min": "13.8"},
|
|
||||||
"sleep_per_request_s": {"max": "0.75", "min": "0.0"},
|
|
||||||
"sleep_per_subscription_s": {"max": "26.1", "min": "16.3"},
|
|
||||||
},
|
|
||||||
"video_tags": {
|
|
||||||
"contentRating": "{episode_content_rating}",
|
|
||||||
"date": "{episode_date_standardized}",
|
|
||||||
"episode_id": "{episode_number}",
|
|
||||||
"genre": "{tv_show_genre}",
|
|
||||||
"show": "{tv_show_name}",
|
|
||||||
"synopsis": "{episode_plot}",
|
|
||||||
"title": "{episode_title}",
|
|
||||||
"year": "{episode_year}",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue