lint 10, channel tests passing. Need dry-run for split and merge video

This commit is contained in:
jbannon 2022-07-02 17:09:04 +00:00
parent 0f38f3ee77
commit 179540093c
3 changed files with 171 additions and 78 deletions

View file

@ -1,6 +1,7 @@
import os import os
from pathlib import Path from pathlib import Path
from shutil import copyfile from shutil import copyfile
from typing import Any
from typing import Dict from typing import Dict
from typing import List from typing import List
from typing import Optional from typing import Optional
@ -9,19 +10,43 @@ from typing import Union
class FileMetadata: class FileMetadata:
"""
Stores pretty-printed information about a file
"""
def __init__(self, metadata: Optional[List[str]] = None): def __init__(self, metadata: Optional[List[str]] = None):
self.metadata: List[str] = metadata if metadata else [] self.metadata: List[str] = metadata if metadata else []
def append(self, line: str) -> "FileMetadata": def append(self, line: str) -> "FileMetadata":
"""
Parameters
----------
line
Line of metadata to append
"""
self.metadata.append(line) self.metadata.append(line)
return self return self
def extend(self, other: "FileMetadata") -> "FileMetadata": def extend(self, other: "FileMetadata") -> "FileMetadata":
"""
Parameters
----------
other
Other metadata to extend to this one in its entirety
"""
self.metadata.extend(other.metadata) self.metadata.extend(other.metadata)
return self return self
@classmethod @classmethod
def from_dict(cls, value_dict: Dict[str, str], title: Optional[str] = None) -> "FileMetadata": def from_dict(cls, value_dict: Dict[str, Any], title: Optional[str] = None) -> "FileMetadata":
"""
Parameters
----------
value_dict
Dict of things to print indented
title
Optional. Title line to put above the dict
"""
lines: List[str] = [] lines: List[str] = []
if title is not None: if title is not None:
lines.append(title) lines.append(title)
@ -50,6 +75,16 @@ class FileHandlerTransactionLog:
def log_created_file( def log_created_file(
self, file_name: str, file_metadata: Optional[FileMetadata] = None self, file_name: str, file_metadata: Optional[FileMetadata] = None
) -> "FileHandlerTransactionLog": ) -> "FileHandlerTransactionLog":
"""
Adds a created file to the transaction log
Parameters
----------
file_name
Name of the file in the output directory
file_metadata
Optional. If the file has metadata, add it to the transaction log
"""
if not file_metadata: if not file_metadata:
file_metadata = FileMetadata() file_metadata = FileMetadata()
@ -57,6 +92,13 @@ class FileHandlerTransactionLog:
return self return self
def log_removed_file(self, file_name: str) -> "FileHandlerTransactionLog": def log_removed_file(self, file_name: str) -> "FileHandlerTransactionLog":
"""
Records a file removed from the output directory
Parameters
----------
file_name
Name of the file in the output directory getting removed
"""
self.files_removed.add(file_name) self.files_removed.add(file_name)
return self return self
@ -83,14 +125,40 @@ class FileHandler:
@classmethod @classmethod
def copy(cls, src_file_path: Union[str, Path], dst_file_path: Union[str, Path]): def copy(cls, src_file_path: Union[str, Path], dst_file_path: Union[str, Path]):
"""
Parameters
----------
src_file_path
Source file
dst_file_path
Destination file
"""
copyfile(src=src_file_path, dst=dst_file_path) copyfile(src=src_file_path, dst=dst_file_path)
@classmethod @classmethod
def delete(cls, file_path: Union[str, Path]): def delete(cls, file_path: Union[str, Path]):
"""
Parameters
----------
file_path
File to delete
"""
if os.path.isfile(file_path): if os.path.isfile(file_path):
os.remove(file_path) os.remove(file_path)
def copy_file_to_output_directory(self, file_name: str, output_file_name: str): def copy_file_to_output_directory(self, file_name: str, output_file_name: str):
"""
Copies a file from the working directory to the output directory.
All file copies from working to output directory should use this function for tracking and
handling dry-run logic.
Parameters
----------
file_name
File in the working directory
output_file_name
Desired output file name in the output_directory
"""
self._file_handler_transaction_log.log_created_file(output_file_name) self._file_handler_transaction_log.log_created_file(output_file_name)
if not self.dry_run: if not self.dry_run:
@ -102,6 +170,15 @@ class FileHandler:
) )
def delete_file_from_output_directory(self, file_name: str): def delete_file_from_output_directory(self, file_name: str):
"""
Deletes a file from the output directory. All file deletions should use this function
for tracking and handling dry-run logic.
Parameters
----------
file_name
File in the output directory to delete
"""
file_path = Path(self.output_directory) / file_name file_path = Path(self.output_directory) / file_name
exists = os.path.isfile(file_path) exists = os.path.isfile(file_path)

