From f16c0ee73abff334c969aa074f3d19d0adafb37a Mon Sep 17 00:00:00 2001 From: taizan-hokuto <55448286+taizan-hokuto@users.noreply.github.com> Date: Wed, 9 Sep 2020 22:19:10 +0900 Subject: [PATCH 1/3] Fix progress bar line feed and remove pbar option --- pytchat/cli/__init__.py | 33 ++++--------- pytchat/cli/arguments.py | 4 +- .../{progressbar_rich.py => progressbar.py} | 8 ++- pytchat/cli/progressbar_simple.py | 49 ------------------- 4 files changed, 18 insertions(+), 76 deletions(-) rename pytchat/cli/{progressbar_rich.py => progressbar.py} (86%) delete mode 100644 pytchat/cli/progressbar_simple.py diff --git a/pytchat/cli/__init__.py b/pytchat/cli/__init__.py index a448e74..edcb818 100644 --- a/pytchat/cli/__init__.py +++ b/pytchat/cli/__init__.py @@ -1,11 +1,11 @@ import argparse import os -import sys import signal from json.decoder import JSONDecodeError from pathlib import Path from .arguments import Arguments +from .progressbar import ProgressBar from .. exceptions import InvalidVideoIdException, NoContents, PatternUnmatchError from .. processors.html_archiver import HTMLArchiver from .. tool.extract.extractor import Extractor @@ -32,18 +32,12 @@ def main(): 'If ID starts with a hyphen (-), enclose the ID in square brackets.') parser.add_argument('-o', f'--{Arguments.Name.OUTPUT}', type=str, help='Output directory (end with "/"). default="./"', default='./') - parser.add_argument(f'--{Arguments.Name.PBAR}', action='store_true', - help='Display rich progress bar') parser.add_argument(f'--{Arguments.Name.SAVE_ERROR_DATA}', action='store_true', help='Save error data when error occurs(".dat" file)') parser.add_argument(f'--{Arguments.Name.VERSION}', action='store_true', help='Show version') Arguments(parser.parse_args().__dict__) - if Arguments().pbar: - from .progressbar_rich import ProgressBar - else: - from .progressbar_simple import ProgressBar if Arguments().print_version: print(f'pytchat v{__version__} © 2019 taizan-hokuto') return @@ -52,7 +46,7 @@ def main(): if not Arguments().video_ids: parser.print_help() return - for video_id in Arguments().video_ids: + for counter, video_id in enumerate(Arguments().video_ids): if '[' in video_id: video_id = video_id.replace('[', '').replace(']', '') try: @@ -62,7 +56,9 @@ def main(): else: raise FileNotFoundError info = VideoInfo(video_id) - print(f"Extracting...\n" + if len(Arguments().video_ids) > 1: + print(f"\n{'-' * 10} video:{counter + 1} of {len(Arguments().video_ids)} {'-' * 10}") + print(f"\n" f" video_id: {video_id}\n" f" channel: {info.get_channel_name()}\n" f" title: {info.get_title()}") @@ -70,17 +66,14 @@ def main(): print(f" output path: {path.resolve()}") duration = info.get_duration() pbar = ProgressBar(total=(duration * 1000), status="Extracting") - ex = Extractor(video_id, + ex = Extractor(video_id, callback=pbar._disp, div=10) signal.signal(signal.SIGINT, (lambda a, b: cancel(ex, pbar))) data = ex.extract() if data == []: return False - if Arguments().pbar: - pbar.reset("#", "=", total=len(data), status="Rendering ") - else: - pbar.reset("=", "", total=len(data), status="Rendering ") + pbar.reset("#", "=", total=len(data), status="Rendering ") processor = HTMLArchiver(Arguments().output + video_id + '.html', callback=pbar._disp) processor.process( [{'video_id': None, @@ -88,18 +81,12 @@ def main(): 'chatdata': (action["replayChatItemAction"]["actions"][0] for action in data)}] ) processor.finalize() - if Arguments().pbar: - pbar.reset('#', '#', status='Completed ') - pbar.close() - else: - pbar.close() - print("\nCompleted") - + pbar.reset('#', '#', status='Completed ') + pbar.close() print() if pbar.is_cancelled(): print("\nThe extraction process has been discontinued.\n") - return False - return True + except InvalidVideoIdException: print("Invalid Video ID or URL:", video_id) diff --git a/pytchat/cli/arguments.py b/pytchat/cli/arguments.py index e22b293..0a5ce73 100644 --- a/pytchat/cli/arguments.py +++ b/pytchat/cli/arguments.py @@ -19,7 +19,7 @@ class Arguments(metaclass=Singleton): OUTPUT: str = 'output_dir' VIDEO_IDS: str = 'video_id' SAVE_ERROR_DATA: bool = 'save_error_data' - PBAR: bool ='pbar' + PBAR: bool = 'pbar' def __init__(self, arguments: Optional[Dict[str, Union[str, bool, int]]] = None): @@ -37,7 +37,7 @@ class Arguments(metaclass=Singleton): self.output: str = arguments[Arguments.Name.OUTPUT] self.video_ids: List[int] = [] self.save_error_data: bool = arguments[Arguments.Name.SAVE_ERROR_DATA] - self.pbar: bool = arguments[Arguments.Name.PBAR] + # Videos if arguments[Arguments.Name.VIDEO_IDS]: self.video_ids = [video_id diff --git a/pytchat/cli/progressbar_rich.py b/pytchat/cli/progressbar.py similarity index 86% rename from pytchat/cli/progressbar_rich.py rename to pytchat/cli/progressbar.py index 65ca9b0..297119f 100644 --- a/pytchat/cli/progressbar_rich.py +++ b/pytchat/cli/progressbar.py @@ -4,6 +4,7 @@ vladignatyev/progress.py https://gist.github.com/vladignatyev/06860ec2040cb497f0f3 (MIT License) ''' +import shutil import sys @@ -13,8 +14,9 @@ class ProgressBar: self._cancelled = False self.reset(total=total, status=status) self._blinker = 0 - + def reset(self, symbol_done="=", symbol_space=" ", total=100, status=''): + self.con_width = shutil.get_terminal_size(fallback=(80, 24)).columns self._symbol_done = symbol_done self._symbol_space = symbol_space self._total = total @@ -37,7 +39,9 @@ class ProgressBar: bar = self._symbol_done * filled_len + \ self._symbol_space * (self._bar_len - filled_len) - sys.stdout.write(' [%s] %s%s ...%s \r' % (bar, percents, '%', self._status)) + disp = f" [{bar}] {percents:>5.1f}% ...{self._status} "[:self.con_width - 1] + '\r' + + sys.stdout.write(disp) sys.stdout.flush() self._blinker += 1 diff --git a/pytchat/cli/progressbar_simple.py b/pytchat/cli/progressbar_simple.py deleted file mode 100644 index 776fad2..0000000 --- a/pytchat/cli/progressbar_simple.py +++ /dev/null @@ -1,49 +0,0 @@ -''' -This code for this progress bar is based on -vladignatyev/progress.py -https://gist.github.com/vladignatyev/06860ec2040cb497f0f3 -(MIT License) -''' -import sys - - -class ProgressBar: - def __init__(self, total, status): - self._bar_len = 60 - self._cancelled = False - print(''.join([' ' * 10, '|', '-' * (self._bar_len), '|']), end="") - self.reset(total=total, status=status) - - def reset(self, symbol_done="=", symbol_space=" ", total=100, status=''): - self._symbol_done = symbol_done - self._symbol_space = symbol_space - self._total = total - self._status = status - self._old_len = 0 - self._count = 0 - print() - print(f'{status:<11}', end='') - - def _disp(self, _, fetched): - self._progress(fetched, self._total) - - def _progress(self, fillin, total): - if total == 0 or self._cancelled: - return - self._count += fillin - filled_len = int(round(self._bar_len * self._count / float(total))) - if filled_len > self._bar_len: - filled_len = self._bar_len - print((filled_len - self._old_len) * self._symbol_done, end="") - sys.stdout.flush() - self._old_len = filled_len - - def close(self): - if not self._cancelled: - self._progress(self._total, self._total) - - def cancel(self): - self._cancelled = True - - def is_cancelled(self): - return self._cancelled From 2e05803d758965dc824a5dbc8e7453594d1348e3 Mon Sep 17 00:00:00 2001 From: taizan-hokuto <55448286+taizan-hokuto@users.noreply.github.com> Date: Wed, 9 Sep 2020 22:20:09 +0900 Subject: [PATCH 2/3] Remove unnecessary option --- pytchat/cli/arguments.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pytchat/cli/arguments.py b/pytchat/cli/arguments.py index 0a5ce73..0e1baf4 100644 --- a/pytchat/cli/arguments.py +++ b/pytchat/cli/arguments.py @@ -19,7 +19,6 @@ class Arguments(metaclass=Singleton): OUTPUT: str = 'output_dir' VIDEO_IDS: str = 'video_id' SAVE_ERROR_DATA: bool = 'save_error_data' - PBAR: bool = 'pbar' def __init__(self, arguments: Optional[Dict[str, Union[str, bool, int]]] = None): From eb29f274930828c7e15a2d98c316008ff46b2d69 Mon Sep 17 00:00:00 2001 From: taizan-hokuto <55448286+taizan-hokuto@users.noreply.github.com> Date: Wed, 9 Sep 2020 22:22:31 +0900 Subject: [PATCH 3/3] Increment version --- pytchat/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytchat/__init__.py b/pytchat/__init__.py index 161568c..df35478 100644 --- a/pytchat/__init__.py +++ b/pytchat/__init__.py @@ -2,7 +2,7 @@ pytchat is a lightweight python library to browse youtube livechat without Selenium or BeautifulSoup. """ __copyright__ = 'Copyright (C) 2019 taizan-hokuto' -__version__ = '0.2.0' +__version__ = '0.2.1' __license__ = 'MIT' __author__ = 'taizan-hokuto' __author_email__ = '55448286+taizan-hokuto@users.noreply.github.com'