getting there

This commit is contained in:
Jesse Bannon 2023-12-07 16:39:46 -08:00
parent 1ebf91888e
commit 4a7685f284
8 changed files with 45 additions and 43 deletions

View file

@ -22,6 +22,7 @@ from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
from ytdl_sub.downloaders.ytdlp import YTDLP from ytdl_sub.downloaders.ytdlp import YTDLP
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.entry_parent import EntryParent from ytdl_sub.entries.entry_parent import EntryParent
from ytdl_sub.entries.script.variable_definitions import VARIABLES as v
from ytdl_sub.entries.variables.kwargs import COLLECTION_URL from ytdl_sub.entries.variables.kwargs import COLLECTION_URL
from ytdl_sub.entries.variables.kwargs import COMMENTS from ytdl_sub.entries.variables.kwargs import COMMENTS
from ytdl_sub.entries.variables.kwargs import DOWNLOAD_INDEX from ytdl_sub.entries.variables.kwargs import DOWNLOAD_INDEX
@ -181,7 +182,7 @@ class UrlDownloaderCollectionVariablePlugin(SourcePluginExtension):
""" """
# COLLECTION_URL is a recent variable that may not exist for old entries when updating. # COLLECTION_URL is a recent variable that may not exist for old entries when updating.
# Try to use source_webpage_url if it does not exist # Try to use source_webpage_url if it does not exist
entry_collection_url = entry.kwargs_get(COLLECTION_URL, entry.source_webpage_url) entry_collection_url = entry.kwargs_get(COLLECTION_URL, entry.get(v.source_webpage_url))
# If the collection URL cannot find its mapping, use the last URL # If the collection URL cannot find its mapping, use the last URL
collection_url = ( collection_url = (
@ -189,7 +190,7 @@ class UrlDownloaderCollectionVariablePlugin(SourcePluginExtension):
or list(self._collection_url_mapping.values())[-1] or list(self._collection_url_mapping.values())[-1]
) )
entry.add_variables(variables_to_add=collection_url.variables.dict_with_format_strings) entry.add(collection_url.variables.dict_with_format_strings)
return entry return entry
@ -504,7 +505,7 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
return None return None
upload_date_idx = self._enhanced_download_archive.mapping.get_num_entries_with_upload_date( upload_date_idx = self._enhanced_download_archive.mapping.get_num_entries_with_upload_date(
upload_date_standardized=entry.upload_date_standardized upload_date_standardized=entry.get(v.upload_date_standardized)
) )
download_idx = self._enhanced_download_archive.num_entries download_idx = self._enhanced_download_archive.num_entries

View file

@ -304,31 +304,6 @@ class BaseEntry(BaseEntryVariables, ABC):
self._kwargs = dict(self._kwargs, **variables_to_add) self._kwargs = dict(self._kwargs, **variables_to_add)
return self return self
def add_variables(self, variables_to_add: Dict[str, str]) -> "BaseEntry":
"""
Parameters
----------
variables_to_add
Variables to add to this entry
Returns
-------
self
Raises
------
ValueError
If a variable trying to be added already exists as a source variable
"""
for variable_name in variables_to_add.keys():
if self.kwargs_contains(variable_name):
raise ValueError(
f"Cannot add variable '{variable_name}': already exists in the kwargs"
)
self._additional_variables = dict(self._additional_variables, **variables_to_add)
return self
def get_download_info_json_name(self) -> str: def get_download_info_json_name(self) -> str:
""" """
Returns Returns

View file

@ -8,6 +8,7 @@ from typing import final
from ytdl_sub.entries.base_entry import BaseEntry from ytdl_sub.entries.base_entry import BaseEntry
from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.entries.script.variable_definitions import VARIABLES
from ytdl_sub.entries.script.variable_definitions import Variable
from ytdl_sub.utils.scriptable import Scriptable from ytdl_sub.utils.scriptable import Scriptable
from ytdl_sub.validators.audo_codec_validator import AUDIO_CODEC_EXTS from ytdl_sub.validators.audo_codec_validator import AUDIO_CODEC_EXTS
from ytdl_sub.validators.audo_codec_validator import VIDEO_CODEC_EXTS from ytdl_sub.validators.audo_codec_validator import VIDEO_CODEC_EXTS
@ -24,10 +25,13 @@ class Entry(BaseEntry, Scriptable):
BaseEntry.__init__(self, entry_dict=entry_dict, working_directory=working_directory) BaseEntry.__init__(self, entry_dict=entry_dict, working_directory=working_directory)
Scriptable.__init__(self) Scriptable.__init__(self)
self.script.add({VARIABLES.entry_metadata.variable_name: json.dumps(self._kwargs)}) self.script.add({VARIABLES.entry_metadata.variable_name: f"{{{json.dumps(self._kwargs)}}}"})
self.script.add(override_variables) self.script.add(override_variables)
self.script.resolve(update=True) self.script.resolve(update=True)
def get(self, variable: Variable) -> str:
return self.script.resolve(unresolvable=self.unresolvable).get_str(variable.variable_name)
@property @property
def ext(self) -> str: def ext(self) -> str:
""" """
@ -35,12 +39,13 @@ class Entry(BaseEntry, Scriptable):
This is not reflected in the entry. See if the mkv file exists and return "mkv" if so, This is not reflected in the entry. See if the mkv file exists and return "mkv" if so,
otherwise, return the original extension. otherwise, return the original extension.
""" """
for possible_ext in [super().ext, "mkv"]: ext = self.get(VARIABLES.ext)
for possible_ext in [ext, "mkv"]:
file_path = str(Path(self.working_directory()) / f"{self.uid}.{possible_ext}") file_path = str(Path(self.working_directory()) / f"{self.uid}.{possible_ext}")
if os.path.isfile(file_path): if os.path.isfile(file_path):
return possible_ext return possible_ext
return super().ext return ext
def get_download_file_name(self) -> str: def get_download_file_name(self) -> str:
""" """
@ -60,7 +65,7 @@ class Entry(BaseEntry, Scriptable):
------- -------
The download thumbnail's file name The download thumbnail's file name
""" """
return f"{self.uid}.{self.thumbnail_ext}" return f"{self.get(VARIABLES.uid)}.{self.get(VARIABLES.thumbnail_ext)}"
def get_download_thumbnail_path(self) -> str: def get_download_thumbnail_path(self) -> str:
"""Returns the entry's thumbnail's file path to where it was downloaded""" """Returns the entry's thumbnail's file path to where it was downloaded"""

View file

@ -11,6 +11,11 @@ class Variable:
variable_name: str variable_name: str
@dataclass(frozen=True)
class InternalVariable(Variable):
pass
@dataclass(frozen=True) @dataclass(frozen=True)
class Metadata(Variable): class Metadata(Variable):
pass pass

View file

@ -1,4 +1,6 @@
import json
from abc import ABC from abc import ABC
from typing import Any
from typing import Dict from typing import Dict
from typing import Set from typing import Set
@ -14,9 +16,29 @@ class Scriptable(ABC):
} }
return dict(variables, **sanitized_variables) return dict(variables, **sanitized_variables)
@classmethod
def to_script(cls, value: Any) -> str:
if isinstance(value, str):
return value
if isinstance(value, int):
return f"{{%int({value})}}"
if isinstance(value, float):
return f"{{%float({value})}}"
if isinstance(value, bool):
return f"{{%bool({value})}}"
return f"{{{json.dumps(value)}}}"
def __init__(self): def __init__(self):
self.script = Script(VARIABLE_SCRIPTS) self.script = Script(VARIABLE_SCRIPTS)
self.unresolvable: Set[str] = set() self.unresolvable: Set[str] = set()
def update_script(self) -> None: def update_script(self) -> None:
self.script.resolve(unresolvable=self.unresolvable, update=True) self.script.resolve(unresolvable=self.unresolvable, update=True)
def add(self, values: Dict[str, Any]) -> None:
self.script.add(
self.add_sanitized_variables(
{name: self.to_script(value) for name, value in values.items()}
)
)
self.script.resolve(unresolvable=self.unresolvable, update=True)

View file

@ -14,6 +14,7 @@ from yt_dlp import DateRange
from yt_dlp.utils import make_archive_id from yt_dlp.utils import make_archive_id
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.script.variable_definitions import VARIABLES as v
from ytdl_sub.entries.variables.kwargs import SPLIT_BY_CHAPTERS_PARENT_ENTRY from ytdl_sub.entries.variables.kwargs import SPLIT_BY_CHAPTERS_PARENT_ENTRY
from ytdl_sub.utils.file_handler import FileHandler from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
@ -71,7 +72,7 @@ class DownloadMapping:
DownloadMapping for the entry DownloadMapping for the entry
""" """
return DownloadMapping( return DownloadMapping(
upload_date=entry.upload_date_standardized, upload_date=entry.get(v.upload_date_standardized),
extractor=entry.extractor, extractor=entry.extractor,
file_names=set(), file_names=set(),
) )

View file

@ -16,6 +16,7 @@ from ytdl_sub.entries.variables.kwargs import DESCRIPTION
from ytdl_sub.entries.variables.kwargs import EPOCH from ytdl_sub.entries.variables.kwargs import EPOCH
from ytdl_sub.entries.variables.kwargs import EXT from ytdl_sub.entries.variables.kwargs import EXT
from ytdl_sub.entries.variables.kwargs import EXTRACTOR from ytdl_sub.entries.variables.kwargs import EXTRACTOR
from ytdl_sub.entries.variables.kwargs import IE_KEY
from ytdl_sub.entries.variables.kwargs import PLAYLIST_COUNT from ytdl_sub.entries.variables.kwargs import PLAYLIST_COUNT
from ytdl_sub.entries.variables.kwargs import PLAYLIST_ENTRY from ytdl_sub.entries.variables.kwargs import PLAYLIST_ENTRY
from ytdl_sub.entries.variables.kwargs import PLAYLIST_INDEX from ytdl_sub.entries.variables.kwargs import PLAYLIST_INDEX
@ -68,6 +69,7 @@ def mock_entry_dict_factory(mock_downloaded_file_path) -> Callable:
PLAYLIST_INDEX: playlist_index, PLAYLIST_INDEX: playlist_index,
PLAYLIST_COUNT: playlist_count, PLAYLIST_COUNT: playlist_count,
EXTRACTOR: "mock-entry-dict", EXTRACTOR: "mock-entry-dict",
IE_KEY: "mock-ie-key",
TITLE: f"Mock Entry {uid}", TITLE: f"Mock Entry {uid}",
EXT: "mp4", EXT: "mp4",
UPLOAD_DATE: upload_date, UPLOAD_DATE: upload_date,

View file

@ -1,18 +1,9 @@
import json
from typing import Dict
from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.entries.script.variable_definitions import VARIABLES
from ytdl_sub.entries.script.variable_scripts import VARIABLE_SCRIPTS
from ytdl_sub.script.script import Script
class TestEntry(object): class TestEntry(object):
def test_entry_to_dict(self, mock_entry, mock_entry_to_dict): def test_entry_to_dict(self, mock_entry, mock_entry_to_dict):
entry_metadata: Dict[str, str] = { output = mock_entry.script.resolve().as_native()
VARIABLES.entry_metadata.variable_name: f"{{{json.dumps(mock_entry._kwargs)}}}"
}
script = Script(dict(entry_metadata, **VARIABLE_SCRIPTS))
output = {var_name: var_output.native for var_name, var_output in script.resolve().items()}
del output[VARIABLES.entry_metadata.variable_name] del output[VARIABLES.entry_metadata.variable_name]
del output[VARIABLES.ie_key.variable_name] del output[VARIABLES.ie_key.variable_name]
assert output == mock_entry_to_dict assert output == mock_entry_to_dict