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 return ConnectionResults.CANT_DETECT_PORTAL
# We need a "challenge" value stored in a hidden input in the authentication # 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") soup = BeautifulSoup(connection_page.text, features="html.parser")
input_challenge = soup.find("input", {"name": "challenge"}) input_challenge = soup.find("input", {"name": "challenge"})
if input_challenge is None: 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 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__': if __name__ == '__main__':
alcasar_monitor = AlcasarMonitor()
"""
alcasar = Alcasar() alcasar = Alcasar()
print("Checking if the computer is connected on an Alcasar WI-FI...") print("Checking if the computer is connected on an Alcasar WI-FI...")
if alcasar.detect(): if alcasar.detect():
print("Alcasar Detected! Connecting...") print("Alcasar Detected! Connecting...")
result = alcasar.connect("USERNAME", "PASSWORD") result = alcasar.connect("BENDJEY", "Q8CSKR")
# Check result # Check result
match result: match result:
@ -24,4 +112,4 @@ if __name__ == '__main__':
input("disconnect ?") input("disconnect ?")
alcasar.disconnect() alcasar.disconnect()
else: 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 from tkinter import ttk, Tk, Canvas, BOTH, Frame
import time 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): class SettingsWindow(Tk):
@ -23,7 +68,6 @@ class SettingsWindow(Tk):
fieldbackground=self.field_bg_color, bordercolor=self.outline_color, fieldbackground=self.field_bg_color, bordercolor=self.outline_color,
lightcolor=self.outline_color, darkcolor=self.outline_color) lightcolor=self.outline_color, darkcolor=self.outline_color)
print()
self.theme.map("TButton", self.theme.map("TButton",
background=[('!active', self.bg_color), ('active', self.active_field_bg_color)]) 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.username_entry = ttk.Entry(self.credential_frame, style="TEntry")
self.password_entry = ttk.Entry(self.credential_frame, show="", 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 def round_rectangle(self, x1, y1, x2, y2, radius=25, **kwargs): # Creating a rounded rectangle
"""Draw a rounded rectangle """Draw a rounded rectangle
@ -58,6 +111,12 @@ class SettingsWindow(Tk):
return self.base_canvas.create_polygon(points, **kwargs, smooth=True, fill=self.bg_color) 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): def setup(self):
self.title_label.pack(expand=True) self.title_label.pack(expand=True)
@ -73,15 +132,23 @@ class SettingsWindow(Tk):
def loop(self): def loop(self):
self.state = "normal" self.state = "normal"
self.update()
while self.state == "normal": while self.state == "normal":
self.update() self.update()
try:
if self.focus_get() is None: if self.focus_get() is None:
self.quit() self.close()
break
except _tkinter.TclError:
break break
time.sleep(0.05) 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 pystray import Icon as pystray_Icon, Menu as pystray_Menu, MenuItem as pystray_MenuItem
from PIL import Image from PIL import Image
from threading import Thread as threading_Thread from threading import Thread as threading_Thread
@ -9,7 +9,7 @@ from functools import partial
class Menu(): class Menu:
class Default(Enum): class Default(Enum):
DEFAULT = "DefaultValue" DEFAULT = "DefaultValue"
@ -29,8 +29,7 @@ class Menu():
self.id = 0 self.id = 0
self.ItemsFromID = {} # id: pystray.MenuItem, (DicKey, callback, item_type, {"current": bool | None, "requested": bool | None}, index) self.ItemsFromID = {} # id: pystray.MenuItem, (DicKey, callback, item_type, {"current": bool | None, "requested": bool | None}, index)
self.IDsFromItem = {} # pystray.MenuItem: id 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): 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 """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.tray pystray.Icon() object
self.Menu = Menu() self.Menu = Menu()
self.Menu.tray = self
default_image = Image.new("L", (32, 32), 255) default_image = Image.new("L", (32, 32), 255)
self.Icons = [default_image] self.Icons = [default_image]
@ -363,7 +363,7 @@ class TrayManager():
#Set the icon of the app in the notification tray #Set the icon of the app in the notification tray
if ImagePath: if ImagePath:
if __os_path_exists(ImagePath): if exists(ImagePath):
#Open image as PIL.Image.Image object and add it to Icons list #Open image as PIL.Image.Image object and add it to Icons list
image = Image.open(ImagePath) image = Image.open(ImagePath)
self.Icons.append(image) self.Icons.append(image)
@ -412,7 +412,7 @@ class TrayManager():
#Check if IconPath exist #Check if IconPath exist
if ImagePath: if ImagePath:
if __os_path_exists(ImagePath): if exists(ImagePath):
#Open image as PIL.Image.Image object and add it to Icons list #Open image as PIL.Image.Image object and add it to Icons list
image = Image.open(ImagePath) image = Image.open(ImagePath)