Skip to content

Commit

Permalink
[DEV] Refactor entrypoint file (#765)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbannon authored Oct 19, 2023
1 parent a7651b2 commit 1cb70e4
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 137 deletions.
126 changes: 8 additions & 118 deletions src/ytdl_sub/cli/main.py → src/ytdl_sub/cli/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
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
from ytdl_sub.cli.main_args_parser import DEFAULT_CONFIG_FILE_NAME
from ytdl_sub.cli.main_args_parser import parser
from ytdl_sub.cli.output_summary import output_summary
from ytdl_sub.cli.output_transaction_log import _maybe_validate_transaction_log_file
from ytdl_sub.cli.output_transaction_log import output_transaction_log
from ytdl_sub.cli.parsers.dl import DownloadArgsParser
from ytdl_sub.cli.parsers.main import DEFAULT_CONFIG_FILE_NAME
from ytdl_sub.cli.parsers.main import parser
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.exceptions import ExperimentalFeatureNotEnabled
Expand Down Expand Up @@ -181,117 +183,6 @@ def _view_url_from_cli(
return subscription, subscription.download(dry_run=True)


def _maybe_validate_transaction_log_file(transaction_log_file_path: Optional[str]) -> None:
if transaction_log_file_path:
try:
with open(transaction_log_file_path, "w", encoding="utf-8"):
pass
except Exception as exc:
raise ValidationException(
f"Transaction log file '{transaction_log_file_path}' cannot be written to. "
f"Reason: {str(exc)}"
) from exc


def _output_transaction_log(
transaction_logs: List[Tuple[Subscription, FileHandlerTransactionLog]],
transaction_log_file_path: str,
) -> None:
transaction_log_file_contents = ""
for subscription, transaction_log in transaction_logs:
if transaction_log.is_empty:
transaction_log_contents = f"\nNo files changed for {subscription.name}"
else:
transaction_log_contents = (
f"Transaction log for {subscription.name}:\n"
f"{transaction_log.to_output_message(subscription.output_directory)}"
)

if transaction_log_file_path:
transaction_log_file_contents += transaction_log_contents
else:
logger.info(transaction_log_contents)

if transaction_log_file_contents:
with open(transaction_log_file_path, "w", encoding="utf-8") as transaction_log_file:
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 _no_color(value: str) -> str:
return Fore.RESET + value + Fore.RESET


def _str_int(value: int) -> str:
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 _no_color(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(_color_int(subscription.num_entries_added))
)
width_num_entries_modified = max(
width_num_entries_modified, len(_color_int(subscription.num_entries_modified))
)
width_num_entries_removed = max(
width_num_entries_removed, len(_color_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
Expand Down Expand Up @@ -353,12 +244,11 @@ def main() -> List[Tuple[Subscription, FileHandlerTransactionLog]]:
raise ValidationException("Must provide one of the commands: sub, dl, view")

if not args.suppress_transaction_log:
_output_transaction_log(
output_transaction_log(
transaction_logs=transaction_logs,
transaction_log_file_path=args.transaction_log,
)

# Hack to always show download summary, even if logs are set to quiet
logger.warning("Download Summary:\n%s", _output_summary(transaction_logs))
output_summary(transaction_logs)

return transaction_logs
96 changes: 96 additions & 0 deletions src/ytdl_sub/cli/output_summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from typing import List
from typing import Tuple

from colorama import Fore

from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
from ytdl_sub.utils.logger import Logger

logger = Logger.get()


def _green(value: str) -> str:
return Fore.GREEN + value + Fore.RESET


def _red(value: str) -> str:
return Fore.RED + value + Fore.RESET


def _no_color(value: str) -> str:
return Fore.RESET + value + Fore.RESET


def _str_int(value: int) -> str:
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 _no_color(str_int)


def output_summary(transaction_logs: List[Tuple[Subscription, FileHandlerTransactionLog]]) -> str:
"""
Parameters
----------
transaction_logs
Transaction logs from downloaded subscriptions
Returns
-------
Output summary to print
"""
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(_color_int(subscription.num_entries_added))
)
width_num_entries_modified = max(
width_num_entries_modified, len(_color_int(subscription.num_entries_modified))
)
width_num_entries_removed = max(
width_num_entries_removed, len(_color_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}"
)

# Hack to always show download summary, even if logs are set to quiet
logger.warning("Download Summary:\n%s", "\n".join(summary))
56 changes: 56 additions & 0 deletions src/ytdl_sub/cli/output_transaction_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from typing import List
from typing import Optional
from typing import Tuple

from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
from ytdl_sub.utils.logger import Logger

logger = Logger.get()


def _maybe_validate_transaction_log_file(transaction_log_file_path: Optional[str]) -> None:
if transaction_log_file_path:
try:
with open(transaction_log_file_path, "w", encoding="utf-8"):
pass
except Exception as exc:
raise ValidationException(
f"Transaction log file '{transaction_log_file_path}' cannot be written to. "
f"Reason: {str(exc)}"
) from exc


def output_transaction_log(
transaction_logs: List[Tuple[Subscription, FileHandlerTransactionLog]],
transaction_log_file_path: Optional[str],
) -> None:
"""
Maybe print and/or write transaction logs to a file
Parameters
----------
transaction_logs
The transaction logs from downloaded subscriptions
transaction_log_file_path
Optional file path to write to
"""
transaction_log_file_contents = ""
for subscription, transaction_log in transaction_logs:
if transaction_log.is_empty:
transaction_log_contents = f"\nNo files changed for {subscription.name}"
else:
transaction_log_contents = (
f"Transaction log for {subscription.name}:\n"
f"{transaction_log.to_output_message(subscription.output_directory)}"
)

if transaction_log_file_path:
transaction_log_file_contents += transaction_log_contents
else:
logger.info(transaction_log_contents)

if transaction_log_file_contents:
with open(transaction_log_file_path, "w", encoding="utf-8") as transaction_log_file:
transaction_log_file.write(transaction_log_file_contents)
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from mergedeep import mergedeep

from ytdl_sub.cli.main_args_parser import MainArguments
from ytdl_sub.cli.parsers.main import MainArguments
from ytdl_sub.config.config_validator import ConfigOptions
from ytdl_sub.utils.exceptions import InvalidDlArguments

Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions src/ytdl_sub/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sys

from ytdl_sub.cli.main_args_parser import parser
from ytdl_sub.cli.parsers.main import parser
from ytdl_sub.utils.logger import Logger


Expand All @@ -11,11 +11,11 @@ def _main():
Logger.set_log_level(log_level_name=args.ytdl_sub_log_level)

# pylint: disable=import-outside-toplevel
import ytdl_sub.cli.main
import ytdl_sub.cli.entrypoint

# pylint: enable=import-outside-toplevel

ytdl_sub.cli.main.main()
ytdl_sub.cli.entrypoint.main()


def main():
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import pytest

from ytdl_sub.cli.main import main
from ytdl_sub.cli.entrypoint import main
from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/cli/test_download_args_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

import pytest

from ytdl_sub.cli.download_args_parser import DownloadArgsParser
from ytdl_sub.cli.main_args_parser import MainArguments
from ytdl_sub.cli.main_args_parser import parser
from ytdl_sub.cli.parsers.dl import DownloadArgsParser
from ytdl_sub.cli.parsers.main import MainArguments
from ytdl_sub.cli.parsers.main import parser
from ytdl_sub.config.config_validator import ConfigOptions
from ytdl_sub.utils.exceptions import InvalidDlArguments

Expand Down
Loading

0 comments on commit 1cb70e4

Please sign in to comment.