128 lines
4.0 KiB
Python
128 lines
4.0 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, Gtk
|
|
|
|
|
|
class StoragePage(Adw.Bin):
|
|
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
|
|
|
|
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 []
|