doc strings, add refactor
This commit is contained in:
parent
92031fd5b4
commit
e171fd95c2
9 changed files with 65 additions and 74 deletions
|
|
@ -114,7 +114,7 @@ class InfoJsonDownloader(SourcePlugin[InfoJsonDownloaderOptions]):
|
||||||
|
|
||||||
entry.initialize_script(self.overrides).add(
|
entry.initialize_script(self.overrides).add(
|
||||||
{
|
{
|
||||||
inj.variable_name: prior_variables.get(
|
inj: prior_variables.get(
|
||||||
inj.variable_name,
|
inj.variable_name,
|
||||||
VARIABLE_SCRIPTS[inj.variable_name],
|
VARIABLE_SCRIPTS[inj.variable_name],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -452,11 +452,7 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
||||||
url_validator=collection_url, parents=parents, orphans=orphan_entries
|
url_validator=collection_url, parents=parents, orphans=orphan_entries
|
||||||
):
|
):
|
||||||
entry.initialize_script(self.overrides).add(
|
entry.initialize_script(self.overrides).add(
|
||||||
{
|
{v.ytdl_sub_input_url: self.overrides.apply_formatter(collection_url.url)}
|
||||||
v.ytdl_sub_input_url.variable_name: self.overrides.apply_formatter(
|
|
||||||
collection_url.url
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
yield entry
|
yield entry
|
||||||
|
|
||||||
|
|
@ -498,17 +494,17 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
||||||
entry.add(
|
entry.add(
|
||||||
{
|
{
|
||||||
# Tracks number of entries downloaded
|
# Tracks number of entries downloaded
|
||||||
v.download_index.variable_name: download_idx + 1,
|
v.download_index: download_idx + 1,
|
||||||
# Tracks number of entries with the same upload date to make them unique
|
# Tracks number of entries with the same upload date to make them unique
|
||||||
v.upload_date_index.variable_name: upload_date_idx + 1,
|
v.upload_date_index: upload_date_idx + 1,
|
||||||
v.requested_subtitles.variable_name: download_entry.kwargs_get(
|
v.requested_subtitles: download_entry.kwargs_get(
|
||||||
v.requested_subtitles.metadata_key
|
v.requested_subtitles.metadata_key
|
||||||
),
|
),
|
||||||
v.chapters.variable_name: download_entry.kwargs_get(v.chapters.metadata_key),
|
v.chapters: download_entry.kwargs_get(v.chapters.metadata_key),
|
||||||
v.sponsorblock_chapters.variable_name: download_entry.kwargs_get(
|
v.sponsorblock_chapters: download_entry.kwargs_get(
|
||||||
v.sponsorblock_chapters.metadata_key
|
v.sponsorblock_chapters.metadata_key
|
||||||
),
|
),
|
||||||
v.comments.variable_name: download_entry.kwargs_get(v.comments.metadata_key),
|
v.comments: download_entry.kwargs_get(v.comments.metadata_key),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,45 +39,48 @@ class VariableDefinitions:
|
||||||
@property
|
@property
|
||||||
def entry_metadata(self) -> Metadata:
|
def entry_metadata(self) -> Metadata:
|
||||||
"""
|
"""
|
||||||
Returns
|
The entry's info.json
|
||||||
-------
|
|
||||||
dict
|
|
||||||
The entry's info.json in dict form
|
|
||||||
"""
|
"""
|
||||||
return Metadata("entry_metadata")
|
return Metadata("entry_metadata")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def playlist_metadata(self) -> RelativeMetadata:
|
def playlist_metadata(self) -> RelativeMetadata:
|
||||||
|
"""
|
||||||
|
Metadata from the playlist (i.e. the parent metadata, like playlist -> entry)
|
||||||
|
"""
|
||||||
return RelativeMetadata("playlist_metadata", metadata_key="playlist_metadata")
|
return RelativeMetadata("playlist_metadata", metadata_key="playlist_metadata")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def source_metadata(self) -> RelativeMetadata:
|
def source_metadata(self) -> RelativeMetadata:
|
||||||
|
"""
|
||||||
|
Metadata from the source (i.e. the grandparent metadata, like channel -> playlist -> entry)
|
||||||
|
"""
|
||||||
return RelativeMetadata("source_metadata", metadata_key="source_metadata")
|
return RelativeMetadata("source_metadata", metadata_key="source_metadata")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sibling_metadata(self) -> SiblingMetadata:
|
def sibling_metadata(self) -> SiblingMetadata:
|
||||||
|
"""
|
||||||
|
Metadata from any sibling entries that reside in the same playlist as this entry.
|
||||||
|
"""
|
||||||
return SiblingMetadata("sibling_metadata", metadata_key="sibling_metadata")
|
return SiblingMetadata("sibling_metadata", metadata_key="sibling_metadata")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def uid(self) -> MetadataVariable:
|
def uid(self) -> MetadataVariable:
|
||||||
"""
|
"""
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
str
|
|
||||||
The entry's unique ID
|
The entry's unique ID
|
||||||
"""
|
"""
|
||||||
return MetadataVariable(metadata_key="id", variable_name="uid")
|
return MetadataVariable(metadata_key="id", variable_name="uid")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def duration(self) -> MetadataVariable:
|
def duration(self) -> MetadataVariable:
|
||||||
|
"""
|
||||||
|
The duration of the entry in seconds
|
||||||
|
"""
|
||||||
return MetadataVariable("duration", metadata_key="duration")
|
return MetadataVariable("duration", metadata_key="duration")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def uid_sanitized_plex(self) -> Variable:
|
def uid_sanitized_plex(self) -> Variable:
|
||||||
"""
|
"""
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
str
|
|
||||||
The sanitized uid with additional sanitizing for Plex. Replaces numbers with
|
The sanitized uid with additional sanitizing for Plex. Replaces numbers with
|
||||||
fixed-width numbers so Plex does not recognize them as season or episode numbers.
|
fixed-width numbers so Plex does not recognize them as season or episode numbers.
|
||||||
"""
|
"""
|
||||||
|
|
@ -86,39 +89,27 @@ class VariableDefinitions:
|
||||||
@property
|
@property
|
||||||
def ie_key(self) -> MetadataVariable:
|
def ie_key(self) -> MetadataVariable:
|
||||||
"""
|
"""
|
||||||
Returns
|
The ie_key, used in legacy yt-dlp things as the 'info-extractor key'
|
||||||
-------
|
|
||||||
str
|
|
||||||
The info-extractor key
|
|
||||||
"""
|
"""
|
||||||
return MetadataVariable(metadata_key="ie_key", variable_name="ie_key")
|
return MetadataVariable(metadata_key="ie_key", variable_name="ie_key")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extractor_key(self) -> MetadataVariable:
|
def extractor_key(self) -> MetadataVariable:
|
||||||
"""
|
"""
|
||||||
Returns
|
The yt-dlp extractor key
|
||||||
-------
|
|
||||||
str
|
|
||||||
The info-extractor key
|
|
||||||
"""
|
"""
|
||||||
return MetadataVariable(metadata_key="extractor_key", variable_name="extractor_key")
|
return MetadataVariable(metadata_key="extractor_key", variable_name="extractor_key")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extractor(self) -> MetadataVariable:
|
def extractor(self) -> MetadataVariable:
|
||||||
"""
|
"""
|
||||||
Returns
|
The yt-dlp extractor name
|
||||||
-------
|
|
||||||
str
|
|
||||||
The ytdl extractor name
|
|
||||||
"""
|
"""
|
||||||
return MetadataVariable(variable_name="extractor", metadata_key="extractor")
|
return MetadataVariable(variable_name="extractor", metadata_key="extractor")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def epoch(self) -> MetadataVariable:
|
def epoch(self) -> MetadataVariable:
|
||||||
"""
|
"""
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
int
|
|
||||||
The unix epoch of when the metadata was scraped by yt-dlp.
|
The unix epoch of when the metadata was scraped by yt-dlp.
|
||||||
"""
|
"""
|
||||||
return MetadataVariable(metadata_key="epoch", variable_name="epoch")
|
return MetadataVariable(metadata_key="epoch", variable_name="epoch")
|
||||||
|
|
@ -126,9 +117,6 @@ class VariableDefinitions:
|
||||||
@property
|
@property
|
||||||
def epoch_date(self) -> Variable:
|
def epoch_date(self) -> Variable:
|
||||||
"""
|
"""
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
str
|
|
||||||
The epoch's date, in YYYYMMDD format.
|
The epoch's date, in YYYYMMDD format.
|
||||||
"""
|
"""
|
||||||
return Variable("epoch_date")
|
return Variable("epoch_date")
|
||||||
|
|
@ -136,19 +124,13 @@ class VariableDefinitions:
|
||||||
@property
|
@property
|
||||||
def epoch_hour(self) -> Variable:
|
def epoch_hour(self) -> Variable:
|
||||||
"""
|
"""
|
||||||
Returns
|
The epoch's hour
|
||||||
-------
|
|
||||||
str
|
|
||||||
The epoch's hour, padded
|
|
||||||
"""
|
"""
|
||||||
return Variable("epoch_hour")
|
return Variable("epoch_hour")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def title(self) -> MetadataVariable:
|
def title(self) -> MetadataVariable:
|
||||||
"""
|
"""
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
str
|
|
||||||
The title of the entry. If a title does not exist, returns its unique ID.
|
The title of the entry. If a title does not exist, returns its unique ID.
|
||||||
"""
|
"""
|
||||||
return MetadataVariable(variable_name="title", metadata_key="title")
|
return MetadataVariable(variable_name="title", metadata_key="title")
|
||||||
|
|
@ -156,10 +138,7 @@ class VariableDefinitions:
|
||||||
@property
|
@property
|
||||||
def title_sanitized_plex(self) -> Variable:
|
def title_sanitized_plex(self) -> Variable:
|
||||||
"""
|
"""
|
||||||
Returns
|
The sanitized title with additional sanitizing for Plex. It replaces numbers with
|
||||||
-------
|
|
||||||
str
|
|
||||||
The sanitized title with additional sanitizing for Plex. Replaces numbers with
|
|
||||||
fixed-width numbers so Plex does not recognize them as season or episode numbers.
|
fixed-width numbers so Plex does not recognize them as season or episode numbers.
|
||||||
"""
|
"""
|
||||||
return Variable("title_sanitized_plex")
|
return Variable("title_sanitized_plex")
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ class AudioExtractPlugin(Plugin[AudioExtractOptions]):
|
||||||
new_ext = AUDIO_CODEC_TYPES_EXTENSION_MAPPING[self.plugin_options.codec]
|
new_ext = AUDIO_CODEC_TYPES_EXTENSION_MAPPING[self.plugin_options.codec]
|
||||||
extracted_audio_file = entry.get_download_file_path().removesuffix(entry.ext) + new_ext
|
extracted_audio_file = entry.get_download_file_path().removesuffix(entry.ext) + new_ext
|
||||||
|
|
||||||
entry.add({v.ext.variable_name: new_ext})
|
entry.add({v.ext: new_ext})
|
||||||
|
|
||||||
if not self.is_dry_run:
|
if not self.is_dry_run:
|
||||||
if not os.path.isfile(extracted_audio_file):
|
if not os.path.isfile(extracted_audio_file):
|
||||||
|
|
|
||||||
|
|
@ -321,13 +321,7 @@ class ChaptersPlugin(Plugin[ChaptersOptions]):
|
||||||
# If some are actually found, add a special kwarg and embed them
|
# If some are actually found, add a special kwarg and embed them
|
||||||
if chapters.contains_any_chapters():
|
if chapters.contains_any_chapters():
|
||||||
has_chapters_from_comments = True
|
has_chapters_from_comments = True
|
||||||
entry.add(
|
entry.add({ytdl_sub_chapters_from_comments: chapters.to_yt_dlp_chapter_metadata()})
|
||||||
{
|
|
||||||
ytdl_sub_chapters_from_comments.variable_name: (
|
|
||||||
chapters.to_yt_dlp_chapter_metadata()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if not self.is_dry_run:
|
if not self.is_dry_run:
|
||||||
set_ffmpeg_metadata_chapters(
|
set_ffmpeg_metadata_chapters(
|
||||||
|
|
@ -337,7 +331,7 @@ class ChaptersPlugin(Plugin[ChaptersOptions]):
|
||||||
)
|
)
|
||||||
|
|
||||||
if not has_chapters_from_comments:
|
if not has_chapters_from_comments:
|
||||||
entry.add({ytdl_sub_chapters_from_comments.variable_name: []})
|
entry.add({ytdl_sub_chapters_from_comments: []})
|
||||||
|
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ class FileConvertPlugin(Plugin[FileConvertOptions]):
|
||||||
if original_ext != new_ext:
|
if original_ext != new_ext:
|
||||||
self._converted_from_lookup[entry.ytdl_uid()] = original_ext
|
self._converted_from_lookup[entry.ytdl_uid()] = original_ext
|
||||||
|
|
||||||
entry.add({v.ext.variable_name: new_ext})
|
entry.add({v.ext: new_ext})
|
||||||
|
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,8 @@ class SplitByChaptersPlugin(SplitPlugin[SplitByChaptersOptions]):
|
||||||
"chapter_index": 1,
|
"chapter_index": 1,
|
||||||
"chapter_index_padded": "01",
|
"chapter_index_padded": "01",
|
||||||
"chapter_count": 1,
|
"chapter_count": 1,
|
||||||
v.uid.variable_name: entry.uid,
|
v.uid: entry.uid,
|
||||||
ytdl_sub_split_by_chapters_parent_uid.variable_name: entry.uid,
|
ytdl_sub_split_by_chapters_parent_uid: entry.uid,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return entry
|
return entry
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
import json
|
import json
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import Iterable
|
|
||||||
|
|
||||||
|
|
||||||
class ScriptUtils:
|
class ScriptUtils:
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_sanitized_variables(cls, variables: Dict[str, str]) -> Dict[str, str]:
|
def add_sanitized_variables(cls, variables: Dict[str, str]) -> Dict[str, str]:
|
||||||
|
"""
|
||||||
|
Helper to add sanitized variables to a Script
|
||||||
|
"""
|
||||||
sanitized_variables = {
|
sanitized_variables = {
|
||||||
f"{name}_sanitized": f"{{%sanitize({name})}}" for name in variables.keys()
|
f"{name}_sanitized": f"{{%sanitize({name})}}" for name in variables.keys()
|
||||||
}
|
}
|
||||||
|
|
@ -14,6 +16,9 @@ class ScriptUtils:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def to_script(cls, value: Any) -> str:
|
def to_script(cls, value: Any) -> str:
|
||||||
|
"""
|
||||||
|
Converts a python value to a script value
|
||||||
|
"""
|
||||||
if value is None:
|
if value is None:
|
||||||
out = ""
|
out = ""
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from typing import Dict
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS
|
from ytdl_sub.entries.script.function_scripts import CUSTOM_FUNCTION_SCRIPTS
|
||||||
|
from ytdl_sub.entries.script.variable_definitions import Variable
|
||||||
from ytdl_sub.entries.script.variable_scripts import UNRESOLVED_VARIABLES
|
from ytdl_sub.entries.script.variable_scripts import UNRESOLVED_VARIABLES
|
||||||
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
|
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
|
||||||
from ytdl_sub.script.script import Script
|
from ytdl_sub.script.script import Script
|
||||||
|
|
@ -12,6 +13,10 @@ from ytdl_sub.utils.script import ScriptUtils
|
||||||
|
|
||||||
|
|
||||||
class Scriptable(ABC):
|
class Scriptable(ABC):
|
||||||
|
"""
|
||||||
|
Shared class between Entry and Overrides to manage their underlying Script.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.script = Script(
|
self.script = Script(
|
||||||
ScriptUtils.add_sanitized_variables(
|
ScriptUtils.add_sanitized_variables(
|
||||||
|
|
@ -21,13 +26,25 @@ class Scriptable(ABC):
|
||||||
self.unresolvable: Set[str] = copy.deepcopy(UNRESOLVED_VARIABLES)
|
self.unresolvable: Set[str] = copy.deepcopy(UNRESOLVED_VARIABLES)
|
||||||
|
|
||||||
def update_script(self) -> None:
|
def update_script(self) -> None:
|
||||||
|
"""
|
||||||
|
Updates any potential variables to a resolvable. This is done
|
||||||
|
to avoid re-resolving the same variables over-and-over.
|
||||||
|
"""
|
||||||
self.script.resolve(unresolvable=self.unresolvable, update=True)
|
self.script.resolve(unresolvable=self.unresolvable, update=True)
|
||||||
|
|
||||||
def add(self, values: Dict[str, Any]) -> None:
|
def add(self, values: Dict[str | Variable, Any]) -> None:
|
||||||
self.unresolvable -= set(list(values.keys()))
|
"""
|
||||||
|
Add new values to the script
|
||||||
|
"""
|
||||||
|
values_as_str: Dict[str, str] = {
|
||||||
|
(key.variable_name if isinstance(key, Variable) else key): val
|
||||||
|
for key, val in values.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.unresolvable -= set(list(values_as_str.keys()))
|
||||||
self.script.add(
|
self.script.add(
|
||||||
ScriptUtils.add_sanitized_variables(
|
ScriptUtils.add_sanitized_variables(
|
||||||
{name: ScriptUtils.to_script(value) for name, value in values.items()}
|
{name: ScriptUtils.to_script(value) for name, value in values_as_str.items()}
|
||||||
),
|
),
|
||||||
unresolvable=self.unresolvable,
|
unresolvable=self.unresolvable,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue