158 lines
4.8 KiB
Python
158 lines
4.8 KiB
Python
from typing import Dict
|
|
from typing import List
|
|
from typing import Optional
|
|
from typing import Type
|
|
from typing import TypeVar
|
|
|
|
from ytdl_sub.entries.base_entry import BaseEntry
|
|
from ytdl_sub.entries.entry import Entry
|
|
|
|
TChildEntry = TypeVar("TChildEntry", bound=BaseEntry)
|
|
|
|
|
|
class EntryParent(BaseEntry):
|
|
def __init__(
|
|
self, entry_dict: Dict, working_directory: str, entry_parent: Optional["EntryParent"] = None
|
|
):
|
|
super().__init__(entry_dict=entry_dict, working_directory=working_directory)
|
|
self._child_entries: List[TChildEntry] = []
|
|
self._entry_parent = entry_parent
|
|
|
|
# pylint: disable=no-self-use
|
|
def get_children_entry_variables_to_add(self) -> Dict[str, str | int]:
|
|
"""
|
|
Adds source variables to the child entry derived from the parent entry.
|
|
"""
|
|
if not self.child_entries:
|
|
return {}
|
|
|
|
return {
|
|
"playlist_max_upload_year": max(
|
|
entry.upload_year for entry in self.child_entries if isinstance(entry, Entry)
|
|
)
|
|
}
|
|
|
|
# pylint: enable=no-self-use
|
|
|
|
def read_nested_children_from_entry_dicts(self, entry_dicts: List[Dict]):
|
|
child_entries: List["EntryParent"] = []
|
|
|
|
for entry_dict in entry_dicts:
|
|
if entry_dict.get("playlist_id") == self.uid:
|
|
child_entries.append(
|
|
self.__class__(
|
|
entry_dict=entry_dict,
|
|
working_directory=self.working_directory(),
|
|
entry_parent=self,
|
|
)
|
|
)
|
|
|
|
self._child_entries = sorted(
|
|
child_entries, key=lambda entry: entry.kwargs("playlist_index")
|
|
)
|
|
return self._child_entries
|
|
|
|
def read_children_from_entry_dicts(
|
|
self, entry_dicts: List[Dict], child_class: Type[TChildEntry] = Entry
|
|
) -> "EntryParent":
|
|
"""
|
|
Parameters
|
|
----------
|
|
entry_dicts
|
|
Entry dicts to look for children from
|
|
child_class
|
|
The class to convert the entry dict to child_class. Defaults to Entry
|
|
|
|
Returns
|
|
-------
|
|
List of children
|
|
"""
|
|
child_entries: List[TChildEntry] = []
|
|
|
|
for entry_dict in entry_dicts:
|
|
if entry_dict.get("playlist_id") == self.uid:
|
|
child_entries.append(
|
|
child_class(entry_dict=entry_dict, working_directory=self.working_directory())
|
|
)
|
|
|
|
self._child_entries = sorted(
|
|
child_entries, key=lambda entry: entry.kwargs("playlist_index")
|
|
)
|
|
for child_entry in self._child_entries:
|
|
child_entry.add_variables(variables_to_add=self.get_children_entry_variables_to_add())
|
|
|
|
return self
|
|
|
|
@property
|
|
def child_entries(self) -> List[TChildEntry]:
|
|
"""
|
|
Returns
|
|
-------
|
|
List of child entities
|
|
"""
|
|
return self._child_entries
|
|
|
|
@property
|
|
def child_count(self) -> int:
|
|
"""
|
|
Returns
|
|
-------
|
|
Number of child entries
|
|
"""
|
|
return len(self.child_entries)
|
|
|
|
def get_thumbnail_url(self, thumbnail_id: str) -> Optional[str]:
|
|
"""
|
|
Downloads a specific thumbnail from a YTDL entry's thumbnail list
|
|
|
|
Parameters
|
|
----------
|
|
thumbnail_id:
|
|
Id of the thumbnail defined in the parent's thumbnail
|
|
|
|
Returns
|
|
-------
|
|
Desired thumbnail url if it exists. None if it does not.
|
|
"""
|
|
for thumbnail in self.kwargs_get("thumbnails", []):
|
|
if thumbnail["id"] == thumbnail_id:
|
|
return thumbnail["url"]
|
|
return None
|
|
|
|
def __contains__(self, item):
|
|
"""
|
|
Returns
|
|
-------
|
|
True if the the item (entry_dict) has the same id as one of the tracks. False otherwise.
|
|
"""
|
|
uid: Optional[str] = None
|
|
if isinstance(item, BaseEntry):
|
|
uid = item.uid
|
|
elif isinstance(item, dict):
|
|
uid = item.get("id")
|
|
|
|
if uid is not None:
|
|
return any(uid == child_entry.uid for child_entry in self._child_entries)
|
|
return False
|
|
|
|
@classmethod
|
|
def from_entry_dicts_with_children(
|
|
cls,
|
|
entry_dicts: List[Dict],
|
|
working_directory: str,
|
|
child_class: Type[TChildEntry],
|
|
extractor: Optional[str],
|
|
) -> "EntryParent":
|
|
"""
|
|
Load the parent entry and its children
|
|
"""
|
|
entry_parent: EntryParent = cls.from_entry_dicts(
|
|
entry_dicts=entry_dicts, working_directory=working_directory, extractor=extractor
|
|
)
|
|
entry_parent.read_children_from_entry_dicts(
|
|
entry_dicts=entry_dicts, child_class=child_class
|
|
)
|
|
return entry_parent
|
|
|
|
def to_entry(self) -> Entry:
|
|
return Entry(entry_dict=self._kwargs, working_directory=self.working_directory())
|