diff --git a/custom_pvpn_cli_ng/protonvpn_cli/connection.py b/custom_pvpn_cli_ng/protonvpn_cli/connection.py
index ea8a0e4..932e0ad 100644
--- a/custom_pvpn_cli_ng/protonvpn_cli/connection.py
+++ b/custom_pvpn_cli_ng/protonvpn_cli/connection.py
@@ -162,7 +162,9 @@ def fastest(protocol=None, gui_enabled=False):
server_pool.append(server)
fastest_server = get_fastest_server(server_pool)
- openvpn_connect(fastest_server, protocol, gui_enabled)
+ if gui_enabled:
+ return openvpn_connect(fastest_server, protocol, gui_enabled)
+ openvpn_connect(fastest_server, protocol)
def country_f(country_code, protocol=None):
@@ -348,7 +350,7 @@ def disconnect(passed=False):
logger.debug("No connection found")
-def status():
+def status(gui_enabled=False):
"""
Display the current VPN status
diff --git a/protonvpn_linux_gui/constants.py b/protonvpn_linux_gui/constants.py
index f5f1afc..569fa38 100644
--- a/protonvpn_linux_gui/constants.py
+++ b/protonvpn_linux_gui/constants.py
@@ -1,4 +1,4 @@
-VERSION = "1.1.5"
+VERSION = "1.2.0"
PATH_AUTOCONNECT_SERVICE = "/etc/systemd/system/protonvpn-autoconnect.service"
TEMPLATE ="""
[Unit]
diff --git a/protonvpn_linux_gui/gui.py b/protonvpn_linux_gui/gui.py
index cc3498f..1061797 100644
--- a/protonvpn_linux_gui/gui.py
+++ b/protonvpn_linux_gui/gui.py
@@ -3,6 +3,8 @@
import re
import sys
import pathlib
+from threading import Thread
+import time
# ProtonVPN base CLI package import
from custom_pvpn_cli_ng.protonvpn_cli.constants import (USER, CONFIG_FILE, CONFIG_DIR, VERSION)
@@ -110,6 +112,9 @@ def connect_to_selected_server_button_clicked(self, button):
connection.openvpn_connect(selected_server, protocol)
update_labels_status(self.interface)
+ # def log_result(self, res):
+ # return res
+
def quick_connect_button_clicked(self, button):
"""Button/Event handler to connect to the fastest server
"""
@@ -138,9 +143,11 @@ def disconnect_button_clicked(self, button):
def refresh_server_list_button_clicked(self, button):
"""Button/Event handler to refresh/repopulate server list
+ - At the moment, will also refresh the Dashboard information, this will be fixed in the future.
"""
server_list_object = self.interface.get_object("ServerListStore")
populate_server_list(server_list_object)
+ update_labels_status(self.interface)
def about_menu_button_clicked(self, button):
"""Button /Event handlerto open About dialog
@@ -299,27 +306,20 @@ def purge_configurations_button_clicked(self, button):
cli.purge_configuration(gui_enabled=True)
class initialize_gui:
- """Initializes a GUI
- -----
- The GUI only makes external calls to the cli commands.
- -----
- Will request for the same data protonvpn init to initialize a user:
- -Username
- -Password
- -Plan
- -Protocol
-
- There are two ways of starting this GUI, either by reversing the commented code so that it can be launched as part of the CLI:
+ """Initializes the GUI
---
- -protonvpn gui:
- This will start from within the main CLI menu. Gui is invoked through cli()
-
- Or leave it be as it is, and configuration is setup during installation with "pip3 install -e .", this way it can be launched as a separte command from the usual CLI:
- -protonvpn-gui:
- This will start the GUI without invoking cli()
+ If user has not initialized a profile, the GUI will ask for the following data:
+ - Username
+ - Password
+ - Plan
+ - Protocol
+
+ sudo protonvpn-gui
+ - Will start the GUI without invoking cli()
"""
def __init__(self):
check_root()
+
interface = Gtk.Builder()
posixPath = pathlib.PurePath(pathlib.Path(__file__).parent.absolute().joinpath("resources/main.glade"))
@@ -338,6 +338,7 @@ def __init__(self):
window = interface.get_object("LoginWindow")
else:
window = interface.get_object("Dashboard")
+ window.connect("destroy", Gtk.main_quit)
load_on_start(interface)
window.show()
diff --git a/protonvpn_linux_gui/resources/main.glade b/protonvpn_linux_gui/resources/main.glade
index 9b08c17..68f6c36 100644
--- a/protonvpn_linux_gui/resources/main.glade
+++ b/protonvpn_linux_gui/resources/main.glade
@@ -1358,7 +1358,7 @@ ProtonVPN Unofficial GUI: calexandru2018
80
80
15
- 35
+ 15
True
1
@@ -1387,157 +1387,507 @@ ProtonVPN Unofficial GUI: calexandru2018
@@ -1549,6 +1899,8 @@ ProtonVPN Unofficial GUI: calexandru2018
+ -1
+ 4
True
False
30
diff --git a/protonvpn_linux_gui/resources/main.glade~ b/protonvpn_linux_gui/resources/main.glade~
index 68dc6b0..7ab4f66 100644
--- a/protonvpn_linux_gui/resources/main.glade~
+++ b/protonvpn_linux_gui/resources/main.glade~
@@ -1358,7 +1358,7 @@ ProtonVPN Unofficial GUI: calexandru2018
80
80
15
- 35
+ 15
True
1
@@ -1375,38 +1375,6 @@ ProtonVPN Unofficial GUI: calexandru2018
4
-
-
- Start on Boot
- True
- True
- True
-
-
-
- 1
- 1
-
-
-
-
- Disable start on boot
- True
- True
- True
-
-
-
- 2
- 1
-
-
-
-
-
-
-
-
False
@@ -1419,157 +1387,510 @@ ProtonVPN Unofficial GUI: calexandru2018
True
False
- center
+ center
60
60
- 20
- 5
-
-
- -1
- True
- False
- start
- False
- VPN Status:
- fill
-
-
-
-
-
-
- 0
- 0
-
-
+ True
+ 150
+ True
-
- -1
+
True
False
- start
- True
- DNS Protection:
- fill
-
-
-
-
+ 30
+ 20
+ True
+
+
+ -1
+ True
+ False
+ start
+ True
+ Time connected:
+ fill
+
+
+
+
+
+
+ 0
+ 2
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+ 1
+ 2
+
+
+
+
+ -1
+ True
+ False
+ start
+ False
+ VPN Status:
+ fill
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ Running
+ fill
+
+
+
+
+
+
+ 1
+ 0
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ DNS Protection:
+ fill
+
+
+
+
+
+
+ 0
+ 1
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ Custom
+ fill
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ Killswitch Setting:
+ fill
+
+
+
+
+
+
+ 0
+ 3
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ Protocol:
+ fill
+
+
+
+
+
+
+ 0
+ 4
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ Features:
+ fill
+
+
+
+
+
+
+ 0
+ 5
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+
+ 1
+ 3
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+
+ 1
+ 4
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+
+ 1
+ 5
+
+
0
- 1
-
-
-
-
- -1
- True
- False
- start
- True
- Running
- fill
-
-
-
-
-
-
-
- 1
- 0
-
-
-
-
- -1
- True
- False
- start
- True
- Custom
- fill
-
-
-
-
-
-
-
- 1
- 1
-
-
-
-
- -1
- True
- False
- end
- 40
- IP:
-
-
-
-
-
-
- 2
0
+ 2
+ 10
-
- -1
+
True
False
- end
- 40
- Country:
-
-
-
-
+ 100
+ 20
+ True
+
+
+ -1
+ True
+ False
+ start
+ True
+
+
+
+
+
+
+ 1
+ 0
+
+
+
+
+ -1
+ True
+ False
+ start
+ Country:
+
+
+
+
+
+
+ 0
+ 4
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+
+
+
+
+
+
+ 1
+ 4
+
+
+
+
+ -1
+ True
+ False
+ start
+ City:
+
+
+
+
+
+
+ 0
+ 3
+
+
+
+
+ -1
+ True
+ False
+ start
+ Server:
+
+
+
+
+
+
+ 0
+ 2
+
+
+
+
+ -1
+ True
+ False
+ start
+ Load:
+
+
+
+
+
+
+ 0
+ 1
+
+
+
+
+ -1
+ True
+ False
+ start
+ Received:
+
+
+
+
+
+
+ 0
+ 5
+
+
+
+
+ -1
+ True
+ False
+ start
+ Sent:
+
+
+
+
+
+
+ 0
+ 6
+
+
+
+
+ -1
+ True
+ False
+ start
+ IP:
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+ 1
+ 2
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+ 1
+ 3
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+ 1
+ 5
+
+
+
+
+ -1
+ True
+ False
+ start
+ True
+ fill
+
+
+
+
+
+
+ 1
+ 6
+
+
2
- 1
-
-
-
-
- -1
- True
- False
- start
- True
-
-
-
-
-
-
- 3
- 1
-
-
-
-
- -1
- True
- False
- start
- True
-
-
-
-
-
-
- 3
0
+ 4
+ 10
@@ -1581,6 +1902,8 @@ ProtonVPN Unofficial GUI: calexandru2018
+ -1
+ 4
True
False
30
diff --git a/protonvpn_linux_gui/utils.py b/protonvpn_linux_gui/utils.py
index 675e8a3..0261c6c 100644
--- a/protonvpn_linux_gui/utils.py
+++ b/protonvpn_linux_gui/utils.py
@@ -3,6 +3,8 @@
import shutil
import fileinput
import subprocess
+import time
+import datetime
from custom_pvpn_cli_ng.protonvpn_cli.utils import (
pull_server_data,
@@ -13,9 +15,12 @@
set_config_value,
check_root,
is_connected,
- get_ip_info
+ get_ip_info,
+ get_transferred_data
)
+from custom_pvpn_cli_ng.protonvpn_cli.connection import status
+
from custom_pvpn_cli_ng.protonvpn_cli.constants import SPLIT_TUNNEL_FILE
from .constants import PATH_AUTOCONNECT_SERVICE, TEMPLATE
@@ -68,33 +73,128 @@ def load_on_start(interface):
def update_labels_status(interface):
"""Updates labels status
"""
- vpn_status_label = interface.get_object("vpn_status_label")
- dns_status_label = interface.get_object("dns_status_label")
- ip_label = interface.get_object("ip_label")
- country_label = interface.get_object("country_label")
+ servers = get_servers()
+ protonvpn_conn_check = is_connected()
+ is_vpn_connected = True if protonvpn_conn_check else False
+ try:
+ connected_server = get_config_value("metadata", "connected_server")
+ except:
+ connected_server = False
+ left_grid_update_labels(interface, servers, is_vpn_connected, connected_server)
+ right_grid_update_labels(interface, servers, is_vpn_connected, connected_server)
+
+def left_grid_update_labels(interface, servers, is_connected, connected_server):
+ """
+ """
- # Check VPN status
- if is_connected() != True:
- vpn_status_label.set_markup('Not Running')
+ # Left grid
+ vpn_status_label = interface.get_object("vpn_status_label")
+ dns_status_label = interface.get_object("dns_status_label")
+ time_connected_label = interface.get_object("time_connected_label")
+ killswitch_label = interface.get_object("killswitch_label")
+ protocol_label = interface.get_object("openvpn_protocol_label")
+ server_features_label = interface.get_object("server_features_label")
+
+ all_features = {0: "Normal", 1: "Secure-Core", 2: "Tor", 4: "P2P"}
+ connection_time = False
+ connected_to_protocol = False
+
+ # Check and set VPN status label. Get also protocol status if vpn is connected
+ if is_connected != True:
+ vpn_status_label.set_markup('Disconnected')
else:
- vpn_status_label.set_markup('Running')
+ vpn_status_label.set_markup('Connected')
+ try:
+ connected_time = get_config_value("metadata", "connected_time")
+ connection_time = time.time() - int(connected_time)
+ connection_time = str(datetime.timedelta(seconds=connection_time)).split(".")[0]
+ connected_to_protocol = get_config_value("metadata", "connected_proto")
+ except KeyError:
+ connection_time = False
+ connected_to_protocol = False
- # Check DNS status
+ # Check and set DNS status label
dns_enabled = get_config_value("USER", "dns_leak_protection")
if int(dns_enabled) != 1:
dns_status_label.set_markup('Not Enabled')
else:
dns_status_label.set_markup('Enabled')
- ip, isp, country = get_ip_info(gui_enbled=True)
+ # Set time connected label
+ connection_time = connection_time if connection_time else ""
+ time_connected_label.set_markup('{0}'.format(connection_time))
+
+ # Check and set killswitch label
+ connected_time = get_config_value("USER", "killswitch")
+ killswitch_status = "Enabled" if connected_time == 0 else "Disabled"
+ killswitch_label.set_markup('{0}'.format(killswitch_status))
+
+ # Check and set protocol label
+ connected_to_protocol = connected_to_protocol if connected_to_protocol else ""
+ protocol_label.set_markup('{0}'.format(connected_to_protocol))
+
+ # Check and set feature label
+ try:
+ feature = get_server_value(connected_server, "Features", servers)
+ except:
+ feature = False
- ip = "" + ip + ""
- country_isp = "" + country + "/" + isp + ""
+ feature = all_features[feature] if is_connected else ""
+ server_features_label.set_markup('{0}'.format(feature))
+def right_grid_update_labels(interface, servers, is_connected, connected_server):
+ """
+ """
+
+ # Right grid
+ ip_label = interface.get_object("ip_label")
+ server_load_label = interface.get_object("server_load_label")
+ server_name_label = interface.get_object("server_name_label")
+ server_city_label = interface.get_object("server_city_label")
+ country_label = interface.get_object("country_label")
+ data_received_label = interface.get_object("data_received_label")
+ data_sent_label = interface.get_object("data_sent_label")
+
+ tx_amount, rx_amount = get_transferred_data()
+
+ # Get and set IP labels. Get also country and ISP
+ ip, isp, country = get_ip_info(gui_enbled=True)
+ country_isp = "" + country + "/" + isp + ""
ip_label.set_markup(ip)
+
+ # Get and set server load label
+ try:
+ load = get_server_value(connected_server, "Load", servers)
+ except:
+ load = False
+ load = "{0}%".format(load) if load and is_connected else ""
+ server_load_label.set_markup('{0}'.format(load))
+
+ # Get and set server name
+ connected_server = connected_server if connected_server and is_connected else ""
+ server_name_label.set_markup('{0}'.format(connected_server))
+
+ # Get and set city label
+ try:
+ city = get_server_value(connected_server, "City", servers)
+ except:
+ city = False
+ city = city if city else ""
+ server_city_label.set_markup('{0}'.format(city))
+
+ # Set country label and ISP labels
+ ip = "" + ip + ""
country_label.set_markup(country_isp)
+ # Get and set recieved data
+ rx_amount = rx_amount if is_connected else ""
+ data_received_label.set_markup('{0}'.format(rx_amount))
+
+ # Get and set sent data
+ tx_amount = tx_amount if is_connected else ""
+ data_sent_label.set_markup('{0}'.format(tx_amount))
+
def load_configurations(interface):
"""Set and populate user configurations before showing the configurations window
"""
@@ -212,6 +312,12 @@ def populate_server_list(server_list_object):
server_list_object.append([country, servername, tier, load, feature])
+# Autoconnect
+#
+# To- do
+#
+# Autoconnect
+
def manage_autoconnect(mode):
"""Manages autoconnect functionality
"""