From d79e94e7e6052328537a2780fcd6f8f1d0fba954 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Sat, 27 Aug 2022 15:01:14 -0700 Subject: [PATCH] [BACKEND] Use native xml library, remove dicttoxml (#196) --- docs/config.rst | 4 +- setup.cfg | 1 - src/ytdl_sub/plugins/nfo_tags.py | 114 +++++++++++------- .../plugins/output_directory_nfo_tags.py | 58 ++------- src/ytdl_sub/utils/xml.py | 16 +-- .../test_chapters_from_ts_with_subs.json | 2 +- .../test_chapters_sb_and_embedded_subs.json | 2 +- .../plugins/test_subtitles_embedded.json | 2 +- .../test_subtitles_embedded_and_file.json | 2 +- .../youtube/test_channel_full.json | 26 ++-- .../test_channel_no_additional_downloads.json | 2 +- .../youtube/test_channel_recent.json | 6 +- .../youtube/test_channel_rolling_recent.json | 4 +- .../youtube/test_merge_playlist.json | 2 +- .../youtube/test_playlist.json | 6 +- .../youtube/test_split_video.json | 12 +- .../youtube/test_video.json | 2 +- 17 files changed, 122 insertions(+), 139 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index 19fc5bae..77290024 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -195,7 +195,7 @@ music_tags nfo_tags '''''''' .. autoclass:: ytdl_sub.plugins.nfo_tags.NfoTagsOptions() - :members: + :members: nfo_name, nfo_root, tags, kodi_safe :member-order: bysource ------------------------------------------------------------------------------- @@ -203,7 +203,7 @@ nfo_tags output_directory_nfo_tags ''''''''''''''''''''''''' .. autoclass:: ytdl_sub.plugins.output_directory_nfo_tags.OutputDirectoryNfoTagsOptions() - :members: + :members: nfo_name, nfo_root, tags, kodi_safe :member-order: bysource ------------------------------------------------------------------------------- diff --git a/setup.cfg b/setup.cfg index 744893a2..58715f1c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,6 @@ packages=find: install_requires = yt-dlp argparse==1.4.0 - dicttoxml==1.7.4 mergedeep==1.3.4 mediafile==0.9.0 PyYAML==6.0 diff --git a/src/ytdl_sub/plugins/nfo_tags.py b/src/ytdl_sub/plugins/nfo_tags.py index 8cfbeb38..c25ef35b 100644 --- a/src/ytdl_sub/plugins/nfo_tags.py +++ b/src/ytdl_sub/plugins/nfo_tags.py @@ -1,6 +1,10 @@ import os +from abc import ABC from pathlib import Path +from typing import Generic from typing import Optional +from typing import Type +from typing import TypeVar from ytdl_sub.entries.entry import Entry from ytdl_sub.plugins.plugin import Plugin @@ -14,7 +18,69 @@ from ytdl_sub.validators.string_formatter_validators import StringFormatterValid from ytdl_sub.validators.validators import BoolValidator -class NfoTagsOptions(PluginOptions): +class SharedNfoTagsOptions(PluginOptions, ABC): + """ + Shared code between NFO tags and Ouptut Directory NFO Tags + """ + + _formatter_validator: Type[StringFormatterValidator] + _dict_formatter_validator: Type[DictFormatterValidator] + + _required_keys = {"nfo_name", "nfo_root", "tags"} + _optional_keys = {"kodi_safe"} + + def __init__(self, name, value): + super().__init__(name, value) + + self._nfo_name = self._validate_key(key="nfo_name", validator=self._formatter_validator) + self._nfo_root = self._validate_key(key="nfo_root", validator=self._formatter_validator) + self._tags = self._validate_key(key="tags", validator=self._dict_formatter_validator) + self._kodi_safe = self._validate_key_if_present( + key="kodi_safe", validator=BoolValidator, default=False + ).value + + +TSharedNfoTagsOptions = TypeVar("TSharedNfoTagsOptions", bound=SharedNfoTagsOptions) + + +class SharedNfoTagsPlugin(Plugin[TSharedNfoTagsOptions], Generic[TSharedNfoTagsOptions], ABC): + """ + Shared code between NFO tags and Ouptut Directory NFO Tags + """ + + def _create_nfo(self, entry: Optional[Entry] = None) -> None: + nfo = {} + + for tag, tag_formatter in sorted(self.plugin_options.tags.dict.items()): + nfo[tag] = self.overrides.apply_formatter(formatter=tag_formatter, entry=entry) + + # Write the nfo tags to XML with the nfo_root + nfo_root = self.overrides.apply_formatter( + formatter=self.plugin_options.nfo_root, entry=entry + ) + + if self.plugin_options.kodi_safe: + nfo = to_max_3_byte_utf8_dict(nfo) + nfo_root = to_max_3_byte_utf8_string(nfo_root) + + xml = to_xml(nfo_dict=nfo, nfo_root=nfo_root) + + nfo_file_name = self.overrides.apply_formatter( + formatter=self.plugin_options.nfo_name, entry=entry + ) + + # Save the nfo's XML to file + nfo_file_path = Path(self.working_directory) / nfo_file_name + os.makedirs(os.path.dirname(nfo_file_path), exist_ok=True) + with open(nfo_file_path, "wb") as nfo_file: + nfo_file.write(xml) + + # Save the nfo file and log its metadata + nfo_metadata = FileMetadata.from_dict(value_dict={nfo_root: nfo}, title="NFO tags:") + self.save_file(file_name=nfo_file_name, file_metadata=nfo_metadata, entry=entry) + + +class NfoTagsOptions(SharedNfoTagsOptions): """ Adds an NFO file for every download file. An NFO file is simply an XML file with a ``.nfo`` extension. You can add any values into the NFO. @@ -37,18 +103,8 @@ class NfoTagsOptions(PluginOptions): kodi_safe: False """ - _required_keys = {"nfo_name", "nfo_root", "tags"} - _optional_keys = {"kodi_safe"} - - def __init__(self, name, value): - super().__init__(name, value) - - self._nfo_name = self._validate_key(key="nfo_name", validator=StringFormatterValidator) - self._nfo_root = self._validate_key(key="nfo_root", validator=StringFormatterValidator) - self._tags = self._validate_key(key="tags", validator=DictFormatterValidator) - self._kodi_safe = self._validate_key_if_present( - key="kodi_safe", validator=BoolValidator, default=False - ).value + _formatter_validator = StringFormatterValidator + _dict_formatter_validator = DictFormatterValidator @property def nfo_name(self) -> StringFormatterValidator: @@ -96,7 +152,7 @@ class NfoTagsOptions(PluginOptions): return self._kodi_safe -class NfoTagsPlugin(Plugin[NfoTagsOptions]): +class NfoTagsPlugin(SharedNfoTagsPlugin[NfoTagsOptions]): plugin_options_type = NfoTagsOptions def post_process_entry(self, entry: Entry) -> None: @@ -108,32 +164,4 @@ class NfoTagsPlugin(Plugin[NfoTagsOptions]): entry: Entry to create an NFO file for """ - nfo = {} - - for tag, tag_formatter in sorted(self.plugin_options.tags.dict.items()): - nfo[tag] = self.overrides.apply_formatter(formatter=tag_formatter, entry=entry) - - # Write the nfo tags to XML with the nfo_root - nfo_root = self.overrides.apply_formatter( - formatter=self.plugin_options.nfo_root, entry=entry - ) - - if self.plugin_options.kodi_safe: - nfo = to_max_3_byte_utf8_dict(nfo) - nfo_root = to_max_3_byte_utf8_string(nfo_root) - - xml = to_xml(nfo_dict=nfo, nfo_root=nfo_root) - - nfo_file_name = self.overrides.apply_formatter( - formatter=self.plugin_options.nfo_name, entry=entry - ) - - # Save the nfo's XML to file - nfo_file_path = Path(self.working_directory) / nfo_file_name - os.makedirs(os.path.dirname(nfo_file_path), exist_ok=True) - with open(nfo_file_path, "wb") as nfo_file: - nfo_file.write(xml) - - # Save the nfo file and log its metadata - nfo_metadata = FileMetadata.from_dict(value_dict={nfo_root: nfo}, title="NFO tags:") - self.save_file(file_name=nfo_file_name, file_metadata=nfo_metadata, entry=entry) + self._create_nfo(entry=entry) diff --git a/src/ytdl_sub/plugins/output_directory_nfo_tags.py b/src/ytdl_sub/plugins/output_directory_nfo_tags.py index 3b7a16a8..6df40967 100644 --- a/src/ytdl_sub/plugins/output_directory_nfo_tags.py +++ b/src/ytdl_sub/plugins/output_directory_nfo_tags.py @@ -1,19 +1,12 @@ -import os -from pathlib import Path from typing import Optional -from ytdl_sub.plugins.plugin import Plugin -from ytdl_sub.plugins.plugin import PluginOptions -from ytdl_sub.utils.file_handler import FileMetadata -from ytdl_sub.utils.xml import to_max_3_byte_utf8_dict -from ytdl_sub.utils.xml import to_max_3_byte_utf8_string -from ytdl_sub.utils.xml import to_xml +from ytdl_sub.plugins.nfo_tags import SharedNfoTagsOptions +from ytdl_sub.plugins.nfo_tags import SharedNfoTagsPlugin from ytdl_sub.validators.string_formatter_validators import OverridesDictFormatterValidator from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator -from ytdl_sub.validators.validators import BoolValidator -class OutputDirectoryNfoTagsOptions(PluginOptions): +class OutputDirectoryNfoTagsOptions(SharedNfoTagsOptions): """ Adds a single NFO file in the output directory. An NFO file is simply an XML file with a ``.nfo`` extension. You can add any values into the NFO. @@ -34,23 +27,8 @@ class OutputDirectoryNfoTagsOptions(PluginOptions): kodi_safe: False """ - _required_keys = {"nfo_name", "nfo_root", "tags"} - _optional_keys = {"kodi_safe"} - - def __init__(self, name, value): - super().__init__(name, value) - # Since this does not create NFOs for entries, we must use the overrides formatter classes - # to ensure we are only using values defined as string literals or in overrides - self._nfo_name = self._validate_key( - key="nfo_name", validator=OverridesStringFormatterValidator - ) - self._nfo_root = self._validate_key( - key="nfo_root", validator=OverridesStringFormatterValidator - ) - self._tags = self._validate_key(key="tags", validator=OverridesDictFormatterValidator) - self._kodi_safe = self._validate_key_if_present( - key="kodi_safe", validator=BoolValidator, default=False - ).value + _formatter_validator = OverridesStringFormatterValidator + _dict_formatter_validator = OverridesDictFormatterValidator @property def nfo_name(self) -> OverridesStringFormatterValidator: @@ -96,33 +74,11 @@ class OutputDirectoryNfoTagsOptions(PluginOptions): return self._kodi_safe -class OutputDirectoryNfoTagsPlugin(Plugin[OutputDirectoryNfoTagsOptions]): +class OutputDirectoryNfoTagsPlugin(SharedNfoTagsPlugin[OutputDirectoryNfoTagsOptions]): plugin_options_type = OutputDirectoryNfoTagsOptions def post_process_subscription(self): """ Creates an NFO file in the root of the output directory """ - nfo = {} - - for tag, tag_formatter in sorted(self.plugin_options.tags.dict.items()): - nfo[tag] = self.overrides.apply_formatter(formatter=tag_formatter) - - # Write the nfo tags to XML with the nfo_root - nfo_root = self.overrides.apply_formatter(formatter=self.plugin_options.nfo_root) - - if self.plugin_options.kodi_safe: - nfo = to_max_3_byte_utf8_dict(nfo) - nfo_root = to_max_3_byte_utf8_string(nfo_root) - - xml = to_xml(nfo_dict=nfo, nfo_root=nfo_root) - nfo_file_name = self.overrides.apply_formatter(formatter=self.plugin_options.nfo_name) - - # Save the nfo's XML to file - nfo_file_path = Path(self.working_directory) / nfo_file_name - os.makedirs(os.path.dirname(nfo_file_path), exist_ok=True) - with open(nfo_file_path, "wb") as nfo_file: - nfo_file.write(xml) - - nfo_metadata = FileMetadata.from_dict(value_dict={nfo_root: nfo}, title="NFO tags:") - self.save_file(file_name=nfo_file_name, file_metadata=nfo_metadata) + self._create_nfo() diff --git a/src/ytdl_sub/utils/xml.py b/src/ytdl_sub/utils/xml.py index 98248a4b..bf452fd5 100644 --- a/src/ytdl_sub/utils/xml.py +++ b/src/ytdl_sub/utils/xml.py @@ -1,7 +1,6 @@ +import xml.etree.ElementTree as et from typing import Dict -import dicttoxml - def _to_max_3_byte_utf8_char(char: str) -> str: return "□" if len(char.encode("utf-8")) > 3 else char @@ -53,9 +52,10 @@ def to_xml(nfo_dict: Dict[str, str], nfo_root: str) -> bytes: ------- XML bytes """ - return dicttoxml.dicttoxml( - obj=nfo_dict, - root=True, - custom_root=nfo_root, - attr_type=False, - ) + xml_root = et.Element(nfo_root) + for key, value in nfo_dict.items(): + sub_element = et.SubElement(xml_root, key) + sub_element.text = value + + et.indent(tree=xml_root, space=" ", level=0) + return et.tostring(element=xml_root, encoding="utf-8", xml_declaration=True) diff --git a/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_from_ts_with_subs.json b/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_from_ts_with_subs.json index 753bc734..efcc7060 100644 --- a/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_from_ts_with_subs.json +++ b/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_from_ts_with_subs.json @@ -1,5 +1,5 @@ { "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case-thumb.jpg": "b5353a824a4800cc26f884e3025ed969", "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.mp4": "2d40822bf4c0527f9080f00357b26ce0", - "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.nfo": "0c06fe6874588209fccbd9276a446750" + "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.nfo": "b9bd35e4f260c728774d8dd31f83637c" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json b/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json index f8872a7c..32f7cda8 100644 --- a/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json +++ b/tests/e2e/resources/expected_downloads_summaries/plugins/test_chapters_sb_and_embedded_subs.json @@ -1,5 +1,5 @@ { "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case-thumb.jpg": "b5353a824a4800cc26f884e3025ed969", "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.mp4": "6f0bac1c364ff3bb13d3e8a955aaa002", - "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.nfo": "0c06fe6874588209fccbd9276a446750" + "JMC - This GPU SLIDES into this Case! - Silverstone SUGO 16 ITX Case.nfo": "b9bd35e4f260c728774d8dd31f83637c" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded.json b/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded.json index 9017f0c8..90f8b68f 100644 --- a/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded.json +++ b/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded.json @@ -1,5 +1,5 @@ { "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind-thumb.jpg": "50ee47c80f679029f5d3503bb91b045a", "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.mp4": "8562853314b75c1e47abd4f5ba97315c", - "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.nfo": "ffa10f1cbc098ace7b1c7a8fbe3097a8" + "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.nfo": "c64964fab07574080e5da3242e3bfd48" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded_and_file.json b/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded_and_file.json index 13e2fabd..a71b8498 100644 --- a/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded_and_file.json +++ b/tests/e2e/resources/expected_downloads_summaries/plugins/test_subtitles_embedded_and_file.json @@ -3,5 +3,5 @@ "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.de.srt": "b343c3bb9257b7ee7ba38f570a115b37", "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.en.srt": "fe8c6ee92cae6e059fd80fd61691adbe", "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.mp4": "8562853314b75c1e47abd4f5ba97315c", - "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.nfo": "ffa10f1cbc098ace7b1c7a8fbe3097a8" + "JMC - YouTube Rewind 2019: For the Record | #YouTubeRewind.nfo": "c64964fab07574080e5da3242e3bfd48" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json index a6367bc6..d1ae9dac 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json @@ -2,42 +2,42 @@ ".ytdl-sub-pz-download-archive.json": "f0f692ef29653ca8d0af556415bfb065", "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.e0813 - Oblivion Mod "Falcor" p.1.nfo": "2d0738094d8e649eaebbab16fd647da1", "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 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.nfo": "5c258f9e54854ef292ce3c58331da110", "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.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].nfo": "abb3ac33366cc3b86d0467c8fb80a323", "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.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].nfo": "46190954652c9d9812e061fc0c9e1d92", "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.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "30993fa8e00a0e370b4db244f3da8f7d", "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.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).nfo": "11a0e8754c414875bcd454358683da5f", "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.e0630 - Project Zombie |Fin|.nfo": "a464b9c8c48a9a5d4776436d8108f8f5", "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 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].nfo": "3562934ab9a5e802d955eda24ad355de", "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 2012/s2012.e0123 - Project Zombie |Map Trailer|.nfo": "5e810d839be90dab579400a6177f90b3", "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 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.nfo": "83772bec917bb5d71e1ca0c061c1ec78", "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg": "705ca4e0d99b37e9ecdf6bfe4b90c59b", "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.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo": "368d68db0cbe9eb4f43ece0517445e82", "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "28d852ede73b879b9ebf9a061cfc7d46", "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.en.srt": "3d2c4e7f65d2ca5e96da38ce7eecfc4e", "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", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "d9114d43d87907b2afc06eb089a8ac0a", "fanart.jpg": "129c6639b47299bc48062f0365e670ee", "poster.jpg": "5de28eea5a921a041452ab3ce1041f73", - "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" + "tvshow.nfo": "85cef9db54e9afb7af8e4912b5262d3f" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json index 042d17e3..34b1ae5e 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json @@ -2,5 +2,5 @@ ".ytdl-sub-pz-download-archive.json": "99914b932bd37a50b983c5e7c90ae93b", "fanart.jpg": "129c6639b47299bc48062f0365e670ee", "poster.jpg": "5de28eea5a921a041452ab3ce1041f73", - "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" + "tvshow.nfo": "85cef9db54e9afb7af8e4912b5262d3f" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json index 6e29c949..f2f77d53 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json @@ -2,12 +2,12 @@ ".ytdl-sub-pz-download-archive.json": "756b60d7a6c47d8163e3283404493a8d", "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg": "705ca4e0d99b37e9ecdf6bfe4b90c59b", "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.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo": "368d68db0cbe9eb4f43ece0517445e82", "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "28d852ede73b879b9ebf9a061cfc7d46", "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.en.srt": "3d2c4e7f65d2ca5e96da38ce7eecfc4e", "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", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "d9114d43d87907b2afc06eb089a8ac0a", "fanart.jpg": "129c6639b47299bc48062f0365e670ee", "poster.jpg": "5de28eea5a921a041452ab3ce1041f73", - "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" + "tvshow.nfo": "85cef9db54e9afb7af8e4912b5262d3f" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json index e3d76ee8..b8772653 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json @@ -3,8 +3,8 @@ "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "28d852ede73b879b9ebf9a061cfc7d46", "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.en.srt": "3d2c4e7f65d2ca5e96da38ce7eecfc4e", "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", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "d9114d43d87907b2afc06eb089a8ac0a", "fanart.jpg": "129c6639b47299bc48062f0365e670ee", "poster.jpg": "5de28eea5a921a041452ab3ce1041f73", - "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" + "tvshow.nfo": "85cef9db54e9afb7af8e4912b5262d3f" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json index aa26ab2f..878f5792 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json @@ -1,5 +1,5 @@ { "JMC - Jesse's Minecraft Server-thumb.jpg": "a3f1910f9c51f6442f845a528e190829", "JMC - Jesse's Minecraft Server.mkv": "21f246b1c922e11add509ea26c43c53d", - "JMC - Jesse's Minecraft Server.nfo": "10df5dcdb65ab18ecf21b3503c77e48b" + "JMC - Jesse's Minecraft Server.nfo": "d16396c60b63c06a4f2c9239553bdf61" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json index f1021c06..e00ef28a 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json @@ -2,11 +2,11 @@ ".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.1].nfo": "f8fd72bb97ed03938487494ad9094ca0", "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 - Feb.27].nfo": "6de4d997cfb300356072b4ebb09cbe38", "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" + "JMC - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "f000a6ed8caacb62a134a6ca81e3f308" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json index 6dbe5f57..82fbf921 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json @@ -6,15 +6,15 @@ "Project Zombie - 5-6.Part 4.mp4": "de9afd0b6fa5f845b086e2d4915f2f14", "Project Zombie - 6-6.Part 5.mp4": "d485c2a5df9a2d5bf9037a7a96a04d10", "Project Zombie - Intro-thumb.jpg": "fb95b510681676e81c321171fc23143e", - "Project Zombie - Intro.nfo": "ded59ac906f579312cc3cf98a57e7ea3", + "Project Zombie - Intro.nfo": "3a89bd4707e64b66a22d13bb7f81bf16", "Project Zombie - Part 1-thumb.jpg": "fb95b510681676e81c321171fc23143e", - "Project Zombie - Part 1.nfo": "70ff5cd0092b8bc22dc4db93a824789b", + "Project Zombie - Part 1.nfo": "a57a3a98d0b9db655bc4a792953ab96e", "Project Zombie - Part 2-thumb.jpg": "fb95b510681676e81c321171fc23143e", - "Project Zombie - Part 2.nfo": "54450c18a2cbb9d6d2ee5d0a1fb3f279", + "Project Zombie - Part 2.nfo": "68921dd5386fd90e2c0640127dda5dc2", "Project Zombie - Part 3-thumb.jpg": "fb95b510681676e81c321171fc23143e", - "Project Zombie - Part 3.nfo": "0effb13fc4039363a95969d1048dde57", + "Project Zombie - Part 3.nfo": "4198aec2d4cd70e4cb3946f10be205a7", "Project Zombie - Part 4-thumb.jpg": "fb95b510681676e81c321171fc23143e", - "Project Zombie - Part 4.nfo": "74bd0d7c12105469838768a0cc323a8c", + "Project Zombie - Part 4.nfo": "8a87fa99c5ba5b11cd14c592a0b97dbb", "Project Zombie - Part 5-thumb.jpg": "fb95b510681676e81c321171fc23143e", - "Project Zombie - Part 5.nfo": "a8cf2e77721335ea7c18e22734e7996c" + "Project Zombie - Part 5.nfo": "73091166bd5bd3d65d7e481e317ed128" } \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json index 379f2cf0..46ace439 100644 --- a/tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json @@ -1,5 +1,5 @@ { "JMC - Oblivion Mod "Falcor" p.1-thumb.jpg": "fb95b510681676e81c321171fc23143e", "JMC - Oblivion Mod "Falcor" p.1.mp4": "28c14cdac05c803efe71abb9454ab306", - "JMC - Oblivion Mod "Falcor" p.1.nfo": "89f509a8a3d9003e22a9091abeeae5dc" + "JMC - Oblivion Mod "Falcor" p.1.nfo": "24cc4e17d2bebc89b2759ce5471d403e" } \ No newline at end of file