begin working on enhanced download archive, to manage videos that need to be deleted
This commit is contained in:
parent
55a462c71b
commit
713520cb38
4 changed files with 122 additions and 11 deletions
|
|
@ -80,6 +80,13 @@ class Entry:
|
||||||
"""Returns the entry's upload month as an int"""
|
"""Returns the entry's upload month as an int"""
|
||||||
return int(self.upload_day_padded.lstrip("0"))
|
return int(self.upload_day_padded.lstrip("0"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def standardized_upload_date(self) -> str:
|
||||||
|
"""
|
||||||
|
:return: upload date as YYYY-MM-DD
|
||||||
|
"""
|
||||||
|
return f"{self.upload_year}-{self.upload_month_padded}-{self.upload_day_padded}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def description(self) -> str:
|
def description(self) -> str:
|
||||||
return self.kwargs("description")
|
return self.kwargs("description")
|
||||||
|
|
@ -126,6 +133,7 @@ class Entry:
|
||||||
"upload_month_padded": self.upload_month_padded,
|
"upload_month_padded": self.upload_month_padded,
|
||||||
"upload_day": self.upload_day,
|
"upload_day": self.upload_day,
|
||||||
"upload_day_padded": self.upload_day_padded,
|
"upload_day_padded": self.upload_day_padded,
|
||||||
|
"standardized_upload_date": self.standardized_upload_date,
|
||||||
"thumbnail": self.thumbnail,
|
"thumbnail": self.thumbnail,
|
||||||
"thumbnail_ext": self.thumbnail_ext,
|
"thumbnail_ext": self.thumbnail_ext,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import contextlib
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
|
|
@ -126,6 +127,10 @@ class Subscription(Generic[S], ABC):
|
||||||
def _post_process_nfo(self, nfo_options: NFOValidator, entry: Optional[Entry] = None):
|
def _post_process_nfo(self, nfo_options: NFOValidator, entry: Optional[Entry] = None):
|
||||||
"""
|
"""
|
||||||
Creates an entry's NFO file using values defined in the metadata options
|
Creates an entry's NFO file using values defined in the metadata options
|
||||||
|
|
||||||
|
:param nfo_options: Options for the NFO
|
||||||
|
:param entry: Optional. Will pass entry values to nfo string formatters. If None, will only
|
||||||
|
use override variables that must resolve.
|
||||||
"""
|
"""
|
||||||
nfo = {}
|
nfo = {}
|
||||||
|
|
||||||
|
|
@ -151,21 +156,27 @@ class Subscription(Generic[S], ABC):
|
||||||
with open(nfo_file_path, "wb") as nfo_file:
|
with open(nfo_file_path, "wb") as nfo_file:
|
||||||
nfo_file.write(xml)
|
nfo_file.write(xml)
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _maintain_archive_file(self):
|
||||||
|
if not self.output_options.maintain_download_archive:
|
||||||
|
return
|
||||||
|
|
||||||
|
existing_download_archive = Path(self.output_directory) / self.download_archive_file_name
|
||||||
|
working_directory_archive = Path(self.working_directory) / self.download_archive_file_name
|
||||||
|
|
||||||
|
if os.path.exists(existing_download_archive):
|
||||||
|
shutil.copy(existing_download_archive, working_directory_archive)
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
shutil.copy(working_directory_archive, existing_download_archive)
|
||||||
|
|
||||||
def download(self):
|
def download(self):
|
||||||
"""
|
"""
|
||||||
Performs the subscription download.
|
Performs the subscription download.
|
||||||
"""
|
"""
|
||||||
existing_download_archive = Path(self.output_directory) / self.download_archive_file_name
|
with self._maintain_archive_file():
|
||||||
working_directory_archive = Path(self.working_directory) / self.download_archive_file_name
|
self._extract_info()
|
||||||
|
|
||||||
if self.output_options.maintain_download_archive:
|
|
||||||
if os.path.exists(existing_download_archive):
|
|
||||||
shutil.copy(existing_download_archive, working_directory_archive)
|
|
||||||
|
|
||||||
self._extract_info()
|
|
||||||
|
|
||||||
if self.output_options.maintain_download_archive:
|
|
||||||
shutil.copy(working_directory_archive, existing_download_archive)
|
|
||||||
|
|
||||||
def _extract_info(self):
|
def _extract_info(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
0
ytdl_subscribe/ytdl_additions/__init__.py
Normal file
0
ytdl_subscribe/ytdl_additions/__init__.py
Normal file
92
ytdl_subscribe/ytdl_additions/enhanced_download_archive.py
Normal file
92
ytdl_subscribe/ytdl_additions/enhanced_download_archive.py
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
import json
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from ytdl_subscribe.entries.entry import Entry
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DownloadMapping:
|
||||||
|
upload_date: str
|
||||||
|
file_paths: List[str]
|
||||||
|
|
||||||
|
|
||||||
|
class DownloadMappings:
|
||||||
|
def __init__(self):
|
||||||
|
self._entry_mappings: Dict[str, DownloadMapping] = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, file_path: str) -> "DownloadMappings":
|
||||||
|
entry_mappings = DownloadMappings()
|
||||||
|
entry_mappings._entry_mappings = json.load(open(file_path, "r", encoding="utf8"))
|
||||||
|
return entry_mappings
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
return json.dumps(
|
||||||
|
{
|
||||||
|
uid: mapping
|
||||||
|
for uid, mapping in sorted(
|
||||||
|
self._entry_mappings.items(),
|
||||||
|
key=lambda item: item[1]["upload_date"],
|
||||||
|
reverse=True,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DownloadArchive:
|
||||||
|
"""
|
||||||
|
Class to handle any operations to the ytdl download archive. Try to keep it as barebones as
|
||||||
|
possible in case of future changes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
):
|
||||||
|
self._download_archive_lines: List[str] = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_file(cls, file_path: str) -> "DownloadArchive":
|
||||||
|
lines = open(file_path, "r", encoding="utf8").readlines()
|
||||||
|
download_archive = DownloadArchive()
|
||||||
|
download_archive._download_archive_lines = lines
|
||||||
|
return download_archive
|
||||||
|
|
||||||
|
|
||||||
|
class EnhancedDownloadArchive:
|
||||||
|
"""
|
||||||
|
Maintains ytdl's download archive file as well as create an additional mapping file to map
|
||||||
|
ytdl ids to multiple files
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name: str):
|
||||||
|
self.name = name
|
||||||
|
self._download_archive = None
|
||||||
|
self._download_mapping = None
|
||||||
|
self._appended_entries: List[Entry] = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def download_archive_file_name(self):
|
||||||
|
return f".ytdl-subscribe-{self.name}-download-archive.txt"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def download_mapping_file_name(self):
|
||||||
|
return f".ytdl-subscribe-{self.name}-download-mapping.json"
|
||||||
|
|
||||||
|
def load(self, directory: str) -> "EnhancedDownloadArchive":
|
||||||
|
self._download_archive = DownloadArchive.from_file(
|
||||||
|
file_path=str(Path(directory) / self.download_archive_file_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._download_mapping = DownloadMappings.from_json(
|
||||||
|
file_path=str(Path(directory) / self.download_mapping_file_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
# def append(self, entry: Entry, relative_file_path: str):
|
||||||
|
# self._appended_entries.append(
|
||||||
|
# EntryMapping(entry=entry, relative_file_path=relative_file_path))
|
||||||
|
#
|
||||||
Loading…
Reference in a new issue