[FEATURE] Add summary to console output (#515)
This commit is contained in:
parent
fddf3d3088
commit
91e9fe7602
6 changed files with 148 additions and 2 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue