Implemented control from tray
This commit is contained in:
parent
0791ad6191
commit
a3f1fc1dd2
|
@ -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
92
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")"""
|
||||
|
|
|
@ -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
|
||||
|
@ -58,6 +111,12 @@ class SettingsWindow(Tk):
|
|||
|
||||
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()
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue