[FEATURE] Add summary to console output (#515)

This commit is contained in:
Jesse Bannon 2023-03-08 15:34:58 -08:00 committed by GitHub
parent fddf3d3088
commit 91e9fe7602
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 148 additions and 2 deletions

View file

@ -28,6 +28,7 @@ packages=find:
install_requires =
yt-dlp==2023.3.4
argparse==1.4.0
colorama==0.4.6,
mergedeep==1.3.4
mediafile==0.10.1
PyYAML==6.0

View file

@ -1,4 +1,5 @@
import gc
import logging
import os
import sys
from datetime import datetime
@ -7,6 +8,7 @@ from typing import List
from typing import Optional
from typing import Tuple
from colorama import Fore
from yt_dlp.utils import sanitize_filename
from ytdl_sub.cli.download_args_parser import DownloadArgsParser
@ -209,6 +211,79 @@ def _output_transaction_log(
transaction_log_file.write(transaction_log_file_contents)
def _green(value: str) -> str:
return Fore.GREEN + value + Fore.RESET
def _red(value: str) -> str:
return Fore.RED + value + Fore.RESET
def _str_int(value: int) -> str:
if value > 0:
return f"+{value}"
if value < 0:
return f"-{value}"
return str(value)
def _color_int(value: int) -> str:
str_int = _str_int(value)
if value > 0:
return _green(str_int)
if value < 0:
return _red(str_int)
return str_int
def _output_summary(transaction_logs: List[Tuple[Subscription, FileHandlerTransactionLog]]):
summary: List[str] = []
# Initialize widths to 0
width_sub_name: int = 0
width_num_entries_added: int = 0
width_num_entries_modified: int = 0
width_num_entries_removed: int = 0
width_num_entries: int = 0
# Calculate min width needed
for subscription, _ in transaction_logs:
width_sub_name = max(width_sub_name, len(subscription.name))
width_num_entries_added = max(
width_num_entries_added, len(_str_int(subscription.num_entries_added))
)
width_num_entries_modified = max(
width_num_entries_modified, len(_str_int(subscription.num_entries_modified))
)
width_num_entries_removed = max(
width_num_entries_removed, len(_str_int(subscription.num_entries_removed * -1))
)
width_num_entries = max(width_num_entries, len(str(subscription.num_entries)))
# Add spacing for aesthetics
width_sub_name += 4
width_num_entries += 4
# Build the summary
for subscription, _ in transaction_logs:
num_entries_added = _color_int(subscription.num_entries_added)
num_entries_modified = _color_int(subscription.num_entries_modified)
num_entries_removed = _color_int(subscription.num_entries_removed * -1)
num_entries = str(subscription.num_entries)
status = _green("success")
summary.append(
f"{subscription.name:<{width_sub_name}} "
f"{num_entries_added:>{width_num_entries_added}} "
f"{num_entries_modified:>{width_num_entries_modified}} "
f"{num_entries_removed:>{width_num_entries_removed}} "
f"{num_entries:>{width_num_entries}} "
f"{status}"
)
return "\n".join(summary)
def main() -> List[Tuple[Subscription, FileHandlerTransactionLog]]:
"""
Entrypoint for ytdl-sub, without the error handling
@ -253,4 +328,7 @@ def main() -> List[Tuple[Subscription, FileHandlerTransactionLog]]:
transaction_log_file_path=args.transaction_log,
)
# Hack to always show download summary, even if logs are set to quiet
logger.log(logging.WARNING, "Download Summary:\n%s", _output_summary(transaction_logs))
return transaction_logs

View file

@ -458,7 +458,7 @@ class Downloader(DownloadArchiver, Generic[DownloaderOptionsT], ABC):
upload_date_idx = self._enhanced_download_archive.mapping.get_num_entries_with_upload_date(
upload_date_standardized=entry.upload_date_standardized
)
download_idx = self._enhanced_download_archive.mapping.get_num_entries()
download_idx = self._enhanced_download_archive.num_entries
entry.add_kwargs(
{

View file

@ -135,6 +135,42 @@ class BaseSubscription(ABC):
and self.downloader_class.supports_download_archive
)
@property
def num_entries_added(self) -> int:
"""
Returns
-------
Number of entries added
"""
return self._enhanced_download_archive.num_entries_added
@property
def num_entries_modified(self) -> int:
"""
Returns
-------
Number of entries modified
"""
return self._enhanced_download_archive.num_entries_modified
@property
def num_entries_removed(self) -> int:
"""
Returns
-------
Number of entries removed
"""
return self._enhanced_download_archive.num_entries_removed
@property
def num_entries(self) -> int:
"""
Returns
-------
The number of entries
"""
return self._enhanced_download_archive.num_entries
def as_yaml(self) -> str:
"""
Returns

View file

@ -416,7 +416,13 @@ class FileHandler:
Optional. Metadata to record to the transaction log for this file
copy_file
Optional. If True, copy the file. Move otherwise
Returns
-------
bool
True if modified. False otherwise.
"""
is_modified = False
source_file_path = Path(self.working_directory) / file_name
output_file_path = Path(self.output_directory) / output_file_name
@ -429,6 +435,7 @@ class FileHandler:
self.file_handler_transaction_log.log_modified_file(
file_name=output_file_name, file_metadata=file_metadata
)
is_modified = True
# output file does not already exist, creates a new file
else:
self.file_handler_transaction_log.log_created_file(
@ -445,6 +452,8 @@ class FileHandler:
elif self.dry_run and not copy_file:
FileHandler.delete(source_file_path)
return is_modified
def delete_file_from_output_directory(self, file_name: str):
"""
Deletes a file from the output directory. All file deletions should use this function

View file

@ -363,6 +363,19 @@ class EnhancedDownloadArchive:
self._logger = Logger.get(name=subscription_name)
self.num_entries_added: int = 0
self.num_entries_modified: int = 0
self.num_entries_removed: int = 0
@property
def num_entries(self) -> int:
"""
Returns
-------
Total number of entries in the mapping
"""
return self.mapping.get_num_entries()
def reinitialize(self, dry_run: bool) -> "EnhancedDownloadArchive":
"""
Re-initialize the enhanced download archive for successive downloads w/the same
@ -544,6 +557,7 @@ class EnhancedDownloadArchive:
self._file_handler.delete_file_from_output_directory(file_name=file_name)
self.mapping.remove_entry(entry_id=uid)
self.num_entries_removed += 1
return self
@ -600,13 +614,21 @@ class EnhancedDownloadArchive:
elif entry:
self.mapping.add_entry(entry=entry, entry_file_path=output_file_name)
self._file_handler.move_file_to_output_directory(
is_modified = self._file_handler.move_file_to_output_directory(
file_name=file_name,
file_metadata=file_metadata,
output_file_name=output_file_name,
copy_file=copy_file,
)
# Determine if it's the entry file by seeing if the file_name to move matches the entry
# download file name
is_entry_file = entry and entry.get_download_file_name() == file_name
if is_entry_file and is_modified:
self.num_entries_modified += 1
elif is_entry_file:
self.num_entries_added += 1
def get_file_handler_transaction_log(self) -> FileHandlerTransactionLog:
"""
Returns