Implemented control from tray

This commit is contained in:
Yannis 2023-11-21 12:02:57 +01:00
parent 0791ad6191
commit a3f1fc1dd2
4 changed files with 173 additions and 18 deletions

View file

@ -50,7 +50,7 @@ class Alcasar:
return ConnectionResults.CANT_DETECT_PORTAL
# We need a "challenge" value stored in a hidden input in the authentication
# page to be sent to in the post request
# page to be sent to it the post request
soup = BeautifulSoup(connection_page.text, features="html.parser")
input_challenge = soup.find("input", {"name": "challenge"})
if input_challenge is None:

92
main.py
View file

@ -1,12 +1,100 @@
import time
import settings_manager
from alcasar import Alcasar, ConnectionResults, DisconnectResult
from settings_manager import SettingsWindow
from tray_manager import TrayManager
from threading import Thread
class AlcasarMonitor:
def __init__(self):
self.alcasar = Alcasar()
self.tray_manager = TrayManager("AlcasarAuto", default_show=True, ImagePath=r".\assets\desactived_ico.png")
self.connect_button = self.tray_manager.Menu.create_item("Connect",
item_type=self.tray_manager.Menu.ItemType.BUTTON,
callback=self.connect)
self.disconnect_button = self.tray_manager.Menu.create_item("Disconnect",
item_type=self.tray_manager.Menu.ItemType.BUTTON,
callback=self.disconnect)
self.settings_button = self.tray_manager.Menu.create_item("Settings",
item_type=self.tray_manager.Menu.ItemType.BUTTON,
callback=self.ask_credentials)
self.auto_connect_check = self.tray_manager.Menu.create_item("Auto Connect",
item_type=self.tray_manager.Menu.ItemType.CHECK,
callback=self.toggle_auto_connect)
self.settings_window = settings_manager.SettingsWindow()
self.settings_manager = settings_manager.SettingsManager()
self.state = False
self.request_settings_open = False
self.just_disconnected = False
Thread(target=self.connection_state_loop).start()
self.loop()
def ask_credentials(self):
self.request_settings_open = True
def toggle_auto_connect(self):
new_value = self.tray_manager.Menu.get_status(self.auto_connect_check)
self.settings_manager.set("auto_connect", new_value)
def disconnect(self):
self.just_disconnected = True
self.alcasar.disconnect()
def connect(self):
self.alcasar.connect(self.settings_manager.get("username"),
self.settings_manager.get("password"))
self.just_disconnected = False
def loop(self):
last_state = None
while True:
state = self.state
if state != last_state:
if state:
self.tray_manager.set_icon(r".\assets\actived_ico.png")
print("connected")
else:
self.tray_manager.set_icon(r".\assets\desactived_ico.png")
print("Disconnected")
if self.settings_manager.get("auto_connect") and not self.just_disconnected:
self.connect()
last_state = state
if self.request_settings_open:
self.__ask_credentials()
time.sleep(0.2)
def __ask_credentials(self):
self.request_settings_open = False
print("ask credentials")
credentials = self.settings_window.get_credentials(self.settings_manager.get("username"), self.settings_manager.get("password"))
self.settings_manager.set("username", credentials[0])
self.settings_manager.set("password", credentials[1])
def connection_state_loop(self):
while True:
self.state = self.alcasar.update_statut()[0]
time.sleep(2)
if __name__ == '__main__':
alcasar_monitor = AlcasarMonitor()
"""
alcasar = Alcasar()
print("Checking if the computer is connected on an Alcasar WI-FI...")
if alcasar.detect():
print("Alcasar Detected! Connecting...")
result = alcasar.connect("USERNAME", "PASSWORD")
result = alcasar.connect("BENDJEY", "Q8CSKR")
# Check result
match result:
@ -24,4 +112,4 @@ if __name__ == '__main__':
input("disconnect ?")
alcasar.disconnect()
else:
print("Not detected")
print("Not detected")"""

View file

