Files

133 lines
4.2 KiB
Python

import json
import subprocess
from functools import partial
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
from gi.repository import Adw, GObject, Gtk
class StoragePage(Adw.Bin):
__gsignals__ = {
"disk-selected": (GObject.SignalFlags.RUN_FIRST, None, (str,)),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.selected_disk = None
# Main Layout
clamp = Adw.Clamp()
clamp.set_maximum_size(600)
self.set_child(clamp)
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
box.set_spacing(24)
box.set_valign(Gtk.Align.CENTER)
box.set_margin_top(24)
box.set_margin_bottom(24)
clamp.set_child(box)
# Title
title = Gtk.Label(label="Installation Destination")
title.add_css_class("title-1")
box.append(title)
descr = Gtk.Label(
label="Select the storage device where you want to install Iridium OS."
)
descr.set_wrap(True)
box.append(descr)
# Disk List
self.disk_group = Adw.PreferencesGroup()
self.disk_group.set_title("Available Disks")
box.append(self.disk_group)
# Fetch real disks or fallback to mock
disks = self.get_disks()
if not disks:
disks = [
(
"NVMe Samsung 970 EVO (500GB)",
"nvme0n1",
"icon-drive-harddisk-solidstate-symbolic",
),
("SATA Seagate Barracuda (1TB)", "sda", "icon-drive-harddisk-symbolic"),
]
self.disk_rows = []
self.first_radio = None
for i, (name, dev, icon) in enumerate(disks):
row = Adw.ActionRow()
row.set_title(name)
row.set_subtitle(f"/dev/{dev}")
row.set_icon_name(icon)
# Radio button for selection
if not self.first_radio:
radio = Gtk.CheckButton()
self.first_radio = radio
# No default selection to force user interaction, for safety reasons
else:
radio = Gtk.CheckButton()
radio.set_group(self.first_radio)
radio.set_valign(Gtk.Align.CENTER)
# Connect signal to update selection
radio.connect("toggled", self.on_disk_toggled, dev)
row.add_suffix(radio)
row.set_activatable_widget(radio)
self.disk_group.add(row)
self.disk_rows.append(row)
def on_disk_toggled(self, button, device_name):
if button.get_active():
self.selected_disk = device_name
self.emit("disk-selected", device_name)
def get_selected_disk(self):
return self.selected_disk
def get_disks(self):
try:
# lsblk -J -o NAME,SIZE,MODEL,TYPE,TRAN
result = subprocess.run(
["lsblk", "-J", "-o", "NAME,SIZE,MODEL,TYPE,TRAN"],
capture_output=True,
text=True,
)
if result.returncode != 0:
print(f"lsblk failed with code {result.returncode}: {result.stderr}")
return []
data = json.loads(result.stdout)
disks = []
for device in data.get("blockdevices", []):
# Filter for physical disks usually
if device.get("type") == "disk":
model = device.get("model")
size = device.get("size")
name = f"{model} ({size})" if model else f"Unknown Drive ({size})"
dev = device.get("name")
tran = device.get("tran", "").lower() if device.get("tran") else ""
if "usb" in tran:
icon = "drive-removable-media-symbolic"
elif "nvme" in dev:
icon = "drive-harddisk-solidstate-symbolic"
else:
icon = "drive-harddisk-symbolic"
disks.append((name, dev, icon))
return disks
except Exception as e:
print(f"Error getting disks: {e}")
return []