def set_individual_server(servername, images_dict, servers, feature): server_tiers = {0: "Free", 1: "Basic", 2: "Plus/Visionary"} features = {0: "Normal", 1: "Secure-Core", 2: "Tor", 4: "P2P"} secure_core = False load = str(get_server_value(servername, "Load", servers)).rjust(3, " ") load = load + "%" tier = server_tiers[get_server_value(servername, "Tier", servers)] if not "Plus/Visionary".lower() == tier.lower(): plus_feature = images_dict["empty_pix"] else: plus_feature = images_dict["plus_pix"] server_feature = features[get_server_value(servername, 'Features', servers)].lower() if server_feature == "Normal".lower(): feature = images_dict["empty_pix"] elif server_feature == "P2P".lower(): feature = images_dict["p2p_pix"] elif server_feature == "Tor".lower(): feature = images_dict["tor_pix"] else: # Should be secure core secure_core = True return (servername, plus_feature, feature, load, secure_core)
def get_country_avrg_features(self, country, country_servers, servers, only_secure_core): """Function that returns average load and features of a specific country. """ features = {0: "Normal", 1: "Secure-Core", 2: "Tor", 4: "P2P"} # Variables for average per country count = 0 load_sum = 0 # Variable for feature per country features_per_country = set() order_dict = { "normal": 0, "p2p": 1, "tor": 2, "secure-core": 3, } top_choice = 0 for servername in country_servers[country]: # Get average per country load_sum = load_sum + int( str(get_server_value(servername, "Load", servers)).rjust( 3, " ")) count += 1 # Get features per country feature = features[get_server_value(servername, 'Features', servers)] features_per_country.add(feature) # Convert set to list country_feature_list = list(features_per_country) for feature in country_feature_list: for k, v in order_dict.items(): if feature.lower() == k.lower(): # if top_choice < v and (not only_secure_core and not v > 2): if top_choice < v: top_choice = v if top_choice == 0: top_choice = "normal" elif top_choice == 1: top_choice = "p2p" elif top_choice == 2: top_choice = "tor" else: top_choice = "secure-core" # print(country,top_choice) return (str(int(round(load_sum / count))) + "%", top_choice)
def update_serverload(self, _): """Updates server load. """ gui_logger.debug("TRAY >>> Updating server load in update_serverload.") connected_server = False load = False try: connected_server = get_config_value("metadata", "connected_server") except KeyError: gui_logger.debug("[!] Could not find specified key: ".format(KeyError)) return True # force_pull servers try: pull_server_data(force=True) except: gui_logger.debug("[!] Could not pull from servers, possible due to unstable connection.") return True # get_servers servers = get_servers() # get server load try: load = get_server_value(connected_server, "Load", servers) except: gui_logger.debug("[!] Unable to get server load.") return True self.serverload_msg = "Load: {}%".format(load) return True
def get_country_servers(self, servers): countries = {} for server in servers: country = get_country_name(server["ExitCountry"]) if country not in countries.keys(): countries[country] = [] countries[country].append(server["Name"]) country_servers = {} # Order server list by country alphabetically countries = collections.OrderedDict(sorted(countries.items())) for country in countries: country_servers[country] = sorted(countries[country], key=lambda s: get_server_value(s, "Load", servers)) return country_servers
def update_current_connection(self, *dt): """Update the current connection info.""" # Check for active connection self.vpn_connected = self.is_connected() if self.vpn_connected: # Cancel scheduled events, if they exist. if self.data_trans: self.data_trans.cancel() if self.cnxn_time: self.cnxn_time.cancel() servers = pvpncli_utils.get_servers() ip = None while not ip: try: ip = pvpncli_utils.get_ip_info()[0] # except Exception as e: except SystemExit: print( 'Exception from update_current_connection(): SystemExit' ) # noqa print('reconnect cmd sent') self.exec_cmd('protonvpn reconnect') self.ids.main_screen.ids.exit_server_ip.text = f'IP: {ip}' connected_server = None try: connected_server = pvpncli_utils.get_config_value( "metadata", "connected_server", ) self.last_known_connection = connected_server except KeyError: self.last_known_connection = None # Set Secure Core switch if app newly initialized. Otherwise the # switch state is determined by User interaction afterwards. if self.app_newly_initialized: feature = pvpncli_utils.get_server_value( connected_server, "Features", servers, ) if feature == 1: self.secure_core.state = 'down' else: self.secure_core.state = 'normal' self.app_newly_initialized = False country_code = pvpncli_utils.get_server_value( connected_server, "ExitCountry", servers, ) cnxn_window = self.ids.main_screen.ids.connection_window flag = f'./images/flags/large/{country_code.lower()}-large.jpg' cnxn_window.img_source = flag country = pvpncli_utils.get_country_name(country_code) exit_server_info = f'{country} >> {connected_server}' self.ids.main_screen.ids.exit_server.text = exit_server_info self.ids.main_screen.ids.exit_server.color = [1, 1, 1, 1] connected_protocol = pvpncli_utils.get_config_value( "metadata", "connected_proto", ) self.ids.main_screen.ids.protocol.text = ( f'OpenVPN ({connected_protocol.upper()})') load = pvpncli_utils.get_server_value( connected_server, "Load", servers, ) self.ids.main_screen.ids.exit_server_load.text = f'{load}% Load' down = self.ids.main_screen.ids.bitrate_down_arrow down.source = './images/bitrate-download-arrow.png' up = self.ids.main_screen.ids.bitrate_up_arrow up.source = './images/bitrate-upload-arrow.png' # Make text visible. self.ids.main_screen.ids.data_received.color = [1, 1, 1, 1] self.ids.main_screen.ids.data_sent.color = [1, 1, 1, 1] # Set connection window button as 'Disconnect' self.cnxn_wndw_btn.normal_img = './images/disconnect.png' self.cnxn_wndw_btn.hover_img = './images/disconnect_hover.png' self.cnxn_wndw_btn.source = './images/disconnect.png' # Schedule events self.data_trans() self.cnxn_time() else: # VPN isn't connected, so clear the conneciton info on screen. self.set_disconnected()
def status(self) -> str: """ Return the current VPN status. Showing connection status (connected/disconnected), current IP, server name, country, server load """ if not self._check_configs(): return 'Settings problem. Please run "protonvpn init".' killswitch_active = is_killswitch_active(CONFIG_DIR) if not is_connected(): msgs = ['Not connected'] if killswitch_active: msgs.append('Kill Switch is currently active.') ip, isp = get_ip_info() msgs.extend((f'IP: {ip}', f'ISP: {isp}')) return '\n'.join(msgs) pull_server_data() metadata = self.config.get('metadata', {}) current_server = metadata.get("connected_server", None) current_protocol = metadata.get("connected_proto", None) dns_server = metadata.get("dns_server", None) if not metadata or \ not all((current_server, current_protocol, dns_server)): return 'Please connect with "protonvpn connect" first.' if not is_server_reachable(dns_server): msgs = ('Could not reach VPN server', 'You may want to reconnect with "protonvpn reconnect"') return '\n'.join(msgs) servers = get_servers() subs = [s["Servers"] for s in servers if s["Name"] == current_server] server_ips = [subserver["ExitIP"] for subserver in subs[0]] ip, isp = get_ip_info() all_features = {0: "Normal", 1: "Secure-Core", 2: "Tor", 4: "P2P"} country_code = get_server_value(current_server, "ExitCountry", servers) country = get_country_name(country_code) city = get_server_value(current_server, "City", servers) load = get_server_value(current_server, "Load", servers) feature = get_server_value(current_server, "Features", servers) last_connection = metadata.get("connected_time") connection_time = time.time() - int(last_connection) killswitch_status = "Enabled" if killswitch_active else "Disabled" connection_time = str(datetime.timedelta( seconds=connection_time)).split(".")[0] msgs = ( "Status: Connected", f"Time: {connection_time}", f"IP: {ip}", f"Server: {current_server}", f"Features: {all_features[feature]}", f"Protocol: {current_protocol.upper()}", f"Kill Switch: {killswitch_status}", f"Country: {country}", f"City: {city}", f"Load: {load}", ) return '\n'.join(msgs)
def update_labels_status(update_labels_dict): """Function prepares data to update labels. """ gui_logger.debug( ">>> Running \"update_labels_status\" getting servers, is_connected and connected_server." ) if not update_labels_dict["servers"]: servers = get_servers() else: servers = update_labels_dict["servers"] interface = update_labels_dict["interface"] disconnecting = update_labels_dict["disconnecting"] conn_info = update_labels_dict["conn_info"] is_vpn_connected = True if is_connected() else False country_cc = False load = False time_connected_label = interface.get_object("time_connected_label") protocol_label = interface.get_object("protocol_label") conn_disc_button_label = interface.get_object( "main_conn_disc_button_label") ip_label = interface.get_object("ip_label") server_load_label = interface.get_object("server_load_label") country_label = interface.get_object("country_label") isp_label = interface.get_object("isp_label") data_received_label = interface.get_object("data_received_label") data_sent_label = interface.get_object("data_sent_label") background_large_flag = interface.get_object("background_large_flag") protonvpn_sign_green = interface.get_object("protonvpn_sign_green") try: connected_server = get_config_value("metadata", "connected_server") except (KeyError, IndexError): connected_server = False # Get and set server load label try: load = get_server_value(connected_server, "Load", servers) except (KeyError, IndexError): gui_logger.debug("[!] Could not find server load information.") load = "{0}% Load".format(load) if load and is_vpn_connected else "" server_load_label.set_markup('<span>{0}</span>'.format(load)) # Get and set IP labels. Get also country and ISP if not conn_info: result = custom_get_ip_info() if result: ip, isp, country = result else: ip = "None" isp = "None" country = "None" else: ip, isp, country = conn_info for k, v in country_codes.items(): if k == country: if is_vpn_connected: flag_path = LARGE_FLAGS_BASE_PATH + "{}.jpg".format(k.lower()) background_large_flag.set_from_file(flag_path) country_cc = v protonvpn_sign_green.hide() country_server = country_cc if is_vpn_connected: try: country_server = country_server + " >> " + connected_server except TypeError: country_server = country_server + " >> " protonvpn_sign_green.show() ip_label.set_markup(ip) isp_label.set_markup(isp) # Get and set server name connected_server = connected_server if connected_server and is_vpn_connected else "" country_label.set_markup(country_server if country_server else "") # Update sent and received data gobject.timeout_add_seconds( 1, update_sent_received_data, { "is_vpn_connected": is_vpn_connected, "received_label": data_received_label, "sent_label": data_sent_label }) # Check and set VPN status label. Get also protocol status if vpn is connected protocol = "No VPN Connection" conn_disc_button = "Quick Connect" if is_vpn_connected and not disconnecting: try: connected_to_protocol = get_config_value("metadata", "connected_proto") protocol = '<span>OpenVPN >> {0}</span>'.format( connected_to_protocol.upper()) except (KeyError, IndexError): pass conn_disc_button = "Disconnect" conn_disc_button_label.set_markup(conn_disc_button) # Check and set DNS status label dns_enabled = get_config_value("USER", "dns_leak_protection") # Update time connected label gobject.timeout_add_seconds(1, update_connection_time, { "is_vpn_connected": is_vpn_connected, "label": time_connected_label }) # Check and set protocol label protocol_label.set_markup(protocol)
def populate_server_list(populate_servers_dict): """Function that updates server list. """ only_secure_core = True if get_gui_config("connections", "display_secure_core") == "True" else False pull_server_data(force=True) features = {0: "Normal", 1: "Secure-Core", 2: "Tor", 4: "P2P"} server_tiers = {0: "Free", 1: "Basic", 2: "Plus/Visionary"} if not populate_servers_dict["servers"]: servers = get_servers() else: servers = populate_servers_dict["servers"] # Country with respective servers, ex: PT#02 countries = {} if servers: for server in servers: country = get_country_name(server["ExitCountry"]) if country not in countries.keys(): countries[country] = [] countries[country].append(server["Name"]) country_servers = {} # Order server list by country alphabetically countries = collections.OrderedDict(sorted(countries.items())) for country in countries: country_servers[country] = sorted(countries[country], key=lambda s: get_server_value(s, "Load", servers)) populate_servers_dict["tree_object"].clear() CURRDIR = os.path.dirname(os.path.abspath(__file__)) flags_base_path = CURRDIR+"/resources/img/flags/small/" features_base_path = CURRDIR+"/resources/img/utils/" # Create empty image empty_path = features_base_path+"normal.png" empty_pix = empty = GdkPixbuf.Pixbuf.new_from_file_at_size(empty_path, 15,15) # Create P2P image p2p_path = features_base_path+"p2p-arrows.png" p2p_pix = empty = GdkPixbuf.Pixbuf.new_from_file_at_size(p2p_path, 15,15) # Create TOR image tor_path = features_base_path+"tor-onion.png" tor_pix = empty = GdkPixbuf.Pixbuf.new_from_file_at_size(tor_path, 15,15) # Create Plus image plus_server_path = features_base_path+"plus-server.png" plus_pix = GdkPixbuf.Pixbuf.new_from_file_at_size(plus_server_path, 15,15) for country in country_servers: for k,v in country_codes.items(): if country == v: flag_path = flags_base_path+"{}.png".format(v) break else: flag_path = flags_base_path+"Unknown.png" # Get average load and highest feature avrg_load, country_feature = get_country_avrg_features(country, country_servers, servers, features) flag = GdkPixbuf.Pixbuf.new_from_file_at_size(flag_path, 15,15) # Check plus servers if country_feature == "normal" or country_feature == "p2p": plus_feature = empty_pix else: plus_feature = plus_pix # Check correct feature if country_feature == "normal" or country_feature == "secure-core": feature = empty_pix elif country_feature == "p2p": feature = p2p_pix elif country_feature == "tor": feature = tor_pix if country_feature == "secure-core" and only_secure_core: country_row = populate_servers_dict["tree_object"].append(None, [flag, country, plus_feature, feature, avrg_load]) elif not only_secure_core: country_row = populate_servers_dict["tree_object"].append(None, [flag, country, plus_feature, feature, avrg_load]) for servername in country_servers[country]: secure_core = False load = str(get_server_value(servername, "Load", servers)).rjust(3, " ") load = load + "%" tier = server_tiers[get_server_value(servername, "Tier", servers)] if not "Plus/Visionary".lower() == tier.lower(): plus_feature = empty_pix else: plus_feature = plus_pix server_feature = features[get_server_value(servername, 'Features', servers)].lower() if server_feature == "Normal".lower(): feature = empty_pix elif server_feature == "P2P".lower(): feature = p2p_pix elif server_feature == "Tor".lower(): feature = tor_pix else: # Should be secure core secure_core = True if secure_core and only_secure_core: populate_servers_dict["tree_object"].append(country_row, [empty_pix, servername, plus_feature, feature, load]) elif not secure_core and not only_secure_core: populate_servers_dict["tree_object"].append(country_row, [empty_pix, servername, plus_feature, feature, load])
def update_labels(interface, servers, is_connected, connected_server, disconnecting, conn_info=False): """Function that updates the labels. """ gui_logger.debug(">>> Running \"right_grid_update_labels\".") # Right grid time_connected_label = interface.get_object("time_connected_label") protocol_label = interface.get_object("protocol_label") conn_disc_button_label = interface.get_object("main_conn_disc_button_label") ip_label = interface.get_object("ip_label") server_load_label = interface.get_object("server_load_label") country_label = interface.get_object("country_label") isp_label = interface.get_object("isp_label") data_received_label = interface.get_object("data_received_label") data_sent_label = interface.get_object("data_sent_label") background_large_flag = interface.get_object("background_large_flag") protonvpn_sign_green = interface.get_object("protonvpn_sign_green") CURRDIR = os.path.dirname(os.path.abspath(__file__)) flags_base_path = CURRDIR+"/resources/img/flags/large/" # Get and set server load label try: load = get_server_value(connected_server, "Load", servers) except: load = False load = "{0}% Load".format(load) if load and is_connected else "" server_load_label.set_markup('<span>{0}</span>'.format(load)) # Get and set IP labels. Get also country and ISP if not conn_info: result = custom_get_ip_info() if result: ip, isp, country = result else: ip = "None" isp = "None" country = "None" else: ip, isp, country = conn_info country_cc = False for k,v in country_codes.items(): if k == country: if is_connected: try: flag_path = flags_base_path+"{}.jpg".format(k.lower()) background_large_flag.set_from_file(flag_path) except: pass country_cc = v protonvpn_sign_green.hide() country_server = country_cc if is_connected: country_server = country_server + " >> " + connected_server protonvpn_sign_green.show() # Get and set server name connected_server = connected_server if connected_server and is_connected else "" country_label.set_markup(country_server) ip_label.set_markup(ip) isp_label.set_markup(isp) # Get and set city label try: city = get_server_value(connected_server, "City", servers) except: city = False city = city if city else "" # Update sent and received data gobject.timeout_add_seconds(1, update_sent_received_data, {"received_label": data_received_label, "sent_label": data_sent_label}) # Left grid all_features = {0: "Normal", 1: "Secure-Core", 2: "Tor", 4: "P2P"} protocol = "No VPN Connection" # Check and set VPN status label. Get also protocol status if vpn is connected conn_disc_button = "Quick Connect" if is_connected and not disconnecting: try: connected_to_protocol = get_config_value("metadata", "connected_proto") protocol = '<span>OpenVPN >> {0}</span>'.format(connected_to_protocol.upper()) except KeyError: pass conn_disc_button = "Disconnect" conn_disc_button_label.set_markup(conn_disc_button) # Check and set DNS status label dns_enabled = get_config_value("USER", "dns_leak_protection") # Update time connected label gobject.timeout_add_seconds(1, update_connection_time, {"is_connected":is_connected, "label":time_connected_label}) # Check and set protocol label protocol_label.set_markup(protocol)