From f4e1df3d067931103f55a7a214d41060db092df3 Mon Sep 17 00:00:00 2001 From: StefanGreve Date: Sat, 22 Jul 2023 11:22:34 +0300 Subject: [PATCH 1/7] Update changelog: add PR references and config path fix --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86b6bce..118b657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,11 @@ ## Version 1.0.0 (2023-7-18) -- drops support for Python 3.7 and makes 3.8 the new baseline for further development -- updates all dependencies -- adds `size_readable` property to `ParseResponse` -- improves the testing methodology of the library +- drops support for Python 3.7 and makes 3.8 the new baseline for further development (PR #81) +- updates all dependencies (PR #81, #84) +- adds `size_readable` property to `ParseResponse` (PR #80) +- improves the testing methodology of the library (PR #77) +- fixes a bug in which the config directory was set incorrectly on FreeBSD (PR #85) ## Version 0.2.7 (2021-9-12) From ef716c24c259a34203688362470e426cd8dba655 Mon Sep 17 00:00:00 2001 From: StefanGreve Date: Sat, 22 Jul 2023 11:51:41 +0300 Subject: [PATCH 2/7] Refactor code in CLI preview command * note that printing json.dumps produces better results than pprint because pprint does not break the line after opening curly brackets; on the internet some people suggested the width=1 trick but I found that didn't work with newer versions of Python. It's also quite hacky as this solution depends on implementation details --- src/anonfile/__init__.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/anonfile/__init__.py b/src/anonfile/__init__.py index 2b654f1..47592c7 100644 --- a/src/anonfile/__init__.py +++ b/src/anonfile/__init__.py @@ -2,8 +2,9 @@ from __future__ import annotations -import argparse +import json import sys +from argparse import ArgumentParser from collections import namedtuple from distutils.util import strtobool from pathlib import Path @@ -13,25 +14,19 @@ from .anonfile import __version__ -def __print_dict(dictionary: dict, indent: int = 4) -> None: - print("{\n%s\n}" % '\n'.join([f"\033[36m{indent * ' '}{key}\033[0m: \033[32m{value}\033[0m" for key, value in dictionary.items()])) - - def __from_file(path: Path) -> List[str]: with open(path, mode='r', encoding='utf-8') as file_handler: return [line.rstrip() for line in file_handler.readlines() if line[0] != '#'] - def format_proxies(proxies: str) -> dict: return {prot: f"{prot}://{ip}" for (prot, ip) in [proxy.split('://') for proxy in proxies.split()]} - -def main(): - parser = argparse.ArgumentParser(prog=package_name) +def build_parser(package_name: str, version: str) -> ArgumentParser: + parser = ArgumentParser(prog=package_name) parser._positionals.title = 'Commands' parser._optionals.title = 'Arguments' - parser.add_argument('-v', '--version', action='version', version=f"%(prog)s {__version__}") + parser.add_argument('-v', '--version', action='version', version=f"%(prog)s {version}") parser.add_argument('-V', '--verbose', default=True, action='store_true', help="increase output verbosity (default)") parser.add_argument('--no-verbose', dest='verbose', action='store_false', help="run commands silently") parser.add_argument('-l', '--logging', default=True, action='store_true', help="enable URL logging (default)") @@ -59,6 +54,11 @@ def main(): log_parser.add_argument('--path', action='store_true', help="return the log file path") log_parser.add_argument('--read', action='store_true', help='read the log file') + return parser + +def main(): + parser = build_parser(package_name, __version__) + try: args = parser.parse_args() anon = AnonFile(args.token, user_agent=args.user_agent, proxies=format_proxies(args.proxies) if args.proxies else None) @@ -77,19 +77,23 @@ def main(): if args.command == 'preview': for url in args.url: preview = anon.preview(url) - values = ['online' if preview.status else 'offline', preview.file_path.name, preview.url.geturl(), preview.ddl.geturl(), preview.id, f"{preview.size_readable}"] + response = { + 'Status': 'online' if preview.status else 'offline', + 'File Path': preview.file_path.name, + 'URL': preview.url.geturl(), + 'DDL': preview.ddl.geturl(), + 'ID': preview.id, + 'Size': preview.size_readable, + } - if args.verbose: - __print_dict(dict(zip(['Status', 'File Path', 'URL', 'DDL', 'ID', 'Size'], values))) - else: - print(','.join(values)) + print(json.dumps(response, indent=4) if args.verbose else ','.join(response)) if args.command == 'download': for url in (args.url or __from_file(args.batch_file)): download = lambda url: anon.download(url, args.path, progressbar=args.verbose, enable_logging=args.logging) if args.check and anon.preview(url, args.path).file_path.exists(): - print(f"\033[33mWarning:\033[0m A file with the same name already exists in {str(args.path)!r}.") + print(f"Warning: A file with the same name already exists in {str(args.path)!r}.") choice = input("Proceed with download? [Y/n] ") if choice == '' or strtobool(choice): print(f"File: {download(url).file_path}") From 16481880543167fe22a2ad259568e705b1368ba2 Mon Sep 17 00:00:00 2001 From: StefanGreve Date: Sat, 22 Jul 2023 12:10:34 +0300 Subject: [PATCH 3/7] Implement str2bool * as of Python 3.10, distutils has been deprecated * in Python 3.12, distutils will no longer be installed by make install or any of the first-party distribution --- src/anonfile/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/anonfile/__init__.py b/src/anonfile/__init__.py index 47592c7..a61957b 100644 --- a/src/anonfile/__init__.py +++ b/src/anonfile/__init__.py @@ -6,13 +6,14 @@ import sys from argparse import ArgumentParser from collections import namedtuple -from distutils.util import strtobool from pathlib import Path from typing import List from .anonfile import * from .anonfile import __version__ +def str2bool(val: str) -> bool: + return val in ('yes', 'y', 'true', 't', '1', 'on', '') def __from_file(path: Path) -> List[str]: with open(path, mode='r', encoding='utf-8') as file_handler: @@ -94,8 +95,8 @@ def main(): if args.check and anon.preview(url, args.path).file_path.exists(): print(f"Warning: A file with the same name already exists in {str(args.path)!r}.") - choice = input("Proceed with download? [Y/n] ") - if choice == '' or strtobool(choice): + prompt = input("Proceed with download? [Y/n] ") + if str2bool(prompt): print(f"File: {download(url).file_path}") else: print(f"File: {download(url).file_path}") From b8011fdc8752b63e8d05cef51de0bdd391685a04 Mon Sep 17 00:00:00 2001 From: StefanGreve Date: Sat, 22 Jul 2023 12:21:30 +0300 Subject: [PATCH 4/7] Update changelog: refactor CLI code --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 118b657..92fc7ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - adds `size_readable` property to `ParseResponse` (PR #80) - improves the testing methodology of the library (PR #77) - fixes a bug in which the config directory was set incorrectly on FreeBSD (PR #85) +- refactors and future proofs CLI code (PR #89) ## Version 0.2.7 (2021-9-12) From 29546894d0989a7198526a17a84aef5d3aa52149 Mon Sep 17 00:00:00 2001 From: StefanGreve Date: Sat, 22 Jul 2023 12:41:59 +0300 Subject: [PATCH 5/7] Small bug fix: output values in non-verbose mode in preview command --- src/anonfile/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/anonfile/__init__.py b/src/anonfile/__init__.py index a61957b..e4c480a 100644 --- a/src/anonfile/__init__.py +++ b/src/anonfile/__init__.py @@ -10,7 +10,8 @@ from typing import List from .anonfile import * -from .anonfile import __version__ +from .anonfile import __version__, package_name + def str2bool(val: str) -> bool: return val in ('yes', 'y', 'true', 't', '1', 'on', '') @@ -87,7 +88,7 @@ def main(): 'Size': preview.size_readable, } - print(json.dumps(response, indent=4) if args.verbose else ','.join(response)) + print(json.dumps(response, indent=4) if args.verbose else ','.join(response.values)) if args.command == 'download': for url in (args.url or __from_file(args.batch_file)): From 978d73065a060160dbcdb6f0b43b4c3c3a30e419 Mon Sep 17 00:00:00 2001 From: StefanGreve Date: Sat, 22 Jul 2023 12:52:29 +0300 Subject: [PATCH 6/7] Make str2bool case-insensitive --- src/anonfile/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anonfile/__init__.py b/src/anonfile/__init__.py index e4c480a..49c2b9d 100644 --- a/src/anonfile/__init__.py +++ b/src/anonfile/__init__.py @@ -14,7 +14,7 @@ def str2bool(val: str) -> bool: - return val in ('yes', 'y', 'true', 't', '1', 'on', '') + return val.lower() in ('yes', 'y', 'true', 't', '1', 'on', '') def __from_file(path: Path) -> List[str]: with open(path, mode='r', encoding='utf-8') as file_handler: From b7943f948d9d4c13e759a3e50ad6e1687856bbe1 Mon Sep 17 00:00:00 2001 From: StefanGreve Date: Sat, 22 Jul 2023 13:40:08 +0300 Subject: [PATCH 7/7] Update sample code for downloading files --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 65c9634..3e70589 100644 --- a/README.md +++ b/README.md @@ -72,15 +72,15 @@ from anonfile import AnonFile anon = AnonFile() -# upload a file and enable progressbar terminal feedback +# upload a file and enable progressbar terminal feedback (off by default) upload = anon.upload('/home/guest/jims_paperwork.doc', progressbar=True) print(upload.url.geturl()) # download a file and set the download directory from pathlib import Path target_dir = Path.home().joinpath('Downloads') -filename = anon.download("https://anonfiles.com/9ee1jcu6u9/test_txt", path=target_dir) -print(filename) +download = anon.download("https://anonfiles.com/9ee1jcu6u9/test_txt", path=target_dir) +print(download.file_path) ``` And voilĂ , pain-free anonymous file sharing. If you want more information about