diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 17679bd..b7e07a5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -5,4 +5,4 @@ # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. # * @global-owner1 @global-owner2 -* @ghostbsd/developers +* @ghostbsd/contributors @ghostbsd/new-contributors @ghostbsd/core-contributors @ghostbsd/project-leader \ No newline at end of file diff --git a/.gitignore b/.gitignore index 86fe885..480f209 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,5 @@ nosetests.xml .mr.developer.cfg .project .pydevproject -.project -.pydevproject .idea* .settings* \ No newline at end of file diff --git a/src/add_admin.py b/src/add_admin.py index 274579a..c51aa34 100644 --- a/src/add_admin.py +++ b/src/add_admin.py @@ -53,22 +53,22 @@ def save_admin_user(self): set_admin_user(uname, name, up, shell, hf, hst) def on_shell(self, widget): - SHELL = widget.get_active_text() - if SHELL == 'sh': + shell = widget.get_active_text() + if shell == 'sh': self.sh = '/bin/sh' - elif SHELL == 'csh': + elif shell == 'csh': self.sh = '/bin/csh' - elif SHELL == 'tcsh': + elif shell == 'tcsh': self.sh = '/bin/tcsh' - elif SHELL == 'fish': + elif shell == 'fish': self.sh = '/usr/local/bin/fish' - elif SHELL == 'bash': + elif shell == 'bash': self.sh = '/usr/local/bin/bash' - elif SHELL == 'rbash': + elif shell == 'rbash': self.sh = '/usr/local/bin/rbash' - elif SHELL == 'zsh': + elif shell == 'zsh': self.sh = '/usr/local/bin/zsh' - elif SHELL == 'ksh': + elif shell == 'ksh': self.sh = '/usr/local/bin/ksh93' def user_and_host(self, widget): @@ -152,6 +152,7 @@ def __init__(self, button3): self.box3.set_border_width(10) self.vbox1.pack_start(self.box3, True, True, 0) self.box3.show() + # self.label3 = Gtk.Label() # self.box3.pack_start(self.label3, False, False, 0) diff --git a/src/partition.py b/src/partition.py index bdc2771..b50ec61 100644 --- a/src/partition.py +++ b/src/partition.py @@ -3,6 +3,7 @@ import os import gi gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') from gi.repository import Gtk, Gdk from partition_handler import ( create_disk_partition_db, @@ -22,14 +23,13 @@ logo = "/usr/local/lib/gbi/image/logo.png" if not os.path.exists(tmp): os.makedirs(tmp) -disk_scheme = f'{tmp}/scheme' +disk_scheme_file = f'{tmp}/scheme' disk_file = f'{tmp}/disk' slice_file = f'{tmp}/slice' partition_label_file = f'{tmp}/partlabel' disk_db_file = f'{tmp}/disk.db' -ufs_Partiton_list = [] bios_type = bios_or_uefi() cssProvider = Gtk.CssProvider() @@ -43,14 +43,10 @@ ) -class Partitions(): +class Partitions: def set_fs(self, widget): self.fs = widget.get_active_text() - if 'UFS' in self.fs: - self.mountpoint_box.set_sensitive(True) - else: - self.mountpoint_box.set_sensitive(False) def get_mountpoint(self, widget): self.mountpoint = widget.get_active_text() @@ -78,10 +74,10 @@ def cancel(self, widget): self.window.hide() self.update() - def labelEditor(self, path, pslice, size, scheme, modify): + def label_editor(self, path, partition_slice, size, scheme, modify): free_space = int(size) self.window = Gtk.Window() - self.window.set_title("Add Partition") + self.window.set_title(title="Add Partition") self.window.set_border_width(0) self.window.set_size_request(480, 200) self.window.set_icon_from_file(logo) @@ -95,24 +91,20 @@ def labelEditor(self, path, pslice, size, scheme, modify): # create label # label0 = Gtk.Label("Create Partition Label") table = Gtk.Table(1, 2, True) - label1 = Gtk.Label("Type:") - label2 = Gtk.Label("Size(MB):") - label3 = Gtk.Label("Mount point:") + label1 = Gtk.Label(label="Type:") + label2 = Gtk.Label(label="Size(MB):") + label3 = Gtk.Label(label="Mount point:") self.fs_type = Gtk.ComboBoxText() self.fs_type.append_text('ZFS') - self.fs_type.append_text('UFS') - self.fs_type.append_text('UFS+S') - self.fs_type.append_text('UFS+J') - self.fs_type.append_text('UFS+SUJ') self.fs_type.append_text('SWAP') if scheme == 'GPT': if bios_type == "UEFI": self.fs_type.append_text("UEFI") if self.efi_exist is False: - self.fs_type.set_active(6) + self.fs_type.set_active(2) self.fs = "UEFI" elif self.mountpoint_behind == "/" or self.fs_behind == "ZFS": - self.fs_type.set_active(5) + self.fs_type.set_active(1) self.fs = "SWAP" else: self.fs_type.set_active(0) @@ -123,20 +115,20 @@ def labelEditor(self, path, pslice, size, scheme, modify): self.fs_type.set_active(6) self.fs = "BOOT" elif len(self.partitions) == 0: - self.fs_type.set_active(6) + self.fs_type.set_active(2) self.fs = "BOOT" elif self.mountpoint_behind == "/" or self.fs_behind == "ZFS": - self.fs_type.set_active(5) + self.fs_type.set_active(1) self.fs = "SWAP" else: self.fs_type.set_active(0) self.fs = "ZFS" elif self.mountpoint_behind == "/" or self.fs_behind == "ZFS": - self.fs_type.set_active(5) + self.fs_type.set_active(1) self.fs = "SWAP" else: - self.fs_type.set_active(4) - self.fs = "UFS+SUJ" + self.fs_type.set_active(0) + self.fs = "ZFS" self.fs_type.connect("changed", self.set_fs) adj = Gtk.Adjustment(free_space, 0, free_space, 1, 100, 0) self.entry = Gtk.SpinButton(adjustment=adj, numeric=True) @@ -174,8 +166,8 @@ def labelEditor(self, path, pslice, size, scheme, modify): table.attach(self.fs_type, 1, 2, 1, 2) table.attach(label2, 0, 1, 2, 3) table.attach(self.entry, 1, 2, 2, 3) - table.attach(label3, 0, 1, 3, 4) - table.attach(self.mountpoint_box, 1, 2, 3, 4) + # table.attach(label3, 0, 1, 3, 4) + # table.attach(self.mountpoint_box, 1, 2, 3, 4) box2.pack_start(table, False, False, 0) box2 = Gtk.HBox(False, 10) box2.set_border_width(5) @@ -196,8 +188,7 @@ def labelEditor(self, path, pslice, size, scheme, modify): elif scheme == 'GPT' and self.fs == 'BOOT': button.connect("clicked", self.on_add_partition, self.entry, free_space, path, True) - elif (scheme == 'GPT' and self.fs == 'UEFI' - and self.efi_exist is False): + elif scheme == 'GPT' and self.fs == 'UEFI' and self.efi_exist is False: button.connect("clicked", self.on_add_partition, self.entry, free_space, path, True) else: @@ -214,62 +205,6 @@ def labelEditor(self, path, pslice, size, scheme, modify): box2.pack_end(bbox, True, True, 5) self.window.show_all() - def on_fs(self, widget): - self.fs = widget.get_active_text() - - def choose_fs(self): - self.window = Gtk.Window() - self.window.set_title("Choose file system") - self.window.set_border_width(0) - self.window.set_size_request(480, 200) - self.window.set_icon_from_file(logo) - box1 = Gtk.VBox(False, 0) - self.window.add(box1) - box1.show() - box2 = Gtk.VBox(False, 10) - box2.set_border_width(10) - box1.pack_start(box2, True, True, 0) - box2.show() - table = Gtk.Table(1, 2, True) - label1 = Gtk.Label("File System:") - self.fs_type = Gtk.ComboBoxText() - self.fs_type.append_text('ZFS') - self.fs_type.append_text('UFS') - self.fs_type.append_text('UFS+S') - self.fs_type.append_text('UFS+J') - self.fs_type.append_text('UFS+SUJ') - if self.scheme == 'GPT': - self.fs_type.set_active(0) - self.fs = "ZFS" - else: - self.fs_type.set_active(4) - self.fs = "UFS+SUJ" - self.fs_type.connect("changed", self.on_fs) - table.attach(label1, 0, 1, 1, 2) - table.attach(self.fs_type, 1, 2, 1, 2) - box2.pack_start(table, False, False, 0) - box2 = Gtk.HBox(False, 10) - box2.set_border_width(5) - box1.pack_start(box2, False, True, 0) - box2.show() - # Add button - bbox = Gtk.HButtonBox() - bbox.set_border_width(5) - bbox.set_spacing(10) - button = Gtk.Button(stock=Gtk.STOCK_CANCEL) - button.connect("clicked", self.cancel) - bbox.add(button) - button = Gtk.Button(stock=Gtk.STOCK_ADD) - button.connect("clicked", self.set_auto_partition) - bbox.add(button) - box2.pack_end(bbox, True, True, 5) - self.window.show_all() - - def set_auto_partition(self, widget): - autoFreeSpace(self.path, self.size, self.fs, self.efi_exist, - self.disk, self.scheme) - self.window.hide() - self.update() def scheme_selection(self, combobox): model = combobox.get_model() @@ -283,7 +218,16 @@ def add_gpt_mbr(self, widget): self.update() self.window.hide() - def schemeEditor(self): + def scheme_editor(self): + """ + This method is used to create a partition scheme editor window. + + Return: + None + + Example: + - scheme_editor() + """ self.window = Gtk.Window() self.window.set_title("Partition Scheme") self.window.set_border_width(0) @@ -297,7 +241,7 @@ def schemeEditor(self): box1.pack_start(box2, True, True, 0) box2.show() # Creating MBR or GPT drive - label = Gtk.Label('Select a partition scheme for this drive:') + label = Gtk.Label(label='Select a partition scheme for this drive:') label.set_use_markup(True) # Adding a combo box to selecting MBR or GPT scheme. self.scheme = 'GPT' @@ -325,13 +269,37 @@ def schemeEditor(self): self.window.show_all() def get_value(self, widget, entry): + """ + This method is called when the user clicks a button to get the value from the widget and entry fields. It + performs the following actions: + + - Gets the partition size as an integer from the entry field by calling the 'get_value_as_int()' method on + the entry object. + - Calculates the remaining size by subtracting the partition size from the total size, which is stored + in the 'self.size' variable. + - Calls the 'createSlice(partition_size, rs, self.path, self.disk)' method passing the partition size, + remaining size, path, and disk as arguments. + - Calls the 'update()' method to update the widget or perform any necessary updates. + - Hides the window by calling the 'hide()' method on the 'self.window' object. + + Parameters: + - self: The reference to the class instance. + - widget: The widget object in which the button is located. + - entry: The entry field object from which the partition size is fetched. + + Returns: + This method does not return any value. + """ partition_size = int(entry.get_value_as_int()) rs = int(self.size) - partition_size createSlice(partition_size, rs, self.path, self.disk) self.update() self.window.hide() - def sliceEditor(self): + def slice_editor(self): + """ + This method creates a window for editing the partition slice. + """ free_space = int(self.size) self.window = Gtk.Window() self.window.set_title("Add Partition") @@ -350,7 +318,7 @@ def sliceEditor(self): # label.set_use_markup(True) # label.set_alignment(0, .5) table = Gtk.Table(1, 2, True) - label1 = Gtk.Label("Size(MB):") + label1 = Gtk.Label(label="Size(MB):") adj = Gtk.Adjustment(free_space, 0, free_space, 1, 100, 0) self.entry = Gtk.SpinButton(adjustment=adj, numeric=True) self.entry.set_numeric(True) @@ -376,13 +344,22 @@ def sliceEditor(self): self.window.show_all() def update(self): - oldpath = self.path - self.Tree_Store() + """ + Update the treeview, expanding all rows and activating the previously selected row. + """ + old_path = self.path + self.tree_store() self.treeview.expand_all() - self.treeview.row_activated(oldpath, self.treeview.get_columns()[0]) - self.treeview.set_cursor(oldpath) + self.treeview.row_activated(old_path, self.treeview.get_columns()[0]) + self.treeview.set_cursor(old_path) def delete_partition(self, widget): + """ + Delete a partition. + + Parameters: + widget: The widget associated with the partition. + """ part = self.slice if self.label == "Not selected" else self.label Delete_partition(part, self.path) self.update() @@ -391,48 +368,65 @@ def delete_create_button(self): bbox = Gtk.HButtonBox() bbox.set_border_width(5) bbox.set_spacing(10) - self.create_bt = Gtk.Button("Create") + self.create_bt = Gtk.Button(label="Create") self.create_bt.connect("clicked", self.create_partition) bbox.add(self.create_bt) - self.delete_bt = Gtk.Button("Delete") + self.delete_bt = Gtk.Button(label="Delete") self.delete_bt.connect("clicked", self.delete_partition) bbox.add(self.delete_bt) - self.modify_bt = Gtk.Button("Modify") + self.modify_bt = Gtk.Button(label="Modify") self.modify_bt.connect("clicked", self.modify_partition) # bbox.add(self.modify_bt) - self.revert_bt = Gtk.Button("Revert") - self.revert_bt.connect("clicked", self.revertChange) + self.revert_bt = Gtk.Button(label="Revert") + self.revert_bt.connect("clicked", self.revert_change) self.revert_bt.set_sensitive(False) bbox.add(self.revert_bt) - self.auto_bt = Gtk.Button("Auto") - self.auto_bt.connect("clicked", self.autoPartition) + self.auto_bt = Gtk.Button(label="Auto") + self.auto_bt.connect("clicked", self.auto_partition) bbox.add(self.auto_bt) return bbox def modify_partition(self, widget): if len(self.path) == 3: if 'freespace' not in self.slice: - self.labelEditor(self.path, self.slice, self.size, 'MBR', True) + self.label_editor(self.path, self.slice, self.size, 'MBR', True) elif len(self.path) == 2 and 'freespace' not in self.slice: if self.scheme == "GPT": - self.labelEditor(self.path, self.slice, self.size, 'GPT', True) + self.label_editor(self.path, self.slice, self.size, 'GPT', True) + + def auto_partition(self, widget): + """ + Automatically partitions the disk based on given parameters. - def autoPartition(self, widget): + :param widget: The widget triggering the method. + """ self.create_bt.set_sensitive(False) self.delete_bt.set_sensitive(False) self.modify_bt.set_sensitive(False) self.auto_bt.set_sensitive(False) self.revert_bt.set_sensitive(False) if 'freespace' in self.slice: - self.choose_fs() + autoFreeSpace(self.path, self.size, 'ZFS', self.efi_exist, + self.disk, self.scheme) + self.update() else: print('wrong utilization') - def revertChange(self, widget): + def revert_change(self, widget): + """ + Reverts the changes made to the widget. + + This method removes temporary files related to creating, deleting, and destroying disk partitions. + It also removes the disk scheme file, disk file, slice file, and partition label file if they exist. + After removing the files, it recreates the disk partition database, updates the Tree Store, and expands + all nodes in the Tree View. + + :param widget: The widget that triggered the revert change action. + """ if os.path.exists(f'{tmp}/create'): os.remove(f'{tmp}/create') - if os.path.exists(disk_scheme): - os.remove(disk_scheme) + if os.path.exists(disk_scheme_file): + os.remove(disk_scheme_file) if os.path.exists(disk_file): os.remove(disk_file) if os.path.exists(slice_file): @@ -444,134 +438,332 @@ def revertChange(self, widget): if os.path.exists(partition_label_file): os.remove(partition_label_file) create_disk_partition_db() - self.Tree_Store() + self.tree_store() self.treeview.expand_all() def create_partition(self, widget): + """ + Create partition method. + + :param widget: The widget triggering the method. + :type widget: Any + """ self.create_bt.set_sensitive(False) self.delete_bt.set_sensitive(False) self.modify_bt.set_sensitive(False) self.auto_bt.set_sensitive(False) self.revert_bt.set_sensitive(False) if self.change_schemes is True: - self.schemeEditor() + self.scheme_editor() elif 'freespace' in self.label: - self.labelEditor(self.path, self.slice, self.size, 'MBR', False) + self.label_editor(self.path, self.slice, self.size, 'MBR', False) elif 'freespace' in self.slice: if self.scheme == "MBR" and self.path[1] < 4: - self.sliceEditor() + self.slice_editor() elif self.scheme == "GPT": - self.labelEditor(self.path, self.slice, self.size, 'GPT', - False) + self.label_editor(self.path, self.slice, self.size, 'GPT', + False) else: print('This method of creating partition is not implemented') - def partition_selection(self, widget): + def partition_selection_new(self, widget): + """ + This method is used to perform various operations based on the selected partition in the given widget. + + :param widget: The widget containing the partition selection. + """ model, self.iter, = widget.get_selected() - if self.iter is not None: - self.path = model.get_path(self.iter) - main_tree_iter = model.get_iter(self.path) - self.size = model.get_value(main_tree_iter, 1) - tree_iter1 = model.get_iter(self.path[0]) - self.scheme = model.get_value(tree_iter1, 3) - self.disk = model.get_value(tree_iter1, 0) - if len(self.path) >= 2: - tree_iter2 = model.get_iter(self.path[:2]) - self.slice = model.get_value(tree_iter2, 0) - self.change_schemes = False - else: - if len(self.path) == 1: - if how_partition(self.disk) == 0: - self.change_schemes = True - elif how_partition(self.disk) == 1: - slice_path = f'{self.path[0]}:0' - # Try to see if tree_iter2 exist - try: - tree_iter2 = model.get_iter(slice_path) - if 'freespace' in model.get_value(tree_iter2, 0): - self.change_schemes = True - else: - self.change_schemes = False - except ValueError: + if self.iter is None: + self.button3.set_sensitive(False) + return None + self.path = model.get_path(self.iter) + main_tree_iter = model.get_iter(self.path) + self.size = model.get_value(main_tree_iter, 1) + tree_iter1 = model.get_iter(self.path[0]) + self.scheme = model.get_value(tree_iter1, 3) + self.disk = model.get_value(tree_iter1, 0) + if len(self.path) >= 2: + tree_iter2 = model.get_iter(self.path[:2]) + self.slice = model.get_value(tree_iter2, 0) + self.change_schemes = False + else: + if len(self.path) == 1: + if how_partition(self.disk) == 0: + self.change_schemes = True + elif how_partition(self.disk) == 1: + slice_path = f'{self.path[0]}:0' + # Try to see if tree_iter2 exist + try: + tree_iter2 = model.get_iter(slice_path) + if 'freespace' in model.get_value(tree_iter2, 0): self.change_schemes = True - else: - self.change_schemes = False - self.slice = 'Not selected' + else: + self.change_schemes = False + except ValueError: + self.change_schemes = True else: - self.slice = 'Not selected' self.change_schemes = False - if len(self.path) == 3: - tree_iter3 = model.get_iter(self.path[:3]) - self.label = model.get_value(tree_iter3, 0) + self.slice = 'Not selected' else: - self.label = 'Not selected' - if (len(self.path) == 2 and self.path[1] > 0 - and self.scheme == "GPT"): - pathbehind = f'{self.path[0]}:{str(int(self.path[1] - 1))}' - tree_iter4 = model.get_iter(pathbehind) - self.mountpoint_behind = model.get_value(tree_iter4, 2) - self.fs_behind = model.get_value(tree_iter4, 3) - elif (len(self.path) == 3 and self.path[2] > 0 - and self.scheme == "MBR"): - path1 = self.path[0] - path2 = str(self.path[1]) - path3 = str(int(self.path[2] - 1)) - pathbehind2 = f'{path1}:{path2}:{path3}' - tree_iter1 = model.get_iter(pathbehind2) - self.mountpoint_behind = model.get_value(tree_iter1, 2) - self.fs_behind = model.get_value(tree_iter1, 3) + self.slice = 'Not selected' + self.change_schemes = False + if len(self.path) == 3: + tree_iter3 = model.get_iter(self.path[:3]) + self.label = model.get_value(tree_iter3, 0) + else: + self.label = 'Not selected' + if (len(self.path) == 2 and self.path[1] > 0 + and self.scheme == "GPT"): + pathbehind = f'{self.path[0]}:{str(int(self.path[1] - 1))}' + tree_iter4 = model.get_iter(pathbehind) + self.mountpoint_behind = model.get_value(tree_iter4, 2) + self.fs_behind = model.get_value(tree_iter4, 3) + elif (len(self.path) == 3 and self.path[2] > 0 + and self.scheme == "MBR"): + path1 = self.path[0] + path2 = str(self.path[1]) + path3 = str(int(self.path[2] - 1)) + pathbehind2 = f'{path1}:{path2}:{path3}' + tree_iter1 = model.get_iter(pathbehind2) + self.mountpoint_behind = model.get_value(tree_iter1, 2) + self.fs_behind = model.get_value(tree_iter1, 3) + else: + self.mountpoint_behind = None + self.fs_behind = None + if 'freespace' in self.slice: + self.create_bt.set_sensitive(True) + self.delete_bt.set_sensitive(False) + self.modify_bt.set_sensitive(False) + self.auto_bt.set_sensitive(True) + # scan for efi partition + for num in range(self.path[1]): + partition_path = f"{self.path[0]}:{num}" + tree_iter_1 = model.get_iter(partition_path) + first_fs = model.get_value(tree_iter_1, 3) + if first_fs == "UEFI" or 'efi' in first_fs: + self.efi_exist = True + break + else: + self.efi_exist = False + elif 'freespace' in self.label: + if self.path[1] > 3: + self.create_bt.set_sensitive(False) else: - self.mountpoint_behind = None - self.fs_behind = None - if 'freespace' in self.slice: self.create_bt.set_sensitive(True) - self.delete_bt.set_sensitive(False) - self.modify_bt.set_sensitive(False) self.auto_bt.set_sensitive(True) - # scan for efi partition - for num in range(self.path[1]): - partition_path = f"{self.path[0]}:{num}" - tree_iter_1 = model.get_iter(partition_path) - first_fs = model.get_value(tree_iter_1, 3) - if first_fs == "UEFI" or 'efi' in first_fs: - self.efi_exist = True - break + self.delete_bt.set_sensitive(False) + self.modify_bt.set_sensitive(False) + elif 's' in self.slice and len(self.path) > 1: + self.create_bt.set_sensitive(False) + self.delete_bt.set_sensitive(True) + # self.modify_bt.set_sensitive(True) + self.auto_bt.set_sensitive(False) + elif 'p' in self.slice and len(self.path) > 1: + self.create_bt.set_sensitive(False) + self.delete_bt.set_sensitive(True) + # self.modify_bt.set_sensitive(True) + self.auto_bt.set_sensitive(False) + else: + self.delete_bt.set_sensitive(False) + self.modify_bt.set_sensitive(False) + self.auto_bt.set_sensitive(False) + if how_partition(self.disk) == 0: + self.create_bt.set_sensitive(True) + elif self.change_schemes is True: + self.create_bt.set_sensitive(True) + else: + self.create_bt.set_sensitive(False) + if os.path.exists(partition_label_file): + rd = open(partition_label_file, 'r') + self.partitions = rd.readlines() + if not self.partitions: + self.button3.set_sensitive(False) + return None + # Find if GPT scheme. + if os.path.exists(disk_scheme_file): + rschm = open(disk_scheme_file, 'r') + schm = rschm.read() + if 'GPT' in schm: + if os.path.exists(disk_file): + diskfile = open(disk_file, 'r') + disk = diskfile.readlines()[0].strip() + diskfile.close() + disk_id = self.disk_index.index(disk) + num = 0 + while True: + partition_path = f"{disk_id}:{num}" + try: + tree_iter_1 = model.get_iter(partition_path) + first_fs = model.get_value(tree_iter_1, 3) + if 'efi' in first_fs: + efi_already_exist = True + break + except ValueError: + efi_already_exist = False + break + num += 1 + if 'BOOT' in self.partitions[0] and bios_type == 'BIOS': + if len(self.partitions) >= 2 and 'ZFS' in self.partitions[1]: + self.button3.set_sensitive(True) + else: + self.button3.set_sensitive(False) + elif efi_already_exist is True and bios_type == 'UEFI': + if 'ZFS' in self.partitions[0]: + self.button3.set_sensitive(True) + else: + self.button3.set_sensitive(False) + elif len(self.partitions) >= 2and 'UEFI' in self.partitions[0] and 'ZFS' in self.partitions[1]: + self.button3.set_sensitive(True) + else: + self.button3.set_sensitive(False) else: self.efi_exist = False - elif 'freespace' in self.label: - if self.path[1] > 3: - self.create_bt.set_sensitive(False) - else: - self.create_bt.set_sensitive(True) - self.auto_bt.set_sensitive(True) - self.delete_bt.set_sensitive(False) - self.modify_bt.set_sensitive(False) - elif 's' in self.slice and len(self.path) > 1: - self.create_bt.set_sensitive(False) - self.delete_bt.set_sensitive(True) - # self.modify_bt.set_sensitive(True) - self.auto_bt.set_sensitive(False) - elif 'p' in self.slice and len(self.path) > 1: - self.create_bt.set_sensitive(False) - self.delete_bt.set_sensitive(True) - # self.modify_bt.set_sensitive(True) - self.auto_bt.set_sensitive(False) + if len(self.partitions) >= 1: + if "/boot\n" in self.partitions[0]: + if len(self.partitions) >= 2 and 'ZFS' in self.partitions[1]: + self.button3.set_sensitive(True) + else: + self.button3.set_sensitive(False) + elif 'ZFS' in self.partitions[0]: + self.button3.set_sensitive(True) + else: + self.button3.set_sensitive(False) + else: + self.button3.set_sensitive(False) else: - self.delete_bt.set_sensitive(False) - self.modify_bt.set_sensitive(False) - self.auto_bt.set_sensitive(False) + self.button3.set_sensitive(False) + else: + self.button3.set_sensitive(False) + path_exist = [ + os.path.exists(f'{tmp}/create'), + os.path.exists(disk_scheme_file), + os.path.exists(disk_file), + os.path.exists(slice_file), + os.path.exists(f'{tmp}/delete'), + os.path.exists(f'{tmp}/destroy'), + os.path.exists(partition_label_file) + ] + if any(path_exist): + self.revert_bt.set_sensitive(True) + else: + self.revert_bt.set_sensitive(False) + + def partition_selection(self, widget): + """ + This method is used to perform various operations based on the selected partition in the given widget. + + :param widget: The widget containing the partition selection. + """ + model, self.iter, = widget.get_selected() + if self.iter is None: + self.button3.set_sensitive(False) + return None + self.path = model.get_path(self.iter) + main_tree_iter = model.get_iter(self.path) + self.size = model.get_value(main_tree_iter, 1) + tree_iter1 = model.get_iter(self.path[0]) + self.scheme = model.get_value(tree_iter1, 3) + self.disk = model.get_value(tree_iter1, 0) + if len(self.path) >= 2: + tree_iter2 = model.get_iter(self.path[:2]) + self.slice = model.get_value(tree_iter2, 0) + self.change_schemes = False + else: + if len(self.path) == 1: if how_partition(self.disk) == 0: - self.create_bt.set_sensitive(True) - elif self.change_schemes is True: - self.create_bt.set_sensitive(True) + self.change_schemes = True + elif how_partition(self.disk) == 1: + slice_path = f'{self.path[0]}:0' + # Try to see if tree_iter2 exist + try: + tree_iter2 = model.get_iter(slice_path) + if 'freespace' in model.get_value(tree_iter2, 0): + self.change_schemes = True + else: + self.change_schemes = False + except ValueError: + self.change_schemes = True else: - self.create_bt.set_sensitive(False) + self.change_schemes = False + self.slice = 'Not selected' + else: + self.slice = 'Not selected' + self.change_schemes = False + if len(self.path) == 3: + tree_iter3 = model.get_iter(self.path[:3]) + self.label = model.get_value(tree_iter3, 0) + else: + self.label = 'Not selected' + if (len(self.path) == 2 and self.path[1] > 0 + and self.scheme == "GPT"): + pathbehind = f'{self.path[0]}:{str(int(self.path[1] - 1))}' + tree_iter4 = model.get_iter(pathbehind) + self.mountpoint_behind = model.get_value(tree_iter4, 2) + self.fs_behind = model.get_value(tree_iter4, 3) + elif (len(self.path) == 3 and self.path[2] > 0 + and self.scheme == "MBR"): + path1 = self.path[0] + path2 = str(self.path[1]) + path3 = str(int(self.path[2] - 1)) + pathbehind2 = f'{path1}:{path2}:{path3}' + tree_iter1 = model.get_iter(pathbehind2) + self.mountpoint_behind = model.get_value(tree_iter1, 2) + self.fs_behind = model.get_value(tree_iter1, 3) + else: + self.mountpoint_behind = None + self.fs_behind = None + if 'freespace' in self.slice: + self.create_bt.set_sensitive(True) + self.delete_bt.set_sensitive(False) + self.modify_bt.set_sensitive(False) + self.auto_bt.set_sensitive(True) + # scan for efi partition + for num in range(self.path[1]): + partition_path = f"{self.path[0]}:{num}" + tree_iter_1 = model.get_iter(partition_path) + first_fs = model.get_value(tree_iter_1, 3) + if first_fs == "UEFI" or 'efi' in first_fs: + self.efi_exist = True + break + else: + self.efi_exist = False + elif 'freespace' in self.label: + if self.path[1] > 3: + self.create_bt.set_sensitive(False) + else: + self.create_bt.set_sensitive(True) + self.auto_bt.set_sensitive(True) + self.delete_bt.set_sensitive(False) + self.modify_bt.set_sensitive(False) + elif 's' in self.slice and len(self.path) > 1: + self.create_bt.set_sensitive(False) + self.delete_bt.set_sensitive(True) + # self.modify_bt.set_sensitive(True) + self.auto_bt.set_sensitive(False) + elif 'p' in self.slice and len(self.path) > 1: + self.create_bt.set_sensitive(False) + self.delete_bt.set_sensitive(True) + # self.modify_bt.set_sensitive(True) + self.auto_bt.set_sensitive(False) + else: + self.delete_bt.set_sensitive(False) + self.modify_bt.set_sensitive(False) + self.auto_bt.set_sensitive(False) + if how_partition(self.disk) == 0: + self.create_bt.set_sensitive(True) + elif self.change_schemes is True: + self.create_bt.set_sensitive(True) + else: + self.create_bt.set_sensitive(False) if os.path.exists(partition_label_file): rd = open(partition_label_file, 'r') self.partitions = rd.readlines() + if not self.partitions: + self.button3.set_sensitive(False) + return None # Find if GPT scheme. - if os.path.exists(disk_scheme): - rschm = open(disk_scheme, 'r') + if os.path.exists(disk_scheme_file): + rschm = open(disk_scheme_file, 'r') schm = rschm.read() if 'GPT' in schm: if os.path.exists(disk_file): @@ -678,7 +870,7 @@ def partition_selection(self, widget): self.button3.set_sensitive(False) path_exist = [ os.path.exists(f'{tmp}/create'), - os.path.exists(disk_scheme), + os.path.exists(disk_scheme_file), os.path.exists(disk_file), os.path.exists(slice_file), os.path.exists(f'{tmp}/delete'), @@ -691,24 +883,36 @@ def partition_selection(self, widget): self.revert_bt.set_sensitive(False) def __init__(self, button3): + """ + Initialize the object. + + :param button3: the button3 parameter used in the method + """ + self.window = None + self.efi_exist = True + self.fs_behind = None + self.disk_index = None + self.path = None + self.disk = None + self.fs = None self.button3 = button3 self.vbox1 = Gtk.VBox(False, 0) self.vbox1.show() # Title - Title = Gtk.Label("Partition Editor", name="Header") - Title.set_property("height-request", 50) - self.vbox1.pack_start(Title, False, False, 0) + title_label = Gtk.Label(label="Partition Editor", name="Header") + title_label.set_property("height-request", 50) + self.vbox1.pack_start(title_label, False, False, 0) sw = Gtk.ScrolledWindow(hexpand=True, vexpand=True) - sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + # sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.store = Gtk.TreeStore(str, str, str, str, 'gboolean') - self.Tree_Store() + self.tree_store() self.treeview = Gtk.TreeView(self.store) self.treeview.set_model(self.store) self.treeview.set_rules_hint(True) cell = Gtk.CellRendererText() column = Gtk.TreeViewColumn(None, cell, text=0) - column_header = Gtk.Label('Partition') + column_header = Gtk.Label(label='Partition') column_header.set_use_markup(True) column_header.show() column.set_widget(column_header) @@ -717,7 +921,7 @@ def __init__(self, button3): column.set_sort_column_id(0) cell2 = Gtk.CellRendererText() column2 = Gtk.TreeViewColumn(None, cell2, text=0) - column_header2 = Gtk.Label('Size(MB)') + column_header2 = Gtk.Label(label='Size(MB)') column_header2.set_use_markup(True) column_header2.show() column2.set_widget(column_header2) @@ -725,7 +929,7 @@ def __init__(self, button3): column2.set_fixed_width(150) cell3 = Gtk.CellRendererText() column3 = Gtk.TreeViewColumn(None, cell3, text=0) - column_header3 = Gtk.Label('Mount Point') + column_header3 = Gtk.Label(label='Mount Point') column_header3.set_use_markup(True) column_header3.show() column3.set_widget(column_header3) @@ -733,7 +937,7 @@ def __init__(self, button3): column3.set_fixed_width(150) cell4 = Gtk.CellRendererText() column4 = Gtk.TreeViewColumn(None, cell4, text=0) - column_header4 = Gtk.Label('System/Type') + column_header4 = Gtk.Label(label='System/Type') column_header4.set_use_markup(True) column_header4.show() column4.set_widget(column_header4) @@ -751,7 +955,7 @@ def __init__(self, button3): self.treeview.expand_all() self.tree_selection = self.treeview.get_selection() self.tree_selection.set_mode(Gtk.SelectionMode.SINGLE) - self.tree_selection.connect("changed", self.partition_selection) + self.tree_selection.connect("changed", self.partition_selection_new) sw.add(self.treeview) sw.show() self.vbox1.pack_start(sw, True, True, 0) @@ -761,21 +965,25 @@ def __init__(self, button3): hbox1.show() self.scheme = 'GPT' hbox1.pack_start(self.delete_create_button(), False, False, 10) - return - def Tree_Store(self): + def tree_store(self): + """ + The tree_store method populates a tree store with disk and partition information from a disk database. + + :return: The populated tree store. + """ self.store.clear() disk_db = disk_database() self.disk_index = list(disk_db.keys()) for disk in disk_db: disk_info = disk_db[disk] - disk_schemee = disk_info['scheme'] + disk_scheme = disk_info['scheme'] mount_point = '' disk_size = str(disk_info['size']) disk_partitions = disk_info['partitions'] partition_list = disk_info['partition-list'] pinter1 = self.store.append(None, [disk, disk_size, mount_point, - disk_schemee, True]) + disk_scheme, True]) for partition in partition_list: partition_info = disk_partitions[partition] file_system = partition_info['file-system'] @@ -796,5 +1004,11 @@ def Tree_Store(self): return self.store def get_model(self): + """ + Returns the model associated with the tree selection. + + Return: + The model associated with the tree selection. + """ self.tree_selection.select_path(0) return self.vbox1 diff --git a/src/use_zfs.py b/src/use_zfs.py index edf5df7..c8d8948 100644 --- a/src/use_zfs.py +++ b/src/use_zfs.py @@ -2,7 +2,6 @@ from gi.repository import Gtk, Gdk import os -import os.path import re from gbi_common import zfs_datasets, be_name from partition_handler import (