def get_server_list(self): """Build list of servers by Country.""" # Check for latest data. pvpncli_utils.pull_server_data(force=True) # Get server details from raw server data. servers_data = pvpncli_utils.get_servers() # Compile dictionary of countries and server details; key=country name. unsorted_countries = {} for server in servers_data: country = pvpncli_utils.get_country_name(server['ExitCountry']) if country not in unsorted_countries.keys(): unsorted_countries[country] = [] server_details = {} server_name = server['Name'] server_details[server_name] = {} for k, v in server.items(): server_details[server_name][k] = v unsorted_countries[country].append(server_details) # Alphabetize countries by country name. sorted_countries = sorted(unsorted_countries.keys()) servers_by_country = {} for country in sorted_countries: servers_by_country[country] = unsorted_countries[country] return servers_by_country
def generate_autoconnect_list(self): countries = {} servers = get_servers() autoconnect_alternatives = ["dis", "fast", "rand", "p2p", "sc", "tor"] for server in servers: country = get_country_name(server["ExitCountry"]) if country not in countries.keys(): countries[country] = [] countries[country].append(server["Name"]) for country in sorted(countries): autoconnect_alternatives.append(country) return autoconnect_alternatives
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 populate_autoconnect_list(interface, return_list=False): """Function that populates autoconnect dropdown list. """ autoconnect_liststore = interface.get_object("AutoconnectListStore") countries = {} servers = get_servers() other_choice_dict = { "dis": "Disabled", "fast": "Fastest", "rand": "Random", "p2p": "Peer2Peer", "sc": "Secure Core (Plus/Visionary)", "tor": "Tor (Plus/Visionary)" } autoconnect_alternatives = ["dis", "fast", "rand", "p2p", "sc", "tor"] # return_values = collections.OrderedDict() return_values = collections.OrderedDict() for server in servers: country = get_country_name(server["ExitCountry"]) if country not in countries.keys(): countries[country] = [] countries[country].append(server["Name"]) for country in sorted(countries): autoconnect_alternatives.append(country) for alt in autoconnect_alternatives: if alt in other_choice_dict: # if return_list: return_values[alt] = other_choice_dict[alt] # else: autoconnect_liststore.append([alt, other_choice_dict[alt], alt]) else: for k, v in country_codes.items(): if alt.lower() == v.lower(): # if return_list: return_values[k] = v # else: autoconnect_liststore.append([k, v, k]) if return_list: return return_values
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 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 get_available_countries(servers): return sorted(list({utils.get_country_name(server['ExitCountry']) for server in servers}))