[REFACTOR] Use JSON files instead of hard-coded classes for expected downloads (#165)
* Expected download summaries WIP * jesse/fix-tests * working * tests passing * remove fixture usage * fix ignore md5 logic
This commit is contained in:
parent
3e60f7d1da
commit
bcf45f7f7e
25 changed files with 397 additions and 441 deletions
|
|
@ -161,7 +161,8 @@ class YoutubeSplitVideoDownloader(
|
|||
entry = YoutubeVideo(entry_dict=entry_dict, working_directory=self.working_directory)
|
||||
# convert the entry thumbnail early so we do not have to guess the thumbnail extension
|
||||
# when copying it
|
||||
convert_download_thumbnail(entry=entry)
|
||||
if not self.is_dry_run:
|
||||
convert_download_thumbnail(entry=entry)
|
||||
|
||||
for idx, title in enumerate(chapters.titles):
|
||||
new_uid = _split_video_uid(source_uid=entry.uid, idx=idx)
|
||||
|
|
@ -181,12 +182,12 @@ class YoutubeSplitVideoDownloader(
|
|||
)
|
||||
)
|
||||
|
||||
# Copy the original vid thumbnail to the working directory with the new uid. This so
|
||||
# downstream logic thinks this split video has its own thumbnail
|
||||
FileHandler.copy(
|
||||
src_file_path=entry.get_download_thumbnail_path(),
|
||||
dst_file_path=Path(self.working_directory) / f"{new_uid}.{entry.thumbnail_ext}",
|
||||
)
|
||||
# Copy the original vid thumbnail to the working directory with the new uid. This so
|
||||
# downstream logic thinks this split video has its own thumbnail
|
||||
FileHandler.copy(
|
||||
src_file_path=entry.get_download_thumbnail_path(),
|
||||
dst_file_path=Path(self.working_directory) / f"{new_uid}.{entry.thumbnail_ext}",
|
||||
)
|
||||
|
||||
# Format the split video as a YoutubePlaylistVideo
|
||||
split_videos_and_metadata.append(
|
||||
|
|
|
|||
|
|
@ -1,19 +1,33 @@
|
|||
import hashlib
|
||||
import json
|
||||
import os.path
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from ytdl_sub.utils.file_handler import FileMetadata
|
||||
_EXPECTED_DOWNLOADS_SUMMARY_PATH = Path("tests/e2e/resources/expected_downloads_summaries")
|
||||
|
||||
|
||||
def _get_files_in_directory(relative_directory: Path | str) -> List[Path]:
|
||||
relative_file_paths: List[Path] = []
|
||||
for path in Path(relative_directory).rglob("*"):
|
||||
if path.is_file():
|
||||
relative_path = Path(*path.parts[3:])
|
||||
relative_file_paths.append(relative_path)
|
||||
|
||||
return relative_file_paths
|
||||
|
||||
|
||||
def _get_file_md5_hash(full_file_path: Path | str) -> str:
|
||||
with open(full_file_path, "rb") as file:
|
||||
return hashlib.md5(file.read()).hexdigest()
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExpectedDownloadFile:
|
||||
path: Path
|
||||
md5: Optional[Union[str, List[str]]] = None
|
||||
metadata: Optional[FileMetadata] = None
|
||||
md5: str
|
||||
|
||||
|
||||
class ExpectedDownloads:
|
||||
|
|
@ -35,21 +49,21 @@ class ExpectedDownloads:
|
|||
def contains(self, relative_path: Path) -> bool:
|
||||
return sum(relative_path == download.path for download in self.expected_downloads) == 1
|
||||
|
||||
def assert_files_exist(self, relative_directory: Path):
|
||||
def assert_files_exist(
|
||||
self, relative_directory: str | Path, ignore_md5_hashes_for: Optional[List[str]] = None
|
||||
):
|
||||
"""
|
||||
Assert each expected file exists and that its respective md5 hash matches.
|
||||
"""
|
||||
num_files = 0
|
||||
for path in Path(relative_directory).rglob("*"):
|
||||
if path.is_file():
|
||||
num_files += 1
|
||||
if ignore_md5_hashes_for is None:
|
||||
ignore_md5_hashes_for = []
|
||||
|
||||
relative_path = Path(*path.parts[3:])
|
||||
assert self.contains(
|
||||
relative_path
|
||||
), f"File {relative_path} was created but not expected"
|
||||
relative_file_paths = _get_files_in_directory(relative_directory=relative_directory)
|
||||
|
||||
assert num_files == self.file_count, "Mismatch in number of created files"
|
||||
for file_path in relative_file_paths:
|
||||
assert self.contains(file_path), f"File {file_path} was created but not expected"
|
||||
|
||||
assert len(relative_file_paths) == self.file_count, "Mismatch in number of created files"
|
||||
|
||||
for expected_download in self.expected_downloads:
|
||||
full_path = Path(relative_directory) / expected_download.path
|
||||
|
|
@ -57,17 +71,69 @@ class ExpectedDownloads:
|
|||
full_path
|
||||
), f"Expected {str(expected_download.path)} to be a file but it is not"
|
||||
|
||||
if expected_download.md5 is None:
|
||||
if str(expected_download.path) in ignore_md5_hashes_for:
|
||||
continue
|
||||
|
||||
with open(full_path, "rb") as file:
|
||||
md5_hash = hashlib.md5(file.read()).hexdigest()
|
||||
|
||||
expected_md5_hash = expected_download.md5
|
||||
if isinstance(expected_download.md5, str):
|
||||
expected_md5_hash = [expected_download.md5]
|
||||
|
||||
assert md5_hash in expected_md5_hash, (
|
||||
md5_hash = _get_file_md5_hash(full_file_path=full_path)
|
||||
assert md5_hash in expected_download.md5, (
|
||||
f"MD5 hash for {str(expected_download.path)} does not match: "
|
||||
f"{md5_hash} != {expected_md5_hash}"
|
||||
f"{md5_hash} != {expected_download.md5}"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, expected_downloads_dict) -> "ExpectedDownloads":
|
||||
expected_downloads: List[ExpectedDownloadFile] = []
|
||||
for file_path, md5_hash in expected_downloads_dict.items():
|
||||
expected_downloads.append(ExpectedDownloadFile(path=Path(file_path), md5=md5_hash))
|
||||
|
||||
return cls(expected_downloads=expected_downloads)
|
||||
|
||||
@classmethod
|
||||
def from_file(cls, file_path: str | Path) -> "ExpectedDownloads":
|
||||
with open(file_path, mode="r", encoding="utf-8") as file:
|
||||
expected_downloads_dict = json.load(file)
|
||||
return cls.from_dict(expected_downloads_dict)
|
||||
|
||||
@classmethod
|
||||
def from_directory(cls, directory_path: str | Path) -> "ExpectedDownloads":
|
||||
relative_file_paths = _get_files_in_directory(relative_directory=directory_path)
|
||||
expected_downloads_dict = {
|
||||
str(file_path): _get_file_md5_hash(full_file_path=Path(directory_path) / file_path)
|
||||
for file_path in relative_file_paths
|
||||
}
|
||||
return cls.from_dict(expected_downloads_dict)
|
||||
|
||||
def to_summary_file(self, summary_file_path: Path | str) -> None:
|
||||
expected_downloads_dict = {
|
||||
str(exp_dl.path): exp_dl.md5 for exp_dl in self.expected_downloads
|
||||
}
|
||||
|
||||
with open(summary_file_path, mode="w", encoding="utf-8") as file:
|
||||
json.dump(
|
||||
obj=expected_downloads_dict, fp=file, sort_keys=True, ensure_ascii=False, indent=2
|
||||
)
|
||||
|
||||
|
||||
def assert_expected_downloads(
|
||||
output_directory: str | Path,
|
||||
dry_run: bool,
|
||||
expected_download_summary_file_name: str,
|
||||
ignore_md5_hashes_for: Optional[List[str]] = None,
|
||||
regenerate_expected_download_summary: bool = False,
|
||||
):
|
||||
if dry_run:
|
||||
output_directory_contents = list(Path(output_directory).rglob("*"))
|
||||
assert (
|
||||
len(output_directory_contents) == 0
|
||||
), f"Expected output directory to be empty after a dry-run, but found {output_directory_contents}"
|
||||
return
|
||||
|
||||
summary_full_path = _EXPECTED_DOWNLOADS_SUMMARY_PATH / expected_download_summary_file_name
|
||||
if regenerate_expected_download_summary:
|
||||
ExpectedDownloads.from_directory(directory_path=output_directory).to_summary_file(
|
||||
summary_file_path=summary_full_path
|
||||
)
|
||||
|
||||
ExpectedDownloads.from_file(summary_full_path).assert_files_exist(
|
||||
relative_directory=output_directory, ignore_md5_hashes_for=ignore_md5_hashes_for
|
||||
)
|
||||
|
|
|
|||
|
|
@ -44,5 +44,4 @@ class TestNfoTagsPlugins:
|
|||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="plugins/test_kodi_safe_xml.txt",
|
||||
regenerate_transaction_log=True,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
".ytdl-sub-jb-download-archive.json": "1a99156e9ece62539fb2608416a07200",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3": "bffbd558e12c6a9e029dc136a88342c4",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/folder.jpg": "967892be44b8c47e1be73f055a7c6f08",
|
||||
"j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3": "038db58aebe2ba875b733932b42a94d6",
|
||||
"j_b/[2021] Purple Clouds/folder.jpg": "967892be44b8c47e1be73f055a7c6f08",
|
||||
"j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3": "e145f0a2f6012768280c38655ca58065",
|
||||
"j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3": "60c8b8817a197a13e4bb90903af612c5",
|
||||
"j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3": "8265b7e4f79878af877bc6ecd9757efe",
|
||||
"j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3": "accf46b76891d2954b893d0f91d82816",
|
||||
"j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3": "e1f584f523336160d5c1104a61de77f3",
|
||||
"j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3": "f6885b25901177f0357649afe97328cc",
|
||||
"j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3": "fa057f221cbe4cf2442cd2fdb960743e",
|
||||
"j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3": "7794ae812c64580e2ac8fc457d5cc85f",
|
||||
"j_b/[2022] Acoustic Treats/09 - Finding Home.mp3": "adbf02eddb2090c008eb497d13ff84b9",
|
||||
"j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3": "65bb10c84366c71498161734f953e93d",
|
||||
"j_b/[2022] Acoustic Treats/11 - Untold History.mp3": "6904b2918e5dc38d9a9f72d967eb74bf",
|
||||
"j_b/[2022] Acoustic Treats/folder.jpg": "967892be44b8c47e1be73f055a7c6f08"
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
".ytdl-sub-pz-download-archive.json": "ce0ef71efbe27d9f67d80b5fbc57fc84",
|
||||
"Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.mp4": "931a705864c57d21d6fedebed4af6bbc",
|
||||
"Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.nfo": "67d8d71d048039080acbba3bce4febaa",
|
||||
"Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2-thumb.jpg": "8b32ee9c037fa669e444a0ac181525a1",
|
||||
"Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.mp4": "d3469b4dca7139cb3dbc38712b6796bf",
|
||||
"Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.nfo": "d81f49cedbd7edaee987521e89b37904",
|
||||
"Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg": "b232d253df621aa770b780c1301d364d",
|
||||
"Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].mp4": "e66287b9832277b6a4d1554e29d9fdcc",
|
||||
"Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].nfo": "f7c0de89038f8c491bded8a3968720a2",
|
||||
"Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg": "d17c379ea8b362f5b97c6b213b0342cb",
|
||||
"Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].mp4": "04ab5cb3cc12325d0c96a7cd04a8b91d",
|
||||
"Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].nfo": "ee1eda78fa0980bc703e602b5012dd1f",
|
||||
"Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530",
|
||||
"Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].mp4": "025de6099a5c98e6397153c7a62d517d",
|
||||
"Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "61eb6369430da0ab6134d78829a7621b",
|
||||
"Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net)-thumb.jpg": "c956192a379b3661595c9920972d4819",
|
||||
"Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).mp4": "3d9c19835b03355d6fd5d00cd59dbe5b",
|
||||
"Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).nfo": "60f72b99f5c69f9e03a071a12160928f",
|
||||
"Season 2011/s2011.e0630 - Project Zombie |Fin|-thumb.jpg": "00ed383591779ffe98291de60f198fe9",
|
||||
"Season 2011/s2011.e0630 - Project Zombie |Fin|.mp4": "4971cb2d4fa29460361031f3fa8e1ea9",
|
||||
"Season 2011/s2011.e0630 - Project Zombie |Fin|.nfo": "a7b5d9e57d20852f5daf360a1373bb7a",
|
||||
"Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC]-thumb.jpg": "1718599d5189c65f7d8cf6acfa5ea851",
|
||||
"Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].mp4": "55e9b0add08c48c9c66105da0def2426",
|
||||
"Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].nfo": "fe60e2b6b564f9316b6c7c183e1cf300",
|
||||
"Season 2012/s2012.e0123 - Project Zombie |Map Trailer|-thumb.jpg": "54ebe9df801b278fdd17b21afa8373a6",
|
||||
"Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.mp4": "65e4ce53ed5ec4139995469f99477a50",
|
||||
"Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.nfo": "c8900adcca83c473c79a4afbc7ad2de1",
|
||||
"Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|-thumb.jpg": "e29d49433175de8a761af35c5307791f",
|
||||
"Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.mp4": "18620a8257a686beda65e54add4d4cd1",
|
||||
"Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.nfo": "1c993c41d4308a6049333154d0adee16",
|
||||
"Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg": "6f8f5e1e031ec2a04b0a4906c04a19ee",
|
||||
"Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4": "82f6ee7253e1dbb83ae7215af08ffacc",
|
||||
"Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo": "cc7886aae3af6b7b0facd82f95390242",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "49cc64b25314155c1b8ab0361ac0c34f",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "e733b4cc385b953b08c8eb0f47e03c1e",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "2b3ccb3f1ef81ee49fe1afb88f275a09",
|
||||
"fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3",
|
||||
"poster.jpg": "e92872ff94c96ad49e9579501c791578",
|
||||
"tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157"
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
".ytdl-sub-pz-download-archive.json": "99914b932bd37a50b983c5e7c90ae93b",
|
||||
"fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3",
|
||||
"poster.jpg": "e92872ff94c96ad49e9579501c791578",
|
||||
"tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157"
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
".ytdl-sub-pz-download-archive.json": "523518e883758d9d89b656f9e9966efa",
|
||||
"Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg": "6f8f5e1e031ec2a04b0a4906c04a19ee",
|
||||
"Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4": "82f6ee7253e1dbb83ae7215af08ffacc",
|
||||
"Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo": "cc7886aae3af6b7b0facd82f95390242",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "49cc64b25314155c1b8ab0361ac0c34f",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "e733b4cc385b953b08c8eb0f47e03c1e",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "2b3ccb3f1ef81ee49fe1afb88f275a09",
|
||||
"fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3",
|
||||
"poster.jpg": "e92872ff94c96ad49e9579501c791578",
|
||||
"tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
".ytdl-sub-pz-download-archive.json": "9639fffe58c44d084124c8398b46ef32",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "49cc64b25314155c1b8ab0361ac0c34f",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "e733b4cc385b953b08c8eb0f47e03c1e",
|
||||
"Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "2b3ccb3f1ef81ee49fe1afb88f275a09",
|
||||
"fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3",
|
||||
"poster.jpg": "e92872ff94c96ad49e9579501c791578",
|
||||
"tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"JMC - Jesse's Minecraft Server-thumb.jpg": "a3f1910f9c51f6442f845a528e190829",
|
||||
"JMC - Jesse's Minecraft Server.mkv": "f523ac968dd9dfbd1954cbca72ad4108",
|
||||
"JMC - Jesse's Minecraft Server.nfo": "10df5dcdb65ab18ecf21b3503c77e48b"
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
".ytdl-sub-music_video_playlist_test-download-archive.json": "9f785c29194a6ecfba6a6b4018763ddc",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg": "b232d253df621aa770b780c1301d364d",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Feb.1].mp4": "e66287b9832277b6a4d1554e29d9fdcc",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Feb.1].nfo": "3d272fe58487b6011ad049b6000b046f",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg": "d17c379ea8b362f5b97c6b213b0342cb",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Feb.27].mp4": "04ab5cb3cc12325d0c96a7cd04a8b91d",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Feb.27].nfo": "6f99af10bef67276a507d1d9770c5e92",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Mar.21].mp4": "025de6099a5c98e6397153c7a62d517d",
|
||||
"JMC - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "beec3c1326654bd8c858cecf4e40977a"
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"Project Zombie - 1-6.Intro.mp4": "eaec6f50f364b13ef1a201e736ec9c05",
|
||||
"Project Zombie - 2-6.Part 1.mp4": "5850b19acb250cc13db36f80fa1bba5a",
|
||||
"Project Zombie - 3-6.Part 2.mp4": "445d95eba437db6df284df7e1ab633e8",
|
||||
"Project Zombie - 4-6.Part 3.mp4": "2b6e7532d515c9e64ed2a33d850cf199",
|
||||
"Project Zombie - 5-6.Part 4.mp4": "842bf3c4d1fcc4c5ab110635935dac66",
|
||||
"Project Zombie - 6-6.Part 5.mp4": "238de99f00f829ab72f042b79da9a33a",
|
||||
"Project Zombie - Intro-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"Project Zombie - Intro.nfo": "ded59ac906f579312cc3cf98a57e7ea3",
|
||||
"Project Zombie - Part 1-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"Project Zombie - Part 1.nfo": "70ff5cd0092b8bc22dc4db93a824789b",
|
||||
"Project Zombie - Part 2-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"Project Zombie - Part 2.nfo": "54450c18a2cbb9d6d2ee5d0a1fb3f279",
|
||||
"Project Zombie - Part 3-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"Project Zombie - Part 3.nfo": "0effb13fc4039363a95969d1048dde57",
|
||||
"Project Zombie - Part 4-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"Project Zombie - Part 4.nfo": "74bd0d7c12105469838768a0cc323a8c",
|
||||
"Project Zombie - Part 5-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"Project Zombie - Part 5.nfo": "a8cf2e77721335ea7c18e22734e7996c"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"JMC - Oblivion Mod "Falcor" p.1-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"JMC - Oblivion Mod "Falcor" p.1.mp4": "931a705864c57d21d6fedebed4af6bbc",
|
||||
"JMC - Oblivion Mod "Falcor" p.1.nfo": "89f509a8a3d9003e22a9091abeeae5dc"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"JMC - Oblivion Mod "Falcor" p.1-thumb.jpg": "fb95b510681676e81c321171fc23143e",
|
||||
"JMC - Oblivion Mod "Falcor" p.1.mp4": "76b8a7dd428e67e5072d003983bb7e33",
|
||||
"JMC - Oblivion Mod "Falcor" p.1.nfo": "89f509a8a3d9003e22a9091abeeae5dc"
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
Files created in '{output_directory}'
|
||||
----------------------------------------
|
||||
Rick Beato - Can you hear the difference 🎸🔥 #shorts-thumb.jpg
|
||||
Rick Beato - Can you hear the difference 🎸🔥 #shorts.3gp
|
||||
Rick Beato - Can you hear the difference 🎸🔥 #shorts.nfo
|
||||
Rick Beato - Can you hear the difference? 🎸🔥 #shorts-thumb.jpg
|
||||
Rick Beato - Can you hear the difference? 🎸🔥 #shorts.3gp
|
||||
Rick Beato - Can you hear the difference? 🎸🔥 #shorts.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
Files created in '{output_directory}'
|
||||
----------------------------------------
|
||||
.ytdl-sub-pz-download-archive.json
|
||||
Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1-thumb.jpg
|
||||
Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.mp4
|
||||
Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo
|
||||
Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1-thumb.jpg
|
||||
Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.mp4
|
||||
Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2010-08-13
|
||||
|
|
@ -18,9 +18,9 @@ Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo
|
|||
season: 2010
|
||||
title: Oblivion Mod "Falcor" p.1
|
||||
year: 2010
|
||||
Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2-thumb.jpg
|
||||
Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.mp4
|
||||
Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.nfo
|
||||
Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2-thumb.jpg
|
||||
Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.mp4
|
||||
Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2010-12-02
|
||||
|
|
@ -127,9 +127,9 @@ Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo
|
|||
season: 2011
|
||||
title: Jesse's Minecraft Server [Trailer - Mar.21]
|
||||
year: 2011
|
||||
Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net)-thumb.jpg
|
||||
Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).mp4
|
||||
Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).nfo
|
||||
Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net)-thumb.jpg
|
||||
Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).mp4
|
||||
Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2011-05-29
|
||||
|
|
@ -154,9 +154,9 @@ Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzomb
|
|||
season: 2011
|
||||
title: Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net)
|
||||
year: 2011
|
||||
Season 2011/s2011.e0630 - Project Zombie _Fin-thumb.jpg
|
||||
Season 2011/s2011.e0630 - Project Zombie _Fin.mp4
|
||||
Season 2011/s2011.e0630 - Project Zombie _Fin.nfo
|
||||
Season 2011/s2011.e0630 - Project Zombie |Fin|-thumb.jpg
|
||||
Season 2011/s2011.e0630 - Project Zombie |Fin|.mp4
|
||||
Season 2011/s2011.e0630 - Project Zombie |Fin|.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2011-06-30
|
||||
|
|
@ -167,9 +167,9 @@ Season 2011/s2011.e0630 - Project Zombie _Fin.nfo
|
|||
season: 2011
|
||||
title: Project Zombie |Fin|
|
||||
year: 2011
|
||||
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC]-thumb.jpg
|
||||
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].mp4
|
||||
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo
|
||||
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC]-thumb.jpg
|
||||
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].mp4
|
||||
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2011-11-21
|
||||
|
|
@ -187,9 +187,9 @@ Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo
|
|||
season: 2011
|
||||
title: Skyrim 'Ultra HD w/Mods' [PC]
|
||||
year: 2011
|
||||
Season 2012/s2012.e0123 - Project Zombie _Map Trailer-thumb.jpg
|
||||
Season 2012/s2012.e0123 - Project Zombie _Map Trailer.mp4
|
||||
Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo
|
||||
Season 2012/s2012.e0123 - Project Zombie |Map Trailer|-thumb.jpg
|
||||
Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.mp4
|
||||
Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2012-01-23
|
||||
|
|
@ -207,9 +207,9 @@ Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo
|
|||
season: 2012
|
||||
title: Project Zombie |Map Trailer|
|
||||
year: 2012
|
||||
Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer-thumb.jpg
|
||||
Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.mp4
|
||||
Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo
|
||||
Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|-thumb.jpg
|
||||
Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.mp4
|
||||
Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2013-07-19
|
||||
|
|
@ -222,9 +222,9 @@ Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo
|
|||
season: 2013
|
||||
title: Project Zombie Rewind |Trailer|
|
||||
year: 2013
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2018-10-29
|
||||
|
|
@ -242,9 +242,9 @@ Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo
|
|||
season: 2018
|
||||
title: Jesse's Minecraft Server | Teaser Trailer
|
||||
year: 2018
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2018-11-02
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
Files created in '{output_directory}'
|
||||
----------------------------------------
|
||||
.ytdl-sub-pz-download-archive.json
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2018-10-29
|
||||
|
|
@ -21,9 +21,9 @@ Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo
|
|||
season: 2018
|
||||
title: Jesse's Minecraft Server | Teaser Trailer
|
||||
year: 2018
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4
|
||||
Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo
|
||||
NFO tags:
|
||||
episodedetails:
|
||||
aired: 2018-11-02
|
||||
|
|
|
|||
|
|
@ -10,6 +10,6 @@ tvshow.nfo
|
|||
|
||||
Files removed from '{output_directory}'
|
||||
----------------------------------------
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4
|
||||
Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
Files created in '{output_directory}'
|
||||
----------------------------------------
|
||||
JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg
|
||||
JMC - Oblivion Mod 'Falcor' p.1.mp4
|
||||
JMC - Oblivion Mod 'Falcor' p.1.nfo
|
||||
JMC - Oblivion Mod "Falcor" p.1-thumb.jpg
|
||||
JMC - Oblivion Mod "Falcor" p.1.mp4
|
||||
JMC - Oblivion Mod "Falcor" p.1.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Files created in '{output_directory}'
|
||||
----------------------------------------
|
||||
JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg
|
||||
JMC - Oblivion Mod 'Falcor' p.1.mp4
|
||||
JMC - Oblivion Mod "Falcor" p.1-thumb.jpg
|
||||
JMC - Oblivion Mod "Falcor" p.1.mp4
|
||||
Chapters embedded into the video:
|
||||
0:00: Intro
|
||||
0:10: Part 1
|
||||
|
|
@ -9,7 +9,7 @@ JMC - Oblivion Mod 'Falcor' p.1.mp4
|
|||
0:30: Part 3
|
||||
0:40: Part 4
|
||||
1:01: Part 5
|
||||
JMC - Oblivion Mod 'Falcor' p.1.nfo
|
||||
JMC - Oblivion Mod "Falcor" p.1.nfo
|
||||
NFO tags:
|
||||
musicvideo:
|
||||
album: Music Videos
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from e2e.expected_download import ExpectedDownloadFile
|
||||
from e2e.expected_download import ExpectedDownloads
|
||||
from e2e.expected_download import assert_expected_downloads
|
||||
from e2e.expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.config.preset import Preset
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
|
||||
|
||||
|
|
@ -25,40 +20,6 @@ def subscription_dict(output_directory):
|
|||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_discography_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
# Download mapping
|
||||
ExpectedDownloadFile(path=Path(".ytdl-sub-jb-download-archive.json"), md5="1a99156e9ece62539fb2608416a07200"),
|
||||
|
||||
# Entry files (singles)
|
||||
ExpectedDownloadFile(path=Path("j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3"), md5="bffbd558e12c6a9e029dc136a88342c4"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2021] Baby Santana's Dorian Groove/folder.jpg"), md5="967892be44b8c47e1be73f055a7c6f08"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3"), md5="038db58aebe2ba875b733932b42a94d6"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2021] Purple Clouds/folder.jpg"), md5="967892be44b8c47e1be73f055a7c6f08"),
|
||||
|
||||
# Entry files (albums)
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3"), md5="e145f0a2f6012768280c38655ca58065"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3"), md5="60c8b8817a197a13e4bb90903af612c5"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3"), md5="8265b7e4f79878af877bc6ecd9757efe"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3"), md5="accf46b76891d2954b893d0f91d82816"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3"), md5="e1f584f523336160d5c1104a61de77f3"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3"), md5="f6885b25901177f0357649afe97328cc"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3"), md5="fa057f221cbe4cf2442cd2fdb960743e"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3"), md5="7794ae812c64580e2ac8fc457d5cc85f"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/09 - Finding Home.mp3"), md5="adbf02eddb2090c008eb497d13ff84b9"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3"), md5="65bb10c84366c71498161734f953e93d"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/11 - Untold History.mp3"), md5="6904b2918e5dc38d9a9f72d967eb74bf"),
|
||||
ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/folder.jpg"), md5="967892be44b8c47e1be73f055a7c6f08"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
class TestSoundcloudDiscography:
|
||||
"""
|
||||
Downloads my (bad) SC recordings I made. Ensure the above files exist and have the
|
||||
|
|
@ -70,7 +31,6 @@ class TestSoundcloudDiscography:
|
|||
self,
|
||||
subscription_dict,
|
||||
soundcloud_discography_config,
|
||||
expected_discography_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -85,5 +45,8 @@ class TestSoundcloudDiscography:
|
|||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="soundcloud/test_soundcloud_discography.txt",
|
||||
)
|
||||
if not dry_run:
|
||||
expected_discography_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="soundcloud/test_soundcloud_discography.json",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import copy
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
import mergedeep
|
||||
import pytest
|
||||
from conftest import assert_debug_log
|
||||
from e2e.expected_download import ExpectedDownloadFile
|
||||
from e2e.expected_download import ExpectedDownloads
|
||||
from e2e.expected_download import assert_expected_downloads
|
||||
from e2e.expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
import ytdl_sub.downloaders.downloader
|
||||
|
|
@ -45,77 +43,6 @@ def channel_subscription_generator(channel_as_tv_show_config, subscription_name)
|
|||
return _channel_subscription_generator
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# FULL CHANNEL FIXTURES
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_full_channel_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
# Download mapping
|
||||
ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="dd3c6236a107a665b884f701b8d14d4d"),
|
||||
|
||||
# Output directory files
|
||||
ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"),
|
||||
ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"),
|
||||
ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"),
|
||||
|
||||
# Entry files
|
||||
ExpectedDownloadFile(path=Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1-thumb.jpg"), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.mp4"), md5="931a705864c57d21d6fedebed4af6bbc"),
|
||||
ExpectedDownloadFile(path=Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo"), md5="67d8d71d048039080acbba3bce4febaa"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2-thumb.jpg"), md5="8b32ee9c037fa669e444a0ac181525a1"),
|
||||
ExpectedDownloadFile(path=Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.mp4"), md5="d3469b4dca7139cb3dbc38712b6796bf"),
|
||||
ExpectedDownloadFile(path=Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.nfo"), md5="d81f49cedbd7edaee987521e89b37904"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg"), md5="b232d253df621aa770b780c1301d364d"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].mp4"), md5="e66287b9832277b6a4d1554e29d9fdcc"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].nfo"), md5="f7c0de89038f8c491bded8a3968720a2"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg"), md5="d17c379ea8b362f5b97c6b213b0342cb"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].mp4"), md5="04ab5cb3cc12325d0c96a7cd04a8b91d"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].nfo"), md5="ee1eda78fa0980bc703e602b5012dd1f"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg"), md5="e7830aa8a64b0cde65ba3f7e5fc56530"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].mp4"), md5="025de6099a5c98e6397153c7a62d517d"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo"), md5="61eb6369430da0ab6134d78829a7621b"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net)-thumb.jpg"), md5="c956192a379b3661595c9920972d4819"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).mp4"), md5="3d9c19835b03355d6fd5d00cd59dbe5b"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).nfo"), md5="60f72b99f5c69f9e03a071a12160928f"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0630 - Project Zombie _Fin-thumb.jpg"), md5="00ed383591779ffe98291de60f198fe9"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0630 - Project Zombie _Fin.mp4"), md5="4971cb2d4fa29460361031f3fa8e1ea9"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e0630 - Project Zombie _Fin.nfo"), md5="a7b5d9e57d20852f5daf360a1373bb7a"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC]-thumb.jpg"), md5="1718599d5189c65f7d8cf6acfa5ea851"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].mp4"), md5="55e9b0add08c48c9c66105da0def2426"),
|
||||
ExpectedDownloadFile(path=Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo"), md5="fe60e2b6b564f9316b6c7c183e1cf300"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer-thumb.jpg"), md5="54ebe9df801b278fdd17b21afa8373a6"),
|
||||
ExpectedDownloadFile(path=Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer.mp4"), md5="65e4ce53ed5ec4139995469f99477a50"),
|
||||
ExpectedDownloadFile(path=Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo"), md5="c8900adcca83c473c79a4afbc7ad2de1"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer-thumb.jpg"), md5="e29d49433175de8a761af35c5307791f"),
|
||||
ExpectedDownloadFile(path=Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.mp4"), md5="18620a8257a686beda65e54add4d4cd1"),
|
||||
ExpectedDownloadFile(path=Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo"), md5="1c993c41d4308a6049333154d0adee16"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg"), md5="6f8f5e1e031ec2a04b0a4906c04a19ee"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"), md5="82f6ee7253e1dbb83ae7215af08ffacc"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"), md5="cc7886aae3af6b7b0facd82f95390242"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg"), md5="49cc64b25314155c1b8ab0361ac0c34f"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"), md5="e733b4cc385b953b08c8eb0f47e03c1e"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# RECENT CHANNEL FIXTURES
|
||||
@pytest.fixture
|
||||
|
|
@ -132,55 +59,6 @@ def recent_channel_preset_dict(channel_preset_dict):
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_recent_channel_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
# Download mapping
|
||||
ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="91534d1c5921d121aa35d7a197ba1940"),
|
||||
|
||||
# Output directory files
|
||||
ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"),
|
||||
ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"),
|
||||
ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"),
|
||||
|
||||
# Recent Entry files
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg"), md5="6f8f5e1e031ec2a04b0a4906c04a19ee"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"), md5="82f6ee7253e1dbb83ae7215af08ffacc"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"), md5="cc7886aae3af6b7b0facd82f95390242"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg"), md5="49cc64b25314155c1b8ab0361ac0c34f"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"), md5="e733b4cc385b953b08c8eb0f47e03c1e"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# RECENT CHANNEL FIXTURES -- NO VIDS IN RANGE
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_recent_channel_no_vids_in_range_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
# Download mapping
|
||||
ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="99914b932bd37a50b983c5e7c90ae93b"),
|
||||
|
||||
# Output directory files
|
||||
ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"),
|
||||
ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"),
|
||||
ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# ROLLING RECENT CHANNEL FIXTURES
|
||||
@pytest.fixture
|
||||
|
|
@ -195,29 +73,6 @@ def rolling_recent_channel_preset_dict(recent_channel_preset_dict):
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_rolling_recent_channel_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
# Download mapping
|
||||
ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="97ff47a7c5d89a426a653493ad1a3f06"),
|
||||
|
||||
# Output directory files
|
||||
ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"),
|
||||
ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"),
|
||||
ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"),
|
||||
|
||||
# Rolling Recent Entry files
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg"), md5="49cc64b25314155c1b8ab0361ac0c34f"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"), md5="e733b4cc385b953b08c8eb0f47e03c1e"),
|
||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
class TestChannelAsKodiTvShow:
|
||||
"""
|
||||
Downloads my old minecraft youtube channel. Ensure the above files exist and have the
|
||||
|
|
@ -229,7 +84,6 @@ class TestChannelAsKodiTvShow:
|
|||
self,
|
||||
channel_subscription_generator,
|
||||
channel_preset_dict,
|
||||
expected_full_channel_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -240,15 +94,17 @@ class TestChannelAsKodiTvShow:
|
|||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_channel_full.txt",
|
||||
)
|
||||
if not dry_run:
|
||||
expected_full_channel_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_channel_full.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_recent_channel_download(
|
||||
self,
|
||||
channel_subscription_generator,
|
||||
recent_channel_preset_dict,
|
||||
expected_recent_channel_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -262,9 +118,12 @@ class TestChannelAsKodiTvShow:
|
|||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_channel_recent.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_channel_recent.json",
|
||||
)
|
||||
if not dry_run:
|
||||
expected_recent_channel_download.assert_files_exist(relative_directory=output_directory)
|
||||
|
||||
# try downloading again, ensure nothing more was downloaded
|
||||
with assert_debug_log(
|
||||
logger=ytdl_sub.downloaders.downloader.download_logger,
|
||||
|
|
@ -278,8 +137,10 @@ class TestChannelAsKodiTvShow:
|
|||
"youtube/test_channel_no_additional_downloads.txt"
|
||||
),
|
||||
)
|
||||
expected_recent_channel_download.assert_files_exist(
|
||||
relative_directory=output_directory
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_channel_recent.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
|
|
@ -287,7 +148,6 @@ class TestChannelAsKodiTvShow:
|
|||
self,
|
||||
channel_subscription_generator,
|
||||
recent_channel_preset_dict,
|
||||
expected_recent_channel_no_vids_in_range_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -304,10 +164,11 @@ class TestChannelAsKodiTvShow:
|
|||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt",
|
||||
)
|
||||
if not dry_run:
|
||||
expected_recent_channel_no_vids_in_range_download.assert_files_exist(
|
||||
relative_directory=output_directory
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_channel_no_additional_downloads.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_rolling_recent_channel_download(
|
||||
|
|
@ -315,8 +176,6 @@ class TestChannelAsKodiTvShow:
|
|||
channel_subscription_generator,
|
||||
recent_channel_preset_dict,
|
||||
rolling_recent_channel_preset_dict,
|
||||
expected_recent_channel_download,
|
||||
expected_rolling_recent_channel_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -333,14 +192,18 @@ class TestChannelAsKodiTvShow:
|
|||
logger=ytdl_sub.downloaders.downloader.download_logger,
|
||||
expected_message="RejectedVideoReached, stopping additional downloads",
|
||||
):
|
||||
transaction_log = recent_channel_subscription.download()
|
||||
transaction_log = recent_channel_subscription.download(dry_run=False)
|
||||
|
||||
expected_recent_channel_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_channel_recent.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name="youtube/test_channel_recent.json",
|
||||
)
|
||||
|
||||
# Then, download the rolling recent vids subscription. This should remove one of the
|
||||
# two videos
|
||||
|
|
@ -350,16 +213,22 @@ class TestChannelAsKodiTvShow:
|
|||
):
|
||||
transaction_log = rolling_recent_channel_subscription.download(dry_run=dry_run)
|
||||
|
||||
expected_downloads_summary = (
|
||||
"youtube/test_channel_recent.json"
|
||||
if dry_run
|
||||
else "youtube/test_channel_rolling_recent.json"
|
||||
)
|
||||
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_channel_rolling_recent.txt",
|
||||
regenerate_transaction_log=True,
|
||||
)
|
||||
if not dry_run:
|
||||
expected_rolling_recent_channel_download.assert_files_exist(
|
||||
relative_directory=output_directory
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name=expected_downloads_summary,
|
||||
)
|
||||
|
||||
# Invoke the rolling download again, ensure downloading stopped early from it already
|
||||
# existing
|
||||
|
|
@ -375,6 +244,8 @@ class TestChannelAsKodiTvShow:
|
|||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt",
|
||||
)
|
||||
expected_rolling_recent_channel_download.assert_files_exist(
|
||||
relative_directory=output_directory
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=False,
|
||||
expected_download_summary_file_name=expected_downloads_summary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from e2e.expected_download import ExpectedDownloadFile
|
||||
from e2e.expected_download import ExpectedDownloads
|
||||
from e2e.expected_download import assert_expected_downloads
|
||||
from e2e.expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
|
|
@ -63,17 +60,17 @@ def playlist_subscription(config, subscription_name, subscription_dict):
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_playlist_download():
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server-thumb.jpg"), md5="a3f1910f9c51f6442f845a528e190829"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.mkv")), # not bitexact TODO: check size
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.nfo"), md5="10df5dcdb65ab18ecf21b3503c77e48b"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
# @pytest.fixture
|
||||
# def expected_playlist_download():
|
||||
# # fmt: off
|
||||
# return ExpectedDownloads(
|
||||
# expected_downloads=[
|
||||
# ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server-thumb.jpg"), md5="a3f1910f9c51f6442f845a528e190829"),
|
||||
# ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.mkv")), # not bitexact TODO: check size
|
||||
# ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.nfo"), md5="10df5dcdb65ab18ecf21b3503c77e48b"),
|
||||
# ]
|
||||
# )
|
||||
# # fmt: on
|
||||
|
||||
|
||||
class TestYoutubeMergePlaylist:
|
||||
|
|
@ -83,15 +80,16 @@ class TestYoutubeMergePlaylist:
|
|||
"""
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_merge_playlist_download(
|
||||
self, playlist_subscription, expected_playlist_download, output_directory, dry_run
|
||||
):
|
||||
def test_merge_playlist_download(self, playlist_subscription, output_directory, dry_run):
|
||||
transaction_log = playlist_subscription.download(dry_run=dry_run)
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_merge_playlist.txt",
|
||||
)
|
||||
|
||||
if not dry_run:
|
||||
expected_playlist_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
ignore_md5_hashes_for=["JMC - Jesse's Minecraft Server.mkv"], # TODO, better test here
|
||||
expected_download_summary_file_name="youtube/test_merge_playlist.json",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from conftest import assert_debug_log
|
||||
from e2e.conftest import mock_run_from_cli
|
||||
from e2e.expected_download import ExpectedDownloadFile
|
||||
from e2e.expected_download import ExpectedDownloads
|
||||
from e2e.expected_download import assert_expected_downloads
|
||||
from e2e.expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
import ytdl_sub.downloaders.downloader
|
||||
|
|
@ -26,32 +23,6 @@ def playlist_preset_dict(output_directory):
|
|||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_playlist_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
# Download mapping
|
||||
ExpectedDownloadFile(path=Path(".ytdl-sub-music_video_playlist_test-download-archive.json"), md5="9f785c29194a6ecfba6a6b4018763ddc"),
|
||||
|
||||
# Entry files
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg"), md5="b232d253df621aa770b780c1301d364d"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.1].mp4"), md5="e66287b9832277b6a4d1554e29d9fdcc"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.1].nfo"), md5="3d272fe58487b6011ad049b6000b046f"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg"), md5="d17c379ea8b362f5b97c6b213b0342cb"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.27].mp4"), md5="04ab5cb3cc12325d0c96a7cd04a8b91d"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.27].nfo"), md5="6f99af10bef67276a507d1d9770c5e92"),
|
||||
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg"), md5="e7830aa8a64b0cde65ba3f7e5fc56530"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Mar.21].mp4"), md5="025de6099a5c98e6397153c7a62d517d"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Mar.21].nfo"), md5="beec3c1326654bd8c858cecf4e40977a"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
class TestPlaylistAsKodiMusicVideo:
|
||||
"""
|
||||
Downloads my old minecraft youtube channel, pretends they are music videos. Ensure the above
|
||||
|
|
@ -63,7 +34,6 @@ class TestPlaylistAsKodiMusicVideo:
|
|||
self,
|
||||
music_video_config,
|
||||
playlist_preset_dict,
|
||||
expected_playlist_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -73,24 +43,32 @@ class TestPlaylistAsKodiMusicVideo:
|
|||
preset_dict=playlist_preset_dict,
|
||||
)
|
||||
|
||||
transaction_log = playlist_subscription.download()
|
||||
transaction_log = playlist_subscription.download(dry_run=dry_run)
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_playlist.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_playlist.json",
|
||||
)
|
||||
|
||||
# Ensure another invocation will hit ExistingVideoReached
|
||||
if not dry_run:
|
||||
expected_playlist_download.assert_files_exist(relative_directory=output_directory)
|
||||
|
||||
# Ensure another invocation will hit ExistingVideoReached
|
||||
with assert_debug_log(
|
||||
logger=ytdl_sub.downloaders.downloader.download_logger,
|
||||
expected_message="ExistingVideoReached, stopping additional downloads",
|
||||
):
|
||||
transaction_log = playlist_subscription.download()
|
||||
expected_playlist_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert transaction_log.is_empty
|
||||
|
||||
assert transaction_log.is_empty
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_playlist.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_playlist_download_from_cli_sub(
|
||||
|
|
@ -98,7 +76,6 @@ class TestPlaylistAsKodiMusicVideo:
|
|||
preset_dict_to_subscription_yaml_generator,
|
||||
music_video_config_path,
|
||||
playlist_preset_dict,
|
||||
expected_playlist_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -118,17 +95,23 @@ class TestPlaylistAsKodiMusicVideo:
|
|||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_playlist.txt",
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_playlist.json",
|
||||
)
|
||||
|
||||
if not dry_run:
|
||||
expected_playlist_download.assert_files_exist(relative_directory=output_directory)
|
||||
|
||||
# Ensure another invocation will hit ExistingVideoReached
|
||||
with assert_debug_log(
|
||||
logger=ytdl_sub.downloaders.downloader.download_logger,
|
||||
expected_message="ExistingVideoReached, stopping additional downloads",
|
||||
):
|
||||
transaction_log = mock_run_from_cli(args=args)[0][1]
|
||||
expected_playlist_download.assert_files_exist(
|
||||
relative_directory=output_directory
|
||||
)
|
||||
assert transaction_log.is_empty
|
||||
|
||||
assert transaction_log.is_empty
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_playlist.json",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
from pathlib import Path
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
import pytest
|
||||
from e2e.expected_download import ExpectedDownloadFile
|
||||
from e2e.expected_download import ExpectedDownloads
|
||||
from e2e.expected_download import assert_expected_downloads
|
||||
from e2e.expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.config.preset import Preset
|
||||
|
|
@ -50,35 +46,6 @@ def single_video_subscription(music_video_config, subscription_dict):
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_single_video_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - 1-6.Intro.mp4'), md5="eaec6f50f364b13ef1a201e736ec9c05"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - 2-6.Part 1.mp4'), md5="5850b19acb250cc13db36f80fa1bba5a"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - 3-6.Part 2.mp4'), md5="445d95eba437db6df284df7e1ab633e8"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - 4-6.Part 3.mp4'), md5="2b6e7532d515c9e64ed2a33d850cf199"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - 5-6.Part 4.mp4'), md5="842bf3c4d1fcc4c5ab110635935dac66"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - 6-6.Part 5.mp4'), md5="238de99f00f829ab72f042b79da9a33a"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Intro-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Intro.nfo'), md5="ded59ac906f579312cc3cf98a57e7ea3"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 1-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 1.nfo'), md5="70ff5cd0092b8bc22dc4db93a824789b"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 2-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 2.nfo'), md5="54450c18a2cbb9d6d2ee5d0a1fb3f279"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 3-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 3.nfo'), md5="0effb13fc4039363a95969d1048dde57"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 4-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 4.nfo'), md5="74bd0d7c12105469838768a0cc323a8c"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 5-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path('Project Zombie - Part 5.nfo'), md5="a8cf2e77721335ea7c18e22734e7996c"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
class TestPlaylistAsKodiMusicVideo:
|
||||
"""
|
||||
Downloads my old minecraft youtube channel, pretends they are music videos. Ensure the above
|
||||
|
|
@ -86,15 +53,15 @@ class TestPlaylistAsKodiMusicVideo:
|
|||
"""
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_split_video_download(
|
||||
self, single_video_subscription, expected_single_video_download, output_directory, dry_run
|
||||
):
|
||||
transaction_log = single_video_subscription.download()
|
||||
def test_split_video_download(self, single_video_subscription, output_directory, dry_run):
|
||||
transaction_log = single_video_subscription.download(dry_run=dry_run)
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_split_video.txt",
|
||||
)
|
||||
|
||||
if not dry_run:
|
||||
expected_single_video_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_split_video.json",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from conftest import preset_dict_to_dl_args
|
||||
from e2e.conftest import mock_run_from_cli
|
||||
from e2e.expected_download import ExpectedDownloadFile
|
||||
from e2e.expected_download import ExpectedDownloads
|
||||
from e2e.expected_download import assert_expected_downloads
|
||||
from e2e.expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
|
|
@ -30,41 +27,12 @@ def single_video_preset_dict_dl_args(single_video_preset_dict):
|
|||
return preset_dict_to_dl_args(single_video_preset_dict)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_single_video_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg"), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.mp4"), md5="931a705864c57d21d6fedebed4af6bbc"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.nfo"), md5="89f509a8a3d9003e22a9091abeeae5dc"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def expected_single_video_with_chapter_timestamps_download():
|
||||
# turn off black formatter here for readability
|
||||
# fmt: off
|
||||
return ExpectedDownloads(
|
||||
expected_downloads=[
|
||||
ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg"), md5="fb95b510681676e81c321171fc23143e"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.mp4"), md5="76b8a7dd428e67e5072d003983bb7e33"),
|
||||
ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.nfo"), md5="89f509a8a3d9003e22a9091abeeae5dc"),
|
||||
]
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
class TestYoutubeVideo:
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_single_video_download(
|
||||
self,
|
||||
music_video_config,
|
||||
single_video_preset_dict,
|
||||
expected_single_video_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -74,21 +42,23 @@ class TestYoutubeVideo:
|
|||
preset_dict=single_video_preset_dict,
|
||||
)
|
||||
|
||||
transaction_log = single_video_subscription.download()
|
||||
transaction_log = single_video_subscription.download(dry_run=dry_run)
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_video.txt",
|
||||
)
|
||||
if not dry_run:
|
||||
expected_single_video_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_video.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_single_video_download_from_cli_dl(
|
||||
self,
|
||||
music_video_config_path,
|
||||
single_video_preset_dict_dl_args,
|
||||
expected_single_video_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -105,8 +75,11 @@ class TestYoutubeVideo:
|
|||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_video.txt",
|
||||
)
|
||||
if not dry_run:
|
||||
expected_single_video_download.assert_files_exist(relative_directory=output_directory)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_video.json",
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("dry_run", [True, False])
|
||||
def test_single_video_with_timestamp_chapters_download(
|
||||
|
|
@ -114,7 +87,6 @@ class TestYoutubeVideo:
|
|||
timestamps_file_path,
|
||||
music_video_config,
|
||||
single_video_preset_dict,
|
||||
expected_single_video_with_chapter_timestamps_download,
|
||||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
|
|
@ -125,13 +97,14 @@ class TestYoutubeVideo:
|
|||
preset_dict=single_video_preset_dict,
|
||||
)
|
||||
|
||||
transaction_log = single_video_subscription.download()
|
||||
transaction_log = single_video_subscription.download(dry_run=dry_run)
|
||||
assert_transaction_log_matches(
|
||||
output_directory=output_directory,
|
||||
transaction_log=transaction_log,
|
||||
transaction_log_summary_file_name="youtube/test_video_with_chapter_timestamps.txt",
|
||||
)
|
||||
if not dry_run:
|
||||
expected_single_video_with_chapter_timestamps_download.assert_files_exist(
|
||||
relative_directory=output_directory
|
||||
)
|
||||
assert_expected_downloads(
|
||||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="youtube/test_video_with_chapter_timestamps.json",
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue