From 069a112d05bdaced95c84d14a1ed5e2533a3b67c Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Sun, 14 Jun 2020 21:06:13 +0200 Subject: [PATCH 01/24] Ported CLI to argparse, based on functional programming paradigm --- protonvpn_cli/cli.py | 88 +++++++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 786bc14..d97601a 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -51,8 +51,9 @@ import getpass import shutil import time +import argparse # External Libraries -from docopt import docopt +# from docopt import docopt # protonvpn-cli Functions from . import connection from .logger import logger @@ -88,13 +89,15 @@ def cli(): logger.debug("USER: {0}".format(USER)) logger.debug("CONFIG_DIR: {0}".format(CONFIG_DIR)) - args = docopt(__doc__, version="ProtonVPN-CLI v{0}".format(VERSION)) - logger.debug("Arguments\n{0}".format(str(args).replace("\n", ""))) + # args = docopt(__doc__, version="ProtonVPN-CLI v{0}".format(VERSION)) + command, args = functional_cli() + logger.debug("Arguments\n{0}".format(args)) - # Parse arguments - if args.get("init"): + # print("Command: {}\nArgs: {}".format(command, args)) + + if command in ["init"]: init_cli() - elif args.get("c") or args.get("connect"): + elif command in ["c", "connect"]: check_root() check_init() @@ -106,47 +109,88 @@ def cli(): if int(os.environ.get("PVPN_WAIT", 0)) > 0: wait_for_network(int(os.environ["PVPN_WAIT"])) - protocol = args.get("-p") + protocol = args.protocol if protocol is not None and protocol.lower().strip() in ["tcp", "udp"]: protocol = protocol.lower().strip() - if args.get("--random"): + if args.random: connection.random_c(protocol) - elif args.get("--fastest"): + elif args.fastest: connection.fastest(protocol) - elif args.get(""): - connection.direct(args.get(""), protocol) - elif args.get("--cc") is not None: - connection.country_f(args.get("--cc"), protocol) + elif args.servername: + connection.direct(args(""), protocol) + elif args.country_code is not None: + connection.country_f(args("--cc"), protocol) # Features: 1: Secure-Core, 2: Tor, 4: P2P - elif args.get("--p2p"): + elif args.peer2peer: connection.feature_f(4, protocol) - elif args.get("--sc"): + elif args.secure_core: connection.feature_f(1, protocol) - elif args.get("--tor"): + elif args.tor: connection.feature_f(2, protocol) else: connection.dialog() - elif args.get("r") or args.get("reconnect"): + + elif command in ["r", "reconnect"]: check_root() check_init() connection.reconnect() - elif args.get("d") or args.get("disconnect"): + + elif command in ["d", "disconnect"]: check_root() check_init() connection.disconnect() - elif args.get("s") or args.get("status"): + + elif command in ["s", "status"]: connection.status() - elif args.get("configure"): + + elif command in ["cf", "configure"]: check_root() check_init() configure_cli() - elif args.get("refresh"): + + elif command in ["rf", "refresh"]: check_init() pull_server_data(force=True) - elif args.get("examples"): + + elif command in ["ex", "examples"]: print_examples() +def functional_cli(): + parser = argparse.ArgumentParser(description="Official ProtonVPN CLI", prog="protonvpn") + parser.add_argument("-v", "--version", help="Select the fastest ProtonVPN server.", action="store_true") + + subparsers = parser.add_subparsers(metavar="") + + parser_init = subparsers.add_parser(name="init", help="Initialize a ProtonVPN profile.") + + parser_connect = subparsers.add_parser(name="c", aliases=["connect"], help="Connect to a ProtonVPN server.") + group_connect = parser_connect.add_mutually_exclusive_group() + group_connect.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") + group_connect.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true") + group_connect.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") + group_connect.add_argument("-cc", "--country-code", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") + group_connect.add_argument("-sc", "--secure-core", help="Connect to the fastest Secure-Core server.", action="store_true") + group_connect.add_argument("-p2p", "--peer2peer", help="Connect to the fastest torrent server.", action="store_true") + group_connect.add_argument("-t", "--tor", help="Connect to the fastest Tor server.", action="store_true") + parser_connect.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") + + parser_reconnect = subparsers.add_parser("r", aliases=["reconnect"], help="Reconnect to the last server.") + + parser_disconnect = subparsers.add_parser("d", aliases=["disconnect"], help="Disconnect the current session.") + + parser_status = subparsers.add_parser("s", aliases=["status"], help="Show connection status.") + + parser_configure = subparsers.add_parser("cf", aliases=["configure"], help="Change ProtonVPN-CLI configuration.") + + parser_refresh = subparsers.add_parser("rf", aliases=["refresh"], help="Refresh OpenVPN configuration and server data.") + + parser_exmaples = subparsers.add_parser("ex", aliases=["examples"], help="Print some example commands.") + + command = sys.argv[1:2] + args = parser.parse_args() + + return command[0], args def init_cli(): """Initialize the CLI.""" From 5017b7cac167bd6a20fc838962b355fe90805b6b Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Sun, 14 Jun 2020 21:09:02 +0200 Subject: [PATCH 02/24] Ported CLI to argparse, based on OO programming paradigm --- protonvpn_cli/cli.py | 254 ++++++++++++++++++++++++++++++++----------- 1 file changed, 192 insertions(+), 62 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index d97601a..477cb72 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -1,4 +1,4 @@ -""" +usage = """ A CLI for ProtonVPN. Usage: @@ -88,26 +88,167 @@ def cli(): logger.debug(sys.argv) logger.debug("USER: {0}".format(USER)) logger.debug("CONFIG_DIR: {0}".format(CONFIG_DIR)) + + ProtonVPNCLI() # args = docopt(__doc__, version="ProtonVPN-CLI v{0}".format(VERSION)) - command, args = functional_cli() - logger.debug("Arguments\n{0}".format(args)) + # command, args = functional_cli() + # logger.debug("Arguments\n{0}".format(args)) - # print("Command: {}\nArgs: {}".format(command, args)) + # # print("Command: {}\nArgs: {}".format(command, args)) - if command in ["init"]: + # if command in ["init"]: + # init_cli() + # elif command in ["c", "connect"]: + # check_root() + # check_init() + + # # Wait until a connection to the ProtonVPN API can be made + # # As this is mainly for automatically connecting on boot, it only + # # activates when the environment variable PVPN_WAIT is 1 + # # Otherwise it wouldn't connect when a VPN process without + # # internet access exists or the Kill Switch is active + # if int(os.environ.get("PVPN_WAIT", 0)) > 0: + # wait_for_network(int(os.environ["PVPN_WAIT"])) + + # protocol = args.protocol + # if protocol is not None and protocol.lower().strip() in ["tcp", "udp"]: + # protocol = protocol.lower().strip() + + # if args.random: + # connection.random_c(protocol) + # elif args.fastest: + # connection.fastest(protocol) + # elif args.servername is not None: + # connection.direct(args.servername, protocol) + # elif args.country_code is not None: + # connection.country_f(args.country_code, protocol) + # # Features: 1: Secure-Core, 2: Tor, 4: P2P + # elif args.peer2peer: + # connection.feature_f(4, protocol) + # elif args.secure_core: + # connection.feature_f(1, protocol) + # elif args.tor: + # connection.feature_f(2, protocol) + # else: + # connection.dialog() + + # elif command in ["r", "reconnect"]: + # check_root() + # check_init() + # connection.reconnect() + + # elif command in ["d", "disconnect"]: + # check_root() + # check_init() + # connection.disconnect() + + # elif command in ["s", "status"]: + # connection.status() + + # elif command in ["cf", "configure"]: + # check_root() + # check_init() + # configure_cli() + + # elif command in ["rf", "refresh"]: + # check_init() + # pull_server_data(force=True) + + # elif command in ["ex", "examples"]: + # print_examples() + +def functional_cli(): + parser = argparse.ArgumentParser(description="Official ProtonVPN CLI", prog="protonvpn") + parser.add_argument("-v", "--version", help="Select the fastest ProtonVPN server.", action="store_true") + + subparsers = parser.add_subparsers(metavar="") + + parser_init = subparsers.add_parser(name="init", help="Initialize a ProtonVPN profile.") + + parser_connect = subparsers.add_parser(name="c", aliases=["connect"], help="Connect to a ProtonVPN server.") + group_connect = parser_connect.add_mutually_exclusive_group() + group_connect.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") + group_connect.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true") + group_connect.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") + group_connect.add_argument("-cc", "--country-code", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") + group_connect.add_argument("-sc", "--secure-core", help="Connect to the fastest Secure-Core server.", action="store_true") + group_connect.add_argument("-p2p", "--peer2peer", help="Connect to the fastest torrent server.", action="store_true") + group_connect.add_argument("-t", "--tor", help="Connect to the fastest Tor server.", action="store_true") + parser_connect.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") + + parser_reconnect = subparsers.add_parser("r", aliases=["reconnect"], help="Reconnect to the last server.") + + parser_disconnect = subparsers.add_parser("d", aliases=["disconnect"], help="Disconnect the current session.") + + parser_status = subparsers.add_parser("s", aliases=["status"], help="Show connection status.") + + parser_configure = subparsers.add_parser("cf", aliases=["configure"], help="Change ProtonVPN-CLI configuration.") + + parser_refresh = subparsers.add_parser("rf", aliases=["refresh"], help="Refresh OpenVPN configuration and server data.") + + parser_exmaples = subparsers.add_parser("ex", aliases=["examples"], help="Print some example commands.") + + command = sys.argv[1:2] + args = parser.parse_args() + + return command[0], args + +class ProtonVPNCLI(): + def __init__(self): + parser = argparse.ArgumentParser( + description="Official ProtonVPN CLI", + prog="protonvpn", + usage=usage + ) + + parser.add_argument("command", nargs="?", help="Command to be run") + parser.add_argument("-v", "--version", required=False, help="Command to be run", action="store_true") + + args = parser.parse_args(sys.argv[1:2]) + + if args.version: + print("ProtonVPN CLI v.{}".format(VERSION)) + sys.exit(1) + elif args.command is None or not hasattr(self, args.command): + parser.print_usage() + sys.exit(1) + + getattr(self, args.command)() + + # Intialize ProtonVPN profile + def init(self): + """Intialiazes ProtonVPN profile. To intialize profile inline, provide the "-i" option.""" + parser = argparse.ArgumentParser(description="Initialize ProtonVPN profile", prog="protonvpn init") + parser.add_argument("-i", nargs=3, required=False, help="Inline intialize profile. (username password protocol)", metavar="") + args = parser.parse_args(sys.argv[2:]) + if args.i: + print("Inline method invoked") + init_cli() - elif command in ["c", "connect"]: + # print(args) + + # Connect to VPN + def c(self): + """Short for connect""" + self.connect() + def connect(self): check_root() check_init() - - # Wait until a connection to the ProtonVPN API can be made - # As this is mainly for automatically connecting on boot, it only - # activates when the environment variable PVPN_WAIT is 1 - # Otherwise it wouldn't connect when a VPN process without - # internet access exists or the Kill Switch is active - if int(os.environ.get("PVPN_WAIT", 0)) > 0: - wait_for_network(int(os.environ["PVPN_WAIT"])) + + parser = argparse.ArgumentParser(description="Connect to ProtonVPN", prog="protonvpn c") + group = parser.add_mutually_exclusive_group() + group.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") + group.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true") + group.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") + group.add_argument("-cc", "--country-code", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") + group.add_argument("-sc", "--secure-core", help="Connect to the fastest Secure-Core server.", action="store_true") + group.add_argument("-p2p", "--peer2peer", help="Connect to the fastest torrent server.", action="store_true") + group.add_argument("-t", "--tor", help="Connect to the fastest Tor server.", action="store_true") + parser.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") + + args = parser.parse_args(sys.argv[2:]) + # print(args) protocol = args.protocol if protocol is not None and protocol.lower().strip() in ["tcp", "udp"]: @@ -118,9 +259,9 @@ def cli(): elif args.fastest: connection.fastest(protocol) elif args.servername: - connection.direct(args(""), protocol) + connection.direct(args.servername, protocol) elif args.country_code is not None: - connection.country_f(args("--cc"), protocol) + connection.country_f(args.country_code, protocol) # Features: 1: Secure-Core, 2: Tor, 4: P2P elif args.peer2peer: connection.feature_f(4, protocol) @@ -131,66 +272,55 @@ def cli(): else: connection.dialog() - elif command in ["r", "reconnect"]: + # Reconnect to last connected VPN server + def r(self): + """Short for reconnect""" + self.reconnect() + def reconnect(self): check_root() check_init() connection.reconnect() - elif command in ["d", "disconnect"]: + # Disconnect from VPN + def d(self): + """Short for disconnect""" + self.disconnect() + def disconnect(self): check_root() check_init() connection.disconnect() - - elif command in ["s", "status"]: + + # Display VPN status information + def s(self): + """Short for status""" + self.status() + def status(self): connection.status() - - elif command in ["cf", "configure"]: + + # Open configurations menu + def cf(self): + """Short for configure""" + self.configure() + def configure(self): check_root() check_init() configure_cli() - elif command in ["rf", "refresh"]: + # Refresh servers + def rf(self): + """Short for refresh""" + self.refresh() + def refresh(self): check_init() - pull_server_data(force=True) - - elif command in ["ex", "examples"]: + pull_server_data(force=True) + + # Show usage examples + def ex(self): + """Short for examples""" + self.refresh() + def examples(self): print_examples() - -def functional_cli(): - parser = argparse.ArgumentParser(description="Official ProtonVPN CLI", prog="protonvpn") - parser.add_argument("-v", "--version", help="Select the fastest ProtonVPN server.", action="store_true") - - subparsers = parser.add_subparsers(metavar="") - - parser_init = subparsers.add_parser(name="init", help="Initialize a ProtonVPN profile.") - - parser_connect = subparsers.add_parser(name="c", aliases=["connect"], help="Connect to a ProtonVPN server.") - group_connect = parser_connect.add_mutually_exclusive_group() - group_connect.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") - group_connect.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true") - group_connect.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") - group_connect.add_argument("-cc", "--country-code", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") - group_connect.add_argument("-sc", "--secure-core", help="Connect to the fastest Secure-Core server.", action="store_true") - group_connect.add_argument("-p2p", "--peer2peer", help="Connect to the fastest torrent server.", action="store_true") - group_connect.add_argument("-t", "--tor", help="Connect to the fastest Tor server.", action="store_true") - parser_connect.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") - - parser_reconnect = subparsers.add_parser("r", aliases=["reconnect"], help="Reconnect to the last server.") - - parser_disconnect = subparsers.add_parser("d", aliases=["disconnect"], help="Disconnect the current session.") - - parser_status = subparsers.add_parser("s", aliases=["status"], help="Show connection status.") - - parser_configure = subparsers.add_parser("cf", aliases=["configure"], help="Change ProtonVPN-CLI configuration.") - - parser_refresh = subparsers.add_parser("rf", aliases=["refresh"], help="Refresh OpenVPN configuration and server data.") - - parser_exmaples = subparsers.add_parser("ex", aliases=["examples"], help="Print some example commands.") - - command = sys.argv[1:2] - args = parser.parse_args() - - return command[0], args + def init_cli(): """Initialize the CLI.""" From 09753adba4765f8fa0ab2a7a60fffce248d550e3 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Sun, 14 Jun 2020 21:20:08 +0200 Subject: [PATCH 03/24] Added descriptive comments --- protonvpn_cli/cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 477cb72..14862fa 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -89,8 +89,10 @@ def cli(): logger.debug("USER: {0}".format(USER)) logger.debug("CONFIG_DIR: {0}".format(CONFIG_DIR)) + # OO based CLI ProtonVPNCLI() + # Functional based CLI # args = docopt(__doc__, version="ProtonVPN-CLI v{0}".format(VERSION)) # command, args = functional_cli() # logger.debug("Arguments\n{0}".format(args)) From 7e8025497abaaadf4bba0fb0eb1a4efd7a7d8acd Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 15 Jun 2020 12:16:23 +0200 Subject: [PATCH 04/24] Updated usage string Have also added a custom help message. --- protonvpn_cli/cli.py | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 14862fa..ece4acc 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -1,5 +1,5 @@ usage = """ -A CLI for ProtonVPN. +Official ProtonVPN CLI Usage: protonvpn init @@ -13,19 +13,19 @@ protonvpn (r | reconnect) protonvpn (d | disconnect) protonvpn (s | status) - protonvpn configure - protonvpn refresh - protonvpn examples + protonvpn (cf | configure) + protonvpn (rf | refresh) + protonvpn (ex | examples) protonvpn (-h | --help) protonvpn (-v | --version) Options: -f, --fastest Select the fastest ProtonVPN server. -r, --random Select a random ProtonVPN server. - --cc CODE Determine the country for fastest connect. - --sc Connect to the fastest Secure-Core server. - --p2p Connect to the fastest torrent server. - --tor Connect to the fastest Tor server. + -cc CODE Determine the country for fastest connect. + -sc, secure-core Connect to the fastest Secure-Core server. + -p2p, --peer2peer Connect to the fastest torrent server. + -t, --tor Connect to the fastest Tor server. -p PROTOCOL Determine the protocol (UDP or TCP). -h, --help Show this help message. -v, --version Display version. @@ -36,9 +36,9 @@ r, reconnect Reconnect to the last server. d, disconnect Disconnect the current session. s, status Show connection status. - configure Change ProtonVPN-CLI configuration. - refresh Refresh OpenVPN configuration and server data. - examples Print some example commands. + cf, configure Change ProtonVPN-CLI configuration. + rf, refresh Refresh OpenVPN configuration and server data. + ex, examples Print some example commands. Arguments: Servername (CH#4, CH-US-1, HK5-Tor). @@ -199,22 +199,22 @@ def functional_cli(): class ProtonVPNCLI(): def __init__(self): parser = argparse.ArgumentParser( - description="Official ProtonVPN CLI", prog="protonvpn", - usage=usage + add_help=False ) - - parser.add_argument("command", nargs="?", help="Command to be run") - parser.add_argument("-v", "--version", required=False, help="Command to be run", action="store_true") + + parser.add_argument("command", nargs="?") + parser.add_argument("-v", "--version", required=False, action="store_true") + parser.add_argument("-h", "--help", required=False, action="store_true") args = parser.parse_args(sys.argv[1:2]) if args.version: - print("ProtonVPN CLI v.{}".format(VERSION)) - sys.exit(1) - elif args.command is None or not hasattr(self, args.command): - parser.print_usage() - sys.exit(1) + print("\nProtonVPN CLI v.{}".format(VERSION)) + parser.exit(1) + elif args.command is None or not hasattr(self, args.command) or args.help: + print(usage) + parser.exit() getattr(self, args.command)() @@ -319,7 +319,7 @@ def refresh(self): # Show usage examples def ex(self): """Short for examples""" - self.refresh() + self.examples() def examples(self): print_examples() From 2b2ad14f8bf59fc430260b8c812a49db3aebbcb0 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 15 Jun 2020 12:29:54 +0200 Subject: [PATCH 05/24] Added logging --- protonvpn_cli/cli.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index ece4acc..20c4897 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -208,7 +208,9 @@ def __init__(self): parser.add_argument("-h", "--help", required=False, action="store_true") args = parser.parse_args(sys.argv[1:2]) - + + logger.debug("Main argument\n{0}".format(args)) + if args.version: print("\nProtonVPN CLI v.{}".format(VERSION)) parser.exit(1) @@ -223,7 +225,10 @@ def init(self): """Intialiazes ProtonVPN profile. To intialize profile inline, provide the "-i" option.""" parser = argparse.ArgumentParser(description="Initialize ProtonVPN profile", prog="protonvpn init") parser.add_argument("-i", nargs=3, required=False, help="Inline intialize profile. (username password protocol)", metavar="") + args = parser.parse_args(sys.argv[2:]) + logger.debug("Sub-arguments\n{0}".format(args)) + if args.i: print("Inline method invoked") @@ -250,7 +255,7 @@ def connect(self): parser.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") args = parser.parse_args(sys.argv[2:]) - # print(args) + logger.debug("Sub-arguments\n{0}".format(args)) protocol = args.protocol if protocol is not None and protocol.lower().strip() in ["tcp", "udp"]: @@ -322,7 +327,6 @@ def ex(self): self.examples() def examples(self): print_examples() - def init_cli(): """Initialize the CLI.""" From cb290e5abd576f2e6972642a9cf9b4f26ca91dd5 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 15 Jun 2020 13:09:02 +0200 Subject: [PATCH 06/24] Updated exmaples --- protonvpn_cli/cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 20c4897..56de91d 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -463,12 +463,12 @@ def print_examples(): " Connect to NO#3 with TCP.\n\n" "protonvpn c --fastest\n" " Connect to the fastest VPN Server.\n\n" - "protonvpn connect --cc AU\n" + "protonvpn connect -cc AU\n" " Connect to the fastest Australian server\n" " with the default protocol.\n\n" - "protonvpn c --p2p -p tcp\n" + "protonvpn c -p2p -p tcp\n" " Connect to the fastest torrent server with TCP.\n\n" - "protonvpn c --sc\n" + "protonvpn c -sc\n" " Connect to the fastest Secure-Core server with\n" " the default protocol.\n\n" "protonvpn reconnect\n" From 02c1bd4c2821d3b3853cef3d03c127fa48c4531a Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Wed, 17 Jun 2020 17:16:06 +0200 Subject: [PATCH 07/24] Removed function based CLI code Restored some CLI commands so that they are fully compatible with previous versions --- protonvpn_cli/cli.py | 133 +++++-------------------------------------- 1 file changed, 14 insertions(+), 119 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 56de91d..dd92159 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -22,10 +22,10 @@ Options: -f, --fastest Select the fastest ProtonVPN server. -r, --random Select a random ProtonVPN server. - -cc CODE Determine the country for fastest connect. - -sc, secure-core Connect to the fastest Secure-Core server. - -p2p, --peer2peer Connect to the fastest torrent server. - -t, --tor Connect to the fastest Tor server. + --cc CODE Determine the country for fastest connect. + --sc Connect to the fastest Secure-Core server. + --p2p Connect to the fastest torrent server. + --tor Connect to the fastest Tor server. -p PROTOCOL Determine the protocol (UDP or TCP). -h, --help Show this help message. -v, --version Display version. @@ -89,113 +89,8 @@ def cli(): logger.debug("USER: {0}".format(USER)) logger.debug("CONFIG_DIR: {0}".format(CONFIG_DIR)) - # OO based CLI ProtonVPNCLI() - # Functional based CLI - # args = docopt(__doc__, version="ProtonVPN-CLI v{0}".format(VERSION)) - # command, args = functional_cli() - # logger.debug("Arguments\n{0}".format(args)) - - # # print("Command: {}\nArgs: {}".format(command, args)) - - # if command in ["init"]: - # init_cli() - # elif command in ["c", "connect"]: - # check_root() - # check_init() - - # # Wait until a connection to the ProtonVPN API can be made - # # As this is mainly for automatically connecting on boot, it only - # # activates when the environment variable PVPN_WAIT is 1 - # # Otherwise it wouldn't connect when a VPN process without - # # internet access exists or the Kill Switch is active - # if int(os.environ.get("PVPN_WAIT", 0)) > 0: - # wait_for_network(int(os.environ["PVPN_WAIT"])) - - # protocol = args.protocol - # if protocol is not None and protocol.lower().strip() in ["tcp", "udp"]: - # protocol = protocol.lower().strip() - - # if args.random: - # connection.random_c(protocol) - # elif args.fastest: - # connection.fastest(protocol) - # elif args.servername is not None: - # connection.direct(args.servername, protocol) - # elif args.country_code is not None: - # connection.country_f(args.country_code, protocol) - # # Features: 1: Secure-Core, 2: Tor, 4: P2P - # elif args.peer2peer: - # connection.feature_f(4, protocol) - # elif args.secure_core: - # connection.feature_f(1, protocol) - # elif args.tor: - # connection.feature_f(2, protocol) - # else: - # connection.dialog() - - # elif command in ["r", "reconnect"]: - # check_root() - # check_init() - # connection.reconnect() - - # elif command in ["d", "disconnect"]: - # check_root() - # check_init() - # connection.disconnect() - - # elif command in ["s", "status"]: - # connection.status() - - # elif command in ["cf", "configure"]: - # check_root() - # check_init() - # configure_cli() - - # elif command in ["rf", "refresh"]: - # check_init() - # pull_server_data(force=True) - - # elif command in ["ex", "examples"]: - # print_examples() - -def functional_cli(): - parser = argparse.ArgumentParser(description="Official ProtonVPN CLI", prog="protonvpn") - parser.add_argument("-v", "--version", help="Select the fastest ProtonVPN server.", action="store_true") - - subparsers = parser.add_subparsers(metavar="") - - parser_init = subparsers.add_parser(name="init", help="Initialize a ProtonVPN profile.") - - parser_connect = subparsers.add_parser(name="c", aliases=["connect"], help="Connect to a ProtonVPN server.") - group_connect = parser_connect.add_mutually_exclusive_group() - group_connect.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") - group_connect.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true") - group_connect.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") - group_connect.add_argument("-cc", "--country-code", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") - group_connect.add_argument("-sc", "--secure-core", help="Connect to the fastest Secure-Core server.", action="store_true") - group_connect.add_argument("-p2p", "--peer2peer", help="Connect to the fastest torrent server.", action="store_true") - group_connect.add_argument("-t", "--tor", help="Connect to the fastest Tor server.", action="store_true") - parser_connect.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") - - parser_reconnect = subparsers.add_parser("r", aliases=["reconnect"], help="Reconnect to the last server.") - - parser_disconnect = subparsers.add_parser("d", aliases=["disconnect"], help="Disconnect the current session.") - - parser_status = subparsers.add_parser("s", aliases=["status"], help="Show connection status.") - - parser_configure = subparsers.add_parser("cf", aliases=["configure"], help="Change ProtonVPN-CLI configuration.") - - parser_refresh = subparsers.add_parser("rf", aliases=["refresh"], help="Refresh OpenVPN configuration and server data.") - - parser_exmaples = subparsers.add_parser("ex", aliases=["examples"], help="Print some example commands.") - - command = sys.argv[1:2] - args = parser.parse_args() - - return command[0], args - class ProtonVPNCLI(): def __init__(self): parser = argparse.ArgumentParser( @@ -224,7 +119,7 @@ def __init__(self): def init(self): """Intialiazes ProtonVPN profile. To intialize profile inline, provide the "-i" option.""" parser = argparse.ArgumentParser(description="Initialize ProtonVPN profile", prog="protonvpn init") - parser.add_argument("-i", nargs=3, required=False, help="Inline intialize profile. (username password protocol)", metavar="") + parser.add_argument("-i", "--inline", nargs=3, required=False, help="Inline intialize profile. (username password protocol)", metavar="") args = parser.parse_args(sys.argv[2:]) logger.debug("Sub-arguments\n{0}".format(args)) @@ -248,14 +143,14 @@ def connect(self): group.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") group.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true") group.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") - group.add_argument("-cc", "--country-code", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") - group.add_argument("-sc", "--secure-core", help="Connect to the fastest Secure-Core server.", action="store_true") - group.add_argument("-p2p", "--peer2peer", help="Connect to the fastest torrent server.", action="store_true") - group.add_argument("-t", "--tor", help="Connect to the fastest Tor server.", action="store_true") + group.add_argument("--cc", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") + group.add_argument("--sc", help="Connect to the fastest Secure-Core server.", action="store_true") + group.add_argument("--p2p", help="Connect to the fastest torrent server.", action="store_true") + group.add_argument("--tor", help="Connect to the fastest Tor server.", action="store_true") parser.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") args = parser.parse_args(sys.argv[2:]) - logger.debug("Sub-arguments\n{0}".format(args)) + logger.debug("Sub-arguments:\n{0}".format(args)) protocol = args.protocol if protocol is not None and protocol.lower().strip() in ["tcp", "udp"]: @@ -267,12 +162,12 @@ def connect(self): connection.fastest(protocol) elif args.servername: connection.direct(args.servername, protocol) - elif args.country_code is not None: - connection.country_f(args.country_code, protocol) + elif args.cc is not None: + connection.country_f(args.cc, protocol) # Features: 1: Secure-Core, 2: Tor, 4: P2P - elif args.peer2peer: + elif args.p2p: connection.feature_f(4, protocol) - elif args.secure_core: + elif args.sc: connection.feature_f(1, protocol) elif args.tor: connection.feature_f(2, protocol) From e242dbac28c69f2d9f4d72eed05fce8ae1e18af8 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:37:18 +0100 Subject: [PATCH 08/24] Removed docopt dependency --- protonvpn_cli/cli.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index dd92159..3ac5dfa 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -53,7 +53,6 @@ import time import argparse # External Libraries -# from docopt import docopt # protonvpn-cli Functions from . import connection from .logger import logger @@ -67,7 +66,6 @@ CONFIG_DIR, CONFIG_FILE, PASSFILE, USER, VERSION, SPLIT_TUNNEL_FILE ) - def main(): """Main function""" try: @@ -76,7 +74,6 @@ def main(): print("\nQuitting...") sys.exit(1) - def cli(): """Run user's input command.""" From e813a3912a122e7759f4c4f1f4b3c695d626ffd0 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:48:28 +0100 Subject: [PATCH 09/24] Added usage constant --- protonvpn_cli/cli.py | 51 +++----------------------------------- protonvpn_cli/constants.py | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 3ac5dfa..d8f03a1 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -1,48 +1,3 @@ -usage = """ -Official ProtonVPN CLI - -Usage: - protonvpn init - protonvpn (c | connect) [] [-p ] - protonvpn (c | connect) [-f | --fastest] [-p ] - protonvpn (c | connect) [--cc ] [-p ] - protonvpn (c | connect) [--sc] [-p ] - protonvpn (c | connect) [--p2p] [-p ] - protonvpn (c | connect) [--tor] [-p ] - protonvpn (c | connect) [-r | --random] [-p ] - protonvpn (r | reconnect) - protonvpn (d | disconnect) - protonvpn (s | status) - protonvpn (cf | configure) - protonvpn (rf | refresh) - protonvpn (ex | examples) - protonvpn (-h | --help) - protonvpn (-v | --version) - -Options: - -f, --fastest Select the fastest ProtonVPN server. - -r, --random Select a random ProtonVPN server. - --cc CODE Determine the country for fastest connect. - --sc Connect to the fastest Secure-Core server. - --p2p Connect to the fastest torrent server. - --tor Connect to the fastest Tor server. - -p PROTOCOL Determine the protocol (UDP or TCP). - -h, --help Show this help message. - -v, --version Display version. - -Commands: - init Initialize a ProtonVPN profile. - c, connect Connect to a ProtonVPN server. - r, reconnect Reconnect to the last server. - d, disconnect Disconnect the current session. - s, status Show connection status. - cf, configure Change ProtonVPN-CLI configuration. - rf, refresh Refresh OpenVPN configuration and server data. - ex, examples Print some example commands. - -Arguments: - Servername (CH#4, CH-US-1, HK5-Tor). -""" # Standard Libraries import sys import os @@ -63,7 +18,7 @@ ) # Constants from .constants import ( - CONFIG_DIR, CONFIG_FILE, PASSFILE, USER, VERSION, SPLIT_TUNNEL_FILE + CONFIG_DIR, CONFIG_FILE, PASSFILE, USER, VERSION, SPLIT_TUNNEL_FILE, USAGE ) def main(): @@ -107,7 +62,7 @@ def __init__(self): print("\nProtonVPN CLI v.{}".format(VERSION)) parser.exit(1) elif args.command is None or not hasattr(self, args.command) or args.help: - print(usage) + print(USAGE) parser.exit() getattr(self, args.command)() @@ -134,7 +89,7 @@ def c(self): def connect(self): check_root() check_init() - + parser = argparse.ArgumentParser(description="Connect to ProtonVPN", prog="protonvpn c") group = parser.add_mutually_exclusive_group() group.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") diff --git a/protonvpn_cli/constants.py b/protonvpn_cli/constants.py index 224ddb4..348ed13 100644 --- a/protonvpn_cli/constants.py +++ b/protonvpn_cli/constants.py @@ -18,3 +18,49 @@ OVPN_FILE = os.path.join(CONFIG_DIR, "connect.ovpn") PASSFILE = os.path.join(CONFIG_DIR, "pvpnpass") VERSION = "2.2.4" + +USAGE = """ +Official ProtonVPN CLI + +Usage: + protonvpn init + protonvpn (c | connect) [] [-p ] + protonvpn (c | connect) [-f | --fastest] [-p ] + protonvpn (c | connect) [--cc ] [-p ] + protonvpn (c | connect) [--sc] [-p ] + protonvpn (c | connect) [--p2p] [-p ] + protonvpn (c | connect) [--tor] [-p ] + protonvpn (c | connect) [-r | --random] [-p ] + protonvpn (r | reconnect) + protonvpn (d | disconnect) + protonvpn (s | status) + protonvpn (cf | configure) + protonvpn (rf | refresh) + protonvpn (ex | examples) + protonvpn (-h | --help) + protonvpn (-v | --version) + +Options: + -f, --fastest Select the fastest ProtonVPN server. + -r, --random Select a random ProtonVPN server. + --cc CODE Determine the country for fastest connect. + --sc Connect to the fastest Secure-Core server. + --p2p Connect to the fastest torrent server. + --tor Connect to the fastest Tor server. + -p PROTOCOL Determine the protocol (UDP or TCP). + -h, --help Show this help message. + -v, --version Display version. + +Commands: + init Initialize a ProtonVPN profile. + c, connect Connect to a ProtonVPN server. + r, reconnect Reconnect to the last server. + d, disconnect Disconnect the current session. + s, status Show connection status. + cf, configure Change ProtonVPN-CLI configuration. + rf, refresh Refresh OpenVPN configuration and server data. + ex, examples Print some example commands. + +Arguments: + Servername (CH#4, CH-US-1, HK5-Tor). +""" From e5af91faf40b2a73d154b5575861321355006f50 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:49:16 +0100 Subject: [PATCH 10/24] Added back the PVPN_WAIT environment variable --- protonvpn_cli/cli.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index d8f03a1..21f0f09 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -90,6 +90,14 @@ def connect(self): check_root() check_init() + # Wait until a connection to the ProtonVPN API can be made + # As this is mainly for automatically connecting on boot, it only + # activates when the environment variable PVPN_WAIT is 1 + # Otherwise it wouldn't connect when a VPN process without + # internet access exists or the Kill Switch is active + if int(os.environ.get("PVPN_WAIT", 0)) > 0: + wait_for_network(int(os.environ["PVPN_WAIT"])) + parser = argparse.ArgumentParser(description="Connect to ProtonVPN", prog="protonvpn c") group = parser.add_mutually_exclusive_group() group.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") From dfa40185ea6b9d796be09befa8613380f033f605 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:57:38 +0100 Subject: [PATCH 11/24] Addressed Flake8 issues --- protonvpn_cli/cli.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 21f0f09..c3f9d97 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -21,6 +21,7 @@ CONFIG_DIR, CONFIG_FILE, PASSFILE, USER, VERSION, SPLIT_TUNNEL_FILE, USAGE ) + def main(): """Main function""" try: @@ -29,6 +30,7 @@ def main(): print("\nQuitting...") sys.exit(1) + def cli(): """Run user's input command.""" @@ -43,14 +45,15 @@ def cli(): ProtonVPNCLI() + class ProtonVPNCLI(): def __init__(self): parser = argparse.ArgumentParser( prog="protonvpn", add_help=False ) - - parser.add_argument("command", nargs="?") + + parser.add_argument("command", nargs="?") parser.add_argument("-v", "--version", required=False, action="store_true") parser.add_argument("-h", "--help", required=False, action="store_true") @@ -102,12 +105,12 @@ def connect(self): group = parser.add_mutually_exclusive_group() group.add_argument("servername", nargs="?", help="Servername (CH#4, CH-US-1, HK5-Tor).", metavar="") group.add_argument("-f", "--fastest", help="Connect to the fastest ProtonVPN server.", action="store_true") - group.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") + group.add_argument("-r", "--random", help="Connect to a random ProtonVPN server.", action="store_true") group.add_argument("--cc", help="Connect to the specified country code (SE, PT, BR, AR).", metavar="") group.add_argument("--sc", help="Connect to the fastest Secure-Core server.", action="store_true") group.add_argument("--p2p", help="Connect to the fastest torrent server.", action="store_true") group.add_argument("--tor", help="Connect to the fastest Tor server.", action="store_true") - parser.add_argument("-p", "--protocol", help="Connect via specified protocol (UDP or TCP).", choices=["udp", "tcp"], metavar="") + parser.add_argument("-p", "--protocol", help="Connect via specified protocol.", choices=["udp", "tcp"], metavar="") args = parser.parse_args(sys.argv[2:]) logger.debug("Sub-arguments:\n{0}".format(args)) @@ -138,6 +141,7 @@ def connect(self): def r(self): """Short for reconnect""" self.reconnect() + def reconnect(self): check_root() check_init() @@ -147,6 +151,7 @@ def reconnect(self): def d(self): """Short for disconnect""" self.disconnect() + def disconnect(self): check_root() check_init() @@ -156,6 +161,7 @@ def disconnect(self): def s(self): """Short for status""" self.status() + def status(self): connection.status() @@ -163,6 +169,7 @@ def status(self): def cf(self): """Short for configure""" self.configure() + def configure(self): check_root() check_init() @@ -172,6 +179,7 @@ def configure(self): def rf(self): """Short for refresh""" self.refresh() + def refresh(self): check_init() pull_server_data(force=True) @@ -180,9 +188,11 @@ def refresh(self): def ex(self): """Short for examples""" self.examples() + def examples(self): print_examples() + def init_cli(): """Initialize the CLI.""" From 880efe02f84566f682e943ba2adc7d1bb71f8618 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 29 Jun 2020 15:59:43 +0100 Subject: [PATCH 12/24] Addressed Flake8 issues --- protonvpn_cli/cli.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index c3f9d97..2f466f5 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -42,7 +42,7 @@ def cli(): logger.debug(sys.argv) logger.debug("USER: {0}".format(USER)) logger.debug("CONFIG_DIR: {0}".format(CONFIG_DIR)) - + ProtonVPNCLI() @@ -56,7 +56,7 @@ def __init__(self): parser.add_argument("command", nargs="?") parser.add_argument("-v", "--version", required=False, action="store_true") parser.add_argument("-h", "--help", required=False, action="store_true") - + args = parser.parse_args(sys.argv[1:2]) logger.debug("Main argument\n{0}".format(args)) @@ -67,7 +67,7 @@ def __init__(self): elif args.command is None or not hasattr(self, args.command) or args.help: print(USAGE) parser.exit() - + getattr(self, args.command)() # Intialize ProtonVPN profile @@ -81,7 +81,7 @@ def init(self): if args.i: print("Inline method invoked") - + init_cli() # print(args) @@ -89,6 +89,7 @@ def init(self): def c(self): """Short for connect""" self.connect() + def connect(self): check_root() check_init() From 455d78cf89700e9e63f0ab174686ede7850f60f8 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Mon, 29 Jun 2020 16:01:28 +0100 Subject: [PATCH 13/24] Addressed Flake8 issues --- protonvpn_cli/cli.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 2f466f5..c96ac91 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -142,7 +142,7 @@ def connect(self): def r(self): """Short for reconnect""" self.reconnect() - + def reconnect(self): check_root() check_init() @@ -157,7 +157,7 @@ def disconnect(self): check_root() check_init() connection.disconnect() - + # Display VPN status information def s(self): """Short for status""" @@ -165,7 +165,7 @@ def s(self): def status(self): connection.status() - + # Open configurations menu def cf(self): """Short for configure""" @@ -183,8 +183,8 @@ def rf(self): def refresh(self): check_init() - pull_server_data(force=True) - + pull_server_data(force=True) + # Show usage examples def ex(self): """Short for examples""" From be0391bca3fd6ab333e287952560c86a997efc37 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Thu, 2 Jul 2020 09:01:59 +0100 Subject: [PATCH 14/24] Fixed Flake8 issues --- protonvpn_cli/cli.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index c96ac91..a898eac 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -74,7 +74,10 @@ def __init__(self): def init(self): """Intialiazes ProtonVPN profile. To intialize profile inline, provide the "-i" option.""" parser = argparse.ArgumentParser(description="Initialize ProtonVPN profile", prog="protonvpn init") - parser.add_argument("-i", "--inline", nargs=3, required=False, help="Inline intialize profile. (username password protocol)", metavar="") + parser.add_argument( + "-i", "--inline", nargs=3, required=False, + help="Inline intialize profile. (username password protocol)", metavar="" + ) args = parser.parse_args(sys.argv[2:]) logger.debug("Sub-arguments\n{0}".format(args)) @@ -111,7 +114,10 @@ def connect(self): group.add_argument("--sc", help="Connect to the fastest Secure-Core server.", action="store_true") group.add_argument("--p2p", help="Connect to the fastest torrent server.", action="store_true") group.add_argument("--tor", help="Connect to the fastest Tor server.", action="store_true") - parser.add_argument("-p", "--protocol", help="Connect via specified protocol.", choices=["udp", "tcp"], metavar="") + parser.add_argument( + "-p", "--protocol", help="Connect via specified protocol.", + choices=["udp", "tcp"], metavar="" + ) args = parser.parse_args(sys.argv[2:]) logger.debug("Sub-arguments:\n{0}".format(args)) @@ -184,7 +190,7 @@ def rf(self): def refresh(self): check_init() pull_server_data(force=True) - + # Show usage examples def ex(self): """Short for examples""" From 2d28f96ff9c4b63cc3b82d7c7333bc0989d3bf9f Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Thu, 2 Jul 2020 09:05:07 +0100 Subject: [PATCH 15/24] Fixed Flake8 issues --- protonvpn_cli/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protonvpn_cli/constants.py b/protonvpn_cli/constants.py index 348ed13..4816fa0 100644 --- a/protonvpn_cli/constants.py +++ b/protonvpn_cli/constants.py @@ -20,7 +20,7 @@ VERSION = "2.2.4" USAGE = """ -Official ProtonVPN CLI +ProtonVPN CLI Usage: protonvpn init From eb77b4e8755249aa24b9ffc054e95752131f8c10 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Thu, 2 Jul 2020 09:07:14 +0100 Subject: [PATCH 16/24] Fixed Flake8 issues --- protonvpn_cli/cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index a898eac..a9aa660 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -75,7 +75,7 @@ def init(self): """Intialiazes ProtonVPN profile. To intialize profile inline, provide the "-i" option.""" parser = argparse.ArgumentParser(description="Initialize ProtonVPN profile", prog="protonvpn init") parser.add_argument( - "-i", "--inline", nargs=3, required=False, + "-i", "--inline", nargs=3, required=False, help="Inline intialize profile. (username password protocol)", metavar="" ) @@ -115,7 +115,7 @@ def connect(self): group.add_argument("--p2p", help="Connect to the fastest torrent server.", action="store_true") group.add_argument("--tor", help="Connect to the fastest Tor server.", action="store_true") parser.add_argument( - "-p", "--protocol", help="Connect via specified protocol.", + "-p", "--protocol", help="Connect via specified protocol.", choices=["udp", "tcp"], metavar="" ) @@ -190,7 +190,7 @@ def rf(self): def refresh(self): check_init() pull_server_data(force=True) - + # Show usage examples def ex(self): """Short for examples""" From 67c68ac689233e22654c40a891c8fe565d35f664 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Thu, 2 Jul 2020 09:14:45 +0100 Subject: [PATCH 17/24] Examples are now inline with the CLI --- protonvpn_cli/cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index a9aa660..6261268 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -335,12 +335,12 @@ def print_examples(): " Connect to NO#3 with TCP.\n\n" "protonvpn c --fastest\n" " Connect to the fastest VPN Server.\n\n" - "protonvpn connect -cc AU\n" + "protonvpn connect --cc AU\n" " Connect to the fastest Australian server\n" " with the default protocol.\n\n" - "protonvpn c -p2p -p tcp\n" + "protonvpn c --p2p tcp\n" " Connect to the fastest torrent server with TCP.\n\n" - "protonvpn c -sc\n" + "protonvpn c --sc\n" " Connect to the fastest Secure-Core server with\n" " the default protocol.\n\n" "protonvpn reconnect\n" From 7efe076a98dab1d0df30d54d5028c028a80b259e Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Thu, 2 Jul 2020 10:51:05 +0100 Subject: [PATCH 18/24] Removed unncesessary comment --- protonvpn_cli/cli.py | 1 - 1 file changed, 1 deletion(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 6261268..1452f9c 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -7,7 +7,6 @@ import shutil import time import argparse -# External Libraries # protonvpn-cli Functions from . import connection from .logger import logger From d541079573723bc2bca26f31bcb43a62c1bca1d8 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Thu, 2 Jul 2020 15:47:18 +0100 Subject: [PATCH 19/24] Cleaned up code and improved readability --- protonvpn_cli/cli.py | 53 +++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 1452f9c..5e7529b 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -46,6 +46,12 @@ def cli(): class ProtonVPNCLI(): + server_features_dict = dict( + p2p=4, + sc=1, + tor=2 + ) + def __init__(self): parser = argparse.ArgumentParser( prog="protonvpn", @@ -63,15 +69,14 @@ def __init__(self): if args.version: print("\nProtonVPN CLI v.{}".format(VERSION)) parser.exit(1) - elif args.command is None or not hasattr(self, args.command) or args.help: + elif not args.command or not hasattr(self, args.command) or args.help: print(USAGE) - parser.exit() + parser.exit(1) getattr(self, args.command)() - # Intialize ProtonVPN profile def init(self): - """Intialiazes ProtonVPN profile. To intialize profile inline, provide the "-i" option.""" + """CLI command that intialiazes ProtonVPN profile""" parser = argparse.ArgumentParser(description="Initialize ProtonVPN profile", prog="protonvpn init") parser.add_argument( "-i", "--inline", nargs=3, required=False, @@ -85,14 +90,13 @@ def init(self): print("Inline method invoked") init_cli() - # print(args) - # Connect to VPN def c(self): - """Short for connect""" + """Short CLI command for connecting to the VPN""" self.connect() def connect(self): + """Full CLI command for connecting to the VPN""" check_root() check_init() @@ -122,7 +126,7 @@ def connect(self): logger.debug("Sub-arguments:\n{0}".format(args)) protocol = args.protocol - if protocol is not None and protocol.lower().strip() in ["tcp", "udp"]: + if protocol and protocol.lower().strip() in ["tcp", "udp"]: protocol = protocol.lower().strip() if args.random: @@ -131,71 +135,70 @@ def connect(self): connection.fastest(protocol) elif args.servername: connection.direct(args.servername, protocol) - elif args.cc is not None: + elif args.cc: connection.country_f(args.cc, protocol) - # Features: 1: Secure-Core, 2: Tor, 4: P2P elif args.p2p: - connection.feature_f(4, protocol) + connection.feature_f(self.server_features_dict.get("p2p", None), protocol) elif args.sc: - connection.feature_f(1, protocol) + connection.feature_f(self.server_features_dict.get("sc", None), protocol) elif args.tor: - connection.feature_f(2, protocol) + connection.feature_f(self.server_features_dict.get("tor", None), protocol) else: connection.dialog() - # Reconnect to last connected VPN server def r(self): - """Short for reconnect""" + """Short CLI command to reconnect to the last connected VPN Server""" self.reconnect() def reconnect(self): + """Full CLI command to reconnect to the last connected VPN Server""" check_root() check_init() connection.reconnect() - # Disconnect from VPN def d(self): - """Short for disconnect""" + """Short CLI command to disconnect the VPN if a connection is present""" self.disconnect() def disconnect(self): + """Full CLI command to disconnect the VPN if a connection is present""" check_root() check_init() connection.disconnect() - # Display VPN status information def s(self): - """Short for status""" + """Short CLI command to display the current VPN status""" self.status() def status(self): + """Full CLI command to display the current VPN status""" connection.status() - # Open configurations menu def cf(self): - """Short for configure""" + """Short CLI command to change single configuration values""" self.configure() def configure(self): + """Full CLI command to change single configuration values""" check_root() check_init() configure_cli() - # Refresh servers def rf(self): - """Short for refresh""" + """Short CLI command to refresh server list""" self.refresh() def refresh(self): + """Full CLI command to refresh server list""" check_init() pull_server_data(force=True) - # Show usage examples def ex(self): - """Short for examples""" + """Short CLI command to display usage examples""" self.examples() def examples(self): + """Full CLI command to display usage examples""" print_examples() From a0904c011ea847b0a36442239480e61721503fa9 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Fri, 3 Jul 2020 13:04:15 +0100 Subject: [PATCH 20/24] Removed dependencies still they are no longer needed --- requirements.txt | 1 - setup.py | 1 - 2 files changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0ca4cd0..4553af2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ # Call with pip install -r requirements.txt -docopt requests pythondialog jinja2 \ No newline at end of file diff --git a/setup.py b/setup.py index d99700c..c533a9f 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,6 @@ }, install_requires=[ "requests", - "docopt", "pythondialog", "jinja2", ], From 83bee2cd43c1f4463c141c230408e2ff45ccebe5 Mon Sep 17 00:00:00 2001 From: Alexandru Cheltuitor <31934100+calexandru2018@users.noreply.github.com> Date: Fri, 3 Jul 2020 15:27:56 +0100 Subject: [PATCH 21/24] Updated inline command --- protonvpn_cli/cli.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 5e7529b..35b1cd1 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -86,8 +86,9 @@ def init(self): args = parser.parse_args(sys.argv[2:]) logger.debug("Sub-arguments\n{0}".format(args)) - if args.i: - print("Inline method invoked") + if args.inline: + print("Please intialize without '-i/--inline' as it is not fully supported yet.") + sys.exit(1) init_cli() From 60579386dcd60725161f72b488134aba0a28e7af Mon Sep 17 00:00:00 2001 From: Rafficer Date: Fri, 3 Jul 2020 21:56:28 +0200 Subject: [PATCH 22/24] Allow uppercase protocol with -p --- protonvpn_cli/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 35b1cd1..54ecf74 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -120,7 +120,7 @@ def connect(self): group.add_argument("--tor", help="Connect to the fastest Tor server.", action="store_true") parser.add_argument( "-p", "--protocol", help="Connect via specified protocol.", - choices=["udp", "tcp"], metavar="" + choices=["udp", "tcp"], metavar="", type=str.lower ) args = parser.parse_args(sys.argv[2:]) From 36cf1ec25ad909971cfcf67c636f1d27e3f406c9 Mon Sep 17 00:00:00 2001 From: Rafficer Date: Fri, 3 Jul 2020 21:57:26 +0200 Subject: [PATCH 23/24] Allign help message --- protonvpn_cli/constants.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/protonvpn_cli/constants.py b/protonvpn_cli/constants.py index 4816fa0..d5aff0c 100644 --- a/protonvpn_cli/constants.py +++ b/protonvpn_cli/constants.py @@ -57,9 +57,9 @@ r, reconnect Reconnect to the last server. d, disconnect Disconnect the current session. s, status Show connection status. - cf, configure Change ProtonVPN-CLI configuration. - rf, refresh Refresh OpenVPN configuration and server data. - ex, examples Print some example commands. + cf, configure Change ProtonVPN-CLI configuration. + rf, refresh Refresh OpenVPN configuration and server data. + ex, examples Print some example commands. Arguments: Servername (CH#4, CH-US-1, HK5-Tor). From 204676dec5a3f928965fa88f522235939f5523e4 Mon Sep 17 00:00:00 2001 From: Rafficer Date: Fri, 3 Jul 2020 22:02:20 +0200 Subject: [PATCH 24/24] Return missing -p to example --- protonvpn_cli/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protonvpn_cli/cli.py b/protonvpn_cli/cli.py index 54ecf74..c2e37cd 100644 --- a/protonvpn_cli/cli.py +++ b/protonvpn_cli/cli.py @@ -341,7 +341,7 @@ def print_examples(): "protonvpn connect --cc AU\n" " Connect to the fastest Australian server\n" " with the default protocol.\n\n" - "protonvpn c --p2p tcp\n" + "protonvpn c --p2p -p tcp\n" " Connect to the fastest torrent server with TCP.\n\n" "protonvpn c --sc\n" " Connect to the fastest Secure-Core server with\n"