commit c6b0018080fc594255fca99db26ece0b1c912f03
parent f62cbb4836d8e7f14eb7767513624d174fd065fd
Author: archiveanon <>
Date: Sun, 22 Jun 2025 11:17:08 +0000
Use tqdm for fancy-cli extra
Diffstat:
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__":