diff --git a/prismedia/pt_upload.py b/prismedia/pt_upload.py index 7c779ad..6b43151 100644 --- a/prismedia/pt_upload.py +++ b/prismedia/pt_upload.py @@ -14,7 +14,8 @@ from tzlocal import get_localzone from configparser import RawConfigParser from requests_oauthlib import OAuth2Session from oauthlib.oauth2 import LegacyApplicationClient -from requests_toolbelt.multipart.encoder import MultipartEncoder +from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor +from clint.textui.progress import Bar as ProgressBar from . import utils logger = logging.getLogger('Prismedia') @@ -303,7 +304,12 @@ def upload_video(oauth, secret, options): if options.get('--url-only') or options.get('--batch'): logger_stdout = logging.getLogger('stdoutlogs') - multipart_data = MultipartEncoder(fields) + encoder = MultipartEncoder(fields) + if options.get('--quiet'): + multipart_data = encoder + else: + progress_callback = create_callback(encoder, options.get('--progress')) + multipart_data = MultipartEncoderMonitor(encoder, progress_callback) headers = { 'Content-Type': multipart_data.content_type @@ -311,12 +317,14 @@ def upload_video(oauth, secret, options): response = oauth.post(url + "/api/v1/videos/upload", data=multipart_data, headers=headers) + if response is not None: if response.status_code == 200: jresponse = response.json() jresponse = jresponse['video'] uuid = jresponse['uuid'] video_id = str(jresponse['id']) + logger.info('Peertube: Video was successfully uploaded.') template = 'Peertube: Watch it at %s/videos/watch/%s.' logger.info(template % (url, uuid)) @@ -334,6 +342,42 @@ def upload_video(oauth, secret, options): exit(1) +upload_finished = False +def create_callback(encoder, progress_type): + upload_size_MB = encoder.len * (1 / (1024 * 1024)) + + if progress_type is None or "percentage" in progress_type.lower(): + progress_lambda = lambda x: int((x / encoder.len) * 100) # Default to percentage + elif "bigfile" in progress_type.lower(): + progress_lambda = lambda x: x * (1 / (1024 * 1024)) # MB + elif "accurate" in progress_type.lower(): + progress_lambda = lambda x: x * (1 / (1024)) # kB + else: + # Should not happen outside of development when adding partly a progress type + logger.critical("Peertube: Unknown progress type `" + progress_type + "`") + exit(1) + + bar = ProgressBar(expected_size=progress_lambda(encoder.len), label=f"Peertube upload progress ({upload_size_MB:.2f}MB) ", filled_char='=') + + def callback(monitor): + # We want the condition to capture the varible from the parent scope, not a local variable that is created after + global upload_finished + progress = progress_lambda(monitor.bytes_read) + + bar.show(progress) + + if monitor.bytes_read == encoder.len: + if not upload_finished: + # We get two time in the callback with both bytes equals, skip the first + upload_finished = True + else: + # Print a blank line to not (partly) override the progress bar + print() + logger.info("PeertubeĀ : Upload finish, Processingā€¦") + + return callback + + def run(options): secret = RawConfigParser() try: diff --git a/prismedia/upload.py b/prismedia/upload.py index ea907ee..94ca61d 100755 --- a/prismedia/upload.py +++ b/prismedia/upload.py @@ -49,6 +49,7 @@ Options: If the playlist is not found, spawn an error except if --playlistCreate is set. --playlistCreate Create the playlist if not exists. (default do not create) Only relevant if --playlist is set. + --progress=STRING Set the progress bar view, one of percentage, bigFile, accurate. -h --help Show this help. --version Show version. @@ -150,6 +151,7 @@ VALID_LANGUAGES = ('arabic', 'english', 'french', 'german', 'hindi', 'italian', 'japanese', 'korean', 'mandarin', 'portuguese', 'punjabi', 'russian', 'spanish') +VALID_PROGRESS = ('percentage', 'bigfile', 'accurate') def validateVideo(path): @@ -235,6 +237,14 @@ def validateLogLevel(loglevel): return True +def validateProgress(progress): + for prgs in progress.split(','): + if prgs.lower().replace(" ", "") not in VALID_PROGRESS: + return False + + return True + + def _optionnalOrStrict(key, scope, error): option = key.replace('-', '') option = option[0].upper() + option[1:] @@ -385,6 +395,7 @@ def main(): Optional('--channelCreate'): bool, Optional('--playlist'): Or(None, str), Optional('--playlistCreate'): bool, + Optional('--progress'): Or(None, And(str, validateProgress, error="Sorry, progress visualisation not supported")), '--help': bool, '--version': bool, # This allow to return all other options for further use: https://github.com/keleshev/schema#extra-keys diff --git a/prismedia/utils.py b/prismedia/utils.py index fcea677..86d4a33 100644 --- a/prismedia/utils.py +++ b/prismedia/utils.py @@ -166,8 +166,8 @@ def parseNFO(options): elif isfile(video_directory + "/" + "NFO.txt"): nfo_txt = loadNFO(video_directory + "/" + "NFO.txt") - if isfile(video_directory + "/" + directory_name+ ".txt"): - nfo_directory = loadNFO(video_directory + "/" + directory_name+ ".txt") + if isfile(video_directory + "/" + directory_name + ".txt"): + nfo_directory = loadNFO(video_directory + "/" + directory_name + ".txt") if options.get('--name'): if isfile(video_directory + "/" + options.get('--name')): diff --git a/pyproject.toml b/pyproject.toml index 75186f0..bfd8876 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ keywords = ['peertube', 'youtube', 'prismedia'] [tool.poetry.dependencies] python = ">=3.5" +clint = "^0.5.1" configparser = "^3.7.1" docopt = "^0.6.2" future = "^0.17.1" @@ -46,4 +47,3 @@ prismedia = 'prismedia.upload:main' [build-system] requires = ["poetry>=0.12"] build-backend = "poetry.masonry.api" - diff --git a/requirements.txt b/requirements.txt index 59546a1..be9ff52 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ certifi==2020.4.5.1 \ chardet==3.0.4 \ --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 \ --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae +clint==0.5.1 configparser==3.8.1 \ --hash=sha256:45d1272aad6cfd7a8a06cf5c73f2ceb6a190f6acc1fa707e7f82a4c053b28b18 \ --hash=sha256:bc37850f0cc42a1725a796ef7d92690651bf1af37d744cc63161dac62cabee17