View file

@ -375,6 +375,11 @@ class EnhancedDownloadArchive:
@property @property
def is_dry_run(self) -> bool: def is_dry_run(self) -> bool:
"""
Returns
-------
True if this session is a dry-run. False otherwise.
"""
return self._file_handler.dry_run return self._file_handler.dry_run
@property @property
@ -388,10 +393,20 @@ class EnhancedDownloadArchive:
@property @property
def working_directory(self) -> str: def working_directory(self) -> str:
"""
Returns
-------
Path to the working directory
"""
return self._file_handler.working_directory return self._file_handler.working_directory
@property @property
def output_directory(self) -> str: def output_directory(self) -> str:
"""
Returns
-------
Path to the output directory
"""
return self._file_handler.output_directory return self._file_handler.output_directory
@property @property
@ -527,22 +542,8 @@ class EnhancedDownloadArchive:
------- -------
self self
""" """
# TODO: Make sure this logic is actually right...
# Load the download archive from the working directory, which should contain any past
# and new entries downloaded in this session
download_archive = DownloadArchive.from_file(self._archive_working_file_path)
# Keep the download archive in sync with the mapping
for entry_id in self.mapping.entry_ids:
if not download_archive.contains(entry_id):
download_archive.remove_entry(entry_id)
# Save the updated mapping file to the output directory
# TODO: Make this cleaner. It writes the file to the working dir, the copies it to the
# output dir. Should be just a single write
self._download_mapping.to_file(output_json_file=self._mapping_working_file_path) self._download_mapping.to_file(output_json_file=self._mapping_working_file_path)
self.save_file_to_output_directory(file_name=self._mapping_file_name) self.save_file_to_output_directory(file_name=self._mapping_file_name)
return self return self
def save_file_to_output_directory( def save_file_to_output_directory(
@ -572,6 +573,11 @@ class EnhancedDownloadArchive:
) )
def get_file_handler_transaction_log(self) -> FileHandlerTransactionLog: def get_file_handler_transaction_log(self) -> FileHandlerTransactionLog:
"""
Returns
-------
File handler transaction log for this session
"""
return self._file_handler.file_handler_transaction_log return self._file_handler.file_handler_transaction_log
@ -587,10 +593,20 @@ class DownloadArchiver:
@property @property
def working_directory(self) -> str: def working_directory(self) -> str:
"""
Returns
-------
Path to the working directory
"""
return self.__enhanced_download_archive.working_directory return self.__enhanced_download_archive.working_directory
@property @property
def is_dry_run(self) -> bool: def is_dry_run(self) -> bool:
"""
Returns
-------
True if this session is a dry-run. False otherwise.
"""
return self.__enhanced_download_archive.is_dry_run return self.__enhanced_download_archive.is_dry_run
def save_file(self, file_name: str, entry: Optional[Entry] = None) -> None: def save_file(self, file_name: str, entry: Optional[Entry] = None) -> None:

View file

@ -27,12 +27,12 @@ def config(config_path):
@pytest.fixture @pytest.fixture
def subscription_dict(output_directory, subscription_name): def subscription_dict(output_directory):
return { return {
"preset": "yt_channel_as_tv", "preset": "yt_channel_as_tv",
"youtube": {"channel_url": "https://youtube.com/channel/UCcRSMoQqXc_JrBZRHDFGbqA"}, "youtube": {"channel_url": "https://youtube.com/channel/UCcRSMoQqXc_JrBZRHDFGbqA"},
# override the output directory with our fixture-generated dir # override the output directory with our fixture-generated dir
"output_options": {"output_directory": str(Path(output_directory) / subscription_name)}, "output_options": {"output_directory": output_directory},
# download the worst format so it is fast # download the worst format so it is fast
"ytdl_options": { "ytdl_options": {
"format": "worst[ext=mp4]", "format": "worst[ext=mp4]",
@ -68,61 +68,61 @@ def expected_full_channel_download():
return ExpectedDownload( return ExpectedDownload(
expected_md5_file_hashes={ expected_md5_file_hashes={
# Download mapping # Download mapping
Path("pz/.ytdl-sub-pz-download-archive.json"): "b7e7c19d2cf0277e4e42453a64fbaa90", Path(".ytdl-sub-pz-download-archive.json"): "b7e7c19d2cf0277e4e42453a64fbaa90",
# Output directory files # Output directory files
Path("pz/fanart.jpg"): "e6e323373c8902568e96e374817179cf", Path("fanart.jpg"): "e6e323373c8902568e96e374817179cf",
Path("pz/poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01", Path("poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01",
Path("pz/tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157", Path("tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157",
# Entry files # Entry files
Path("pz/Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.jpg"): "b58377dfe7c39527e1990a24b36bbd77", Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.jpg"): "b58377dfe7c39527e1990a24b36bbd77",
Path("pz/Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.mp4"): "931a705864c57d21d6fedebed4af6bbc", Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.mp4"): "931a705864c57d21d6fedebed4af6bbc",
Path("pz/Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo"): "67d8d71d048039080acbba3bce4febaa", Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo"): "67d8d71d048039080acbba3bce4febaa",
Path("pz/Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.jpg"): "a5ee6247c8dce255aec79c9a51d49da4", Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.jpg"): "a5ee6247c8dce255aec79c9a51d49da4",
Path("pz/Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.mp4"): "d3469b4dca7139cb3dbc38712b6796bf", Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.mp4"): "d3469b4dca7139cb3dbc38712b6796bf",
Path("pz/Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.nfo"): "d81f49cedbd7edaee987521e89b37904", Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.nfo"): "d81f49cedbd7edaee987521e89b37904",
Path("pz/Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].jpg"): "048a19cf0f674437351872c3f312ebf1", Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].jpg"): "048a19cf0f674437351872c3f312ebf1",
Path("pz/Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].mp4"): "e66287b9832277b6a4d1554e29d9fdcc", Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].mp4"): "e66287b9832277b6a4d1554e29d9fdcc",
Path("pz/Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].nfo"): "f7c0de89038f8c491bded8a3968720a2", Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].nfo"): "f7c0de89038f8c491bded8a3968720a2",
Path("pz/Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].jpg"): None, Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].jpg"): None,
Path("pz/Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].mp4"): "04ab5cb3cc12325d0c96a7cd04a8b91d", Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].mp4"): "04ab5cb3cc12325d0c96a7cd04a8b91d",
Path("pz/Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].nfo"): "ee1eda78fa0980bc703e602b5012dd1f", Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].nfo"): "ee1eda78fa0980bc703e602b5012dd1f",
Path("pz/Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].jpg"): "9baaddc6b62f5b9ae3781eb4eef0e3b3", Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].jpg"): "9baaddc6b62f5b9ae3781eb4eef0e3b3",
Path("pz/Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].mp4"): "025de6099a5c98e6397153c7a62d517d", Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].mp4"): "025de6099a5c98e6397153c7a62d517d",
Path("pz/Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo"): "61eb6369430da0ab6134d78829a7621b", Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo"): "61eb6369430da0ab6134d78829a7621b",
Path("pz/Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).jpg"): "ce1df7f623fffaefe04606ecbafcfec6", Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).jpg"): "ce1df7f623fffaefe04606ecbafcfec6",
Path("pz/Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).mp4"): "3d9c19835b03355d6fd5d00cd59dbe5b", Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).mp4"): "3d9c19835b03355d6fd5d00cd59dbe5b",
Path("pz/Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).nfo"): "60f72b99f5c69f9e03a071a12160928f", Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).nfo"): "60f72b99f5c69f9e03a071a12160928f",
Path("pz/Season 2011/s2011.e0630 - Project Zombie _Fin.jpg"): "bc3f511915869720c37617a7de706b2b", Path("Season 2011/s2011.e0630 - Project Zombie _Fin.jpg"): "bc3f511915869720c37617a7de706b2b",
Path("pz/Season 2011/s2011.e0630 - Project Zombie _Fin.mp4"): "4971cb2d4fa29460361031f3fa8e1ea9", Path("Season 2011/s2011.e0630 - Project Zombie _Fin.mp4"): "4971cb2d4fa29460361031f3fa8e1ea9",
Path("pz/Season 2011/s2011.e0630 - Project Zombie _Fin.nfo"): "a7b5d9e57d20852f5daf360a1373bb7a", Path("Season 2011/s2011.e0630 - Project Zombie _Fin.nfo"): "a7b5d9e57d20852f5daf360a1373bb7a",
Path("pz/Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].jpg"): "12babdb3b86cd868b90b60d013295f66", Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].jpg"): "12babdb3b86cd868b90b60d013295f66",
Path("pz/Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].mp4"): "55e9b0add08c48c9c66105da0def2426", Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].mp4"): "55e9b0add08c48c9c66105da0def2426",
Path("pz/Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo"): "fe60e2b6b564f9316b6c7c183e1cf300", Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo"): "fe60e2b6b564f9316b6c7c183e1cf300",
Path("pz/Season 2012/s2012.e0123 - Project Zombie _Map Trailer.jpg"): "82d303e16aba75acdde30b15c4154231", Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer.jpg"): "82d303e16aba75acdde30b15c4154231",
Path("pz/Season 2012/s2012.e0123 - Project Zombie _Map Trailer.mp4"): "65e4ce53ed5ec4139995469f99477a50", Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer.mp4"): "65e4ce53ed5ec4139995469f99477a50",
Path("pz/Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo"): "c8900adcca83c473c79a4afbc7ad2de1", Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo"): "c8900adcca83c473c79a4afbc7ad2de1",
Path("pz/Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.jpg"): "83b1af4c3614d262b2ad419586fff730", Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.jpg"): "83b1af4c3614d262b2ad419586fff730",
Path("pz/Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.mp4"): "18620a8257a686beda65e54add4d4cd1", Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.mp4"): "18620a8257a686beda65e54add4d4cd1",
Path("pz/Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo"): "1c993c41d4308a6049333154d0adee16", Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo"): "1c993c41d4308a6049333154d0adee16",
Path("pz/Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.jpg"): "2a24de903059f48c7d0df0476046c975", Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.jpg"): "2a24de903059f48c7d0df0476046c975",
Path("pz/Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"): "82f6ee7253e1dbb83ae7215af08ffacc", Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"): "82f6ee7253e1dbb83ae7215af08ffacc",
Path("pz/Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"): "cc7886aae3af6b7b0facd82f95390242", Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"): "cc7886aae3af6b7b0facd82f95390242",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.jpg"): "c8baea83b9edeb081657f1130a1031f7", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.jpg"): "c8baea83b9edeb081657f1130a1031f7",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"): "e733b4cc385b953b08c8eb0f47e03c1e", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"): "e733b4cc385b953b08c8eb0f47e03c1e",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"): "2b3ccb3f1ef81ee49fe1afb88f275a09", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"): "2b3ccb3f1ef81ee49fe1afb88f275a09",
} }
) )
# fmt: on # fmt: on
@ -164,21 +164,21 @@ def expected_recent_channel_download():
return ExpectedDownload( return ExpectedDownload(
expected_md5_file_hashes={ expected_md5_file_hashes={
# Download mapping # Download mapping
Path("pz/.ytdl-sub-pz-download-archive.json"): "b1675ca4d9f0d4b9c2102b6749e4cdfd", Path(".ytdl-sub-pz-download-archive.json"): "b1675ca4d9f0d4b9c2102b6749e4cdfd",
# Output directory files # Output directory files
Path("pz/fanart.jpg"): "e6e323373c8902568e96e374817179cf", Path("fanart.jpg"): "e6e323373c8902568e96e374817179cf",
Path("pz/poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01", Path("poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01",
Path("pz/tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157", Path("tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157",
# Recent Entry files # Recent Entry files
Path("pz/Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.jpg"): "2a24de903059f48c7d0df0476046c975", Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.jpg"): "2a24de903059f48c7d0df0476046c975",
Path("pz/Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"): "82f6ee7253e1dbb83ae7215af08ffacc", Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"): "82f6ee7253e1dbb83ae7215af08ffacc",
Path("pz/Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"): "cc7886aae3af6b7b0facd82f95390242", Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"): "cc7886aae3af6b7b0facd82f95390242",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.jpg"): "c8baea83b9edeb081657f1130a1031f7", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.jpg"): "c8baea83b9edeb081657f1130a1031f7",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"): "e733b4cc385b953b08c8eb0f47e03c1e", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"): "e733b4cc385b953b08c8eb0f47e03c1e",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"): "2b3ccb3f1ef81ee49fe1afb88f275a09", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"): "2b3ccb3f1ef81ee49fe1afb88f275a09",
} }
) )
# fmt: on # fmt: on
@ -222,12 +222,12 @@ def expected_recent_channel_no_vids_in_range_download():
return ExpectedDownload( return ExpectedDownload(
expected_md5_file_hashes={ expected_md5_file_hashes={
# Download mapping # Download mapping
Path("pz/.ytdl-sub-pz-download-archive.json"): "99914b932bd37a50b983c5e7c90ae93b", Path(".ytdl-sub-pz-download-archive.json"): "99914b932bd37a50b983c5e7c90ae93b",
# Output directory files # Output directory files
Path("pz/fanart.jpg"): "e6e323373c8902568e96e374817179cf", Path("fanart.jpg"): "e6e323373c8902568e96e374817179cf",
Path("pz/poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01", Path("poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01",
Path("pz/tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157", Path("tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157",
} }
) )
# fmt: on # fmt: on
@ -269,17 +269,17 @@ def expected_rolling_recent_channel_download():
return ExpectedDownload( return ExpectedDownload(
expected_md5_file_hashes={ expected_md5_file_hashes={
# Download mapping # Download mapping
Path("pz/.ytdl-sub-pz-download-archive.json"): "9ae3463bd2dc39830003aba68a276df4", Path(".ytdl-sub-pz-download-archive.json"): "9ae3463bd2dc39830003aba68a276df4",
# Output directory files # Output directory files
Path("pz/fanart.jpg"): "e6e323373c8902568e96e374817179cf", Path("fanart.jpg"): "e6e323373c8902568e96e374817179cf",
Path("pz/poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01", Path("poster.jpg"): "a14c593bcc75bb8d2c7145de4767ad01",
Path("pz/tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157", Path("tvshow.nfo"): "83c7db96081ac5bdf289fcf396bec157",
# Rolling Recent Entry files # Rolling Recent Entry files
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.jpg"): "c8baea83b9edeb081657f1130a1031f7", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.jpg"): "c8baea83b9edeb081657f1130a1031f7",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"): "e733b4cc385b953b08c8eb0f47e03c1e", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"): "e733b4cc385b953b08c8eb0f47e03c1e",
Path("pz/Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"): "2b3ccb3f1ef81ee49fe1afb88f275a09", Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"): "2b3ccb3f1ef81ee49fe1afb88f275a09",
} }
) )
# fmt: on # fmt: on