Files
SDG-DRIFT/Ax_Shell/modules/network.py
T
2026-06-03 21:26:54 +02:00

195 lines
7.4 KiB
Python

import gi
gi.require_version('Gtk', '3.0')
gi.require_version('NM', '1.0')
from fabric.utils import bulk_connect
from fabric.widgets.box import Box
from fabric.widgets.button import Button
from fabric.widgets.centerbox import CenterBox
from fabric.widgets.image import Image
from fabric.widgets.label import Label
from fabric.widgets.scrolledwindow import ScrolledWindow
from gi.repository import NM, GLib, Gtk
import modules.icons as icons
from services.network import NetworkClient
class WifiAccessPointSlot(CenterBox):
def __init__(self, ap_data: dict, network_service: NetworkClient, wifi_service, **kwargs):
super().__init__(name="wifi-ap-slot", **kwargs)
self.ap_data = ap_data
self.network_service = network_service
self.wifi_service = wifi_service
ssid = ap_data.get("ssid", "Unknown SSID")
icon_name = ap_data.get("icon-name", "network-wireless-signal-none-symbolic")
self.is_active = False
active_ap_details = ap_data.get("active-ap")
if active_ap_details and hasattr(active_ap_details, 'get_bssid') and active_ap_details.get_bssid() == ap_data.get("bssid"):
self.is_active = True
self.ap_icon = Image(icon_name=icon_name, size=24)
self.ap_label = Label(label=ssid, h_expand=True, h_align="start", ellipsization="end")
self.connect_button = Button(
name="wifi-connect-button",
label="Connected" if self.is_active else "Connect",
sensitive=not self.is_active,
on_clicked=self._on_connect_clicked,
style_classes=["connected"] if self.is_active else None,
)
self.set_start_children([
Box(spacing=8, h_expand=True, h_align="fill", children=[
self.ap_icon,
self.ap_label,
])
])
self.set_end_children([self.connect_button])
def _on_connect_clicked(self, _):
if not self.is_active and self.ap_data.get("bssid"):
self.connect_button.set_label("Connecting...")
self.connect_button.set_sensitive(False)
self.network_service.connect_wifi_bssid(self.ap_data["bssid"])
class NetworkConnections(Box):
def __init__(self, **kwargs):
super().__init__(
name="network-connections",
orientation="vertical",
spacing=4,
**kwargs,
)
self.widgets = kwargs.get("widgets")
self.network_client = NetworkClient()
self.status_label = Label(label="Initializing Wi-Fi...", h_expand=True, h_align="center")
self.back_button = Button(
name="network-back",
child=Label(name="network-back-label", markup=icons.chevron_left),
on_clicked=lambda *_: self.widgets.show_notif()
)
self.wifi_toggle_button_icon = Label(markup=icons.wifi_3)
self.wifi_toggle_button = Button(
name="wifi-toggle-button",
child=self.wifi_toggle_button_icon,
tooltip_text="Toggle Wi-Fi",
on_clicked=self._toggle_wifi
)
self.refresh_button_icon = Label(name="network-refresh-label", markup=icons.reload)
self.refresh_button = Button(
name="network-refresh",
child=self.refresh_button_icon,
tooltip_text="Scan for Wi-Fi networks",
on_clicked=self._refresh_access_points
)
header_box = CenterBox(
name="network-header",
start_children=[self.back_button],
center_children=[Label(name="network-title", label="Wi-Fi Networks")],
end_children=[Box(orientation="horizontal", spacing=4, children=[self.refresh_button])]
)
self.ap_list_box = Box(orientation="vertical", spacing=4)
scrolled_window = ScrolledWindow(
name="network-ap-scrolled-window",
child=self.ap_list_box,
h_expand=True,
v_expand=True,
propagate_width=False,
propagate_height=False,
)
self.add(header_box)
self.add(self.status_label)
self.add(scrolled_window)
self.network_client.connect("device-ready", self._on_device_ready)
self.wifi_toggle_button.set_sensitive(False)
self.refresh_button.set_sensitive(False)
def _on_device_ready(self, _client):
if self.network_client.wifi_device:
self.network_client.wifi_device.connect("changed", self._load_access_points)
self.network_client.wifi_device.connect("notify::enabled", self._update_wifi_status_ui)
self._update_wifi_status_ui()
if self.network_client.wifi_device.enabled:
self._load_access_points()
else:
self.status_label.set_label("Wi-Fi disabled.")
self.status_label.set_visible(True)
else:
self.status_label.set_label("Wi-Fi device not available.")
self.status_label.set_visible(True)
self.wifi_toggle_button.set_sensitive(False)
self.refresh_button.set_sensitive(False)
def _update_wifi_status_ui(self, *args):
if self.network_client.wifi_device:
enabled = self.network_client.wifi_device.enabled
self.wifi_toggle_button.set_sensitive(True)
self.refresh_button.set_sensitive(enabled)
if enabled:
self.wifi_toggle_button_icon.set_markup(icons.wifi_3)
else:
self.wifi_toggle_button_icon.set_markup(icons.wifi_off)
self.status_label.set_label("Wi-Fi disabled.")
self.status_label.set_visible(True)
self._clear_ap_list()
if enabled and not self.ap_list_box.get_children():
GLib.idle_add(self._refresh_access_points)
else:
self.wifi_toggle_button.set_sensitive(False)
self.refresh_button.set_sensitive(False)
def _toggle_wifi(self, _):
if self.network_client.wifi_device:
self.network_client.wifi_device.toggle_wifi()
def _refresh_access_points(self, _=None):
if self.network_client.wifi_device and self.network_client.wifi_device.enabled:
self.status_label.set_label("Scanning for Wi-Fi networks...")
self.status_label.set_visible(True)
self._clear_ap_list()
self.network_client.wifi_device.scan()
return False
def _clear_ap_list(self):
for child in self.ap_list_box.get_children():
child.destroy()
def _load_access_points(self, *args):
if not self.network_client.wifi_device or not self.network_client.wifi_device.enabled:
self._clear_ap_list()
self.status_label.set_label("Wi-Fi disabled.")
self.status_label.set_visible(True)
return
self._clear_ap_list()
access_points = self.network_client.wifi_device.access_points
if not access_points:
self.status_label.set_label("No Wi-Fi networks found.")
self.status_label.set_visible(True)
else:
self.status_label.set_visible(False)
sorted_aps = sorted(access_points, key=lambda x: x.get("strength", 0), reverse=True)
for ap_data in sorted_aps:
slot = WifiAccessPointSlot(ap_data, self.network_client, self.network_client.wifi_device)
self.ap_list_box.add(slot)
self.ap_list_box.show_all()