Untitled

 avatar
unknown
plain_text
5 months ago
8.9 kB
3
Indexable
import customtkinter as ctk
import subprocess
import threading
from tkinter import StringVar
from CTkPopupKeyboard import PopupKeyboard

class WifiConfiguratorApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("Wi-Fi Configurator")
        self.attributes('-fullscreen', True)
        self.protocol("WM_DELETE_WINDOW", self.close_app)

        self.networks = []
        self.selected_network = StringVar()
        self.password = StringVar()
        self.show_password = ctk.BooleanVar(value=False)
        self.keyboard_enabled = ctk.BooleanVar(value=True)  # Changed to keyboard_enabled

        self.current_connection = {
            "SSID": "Not connected",
            "Signal Strength": "N/A",
            "IP Address": "N/A"
        }
        self.status_message = StringVar(value="Idle")

        # UI Elements
        self.create_widgets()
        self.scan_wifi_networks()
        self.update_current_connection()

    def create_widgets(self):
        # Title Label
        title_label = ctk.CTkLabel(self, text="Wi-Fi Configurator", font=("Arial", 32, "bold"))
        title_label.pack(pady=10)

        # Status Label
        self.status_label = ctk.CTkLabel(self, textvariable=self.status_message, font=("Arial", 14), text_color="green")
        self.status_label.pack(pady=5)

        # Current Connection Details
        self.connection_frame = ctk.CTkFrame(self)
        self.connection_frame.pack(pady=5, padx=20, fill="x")

        connection_title = ctk.CTkLabel(self.connection_frame, text="Current Connection", font=("Arial", 18, "bold"))
        connection_title.grid(row=0, column=0, columnspan=2, pady=5)

        self.ssid_label = ctk.CTkLabel(self.connection_frame, text="SSID: Not connected")
        self.ssid_label.grid(row=1, column=0, padx=5, sticky="w")
        self.signal_label = ctk.CTkLabel(self.connection_frame, text="Signal Strength: N/A")
        self.signal_label.grid(row=2, column=0, padx=5, sticky="w")
        self.ip_label = ctk.CTkLabel(self.connection_frame, text="IP Address: N/A")
        self.ip_label.grid(row=3, column=0, padx=5, sticky="w")

        # Network Selection
        self.network_dropdown = ctk.CTkOptionMenu(self, variable=self.selected_network, values=self.networks)
        self.network_dropdown.pack(pady=5)

        # Password Entry and Keyboard
        password_frame = ctk.CTkFrame(self)
        password_frame.pack(pady=5)

        password_label = ctk.CTkLabel(password_frame, text="Enter Wi-Fi Password:")
        password_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")

        self.password_entry = ctk.CTkEntry(
            password_frame, textvariable=self.password, show="*")
        self.password_entry.grid(row=1, column=0, padx=5, pady=5)

        # Initialize PopupKeyboard
        self.keyboard = PopupKeyboard(self.password_entry)
        self.keyboard.disable = False  # Enable keyboard by default

        toggle_password_button = ctk.CTkButton(
            password_frame, text="Show", width=60, command=self.toggle_password_visibility)
        toggle_password_button.grid(row=1, column=1, padx=5, pady=5)

        reset_password_button = ctk.CTkButton(
            password_frame, text="Reset", width=60, command=self.reset_password)
        reset_password_button.grid(row=1, column=2, padx=5, pady=5)

        # On-screen Keyboard Switch
        self.keyboard_switch = ctk.CTkSwitch(
            self, 
            text="On-Screen Keyboard", 
            command=self.toggle_keyboard,
            variable=self.keyboard_enabled
        )
        self.keyboard_switch.pack(pady=10)

        # Buttons
        button_frame = ctk.CTkFrame(self)
        button_frame.pack(pady=10)

        connect_button = ctk.CTkButton(button_frame, text="Connect", command=self.start_connecting_to_wifi)
        connect_button.grid(row=0, column=0, padx=10)

        refresh_button = ctk.CTkButton(button_frame, text="Refresh", command=self.scan_wifi_networks)
        refresh_button.grid(row=0, column=1, padx=10)

        exit_button = ctk.CTkButton(button_frame, text="Exit (Prototyping)", command=self.close_app)
        exit_button.grid(row=0, column=2, padx=10)

    def toggle_keyboard(self):
        if self.keyboard_enabled.get():
            self.keyboard.disable = False
        else:
            self.keyboard.disable = True

    def scan_wifi_networks(self):
        self.status_message.set("Scanning for Wi-Fi networks...")
        self.update()
        try:
            result = subprocess.run(
                ["nmcli", "-t", "-f", "SSID,SIGNAL", "dev", "wifi"],
                capture_output=True, text=True
            )
            if result.returncode == 0:
                networks = []
                for line in result.stdout.split("\n"):
                    if line and line.split(":")[0]:
                        ssid, _ = line.split(":")
                        if ssid and ssid not in networks:
                            networks.append(ssid)

                self.networks = networks
                self.network_dropdown.configure(values=self.networks)
                if self.networks:
                    self.selected_network.set(self.networks[0])
                self.status_message.set("Wi-Fi scan completed.")
            else:
                self.status_message.set("Failed to scan Wi-Fi networks.")
        except Exception as e:
            self.status_message.set(f"Error: {e}")

    def start_connecting_to_wifi(self):
        threading.Thread(target=self.connect_to_wifi).start()

    def connect_to_wifi(self):
        ssid = self.selected_network.get()
        password = self.password.get()
        self.status_message.set(f"Connecting to {ssid}...")
        self.update()
        try:
            result = subprocess.run(
                ["nmcli", "dev", "wifi", "connect", ssid, "password", password],
                capture_output=True, text=True
            )
            if result.returncode == 0:
                self.status_message.set(f"Successfully connected to {ssid}.")
                self.update_current_connection()
            else:
                error_message = result.stderr.strip()
                if "802-11-wireless-security.psk: property is invalid" in error_message:
                    self.status_message.set("Incorrect password. Please try again.")
                else:
                    self.status_message.set(f"Connection failed: {error_message}")
                self.reset_password()
                self.password_entry.focus()
        except Exception as e:
            self.status_message.set(f"Error: {e}")

    def update_current_connection(self):
        try:
            ssid_result = subprocess.run(
                ["nmcli", "-t", "-f", "ACTIVE,SSID,SIGNAL", "dev", "wifi"],
                capture_output=True, text=True
            )
            ip_result = subprocess.run(
                ["hostname", "-I"], capture_output=True, text=True
            )

            if ssid_result.returncode == 0:
                for line in ssid_result.stdout.split("\n"):
                    if line.startswith("yes"):
                        _, ssid, signal = line.split(":")
                        self.current_connection["SSID"] = ssid
                        self.current_connection["Signal Strength"] = f"{signal}%"
                        break
                else:
                    self.current_connection["SSID"] = "Not connected"
                    self.current_connection["Signal Strength"] = "N/A"

            if ip_result.returncode == 0:
                self.current_connection["IP Address"] = ip_result.stdout.strip()
            else:
                self.current_connection["IP Address"] = "N/A"

            self.ssid_label.configure(text=f"SSID: {self.current_connection['SSID']}")
            self.signal_label.configure(text=f"Signal Strength: {self.current_connection['Signal Strength']}")
            self.ip_label.configure(text=f"IP Address: {self.current_connection['IP Address']}")
        except Exception as e:
            self.status_message.set(f"Failed to retrieve connection details: {e}")

    def toggle_password_visibility(self):
        if self.show_password.get():
            self.password_entry.configure(show="*")
            self.show_password.set(False)
        else:
            self.password_entry.configure(show="")
            self.show_password.set(True)

    def reset_password(self):
        self.password.set("")

    def close_app(self):
        self.destroy()


if __name__ == "__main__":
    ctk.set_appearance_mode("System")
    ctk.set_default_color_theme("blue")
    app = WifiConfiguratorApp()
    app.mainloop()
Editor is loading...
Leave a Comment