1
- """
2
- A CLI for ProtonVPN.
3
-
4
- Usage:
5
- protonvpn init
6
- protonvpn (c | connect) [<servername>] [-p <protocol>]
7
- protonvpn (c | connect) [-f | --fastest] [-p <protocol>]
8
- protonvpn (c | connect) [--cc <code>] [-p <protocol>]
9
- protonvpn (c | connect) [--sc] [-p <protocol>]
10
- protonvpn (c | connect) [--p2p] [-p <protocol>]
11
- protonvpn (c | connect) [--tor] [-p <protocol>]
12
- protonvpn (c | connect) [-r | --random] [-p <protocol>]
13
- protonvpn (r | reconnect)
14
- protonvpn (d | disconnect)
15
- protonvpn (s | status)
16
- protonvpn configure
17
- protonvpn refresh
18
- protonvpn examples
19
- protonvpn (-h | --help)
20
- protonvpn (-v | --version)
21
-
22
- Options:
23
- -f, --fastest Select the fastest ProtonVPN server.
24
- -r, --random Select a random ProtonVPN server.
25
- --cc CODE Determine the country for fastest connect.
26
- --sc Connect to the fastest Secure-Core server.
27
- --p2p Connect to the fastest torrent server.
28
- --tor Connect to the fastest Tor server.
29
- -p PROTOCOL Determine the protocol (UDP or TCP).
30
- -h, --help Show this help message.
31
- -v, --version Display version.
32
-
33
- Commands:
34
- init Initialize a ProtonVPN profile.
35
- c, connect Connect to a ProtonVPN server.
36
- r, reconnect Reconnect to the last server.
37
- d, disconnect Disconnect the current session.
38
- s, status Show connection status.
39
- configure Change ProtonVPN-CLI configuration.
40
- refresh Refresh OpenVPN configuration and server data.
41
- examples Print some example commands.
42
-
43
- Arguments:
44
- <servername> Servername (CH#4, CH-US-1, HK5-Tor).
45
- """
46
1
# Standard Libraries
47
2
import sys
48
3
import os
51
6
import getpass
52
7
import shutil
53
8
import time
54
- # External Libraries
55
- from docopt import docopt
9
+ import argparse
56
10
# protonvpn-cli Functions
57
11
from . import connection
58
12
from .logger import logger
63
17
)
64
18
# Constants
65
19
from .constants import (
66
- CONFIG_DIR , CONFIG_FILE , PASSFILE , USER , VERSION , SPLIT_TUNNEL_FILE
20
+ CONFIG_DIR , CONFIG_FILE , PASSFILE , USER , VERSION , SPLIT_TUNNEL_FILE , USAGE
67
21
)
68
22
69
23
@@ -88,13 +42,62 @@ def cli():
88
42
logger .debug ("USER: {0}" .format (USER ))
89
43
logger .debug ("CONFIG_DIR: {0}" .format (CONFIG_DIR ))
90
44
91
- args = docopt (__doc__ , version = "ProtonVPN-CLI v{0}" .format (VERSION ))
92
- logger .debug ("Arguments\n {0}" .format (str (args ).replace ("\n " , "" )))
45
+ ProtonVPNCLI ()
46
+
47
+
48
+ class ProtonVPNCLI ():
49
+ server_features_dict = dict (
50
+ p2p = 4 ,
51
+ sc = 1 ,
52
+ tor = 2
53
+ )
54
+
55
+ def __init__ (self ):
56
+ parser = argparse .ArgumentParser (
57
+ prog = "protonvpn" ,
58
+ add_help = False
59
+ )
60
+
61
+ parser .add_argument ("command" , nargs = "?" )
62
+ parser .add_argument ("-v" , "--version" , required = False , action = "store_true" )
63
+ parser .add_argument ("-h" , "--help" , required = False , action = "store_true" )
64
+
65
+ args = parser .parse_args (sys .argv [1 :2 ])
66
+
67
+ logger .debug ("Main argument\n {0}" .format (args ))
68
+
69
+ if args .version :
70
+ print ("\n ProtonVPN CLI v.{}" .format (VERSION ))
71
+ parser .exit (1 )
72
+ elif not args .command or not hasattr (self , args .command ) or args .help :
73
+ print (USAGE )
74
+ parser .exit (1 )
75
+
76
+ getattr (self , args .command )()
77
+
78
+ def init (self ):
79
+ """CLI command that intialiazes ProtonVPN profile"""
80
+ parser = argparse .ArgumentParser (description = "Initialize ProtonVPN profile" , prog = "protonvpn init" )
81
+ parser .add_argument (
82
+ "-i" , "--inline" , nargs = 3 , required = False ,
83
+ help = "Inline intialize profile. (username password protocol)" , metavar = ""
84
+ )
85
+
86
+ args = parser .parse_args (sys .argv [2 :])
87
+ logger .debug ("Sub-arguments\n {0}" .format (args ))
88
+
89
+ if args .inline :
90
+ print ("Please intialize without '-i/--inline' as it is not fully supported yet." )
91
+ sys .exit (1 )
93
92
94
- # Parse arguments
95
- if args .get ("init" ):
96
93
init_cli ()
97
- elif args .get ("c" ) or args .get ("connect" ):
94
+
95
+ def c (self ):
96
+ """Short CLI command for connecting to the VPN"""
97
+ self .connect ()
98
+
99
+ def connect (self ):
100
+ """Full CLI command for connecting to the VPN"""
98
101
check_root ()
99
102
check_init ()
100
103
@@ -106,45 +109,97 @@ def cli():
106
109
if int (os .environ .get ("PVPN_WAIT" , 0 )) > 0 :
107
110
wait_for_network (int (os .environ ["PVPN_WAIT" ]))
108
111
109
- protocol = args .get ("-p" )
110
- if protocol is not None and protocol .lower ().strip () in ["tcp" , "udp" ]:
112
+ parser = argparse .ArgumentParser (description = "Connect to ProtonVPN" , prog = "protonvpn c" )
113
+ group = parser .add_mutually_exclusive_group ()
114
+ group .add_argument ("servername" , nargs = "?" , help = "Servername (CH#4, CH-US-1, HK5-Tor)." , metavar = "" )
115
+ group .add_argument ("-f" , "--fastest" , help = "Connect to the fastest ProtonVPN server." , action = "store_true" )
116
+ group .add_argument ("-r" , "--random" , help = "Connect to a random ProtonVPN server." , action = "store_true" )
117
+ group .add_argument ("--cc" , help = "Connect to the specified country code (SE, PT, BR, AR)." , metavar = "" )
118
+ group .add_argument ("--sc" , help = "Connect to the fastest Secure-Core server." , action = "store_true" )
119
+ group .add_argument ("--p2p" , help = "Connect to the fastest torrent server." , action = "store_true" )
120
+ group .add_argument ("--tor" , help = "Connect to the fastest Tor server." , action = "store_true" )
121
+ parser .add_argument (
122
+ "-p" , "--protocol" , help = "Connect via specified protocol." ,
123
+ choices = ["udp" , "tcp" ], metavar = "" , type = str .lower
124
+ )
125
+
126
+ args = parser .parse_args (sys .argv [2 :])
127
+ logger .debug ("Sub-arguments:\n {0}" .format (args ))
128
+
129
+ protocol = args .protocol
130
+ if protocol and protocol .lower ().strip () in ["tcp" , "udp" ]:
111
131
protocol = protocol .lower ().strip ()
112
132
113
- if args .get ( "-- random" ) :
133
+ if args .random :
114
134
connection .random_c (protocol )
115
- elif args .get ( "-- fastest" ) :
135
+ elif args .fastest :
116
136
connection .fastest (protocol )
117
- elif args .get ("<servername>" ):
118
- connection .direct (args .get ("<servername>" ), protocol )
119
- elif args .get ("--cc" ) is not None :
120
- connection .country_f (args .get ("--cc" ), protocol )
121
- # Features: 1: Secure-Core, 2: Tor, 4: P2P
122
- elif args .get ("--p2p" ):
123
- connection .feature_f (4 , protocol )
124
- elif args .get ("--sc" ):
125
- connection .feature_f (1 , protocol )
126
- elif args .get ("--tor" ):
127
- connection .feature_f (2 , protocol )
137
+ elif args .servername :
138
+ connection .direct (args .servername , protocol )
139
+ elif args .cc :
140
+ connection .country_f (args .cc , protocol )
141
+ elif args .p2p :
142
+ connection .feature_f (self .server_features_dict .get ("p2p" , None ), protocol )
143
+ elif args .sc :
144
+ connection .feature_f (self .server_features_dict .get ("sc" , None ), protocol )
145
+ elif args .tor :
146
+ connection .feature_f (self .server_features_dict .get ("tor" , None ), protocol )
128
147
else :
129
148
connection .dialog ()
130
- elif args .get ("r" ) or args .get ("reconnect" ):
149
+
150
+ def r (self ):
151
+ """Short CLI command to reconnect to the last connected VPN Server"""
152
+ self .reconnect ()
153
+
154
+ def reconnect (self ):
155
+ """Full CLI command to reconnect to the last connected VPN Server"""
131
156
check_root ()
132
157
check_init ()
133
158
connection .reconnect ()
134
- elif args .get ("d" ) or args .get ("disconnect" ):
159
+
160
+ def d (self ):
161
+ """Short CLI command to disconnect the VPN if a connection is present"""
162
+ self .disconnect ()
163
+
164
+ def disconnect (self ):
165
+ """Full CLI command to disconnect the VPN if a connection is present"""
135
166
check_root ()
136
167
check_init ()
137
168
connection .disconnect ()
138
- elif args .get ("s" ) or args .get ("status" ):
169
+
170
+ def s (self ):
171
+ """Short CLI command to display the current VPN status"""
172
+ self .status ()
173
+
174
+ def status (self ):
175
+ """Full CLI command to display the current VPN status"""
139
176
connection .status ()
140
- elif args .get ("configure" ):
177
+
178
+ def cf (self ):
179
+ """Short CLI command to change single configuration values"""
180
+ self .configure ()
181
+
182
+ def configure (self ):
183
+ """Full CLI command to change single configuration values"""
141
184
check_root ()
142
185
check_init ()
143
186
configure_cli ()
144
- elif args .get ("refresh" ):
187
+
188
+ def rf (self ):
189
+ """Short CLI command to refresh server list"""
190
+ self .refresh ()
191
+
192
+ def refresh (self ):
193
+ """Full CLI command to refresh server list"""
145
194
check_init ()
146
195
pull_server_data (force = True )
147
- elif args .get ("examples" ):
196
+
197
+ def ex (self ):
198
+ """Short CLI command to display usage examples"""
199
+ self .examples ()
200
+
201
+ def examples (self ):
202
+ """Full CLI command to display usage examples"""
148
203
print_examples ()
149
204
150
205
0 commit comments