gofile

Module and tool to upload files to gofile.io
git clone https://code.alwayswait.ing/gofile
Log | Files | Refs

commit c6b0018080fc594255fca99db26ece0b1c912f03
parent f62cbb4836d8e7f14eb7767513624d174fd065fd
Author: archiveanon <>
Date:   Sun, 22 Jun 2025 11:17:08 +0000

Use tqdm for fancy-cli extra

Diffstat:
Mpyproject.toml | 3+++
Msrc/gofile/cli.py | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
2 files changed, 67 insertions(+), 19 deletions(-)

diff --git a/pyproject.toml b/pyproject.toml @@ -15,6 +15,9 @@ dev = [ "mypy == 1.9.0", "ruff == 0.3.7", ] +fancy-cli = [ + "tqdm ~= 4.67", +] [build-system] build-backend = 'setuptools.build_meta' diff --git a/src/gofile/cli.py b/src/gofile/cli.py @@ -2,11 +2,45 @@ import argparse import asyncio +import contextlib import os import pathlib +import textwrap +from types import ModuleType from . import api +tqdm: ModuleType | None = None +try: + import tqdm +except ImportError: + pass + + +@contextlib.contextmanager +def file_upload_progress(file: pathlib.Path): + if not tqdm: + print(f"Uploading '{file.name}'...") + yield file.open("rb") + print(f"Closed '{file.name}'.") + return + + termsize = os.get_terminal_size() + short_file_name = textwrap.shorten( + file.name, width=int(termsize.columns * 0.6), placeholder=f"\u2026{file.suffix}" + ) + + file_size = file.stat().st_size + with tqdm.tqdm( + desc=short_file_name, + total=file_size, + unit="B", + unit_scale=True, + unit_divisor=1024, + dynamic_ncols=True, + ) as progress: + yield tqdm.utils.CallbackIOWrapper(progress.update, file.open("rb"), "read") + async def main(): # you may save and reuse a guest token @@ -66,29 +100,40 @@ async def main(): elif args.path.is_file(): files = [args.path] - uploads = api.upload_multiple( - (f.open("rb") for f in files), token=args.token, folder_id=args.folder_id - ) - - # force generator to evaluate and yield the first result - first_upload = await anext(uploads) + with contextlib.ExitStack() as stack: + first_file, *other_files = files - print(f"- Download URL: {first_upload.result.download_page}") - print(f"- Folder ID: {first_upload.result.parent_folder}") + first_upload = await api.upload_single( + stack.enter_context(file_upload_progress(first_file)), + token=args.token, + folder_id=args.folder_id, + ) - if first_upload.result.guest_token: - print(f"- Guest token: {first_upload.result.guest_token}") - - # let the rest of the uploads process - try: - async for upload in uploads: - pass - except KeyboardInterrupt: - # reprint the information in case we bail out print() - print("Cancelling upload. Resume with the following options:") + print(f"- Download URL: {first_upload.result.download_page}") print(f"- Folder ID: {first_upload.result.parent_folder}") - print(f"- Token: {first_upload.result.guest_token or args.token}") + + if first_upload.result.guest_token: + print(f"- Guest token: {first_upload.result.guest_token}") + + # let the rest of the uploads process + try: + async with asyncio.TaskGroup() as tg: + for file in other_files: + tg.create_task( + api.upload_single( + stack.enter_context(file_upload_progress(file)), + token=first_upload.result.guest_token or args.token, + folder_id=first_upload.result.parent_folder or args.folder_id, + ) + ) + except asyncio.CancelledError: + # close all file progress meters and reprint the information if we bail out + stack.close() + print() + print("Cancelling upload. Resume with the following options:") + print(f"- Folder ID: {first_upload.result.parent_folder}") + print(f"- Token: {first_upload.result.guest_token or args.token}") if __name__ == "__main__":