Last active
June 27, 2020 08:33
-
-
Save tano297/4ed849ce1f64194c3dfdd475f98f2e9c to your computer and use it in GitHub Desktop.
Creates a tray notification for connecting, reconnecting, and disconnecting using protonvpn-cli in Ubuntu. Also displays the status.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import os | |
import gi | |
import random | |
import yaml | |
import subprocess | |
import queue | |
from threading import Thread | |
from queue import Queue | |
gi.require_version('Gtk', '3.0') | |
gi.require_version('AppIndicator3', '0.1') | |
from gi.repository import Gtk as gtk, GLib as glib, AppIndicator3 as appindicator # nopep8 | |
class Window(): | |
def __init__(self): | |
# make the indicator app | |
self.indicator = appindicator.Indicator.new( | |
"protonvpn-status", "semi-starred-symbolic", appindicator.IndicatorCategory.APPLICATION_STATUS) | |
self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE) | |
# add the menu with button | |
self.indicator.set_menu(self.menu()) | |
def run(self): | |
# Read the status in a separate thread | |
self.status_queue = Queue(1) | |
self.status_runner_stop = False | |
self.status_runner = Thread(target=self.get_status, daemon=True) | |
# periodically check the queue and plot the status | |
glib.timeout_add(1000, self.set_status) | |
# run the app! | |
self.status_runner.start() | |
gtk.main() | |
# exit the status runner | |
self.status_runner_stop = True | |
def get_status(self): | |
while not self.status_runner_stop: | |
# get the status from the commandline | |
cmd = ['sudo', 'protonvpn', 'status'] | |
try: | |
# try to run the status | |
output = subprocess.Popen(cmd, stdout=subprocess.PIPE | |
).communicate(timeout=15)[0] | |
# turn it into a dictionary | |
response = yaml.safe_load(output.decode('UTF-8')) | |
except: | |
self.status_queue.put("MEGA-FAIL!") | |
continue | |
# check if connected or disconnected | |
if response["Status"] == "Connected": | |
status = "OK: {}, {} [{}]".format( | |
response["City"], response["Server"], response["Time"]) | |
elif response["Status"] == "Disconnected": | |
status = "Disconnected" | |
else: | |
status = "Unknown" | |
# set label! | |
print("Received status: {}".format(status)) | |
self.status_queue.put(status) | |
def set_status(self): | |
# get all status from queue and display them | |
if not self.status_queue.empty(): | |
status = self.status_queue.get() | |
print("Setting icon status: {}".format(status)) | |
self.indicator.set_label(status, '') | |
return True | |
def menu(self): | |
menu = gtk.Menu() | |
# make a separator | |
menu_sep = gtk.SeparatorMenuItem() | |
menu.append(menu_sep) | |
# make a connect button | |
connect_button = gtk.MenuItem('Connect (c)') | |
connect_button.connect('activate', self.connect) | |
menu.append(connect_button) | |
# make a connect fastst button | |
connect_fast_button = gtk.MenuItem('Connect Fastest (c -f)') | |
connect_fast_button.connect('activate', self.connect_fast) | |
menu.append(connect_fast_button) | |
# make a reconnect button | |
reconnect_button = gtk.MenuItem('Reconnect (r)') | |
reconnect_button.connect('activate', self.reconnect) | |
menu.append(reconnect_button) | |
# make a disconnect button | |
disconnect_button = gtk.MenuItem('Disconnect (d)') | |
disconnect_button.connect('activate', self.disconnect) | |
menu.append(disconnect_button) | |
# make an exit button | |
exti_button = gtk.MenuItem('Exit Tray') | |
exti_button.connect('activate', self.quit) | |
menu.append(exti_button) | |
menu.show_all() | |
return menu | |
def connect(self, _): | |
os.system("gnome-terminal -e \"sudo protonvpn c\"") | |
def connect_fast(self, _): | |
os.system("sudo protonvpn c -f") | |
def reconnect(self, _): | |
os.system("sudo protonvpn r") | |
def disconnect(self, _): | |
os.system("sudo protonvpn d") | |
def quit(self, _): | |
gtk.main_quit() | |
self.status_runner_stop = True | |
self.status_queue.get() | |
if __name__ == "__main__": | |
w = Window() | |
w.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use:
This is how it looks like