@ -1,5 +1,50 @@
import os
import tkinter
from tkinter import ttk, Tk, Canvas, BOTH, Frame
import time
import json
import pathlib
import _tkinter
SETTINGS_FOLDER = os.getenv('APPDATA')+"\\AlcasarAuto\\"
SETTINGS_FILE = SETTINGS_FOLDER + "settings.json"
class SettingsManager:
def __init__(self):
if not os.path.isdir(SETTINGS_FOLDER):
os.mkdir(SETTINGS_FOLDER)
self.settings = {}
if not os.path.isfile(SETTINGS_FILE):
self.setup_default_settings()
else:
self.load_settings()
def load_settings(self):
with open(SETTINGS_FILE, "r") as file:
self.settings = json.loads(file.read())
def get(self, key):
return self.settings[key]
def set(self, key, value):
self.settings[key] = value
self.save_settings()
def save_settings(self):
with open(SETTINGS_FILE, "w") as file:
file.write(json.dumps(self.settings))
def setup_default_settings(self):
self.settings = {
"username": "",
"password": "",
"auto_connect": False
}
self.save_settings()
class SettingsWindow(Tk):
@ -23,7 +68,6 @@ class SettingsWindow(Tk):
fieldbackground=self.field_bg_color, bordercolor=self.outline_color,
lightcolor=self.outline_color, darkcolor=self.outline_color)
print()
self.theme.map("TButton",
background=[('!active', self.bg_color), ('active', self.active_field_bg_color)])
@ -44,7 +88,16 @@ class SettingsWindow(Tk):
self.username_entry = ttk.Entry(self.credential_frame, style="TEntry")
self.password_entry = ttk.Entry(self.credential_frame, show="", style="TEntry")
self.save_button = ttk.Button(self.base_canvas, text="Save", style="TButton")
self.save_button = ttk.Button(self.base_canvas, text="Save", style="TButton", command=self.close)
self.username = ""
self.password = ""
def close(self):
self.state = None
self.username = self.username_entry.get()
self.password = self.password_entry.get()
self.withdraw()
def round_rectangle(self, x1, y1, x2, y2, radius=25, **kwargs): # Creating a rounded rectangle
"""Draw a rounded rectangle
@ -57,7 +110,13 @@ class SettingsWindow(Tk):
x1, y1 + radius, x1, y1 + radius, x1, y1]
return self.base_canvas.create_polygon(points, **kwargs, smooth=True, fill=self.bg_color)
def fill_credentials(self, username, password):
self.username_entry.delete(0, tkinter.END)
self.password_entry.delete(0, tkinter.END)
self.username_entry.insert(0, username)
self.password_entry.insert(0, password)
def setup(self):
self.title_label.pack(expand=True)
@ -73,15 +132,23 @@ class SettingsWindow(Tk):
def loop(self):
self.state = "normal"
self.update()
while self.state == "normal":
self.update()
if self.focus_get() is None:
self.quit()
try:
if self.focus_get() is None:
self.close()
break
except _tkinter.TclError:
break
time.sleep(0.05)
def get_credentials(self, username, password):
"""Username and password used to prefill entries"""
self.fill_credentials(username, password)
self.deiconify()
self.focus_force()
self.setup()
self.loop()
return self.username, self.password
settings = SettingsWindow()
settings.setup()
settings.loop()

View file

@ -1,4 +1,4 @@
from os.path import exists as __os_path_exists
from os.path import exists
from pystray import Icon as pystray_Icon, Menu as pystray_Menu, MenuItem as pystray_MenuItem
from PIL import Image
from threading import Thread as threading_Thread
@ -9,7 +9,7 @@ from functools import partial
class Menu():
class Menu:
class Default(Enum):
DEFAULT = "DefaultValue"
@ -29,8 +29,7 @@ class Menu():
self.id = 0
self.ItemsFromID = {} # id: pystray.MenuItem, (DicKey, callback, item_type, {"current": bool | None, "requested": bool | None}, index)
self.IDsFromItem = {} # pystray.MenuItem: id
self.tray = None
def create_item(self, text: str, callback: FunctionType | None = None, item_type: ItemType = ItemType.LABEL, checkdefault: bool = False, index: int | None = None, FORCE_ID: int | None = None):
"""Create an item that will be displayed in the options of the app notification in the notification tray\n
@ -355,6 +354,7 @@ class TrayManager():
#self.tray pystray.Icon() object
self.Menu = Menu()
self.Menu.tray = self
default_image = Image.new("L", (32, 32), 255)
self.Icons = [default_image]
@ -363,7 +363,7 @@ class TrayManager():
#Set the icon of the app in the notification tray
if ImagePath:
if __os_path_exists(ImagePath):
if exists(ImagePath):
#Open image as PIL.Image.Image object and add it to Icons list
image = Image.open(ImagePath)
self.Icons.append(image)
@ -412,7 +412,7 @@ class TrayManager():
#Check if IconPath exist
if ImagePath:
if __os_path_exists(ImagePath):
if exists(ImagePath):
#Open image as PIL.Image.Image object and add it to Icons list
image = Image.open(ImagePath)