nordvpntray/nordvpntray.py

321 lines
11 KiB
Python
Raw Normal View History

2024-12-23 11:03:07 +01:00
import pystray
from PIL import Image
import threading # Import the threading module for creating threads
from desktop_notifier import DesktopNotifier, Urgency, Button, ReplyField, DEFAULT_SOUND
from plyer import notification
from urllib.request import Request
from urllib.request import urlopen
from urllib.request import URLError
import sys,os
import gobject
import json
import signal
import subprocess
from random import randint
from platform import system as system_name
from subprocess import call as system_call
def ping(host):
fn = open(os.devnull, 'w')
param = '-n' if system_name().lower() == 'windows' else '-c'
command = ['ping', param, '1', host]
retcode = system_call(command, stdout=fn, stderr=subprocess.STDOUT)
fn.close()
return retcode == 0
def desktop_notifier(title, message, timeout=10, app_icon=None):
notification.notify(
title=title,
message=message,
timeout=timeout,
app_icon=app_icon,
)
def dns_leak():
# Test fuites DNS
leak_id = randint(1000000, 9999999)
for x in range(0, 10):
ping('.'.join([str(x), str(leak_id), "bash.ws"]))
response = urlopen("https://bash.ws/dnsleak/test/"+str(leak_id)+"?json")
dnsleak = "https://bash.ws/dnsleak/test/"+str(leak_id)+"?json" + '\n '
data = response.read().decode("utf-8")
parsed_data = json.loads(data)
dnsleak = dnsleak + '\n ' + "Votre IP "
for dns_server in parsed_data:
if dns_server['type'] == "ip":
if dns_server['country_name']:
if dns_server['asn']:
dnsleak = dnsleak + dns_server['ip'] + '\n ' + " [" + dns_server['country_name'] + ", " + dns_server['asn'] + "]" + '\n '
else:
dnsleak = dnsleak + dns_server['ip'] + '\n ' + " [" + dns_server['country_name'] +" ]" + '\n '
else:
dnsleak = dnsleak + dns_server['ip'] + '\n '
servers = 0
for dns_server in parsed_data:
if dns_server['type'] == "dns":
servers = servers + 1
if servers == 0:
dnsleak = dnsleak + "No DNS servers found"
else:
dnsleak = dnsleak + '\n ' + "Vous utilisez " + str(servers) + " serveur(s) DNS "
for dns_server in parsed_data:
if dns_server['type'] == "dns":
if dns_server['country_name']:
if dns_server['asn']:
dnsleak = dnsleak + dns_server['ip'] + '\n ' + " [" + dns_server['country_name'] + ", " + dns_server['asn'] + "]" + '\n '
else:
dnsleak = dnsleak + dns_server['ip'] + '\n ' + " [" + dns_server['country_name'] + "]" + '\n '
else:
dnsleak = dnsleak + dns_server['ip'] + '\n '
dnsleak = dnsleak + '\n ' + "Conclusion:"
for dns_server in parsed_data:
if dns_server['type'] == "conclusion":
if dns_server['ip']:
dnsleak = dnsleak + dns_server['ip']
# Retour dnsleak
# print(dnsleak)
return dnsleak
def NordVPN(commande, option=""):
global connexion, stest
match commande:
case "status":
sortie=os.popen("nordvpn status", "r").read()
titre="Statut VPN"
case "settings":
sortie=os.popen("nordvpn settings", "r").read()
titre="Paramètres VPN"
case "test":
sortie="Pour les tests"
titre="TESTS"
#desktop_notifier(titre, "Ceci est test",10,"/home/yann/media/dplus/python-dev/nordvpn-yan/nordvpn.jpg")
if stest:
stest = False
icon.icon = connected_img
else:
stest = True
icon.icon = disconnected_img
case "connect":
titre="Connexion VPN"
if not connexion:
sortie=os.popen("nordvpn connect", "r").read()
connexion = True
print(sortie)
icon.icon = connected_img
cmdcli=os.popen("nordvpn status", "r").read()
if not "Disconnected" in cmdcli:
# VPN actif
for line in cmdcli.split('\n'):
if "Server:" in line:
# Extraire le serveur avec suppression espaces début fin
serveur=line[len("Server:"):].strip()
icon.title=serveur
else:
print(sortie)
sortie="Connexion VPN active"
case "disconnect":
titre="Déconnexion VPN"
sortie=os.popen("nordvpn disconnect", "r").read()
if "You are not connected to NordVPN" in sortie:
sortie="Vous n'êtes pas connecté à NordVPN"
print(sortie)
connexion = False
print(sortie)
icon.icon = disconnected_img
icon.title="Déconnecté"
case "login":
titre="Connexion Compte"
if not connexion:
sortie=os.popen("nordvpn login", "r").read()
else:
sortie=os.popen("nordvpn account", "r").read()
case "dnsleak":
# appel fonction et affichage
titre="DNS Leak test (fuites)"
sortie=dns_leak()
case "countries":
# groupes de serveur
titre="Groupes de serveur"
sortie=os.popen("nordvpn countries", "r").read()
case "groups":
# groupes de serveur
titre="Groupes de serveur"
sortie=os.popen("nordvpn groups", "r").read()
case "version":
titre="Version NordVPN"
sortie=os.popen("nordvpn version", "r").read()
case "_":
print("Oops, quelque chose s'est mal passé 🤯")
# analyse résultat des commandes bash nordvpn
print(sortie)
message = sortie.replace("Server", "Serveur")
message = message.replace("Hostname", "Nom hôte")
message = message.replace("Country", "Pays")
message = message.replace("City", "Ville")
message = message.replace("Current technology", "Technologie actuelle")
message = message.replace("Current protocol", "Protocole actuel")
message = message.replace("Transfer", "Transfert")
message = message.replace("Uptime", "Temps de fonction")
message = message.replace("Connected", "Connecté")
message = message.replace("Disconnected", "Déconnecté")
message = message.replace("second", "seconde")
message = message.replace("Disabled", "Inactif")
message = message.replace("Enabled", "Actif")
message = message.replace("disabled", "Inactif")
message = message.replace("enabled", "Actif")
message = message.replace("Connecting to", "Se connecter à")
message = message.replace("You are connected to", "Vous êtes connecté à")
if commande=="disconnect":
message="Vous êtes déconnecté de NordVPN"
desktop_notifier(titre, message,10,"/home/yann/media/dplus/python-dev/nordvpn-yan/nordvpn.jpg")
#print(message)
def after_click(icon, query):
match str(query):
case "Status":
NordVPN("status")
case "Paramètres":
NordVPN("settings")
case "Connexion VPN rapide":
NordVPN("connect")
case "Déconnexion VPN":
NordVPN("disconnect")
case "Fuites DNS":
NordVPN("dnsleak")
case "Connexion/Infos Compte":
NordVPN("login")
case "TEST":
NordVPN("test")
case "Groupes de serveurs":
NordVPN("groups")
case "Pays":
NordVPN("countries")
case "Version":
NordVPN("version")
case "Quitter":
icon.stop()
def desktop_notifier(title, message, timeout=10, app_icon=""):
notification.notify(
title=title,
message=message,
timeout=timeout,
app_icon=app_icon,
toast=True,
app_name='Desktop Notifier',
# Add more customizations here
)
def vpnactif():
# Tester si la connexion VPN est active
cmdcli=os.popen("nordvpn status", "r").read()
print(cmdcli)
if not "Disconnected" in cmdcli:
# VPN actif
for line in cmdcli.split('\n'):
if "Server:" in line:
# Extraire le serveur avec suppression espaces début fin
serveur=line[len("Server:"):].strip()
icon.title=serveur
return True
else:
# VPN inactif
icon.title="VPN inactif"
return False
'''
def update_icon():
global connexion
if connexion:
icon.icon = connected_img
print("thread update_icon connected_img")
else:
icon.icon = disconnected_img
print("thread update_icon disconnected_img")
'''
def on_clicked(icon, item):
global state
state = not item.checked
'''
# Départ programme
On regarde si le service nordvpnd est actif
'''
state = False
# on regarde si le service nordvpnd est actif pour afficher la couleur du bouton
etat=os.popen("systemctl is-active nordvpnd.service").read()
if 'inactive' in etat:
# nordvpnd inactif
print("Service nordvpnd inactif")
desktop_notifier("Service nordvpnd", "Le service NordVPN daemon est inactif",10,"/home/yann/media/dplus/python-dev/nordvpn-yan/nordvpn.jpg")
# On arrête le script
sys.exit("Service nordvpnd inactif")
else:
print("Service nordvpnd actif")
# Définir les images pour le systray
connected_img = Image.open("/home/yann/media/dplus/python-dev/nordvpntray/nord-logo-vert.png") # image connexion NordVPN active
disconnected_img = Image.open("/home/yann/media/dplus/python-dev/nordvpntray/nord-logo-rouge.png") # image connexion NordVPN inactive
stest = True
icon = pystray.Icon("VPN")
# Test si connexion active
if vpnactif():
# VPN actif
connexion = True
icon.icon = connected_img
print("VPN actif")
else:
# VPN inactif
connexion = False
icon.icon = disconnected_img
icon.title="Déconnecté"
print("VPN inactif")
icon.menu= pystray.Menu(
pystray.MenuItem("Status",
after_click),
pystray.MenuItem("Paramètres",
after_click),
pystray.MenuItem("Fuites DNS",
after_click),
pystray.MenuItem("Connexion VPN rapide",
after_click),
pystray.MenuItem("Déconnexion VPN",
after_click),
pystray.MenuItem("Connexion/Infos Compte",
after_click),
pystray.MenuItem("TEST",
after_click),
pystray.MenuItem("Listes",
pystray.Menu(
pystray.MenuItem('Groupes de serveurs',
after_click),
pystray.MenuItem('Pays',
after_click),
pystray.MenuItem('On/Off',
on_clicked,checked=lambda item: state),
pystray.MenuItem('Version',
after_click)
)),
pystray.MenuItem("Quitter",
after_click)
)
icon.run()