From 3407848597372ded947bde5baf024a378ff53d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Tue, 15 Oct 2019 21:08:41 +0200 Subject: [PATCH] refactor: Add deprecation warnings, improve logging --- src/aria2p/api.py | 17 ++++++++-- src/aria2p/cli.py | 72 ++++++++++++++++------------------------- src/aria2p/client.py | 4 +++ src/aria2p/interface.py | 7 ++-- tests/test_cli.py | 7 ++-- 5 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/aria2p/api.py b/src/aria2p/api.py index f19a5ea..0afa2a3 100644 --- a/src/aria2p/api.py +++ b/src/aria2p/api.py @@ -13,6 +13,7 @@ from .downloads import Download from .options import Options from .stats import Stats +from .utils import get_version class API: @@ -38,6 +39,9 @@ def __init__(self, client=None): self.client = client self.listener = None + def __repr__(self): + return f"API({self.client!r})" + def add_magnet(self, magnet_uri, options=None, position=None): """ Add a download with a Magnet URI. @@ -462,6 +466,9 @@ def autopurge(self): Returns: bool: Success or failure of the operation. """ + version = get_version() + if version.major == 0 and 9 > version.minor >= 7: + logger.warning("Future change warning: API method 'autopurge' will be renamed 'purge' in version 0.9.0.") return self.client.purge_download_result() def purge(self, downloads): @@ -472,14 +479,17 @@ def purge(self, downloads): list of bool: Success or failure of the operation for each download. """ # TODO: batch/multicall candidate + logger.warning( + "Deprecation warning: API method 'purge' is deprecated in favor of method 'remove', " + "and will be removed in version 0.7.0." + ) result = [] for download in downloads: try: self.client.remove_download_result(download.gid) except ClientException as error: - logger.debug(f"Failed to purge download result {download.gid}") - logger.opt(exception=True).trace(error) + logger.exception(error) result.append(error) else: result.append(True) @@ -493,6 +503,9 @@ def purge_all(self): Returns: bool: Success or failure of the operation to purge all downloads. """ + logger.warning( + "Deprecation warning: API method 'purge_all' is deprecated, and will be removed in version 0.7.0." + ) return all(self.purge(self.get_downloads())) def get_options(self, downloads): diff --git a/src/aria2p/cli.py b/src/aria2p/cli.py index 7d9d126..fe5794b 100644 --- a/src/aria2p/cli.py +++ b/src/aria2p/cli.py @@ -29,6 +29,7 @@ from .api import API from .client import DEFAULT_HOST, DEFAULT_PORT, Client, ClientException from .interface import Interface +from .utils import get_version # ============ MAIN FUNCTION ============ # @@ -47,6 +48,8 @@ def main(args=None): logger.debug("Instantiating API") api = API(Client(host=kwargs.pop("host"), port=kwargs.pop("port"), secret=kwargs.pop("secret"))) + logger.info(f"API instantiated: {api!r}") + # Warn if no aria2 daemon process seems to be running logger.debug("Testing connection") try: @@ -89,6 +92,11 @@ def main(args=None): if subcommand: logger.debug("Running subcommand " + subcommand) + else: + print( + "Future change warning: starting at version 0.6, the default command will be 'top' instead of 'show'.", + file=sys.stderr, + ) try: return subcommands.get(subcommand)(api, **kwargs) except ClientException as error: @@ -106,9 +114,11 @@ def check_args(parser, args): elif args.do_all and args.gids: subparser[args.subcommand].error("argument -a/--all: not allowed with arguments gids") elif (args.subcommand or "").endswith("-all"): - logger.warning( - f"Subcommand '{args.subcommand}' is deprecated in favor of '{args.subcommand[:-4]} --all'. " - f"It will be removed in version 0.5.0, please update your scripts/code." + print( + f"Deprecation warning: command '{args.subcommand}' is deprecated " + f"in favor of '{args.subcommand[:-4]} --all', " + f"and will be removed in version 0.5.0.", + file=sys.stderr, ) @@ -258,7 +268,7 @@ def subparser(command, text, **kwargs): return parser -# ============ SHOW SUBCOMMAND ============ # +# ============ SUBCOMMANDS ============ # def subcommand_show(api): """ Show subcommand. @@ -295,7 +305,6 @@ def subcommand_show(api): return 0 -# ============ TOP SUBCOMMAND ============ # def subcommand_top(api): """ Top subcommand. @@ -311,7 +320,6 @@ def subcommand_top(api): return 0 if success else 1 -# ============ CALL SUBCOMMAND ============ # def subcommand_call(api, method, params): """ Call subcommand. @@ -326,9 +334,8 @@ def subcommand_call(api, method, params): """ real_method = get_method(method) if real_method is None: - print(f"[ERROR] call: Unknown method {method}.", file=sys.stderr) - print(file=sys.stderr) - print(f"Run 'aria2p call listmethods' to list the available methods.", file=sys.stderr) + print(f"aria2p: call: Unknown method {method}.", file=sys.stderr) + print(" Run 'aria2p call listmethods' to list the available methods.", file=sys.stderr) return 1 if isinstance(params, str): @@ -354,7 +361,6 @@ def get_method(name, default=None): return methods.get(name, default) -# ============ ADD MAGNET SUBCOMMAND ============ # def subcommand_add_magnet(api, uri): """ Add magnet subcommand. @@ -371,7 +377,6 @@ def subcommand_add_magnet(api, uri): return 0 -# ============ ADD TORRENT SUBCOMMAND ============ # def subcommand_add_torrent(api, torrent_file): """ Add torrent subcommand. @@ -388,7 +393,6 @@ def subcommand_add_torrent(api, torrent_file): return 0 -# ============ ADD METALINK SUBCOMMAND ============ # def subcommand_add_metalink(api: API, metalink_file): """ Add metalink subcommand. @@ -406,7 +410,6 @@ def subcommand_add_metalink(api: API, metalink_file): return 0 -# ============ PAUSE SUBCOMMAND ============ # def subcommand_pause(api: API, gids=None, do_all=False, force=False): """ Pause subcommand. @@ -435,7 +438,6 @@ def subcommand_pause(api: API, gids=None, do_all=False, force=False): return 1 -# ============ PAUSE ALL SUBCOMMAND ============ # def subcommand_pause_all(api: API, force=False): """ Pause all subcommand. @@ -452,7 +454,6 @@ def subcommand_pause_all(api: API, force=False): return 1 -# ============ RESUME SUBCOMMAND ============ # def subcommand_resume(api: API, gids=None, do_all=False): """ Resume subcommand. @@ -480,7 +481,6 @@ def subcommand_resume(api: API, gids=None, do_all=False): return 1 -# ============ RESUME ALL SUBCOMMAND ============ # def subcommand_resume_all(api: API): """ Resume all subcommand. @@ -496,7 +496,6 @@ def subcommand_resume_all(api: API): return 1 -# ============ REMOVE SUBCOMMAND ============ # def subcommand_remove(api: API, gids=None, do_all=False, force=False): """ Remove subcommand. @@ -525,7 +524,6 @@ def subcommand_remove(api: API, gids=None, do_all=False, force=False): return 1 -# ============ REMOVE ALL SUBCOMMAND ============ # def subcommand_remove_all(api: API, force=False): """ Remove all subcommand. @@ -542,7 +540,6 @@ def subcommand_remove_all(api: API, force=False): return 1 -# ============ PURGE SUBCOMMAND ============ # def subcommand_purge(api: API, gids=None, do_all=False): """ Purge subcommand. @@ -555,6 +552,11 @@ def subcommand_purge(api: API, gids=None, do_all=False): Returns: int: 0 if all success, 1 if one failure. """ + print( + "Deprecation warning: command 'purge' is deprecated in favor of command 'remove', " + "and will be removed in version 0.7.0.", + file=sys.stderr, + ) if do_all: if api.purge_all(): return 0 @@ -570,7 +572,6 @@ def subcommand_purge(api: API, gids=None, do_all=False): return 1 -# ============ AUTOPURGE SUBCOMMAND ============ # def subcommand_autopurge(api: API): """ Autopurge subcommand. @@ -581,12 +582,18 @@ def subcommand_autopurge(api: API): Returns: int: 0 if all success, 1 if one failure. """ + version = get_version() + if version.major == 0 and 9 > version.minor >= 7: + print( + "Future change warning: command 'autopurge' will be renamed 'purge' in version 0.9.0, " + "with an 'autoremove' alias.", + file=sys.stderr, + ) if api.autopurge(): return 0 return 1 -# ============ LISTEN SUBCOMMAND ============ # def subcommand_listen(api: API, callbacks_module=None, event_types=None, timeout=5): """ Listen subcommand. @@ -635,26 +642,3 @@ def subcommand_listen(api: API, callbacks_module=None, event_types=None, timeout api.listen_to_notifications(timeout=timeout, handle_signals=True, threaded=False, **callbacks_kwargs) return 0 - - -# ============ INFO SUBCOMMAND ============ # -# def subcommand_info(api: API, gids, select_all=False): -# if select_all: -# downloads = api.get_downloads() -# else: -# downloads = api.get_downloads(gids) -# -# api.info(downloads) -# return 0 - - -# ============ LIST SUBCOMMAND ============ # -# def subcommand_list(api: API, list_format=None, sort=None): -# api.list(list_format=list_format, sort=sort) -# return 0 - - -# ============ SEARCH SUBCOMMAND ============ # -# def subcommand_search(api: API, ): -# api.search() -# return 0 diff --git a/src/aria2p/client.py b/src/aria2p/client.py index 81cdfa4..7379fb5 100644 --- a/src/aria2p/client.py +++ b/src/aria2p/client.py @@ -185,6 +185,9 @@ def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT, secret=""): # nosec def __str__(self): return self.server + def __repr__(self): + return f"Client(host='{self.host}', port={self.port}, secret='********')" + @property def server(self): """Property to return the full remote process / server address.""" @@ -1637,6 +1640,7 @@ def list_notifications(self): """ return self.call(self.LIST_NOTIFICATIONS) + # notifications def listen_to_notifications( self, on_download_start=None, diff --git a/src/aria2p/interface.py b/src/aria2p/interface.py index 4164392..935a68c 100644 --- a/src/aria2p/interface.py +++ b/src/aria2p/interface.py @@ -20,12 +20,12 @@ import time from collections import defaultdict -import pkg_resources from asciimatics.event import KeyboardEvent, MouseEvent from asciimatics.screen import ManagedScreen, Screen from loguru import logger from .api import API +from .utils import get_version class Key: @@ -192,9 +192,6 @@ def name(value): return "name" -# TODO: allow other interfaces to be drawn, like the setup menu or the help menu - - class Interface: """ The main class responsible of drawing the HTOP-like interface. @@ -652,7 +649,7 @@ def follow_focused(self): return False def print_help(self): - version = pkg_resources.get_distribution("aria2p").version + version = get_version() lines = [f"aria2p {version} — (C) 2018-2019 Timothée Mazzucotelli", "Released under the ISC license.", ""] y = 0 diff --git a/tests/test_cli.py b/tests/test_cli.py index 4710967..2d553ae 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -96,8 +96,8 @@ def test_call_subcommand(capsys): with Aria2Server(port=7504) as server: assert cli.subcommand_call(server.api, "wrongMethod", []) == 1 assert ( - capsys.readouterr().err == "[ERROR] call: Unknown method wrongMethod.\n\n" - "Run 'aria2p call listmethods' to list the available methods.\n" + capsys.readouterr().err == "aria2p: call: Unknown method wrongMethod.\n" + " Run 'aria2p call listmethods' to list the available methods.\n" ) @@ -219,7 +219,8 @@ def test_purge_subcommand_one_failure(capsys): while not server.api.get_download("2089b05ecca3d829").is_complete: time.sleep(0.2) assert cli.subcommand_purge(server.api, ["2089b05ecca3d829", "208a3d8299b05ecc"]) == 1 - assert capsys.readouterr().err == "Could not remove download result of GID#208a3d8299b05ecc\n" + lines = err_lines(capsys) + assert lines[1] == "Could not remove download result of GID#208a3d8299b05ecc" def test_purge_all_subcommand():