disk_eraser/app/__init__.py
2024-02-26 10:28:41 +03:00

168 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import platform
from tkinter import ttk
from customtkinter import *
from CTkMenuBar import *
from typing import List
from app.utils_drive import *
class App:
drives: List[Drive] = []
selected = None
drive_tree = None
def __init__(self):
set_default_color_theme("dark-blue")
set_appearance_mode("dark")
self.OS_TYPE = platform.system()
self.root = CTk()
self.root.title("Disk Eraser")
self.root.geometry("700x300")
self.root.minsize(700, 300)
self.__load_menus()
self.__init_table()
self.__update_drives()
self.root.mainloop()
def __load_menus(self):
bg_color = self.root._apply_appearance_mode(ThemeManager.theme["CTkFrame"]["fg_color"])
main_menu = CTkMenuBar(self.root, bg_color=bg_color)
help_menu = main_menu.add_cascade("Справка")
dropdown1 = CustomDropdownMenu(widget=help_menu)
dropdown1.add_option(option="Содержание")
dropdown1.add_separator()
dropdown1.add_option(option="О программе")
self.root.config(menu=main_menu)
self.bottom_frame = CTkFrame(self.root, height=10000)
self.erase_button = CTkButton(
self.bottom_frame, text="Стереть диск", command=self.__erase_drive)
self.erase_button.pack(side=RIGHT)
update_button = CTkButton(
self.bottom_frame, text="Обновить", command=self.__update_drives)
update_button.pack(side=RIGHT, padx=5)
self.method_box = CTkComboBox(master=self.bottom_frame, values=list(erasing_methods.keys()), state="readonly")
self.method_box.pack(side=RIGHT, padx=6)
method_label = CTkLabel(master=self.bottom_frame, text="Метод: ")
method_label.pack(padx=5, side=RIGHT)
self.bottom_frame.pack(side=BOTTOM, fill=BOTH, padx=5, pady=5)
def __update_drives(self):
self.drive_tree.delete(*self.drive_tree.get_children())
self.__load_drives()
for drive in self.drives:
self.drive_tree.insert("", END, values=(
drive.index, drive.name, drive.disk_type, self.__human_size(drive.capacity), drive.serial_num))
def __load_drives(self):
if self.OS_TYPE == "Windows":
import wmi
c = wmi.WMI()
self.drives = []
if disks := c.Win32_DiskDrive():
for disk in disks:
self.drives.append(Drive(disk.Model, disk.Name, disk.InterfaceType, disk.DefaultBlockSize, int(
disk.Size), disk.SerialNumber, disk.Index))
elif self.OS_TYPE == "Linux":
from diskinfo import Disk, DiskInfo
di = DiskInfo()
disks = di.get_disk_list(sorting=True)
self.drives = []
for disk in disks:
if "zram" not in disk.get_path():
self.drives.append(Drive(disk.get_model(), disk.get_path(), disk.get_type_str(
), disk.get_logical_block_size(), int(disk.get_size()*512), disk.get_serial_number(), disk.get_device_id()))
def __init_table(self):
###Treeview Customisation (theme colors are selected)
bg_color = self.root._apply_appearance_mode(ThemeManager.theme["CTkFrame"]["fg_color"])
text_color = self.root._apply_appearance_mode(ThemeManager.theme["CTkLabel"]["text_color"])
selected_color = self.root._apply_appearance_mode(ThemeManager.theme["CTkButton"]["fg_color"])
treestyle = ttk.Style()
treestyle.theme_use()
treestyle.configure("Treeview", background=bg_color, foreground=text_color, fieldbackground=bg_color, borderwidth=0)
treestyle.map('Treeview', background=[('selected', bg_color)], foreground=[('selected', selected_color)])
treestyle.configure("Treeview.Heading", background=bg_color, foreground=text_color, fieldbackground=bg_color, borderwidth=0)
treestyle.map('Treeview.Heading', background=[('selected', bg_color)], foreground=[('selected', selected_color)])
self.root.bind("<<TreeviewSelect>>", lambda event: self.root.focus_set())
# определяем столбцы
columns = ("index", "name", "type", "capacity", "serial_num")
self.drive_tree = ttk.Treeview(
columns=columns, show="headings", selectmode="browse")
self.drive_tree.pack(fill=BOTH, expand=1, side=TOP)
# определяем заголовки
self.drive_tree.heading("index", text="ID", anchor=W, command=lambda: self.__sort(0, False))
self.drive_tree.heading("name", text="Имя", anchor=W, command=lambda: self.__sort(1, False))
self.drive_tree.heading("type", text="Тип", anchor=W, command=lambda: self.__sort(2, False))
self.drive_tree.heading("capacity", text="Объем", anchor=W, command=lambda: self.__sort(3, False))
self.drive_tree.heading("serial_num", text="Серийный номер", anchor=W, command=lambda: self.__sort(4, False))
self.drive_tree.column("#1", stretch=NO, width=60, minwidth=60)
self.drive_tree.column("#2", stretch=YES, width=150, minwidth=120)
self.drive_tree.column("#3", stretch=NO, width=100, minwidth=100)
self.drive_tree.column("#4", stretch=YES, width=150, minwidth=100)
self.drive_tree.column("#5", stretch=YES, width=150, minwidth=100)
self.drive_tree.bind("<<TreeviewSelect>>", self.__drive_selected)
def __human_size(self, size):
units = ['Б', 'КБ', 'МБ', 'ГБ', 'ТБ', 'ПБ']
for unit in units:
if size < 1024:
return f"{size:.1f} {unit}"
size /= 1024
def __drive_selected(self, event):
for selected_item in self.drive_tree.selection():
item = self.drive_tree.item(selected_item)
self.selected = item["values"]
def __erase_drive(self):
if self.selected is not None:
self.erase_button.configure(state='disabled')
thread = None
self.progressbar = CTkProgressBar(master=self.bottom_frame, orientation="horizontal", width=250)
self.progressbar.pack(side=LEFT, padx=6, pady=6)
for drive in self.drives:
if drive.index == self.selected[0]:
thread = drive.erase(self.method_box.get(), progress=self.progressbar)
self.__check_thread(thread)
def __check_thread(self, thread):
if thread.is_alive():
self.root.after(1000, lambda: self.__check_thread(thread))
else:
self.progressbar.pack_forget()
self.erase_button.configure(state='active')
def __sort(self, col, reverse):
# получаем все значения столбцов в виде отдельного списка
l = [(self.drive_tree.set(k, col), k) for k in self.drive_tree.get_children("")]
# сортируем список
l.sort(reverse=reverse)
# переупорядочиваем значения в отсортированном порядке
for index, (_, k) in enumerate(l):
self.drive_tree.move(k, "", index)
# в следующий раз выполняем сортировку в обратном порядке
self.drive_tree.heading(col, command=lambda: self.__sort(col, not reverse))