Skip to content

Instantly share code, notes, and snippets.

@tano297
Last active June 27, 2020 08:33
Show Gist options
  • Save tano297/4ed849ce1f64194c3dfdd475f98f2e9c to your computer and use it in GitHub Desktop.
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.
#!/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()
@tano297
Copy link
Author

tano297 commented Jun 20, 2020

To use:

$ sudo apt install libappindicator-dev
  • Download this script and run:
$ python3 protonvpn-tray.py

This is how it looks like

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment