diff --git a/alcasar.py b/alcasar.py index e659820..2c21577 100644 --- a/alcasar.py +++ b/alcasar.py @@ -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: diff --git a/main.py b/main.py index a191323..02f5233 100644 --- a/main.py +++ b/main.py @@ -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")""" diff --git a/settings_manager.py b/settings_manager.py index 6a8ebae..8173246 100644 --- a/settings_manager.py +++ b/settings_manager.py @@ -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() diff --git a/tray_manager.py b/tray_manager.py index ec43df5..308eb39 100644 --- a/tray_manager.py +++ b/tray_manager.py @@ -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)