Kaydet (Commit) 24da39a8 authored tarafından Hakan Dündar's avatar Hakan Dündar

Several improvements (performance, security, bug fixes, etc)

üst 5aec9a42
......@@ -3,13 +3,14 @@
# ----------------------------------- Disk - Disk Tab Import Function (contains import code of this module in order to avoid running them during module import) -----------------------------------
def disk_import_func():
global Gtk, GLib, Thread, os
global Gtk, GLib, Thread, os, subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
from threading import Thread
import os
import subprocess
global Config, MainGUI, Performance
......@@ -222,8 +223,8 @@ def disk_initial_func():
disk_file_system = _tr("[SWAP]")
if disk_file_system == "fuseblk": # Try to get actual file system by using "lsblk" tool if file system has been get as "fuseblk" (this happens for USB drives). Because "/proc/mounts" file contains file system information as in user space. To be able to get the actual file system, root access is needed for reading from some files or "lsblk" tool could be used.
try:
disk_file_system_from_lsblk = (subprocess.check_output("lsblk -no FSTYPE /dev/" + disk_list[selected_disk_number], shell=True).strip()).decode()
disk_file_system = disk_file_system + " (" + disk_file_system_from_lsblk + ")"
disk_for_file_system = "/dev/" + disk_list[selected_disk_number]
disk_file_system = (subprocess.check_output(["lsblk", "-no", "FSTYPE", disk_for_file_system], shell=False)).decode().strip()
except:
pass
# Get if_system_disk
......
......@@ -232,9 +232,19 @@ def environment_variables_loop_func():
variable_list = []
variable_type_list = []
# Get environment variabes and shell variables
printenv_output_lines = subprocess.check_output("/bin/bash -i -c printenv", shell=True).strip().decode().split("_=")[0].split("\n") # Variables with name starting with "_" are not get. "-i" is used in order to get variables which are get from "printenv" command typed by human user. Otherwise there are different results.
set_output_lines = subprocess.check_output("/bin/bash -i -c set", shell=True).decode().split("_=")[0].split("\n") # Variables with name starting with "_" are not get. "-i" is used in order to get variables which are get from "printenv" command typed by human user. Otherwise there are different results.
# Get environment variables and shell variables
printenv_output_lines = (subprocess.check_output(["/bin/bash", "-i", "-c", "printenv"], stderr=subprocess.STDOUT, shell=False)).decode().strip().split("_=")[0].split("\n") # Variables with name starting with "_" are not get. "-i" is used in order to get variables which are get from "printenv" command typed by human user. Otherwise there are different results.
set_output_lines = (subprocess.check_output(["/bin/bash", "-i", "-c", "set"], stderr=subprocess.STDOUT, shell=False)).decode().strip().split("_=")[0].split("\n") # Variables with name starting with "_" are not get. "-i" is used in order to get variables which are get from "printenv" command typed by human user. Otherwise there are different results.
# Delete some warning information (two warnings per "subprocess.check_output" code and they may be translated into other languages) which are printed when "-i" argument is used for "/bin/bash". Warning 1: "bash: cannot set terminal process group (number): Inappropriate ioctl for device". Warning 2: "bash: no job control in this shell".
if printenv_output_lines[0].startswith("bash: ") == True:
del printenv_output_lines[0]
if printenv_output_lines[0].startswith("bash: ") == True:
del printenv_output_lines[0]
if set_output_lines[0].startswith("bash: ") == True:
del set_output_lines[0]
if set_output_lines[0].startswith("bash: ") == True:
del set_output_lines[0]
# Join Environment and Shell Variables in a list (variable_list). Shell variables output (from "set" command) also contains environment variables. These are removed for preventing dublicated variables.
variable_list = list(printenv_output_lines)
......
......@@ -184,9 +184,9 @@ def gpu_initial_func():
gpu_device_model_name = Performance.gpu_device_model_name
# Get video_memory, if_unified_memory, direct_rendering, mesa_version, opengl_version values of the GPU which is preferred for running this application. "DRI_PRIME application-name" and "DRI_PRIME=1 application-name" could be used for running an application by using internal and external GPUs respectively.
glxinfo_command_list = ["glxinfo -B", "DRI_PRIME=1 glxinfo -B"]
for command in glxinfo_command_list: # "10" is large enough to try for all GPUs on an average computer.
for command in glxinfo_command_list:
try:
glxinfo_output_lines = (subprocess.check_output(command, shell=True).strip()).decode().split("\n") # This command gives current GPU information. If application is run with "DRI_PRIME=1 application-name" this command gives external GPU information.
glxinfo_output_lines = (subprocess.check_output(command, shell=True)).decode().strip().split("\n") # This command gives current GPU information. If application is run with "DRI_PRIME=1 application-name" this command gives external GPU information.
for line in glxinfo_output_lines:
if line.strip().startswith("Vendor:"):
gpu_vendor_in_driver = line.split()[-1].strip("()").split("x")[1].strip()
......@@ -252,15 +252,20 @@ def gpu_loop_func():
drawingarea1501.queue_draw()
current_resolution_and_refresh_rate = (subprocess.check_output("xrandr | grep '*'", shell=True).strip()).decode().split('*')[0].split(' ')
current_resolution_and_refresh_rate = [i for i in current_resolution_and_refresh_rate if i != '']
# Get current resolution and current refresh rate
xrandr_lines = (subprocess.check_output(["xrandr"], shell=False)).decode().strip().split("\n")
for line in xrandr_lines:
if "*" in line:
current_resolution = line.split()[0]
current_refresh_rate = line.split()[1].split("*")[0]
break
# Set and update GPU tab label texts by using information get
label1503.set_text(f'{fps_count[-1]:.0f}')
label1504.set_text(f'{frame_latency:.1f} ms')
label1505.set_text(f'{current_resolution_and_refresh_rate[1]} Hz')
label1506.set_text(f'{current_resolution_and_refresh_rate[0]}')
label1505.set_text(f'{current_refresh_rate} Hz')
label1506.set_text(f'{current_resolution}')
# ----------------------------------- GPU Initial Thread Function (runs the code in the function as threaded in order to avoid blocking/slowing down GUI operations and other operations) -----------------------------------
......
......@@ -60,8 +60,8 @@ def gpu_menus_gui_func():
Config.config_save_func()
if dialog_response == Gtk.ResponseType.CANCEL:
colorchooserdialog1001.hide()
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
def on_button1503p_clicked(widget): # For setting chart background color
red, blue, green, alpha = Config.chart_background_color_all_charts # Get current background color of the chart
......@@ -74,26 +74,26 @@ def gpu_menus_gui_func():
Config.config_save_func()
if dialog_response == Gtk.ResponseType.CANCEL:
colorchooserdialog1001.hide()
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
def on_combobox1501p_changed(widget): # For resetting all GPU tab settings # Option for defining "selected gpu/graphics card" which affects information shown on the GUI
def on_combobox1501p_changed(widget): # Option for defining "selected gpu/graphics card" which affects information shown on the GUI
Config.selected_gpu = Performance.gpu_list[combobox1501p.get_active()]
Performance.set_selected_gpu = Config.selected_gpu
Performance.performance_get_gpu_list_and_set_selected_gpu_func() # Call this function in order to apply changes
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
Config.config_save_func()
def on_button1504p_clicked(widget):
def on_button1504p_clicked(widget): # For resetting all GPU tab settings
Config.config_default_performance_gpu_func()
Config.config_save_func()
Performance.performance_get_gpu_list_and_set_selected_gpu_func() # Call this function in order to apply changes
gpu_tab_customization_popover_disconnect_signals_func()
gpu_tab_popover_set_gui()
gpu_tab_customization_popover_connect_signals_func()
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
Gpu.gpu_initial_func() # Call this function in order to apply changes
Gpu.gpu_loop_func() # Call this function in order to apply changes immediately (without waiting update interval).
# ********************** Connect signals to GUI objects for GPU tab **********************
......
......@@ -133,7 +133,7 @@ def main_gui_func():
# Show information for warning the user if the application has been run with root privileges. Information is shown just below the application window headerbar.
if os.geteuid() == 0: # Check UID if it is "0". This means the application is run with root privileges.
import Gdk # Used for changing default label color
from gi.repository import Gdk # Used for changing default label color
label_root_warning = Gtk.Label(label=_tr("Warning! The application has been run with root privileges, you may harm your system.")) # Generate a new label for the information. This label does not exist in the ".ui" UI file.
# label_root_warning.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0.0, 1.0, 0.0, 1.0))
label_root_warning.modify_bg(Gtk.StateFlags.NORMAL, Gdk.color_parse("red")) # Set background color of the label.
......
......@@ -3,44 +3,39 @@
# ----------------------------------- MainMenusGUI - Main Menus GUI Import Function (contains import code of this module in order to avoid running them during module import) -----------------------------------
def main_menus_gui_import_func():
global Gtk, os, signal, Thread
global Gtk, os
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import os
import signal
from threading import Thread
global Config, MainGUI
import Config, MainGUI
global Config
import Config
# ----------------------------------- MainMenusGUI - Main Menus GUI Function (the code of this module in order to avoid running them during module import and defines GUI functions/signals) -----------------------------------
def main_menus_gui_func():
global builder1001
global builder
global menu1001m
global aboutdialog1001d
builder1001 = Gtk.Builder()
builder1001.add_from_file(os.path.dirname(os.path.realpath(__file__)) + "/../ui/MainMenusDialogs.ui")
builder = Gtk.Builder()
builder.add_from_file(os.path.dirname(os.path.realpath(__file__)) + "/../ui/MainMenusDialogs.ui")
menu1001m = builder1001.get_object('menu1001m')
menuitem1002m = builder1001.get_object('menuitem1002m')
menuitem1003m = builder1001.get_object('menuitem1003m')
menuitem1004m = builder1001.get_object('menuitem1004m')
menuitem1005m = builder1001.get_object('menuitem1005m')
menuitem1006m = builder1001.get_object('menuitem1006m')
checkmenuitem1001m = builder1001.get_object('checkmenuitem1001m')
menu1001m = builder.get_object('menu1001m')
menuitem1002m = builder.get_object('menuitem1002m')
menuitem1003m = builder.get_object('menuitem1003m')
menuitem1004m = builder.get_object('menuitem1004m')
menuitem1005m = builder.get_object('menuitem1005m')
menuitem1006m = builder.get_object('menuitem1006m')
checkmenuitem1001m = builder.get_object('checkmenuitem1001m')
builder1001d = Gtk.Builder()
builder1001d.add_from_file(os.path.dirname(os.path.realpath(__file__)) + "/../ui/MainMenusDialogs.ui")
aboutdialog1001d = builder1001d.get_object('aboutdialog1001d')
aboutdialog1001d = builder.get_object('aboutdialog1001d')
def on_menu1001m_show(widget):
......@@ -52,6 +47,9 @@ def main_menus_gui_func():
checkmenuitem1001m.connect("toggled", on_checkmenuitem1001m_toggled)
def on_menuitem1002m_activate(widget): # "Open Terminal" menu item
if 'Thread' not in globals():
global Thread
from threading import Thread
open_terminal_thread = Thread(target=main_menus_gui_open_terminal_func, daemon=True).start() # Terminal is run in another thread in order not to wait end of the run which occurs in single threaded code execution.
def on_checkmenuitem1001m_toggled(widget): # "Floating Summary" menu item
......@@ -70,6 +68,12 @@ def main_menus_gui_func():
Config.config_save_func()
def on_menuitem1003m_activate(widget): # "Restart as Root" menu item
if 'signal' not in globals():
global signal
import signal
if 'Thread' not in globals():
global Thread
from threading import Thread
def restart_as_root(): # Running action is performed in a separate thread for letting rest of the function code to be run without waiting closing the new opened application.
os.system("pkexec system-monitoring-center") # For running application as root by using polkit authentication window
restart_as_root_thread = Thread(target=restart_as_root, daemon=True).start() # Define a thread and run it
......
......@@ -180,12 +180,18 @@ def network_initial_func():
pci_ids_file_directory = "/usr/share/hwdata/pci.ids"
with open(pci_ids_file_directory) as reader: # Find network card device model from "pci.ids" file by using vendor id and device id.
pci_ids_output = reader.read()
if network_card_vendor_id in pci_ids_output:
if network_card_vendor_id in pci_ids_output: # "vendor" information may not be present in the pci.ids file.
rest_of_the_pci_ids_output = pci_ids_output.split(network_card_vendor_id)[1]
network_card_vendor_name = rest_of_the_pci_ids_output.split("\n")[0].strip()
if network_card_device_id in rest_of_the_pci_ids_output:
else:
network_card_vendor_name = _tr("Unknown")
network_card_vendor_name = f'[{network_card_vendor_name}]'
if network_card_device_id in rest_of_the_pci_ids_output: # "device name" information may not be present in the pci.ids file.
rest_of_the_rest_of_the_pci_ids_output = rest_of_the_pci_ids_output.split(network_card_device_id)[1]
network_card_device_name = rest_of_the_rest_of_the_pci_ids_output.split("\n")[0].strip()
else:
network_card_device_name = _tr("Unknown")
network_card_device_name = f'[{network_card_device_name}]'
network_card_device_model_name = f'{network_card_vendor_name} {network_card_device_name}'
if network_card_list[selected_network_card_number] == "lo": # lo (Loopback Device) is a system device and it is not a physical device. Therefore it could not be found in "pci.ids" file.
network_card_device_model_name = "Loopback Device"
......@@ -200,7 +206,7 @@ def network_initial_func():
with open("/sys/class/net/" + network_card_list[selected_network_card_number] + "/address") as reader:
network_card_mac_address = reader.read().strip().upper()
# Get network_address_ipv4, network_address_ipv6
ip_output_lines = (subprocess.check_output("ip a show " + network_card_list[selected_network_card_number], shell=True).strip()).decode().split("\n")
ip_output_lines = (subprocess.check_output(["ip", "a", "show", network_card_list[selected_network_card_number]], shell=False)).decode().strip().split("\n")
for line in ip_output_lines:
if "inet " in line:
network_address_ipv4 = line.split()[1].split("/")[0]
......@@ -247,7 +253,7 @@ def network_loop_func():
else:
network_card_connected = network_info
# Get network_ssid
nmcli_output_lines = (subprocess.check_output("nmcli -get-values DEVICE,CONNECTION device status", shell=True).strip()).decode().split("\n")
nmcli_output_lines = (subprocess.check_output(["nmcli", "-get-values", "DEVICE,CONNECTION", "device", "status"], shell=False)).decode().strip().split("\n")
for line in nmcli_output_lines:
line_splitted = line.split(":")
if network_card_list[selected_network_card_number] == line_splitted[0]:
......
......@@ -3,15 +3,13 @@
# ----------------------------------- Performance - Import Function (contains import code of this module in order to avoid running them during module import) -----------------------------------
def performance_import_func():
global Gtk, GLib, Thread, os, platform, time
global Gtk, GLib, Thread, os
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
from threading import Thread
import os
import platform
import time
global Config
......@@ -138,12 +136,18 @@ def performance_get_gpu_list_and_set_selected_gpu_func():
pci_ids_file_directory = "/usr/share/hwdata/pci.ids"
with open(pci_ids_file_directory) as reader:
pci_ids_output = reader.read()
if gpu_vendor_id in pci_ids_output:
if gpu_vendor_id in pci_ids_output: # "vendor" information may not be present in the pci.ids file.
rest_of_the_pci_ids_output = pci_ids_output.split(gpu_vendor_id)[1]
gpu_vendor_name = rest_of_the_pci_ids_output.split("\n")[0].strip()
if gpu_device_id in rest_of_the_pci_ids_output:
else:
gpu_vendor_name = _tr("Unknown")
gpu_vendor_name = f'[{gpu_vendor_name}]'
if gpu_device_id in rest_of_the_pci_ids_output: # "device name" information may not be present in the pci.ids file.
rest_of_the_rest_of_the_pci_ids_output = rest_of_the_pci_ids_output.split(gpu_device_id)[1]
gpu_device_name = rest_of_the_rest_of_the_pci_ids_output.split("\n")[0].strip()
else:
gpu_device_name = _tr("Unknown")
gpu_device_name = f'[{gpu_device_name}]'
gpu_device_model_name.append(f'{gpu_vendor_name} {gpu_device_name}')
gpu_vendor_id_list.append(gpu_vendor_id) # This list will be used for matching with GPU information from "glxinfo" command.
gpu_device_id_list.append(gpu_device_id) # This list will be used for matching with GPU information from "glxinfo" command.
......
......@@ -10,11 +10,10 @@ def performance_summary_headerbar_import_func():
from gi.repository import Gtk, GLib
from threading import Thread
import os
import platform
global Config, MainGUI, Performance
import Config, MainGUI, Performance
global Config, Performance
import Config, Performance
# Import locale and gettext modules for defining translation texts which will be recognized by gettext application (will be run by programmer externally) and exported into a ".pot" file.
......
......@@ -98,9 +98,12 @@ def processes_custom_priority_gui_func():
processes_get_process_current_nice_func()
selected_process_nice = int(adjustment2101w2.get_value())
try:
(subprocess.check_output("renice -n " + str(selected_process_nice) + " -p " + selected_process_pid, shell=True).strip()).decode()
(subprocess.check_output(["renice", "-n", str(selected_process_nice), "-p", selected_process_pid], stderr=subprocess.STDOUT, shell=False)).decode() # Command output is not printed by using "stderr=subprocess.STDOUT".
except subprocess.CalledProcessError:
(subprocess.check_output("pkexec renice -n " + str(selected_process_nice) + " -p " + selected_process_pid, shell=True).strip()).decode()
try: # This "try-catch" is used in order to prevent errors if wrong password is used or polkit dialog is closed by user.
(subprocess.check_output(["pkexec", "renice", "-n", str(selected_process_nice), "-p", selected_process_pid], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError:
processes_nice_error_dialog()
window2101w2.hide()
......
......@@ -3,13 +3,12 @@
# ----------------------------------- Processes - Processes Menus GUI Import Function (contains import code of this module in order to avoid running them during module import) -----------------------------------
def processes_menu_customizations_import_func():
global Gtk, os, subprocess
global Gtk, os
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import os
import subprocess
global Config, Processes
......
This diff is collapsed.
......@@ -276,12 +276,12 @@ def services_loop_func():
unit_files_command_parameter_list.append("Description")
unit_files_command_parameter_list = ",".join(unit_files_command_parameter_list) # Join strings with "," between them.
# Construct command for getting service information for all services
unit_files_command = "systemctl show --property=" + unit_files_command_parameter_list
unit_files_command = ["systemctl", "show", "--property=" + unit_files_command_parameter_list]
for service in service_list:
unit_files_command = unit_files_command + " " + service
unit_files_command.append(service)
# Get service data per service file in one attempt in order to obtain lower CPU usage. Because information from all service files will be get by one commandline operation and will be parsed later.
systemctl_show_command_lines = subprocess.check_output(unit_files_command, shell=True).decode().strip().split("\n\n")
systemctl_show_command_lines = (subprocess.check_output(unit_files_command, shell=False)).decode().strip().split("\n\n")
# Get services data (specific information by processing the data get previously)
for i, service in enumerate(service_list):
......
......@@ -163,7 +163,7 @@ def services_details_foreground_func():
services_ram_swap_data_precision = Config.services_ram_swap_data_precision
services_ram_swap_data_unit = Config.services_ram_swap_data_unit
systemctl_show_lines = (subprocess.check_output("systemctl show " + selected_service_name, shell=True).strip()).decode().split("\n")
systemctl_show_lines = (subprocess.check_output(["systemctl", "show", selected_service_name], shell=False)).decode().strip().split("\n")
selected_service_type = "-" # Initial value of "selected_service_type" variable. This value will be used if "selected_service_type" could not be detected.
selected_service_main_pid = "-"
......
......@@ -12,8 +12,25 @@ def services_menu_right_click_import_func():
import subprocess
global Services
import Services
global MainGUI, Services
import MainGUI, Services
# Import locale and gettext modules for defining translation texts which will be recognized by gettext application (will be run by programmer externally) and exported into a ".pot" file.
global _tr # This arbitrary variable will be recognized by gettext application for extracting texts to be translated
import locale
from locale import gettext as _tr
# Define contstants for language translation support
global application_name
application_name = "system-monitoring-center"
translation_files_path = "/usr/share/locale"
system_current_language = os.environ.get("LANG")
# Define functions for language translation support
locale.bindtextdomain(application_name, translation_files_path)
locale.textdomain(application_name)
locale.setlocale(locale.LC_ALL, system_current_language)
# ----------------------------------- Services - Services Menus GUI Function (the code of this module in order to avoid running them during module import and defines "Services" tab menu/popover GUI objects and functions/signals) -----------------------------------
......@@ -42,60 +59,63 @@ def services_menu_right_click_gui_func():
menuitem6109m = builder.get_object('menuitem6109m')
# ********************** Define object functions for Services tab right click menu **********************
def on_menu6101m_show(widget):
pass
def on_menuitem6101m_activate(widget): # "Start" item on the right click menu
service_name = Services.selected_service_name
try:
(subprocess.check_output("systemctl start " + service_name, shell=True).strip()).decode()
except subprocess.CalledProcessError:
pass
(subprocess.check_output(["systemctl", "start", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError as e:
services_action_warning_dialog(e.output.decode("utf-8").strip())
return
def on_menuitem6102m_activate(widget): # "Stop" item on the right click menu
service_name = Services.selected_service_name
try:
(subprocess.check_output("systemctl stop " + service_name, shell=True).strip()).decode()
except subprocess.CalledProcessError:
pass
(subprocess.check_output(["systemctl", "stop", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError as e:
services_action_warning_dialog(e.output.decode("utf-8").strip())
return
def on_menuitem6103m_activate(widget): # "Restart" item on the right click menu
service_name = Services.selected_service_name
try:
(subprocess.check_output("systemctl restart " + service_name, shell=True).strip()).decode()
except subprocess.CalledProcessError:
pass
(subprocess.check_output(["systemctl", "restart", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError as e:
services_action_warning_dialog(e.output.decode("utf-8").strip())
return
def on_menuitem6104m_activate(widget): # "Reload" item on the right click menu
service_name = Services.selected_service_name
try:
(subprocess.check_output("systemctl reload " + service_name, shell=True).strip()).decode()
except subprocess.CalledProcessError:
pass
(subprocess.check_output(["systemctl", "reload", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError as e:
services_action_warning_dialog(e.output.decode("utf-8").strip())
return
def on_menuitem6105m_activate(widget): # "Enable" item on the right click menu
service_name = Services.selected_service_name
try:
(subprocess.check_output("systemctl enable " + service_name, shell=True).strip()).decode()
except subprocess.CalledProcessError:
pass
(subprocess.check_output(["systemctl", "enable", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError as e:
services_action_warning_dialog(e.output.decode("utf-8").strip())
return
def on_menuitem6106m_activate(widget): # "Disable" item on the right click menu
service_name = Services.selected_service_name
try:
(subprocess.check_output("systemctl disable " + service_name, shell=True).strip()).decode()
except subprocess.CalledProcessError:
pass
(subprocess.check_output(["systemctl", "disable", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError as e:
services_action_warning_dialog(e.output.decode("utf-8").strip())
return
def on_checkmenuitem6107m_toggled(widget): # "Mask" item on the right click menu
service_name = Services.selected_service_name
try:
if checkmenuitem6107m.get_active() == True:
(subprocess.check_output("systemctl mask " + service_name, shell=True).strip()).decode()
(subprocess.check_output(["systemctl", "mask", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
if checkmenuitem6107m.get_active() == False:
(subprocess.check_output("systemctl unmask " + service_name, shell=True).strip()).decode()
except subprocess.CalledProcessError:
pass
(subprocess.check_output(["systemctl", "unmask", service_name], stderr=subprocess.STDOUT, shell=False)).decode()
except subprocess.CalledProcessError as e:
services_action_warning_dialog(e.output.decode("utf-8").strip())
def on_menuitem6108m_activate(widget): # "Copy Name" item on the right click menu
service_name = Services.selected_service_name
......@@ -113,7 +133,6 @@ def services_menu_right_click_gui_func():
ServicesDetails.services_details_foreground_thread_run_func()
# ********************** Connect signals to GUI objects for Services tab right click menu **********************
menu6101m.connect("show", on_menu6101m_show)
menuitem6101m.connect("activate", on_menuitem6101m_activate)
menuitem6102m.connect("activate", on_menuitem6102m_activate)
menuitem6103m.connect("activate", on_menuitem6103m_activate)
......@@ -128,9 +147,20 @@ def services_menu_right_click_gui_func():
def services_set_checkmenuitem_func():
service_name = Services.selected_service_name
service_status = subprocess.check_output("systemctl show " + service_name + " --property=UnitFileState", shell=True).decode().strip().split("=")[1]
service_status = (subprocess.check_output(["systemctl", "show", service_name, "--property=UnitFileState"], shell=False)).decode().strip().split("=")[1]
with checkmenuitem6107m.handler_block(checkmenuitem6107m_handler_id):
if service_status == "masked":
checkmenuitem6107m.set_active(True)
if service_status != "masked":
checkmenuitem6107m.set_active(False)
# ----------------------------------- Services - Service Action Warning Dialog Function (shows a warning dialog when an output text is obtained during service actions (start, stop, reload, etc.)) -----------------------------------
def services_action_warning_dialog(dialog_text):
warning_dialog6101 = Gtk.MessageDialog(transient_for=MainGUI.window1, title=_tr("Warning"), flags=0, message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.CLOSE, text=_tr("Information"), )
warning_dialog6101.format_secondary_text(dialog_text)
global warning_dialog6101_response
warning_dialog6101_response = warning_dialog6101.run()
warning_dialog6101.destroy()
......@@ -3,13 +3,12 @@
# ----------------------------------- Startup - Import Function (contains import code of this module in order to avoid running them during module import) -----------------------------------
def startup_import_func():
global Gtk, Gdk, GLib, Thread, subprocess, os
global Gtk, Gdk, GLib, Thread, os
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GLib
from threading import Thread
import subprocess
import os
......
......@@ -255,7 +255,7 @@ def startup_menu_right_click_gui_func():
startup_run_startup_item_warning_dialog(selected_startup_application_name, selected_startup_application_exec_value)
if warning_dialog5101_response == Gtk.ResponseType.YES:
try:
subprocess.Popen(selected_startup_application_exec_value, shell=False) # Run the command of the startup item. If "Yes" is clicked. "shell=False" is used in order to prevent "shell injection" which may cause security problems.
subprocess.Popen([selected_startup_application_exec_value], shell=False) # Run the command of the startup item. If "Yes" is clicked. "shell=False" is used in order to prevent "shell injection" which may cause security problems.
except FileNotFoundError:
startup_run_now_error_dialog(selected_startup_application_file_name, selected_startup_application_exec_value)
if warning_dialog5101_response == Gtk.ResponseType.NO:
......
......@@ -3,13 +3,12 @@
# ----------------------------------- Startup - Startup New Item Window GUI Import Function (contains import code of this module in order to avoid running them during module import) -----------------------------------
def startup_new_item_import_func():
global Gtk, Gdk, os, subprocess
global Gtk, Gdk, os
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
import os
import subprocess
global MainGUI
......
......@@ -380,8 +380,8 @@ def storage_loop_func():
disk_file_system = line_split[2]
if disk_file_system == "fuseblk": # Try to get actual file system by using "lsblk" tool if file system has been get as "fuseblk" (this happens for USB drives). Because "/proc/mounts" file contains file system information as in user space. To be able to get the actual file system, root access is needed for reading from some files or "lsblk" tool could be used.
try:
disk_file_system_from_lsblk = (subprocess.check_output("lsblk -no FSTYPE /dev/" + disk, shell=True).strip()).decode()
disk_file_system = disk_file_system + " (" + disk_file_system_from_lsblk + ")"
disk_for_file_system = "/dev/" + disk
disk_file_system = (subprocess.check_output(["lsblk", "-no", "FSTYPE", disk_for_file_system], shell=False)).decode().strip()
except:
pass
if disk in swap_disk_list:
......
......@@ -248,8 +248,8 @@ def storage_details_foreground_func():
disk_file_system = line_split[2]
if disk_file_system == "fuseblk": # Try to get actual file system by using "lsblk" tool if file system has been get as "fuseblk" (this happens for USB drives). Because "/proc/mounts" file contains file system information as in user space. To be able to get the actual file system, root access is needed for reading from some files or "lsblk" tool could be used.
try:
disk_file_system_from_lsblk = (subprocess.check_output("lsblk -no FSTYPE /dev/" + disk, shell=True).strip()).decode()
disk_file_system = disk_file_system + " (" + disk_file_system_from_lsblk + ")"
disk_for_file_system = "/dev/" + disk
disk_file_system = (subprocess.check_output(["lsblk", "-no", "FSTYPE", disk_for_file_system], shell=False)).decode().strip()
except:
pass
if disk in swap_disk_list:
......
......@@ -85,9 +85,9 @@ def storage_menu_right_click_gui_func():
disk_path = "/dev/" + disk
if disk_path != "-":
try:
(subprocess.check_output("udisksctl mount -b " + disk_path, shell=True).strip()).decode()
except subprocess.CalledProcessError: # Some disks do not have a mountable file system. A warning (Object /org/freedesktop/UDisks2/block_devices/[DISK_NAME] is not a mountable filesystem.) is given by "udisksctl" application for these disks.
pass
remove_output = (subprocess.check_output(["udisksctl", "mount", "-b", disk_path], stderr=subprocess.STDOUT, shell=False)).decode().strip()
except subprocess.CalledProcessError as e: # Some disks do not have a mountable file system. A warning (Object /org/freedesktop/UDisks2/block_devices/[DISK_NAME] is not a mountable filesystem.) is given by "udisksctl" application for these disks.
storage_disk_action_warning_dialog(e.output.decode("utf-8").strip()) # Convert bytes to string by using ".decode("utf-8")".
def on_menuitem4103m_activate(widget): # "Unmount" item on the right click menu
storage_disk_child_disk_mount_point_etc_func()
......@@ -105,9 +105,9 @@ def storage_menu_right_click_gui_func():
disk_path = "/dev/" + disk
if disk_path != "-":
try:
(subprocess.check_output("udisksctl unmount -b " + disk_path, shell=True).strip()).decode()
except subprocess.CalledProcessError: # Some disks do not have a mountable file system. A warning (Object /org/freedesktop/UDisks2/block_devices/[DISK_NAME] is not a mountable filesystem.) is given by "udisksctl" application for these disks.
pass
remove_output = (subprocess.check_output(["udisksctl", "unmount", "-b", disk_path], stderr=subprocess.STDOUT, shell=False)).decode().strip()
except subprocess.CalledProcessError as e: # Some disks do not have a mountable file system. A warning (Object /org/freedesktop/UDisks2/block_devices/[DISK_NAME] is not a mountable filesystem.) is given by "udisksctl" application for these disks.
storage_disk_action_warning_dialog(e.output.decode("utf-8").strip()) # Convert bytes to string by using ".decode("utf-8")".
def on_menuitem4104m_activate(widget): # "Remove" item on the right click menu
on_menuitem4103m_activate(menuitem4103m) # Unmount device before removing it.
......@@ -118,19 +118,19 @@ def storage_menu_right_click_gui_func():
if disk_path != "-":
if "loop" in disk_name and os.path.isdir("/sys/class/block/" + disk_name + "/loop/") == True: # "Remove" operation ("delete loop" operation for optical disks) for loop (virtual disk) devices (also if they are not partition).
try:
remove_output = (subprocess.check_output(["udisksctl loop-delete -b " + disk_path], stderr=subprocess.STDOUT, shell=True)).decode().strip()
remove_output = (subprocess.check_output(["udisksctl", "loop-delete", "-b", disk_path], stderr=subprocess.STDOUT, shell=False)).decode().strip()
except subprocess.CalledProcessError as e:
storage_disk_action_warning_dialog(e.output.decode("utf-8").strip()) # Convert bytes to string by using ".decode("utf-8")".
return
if "sr" in disk_name: # "Remove" operation ("eject" operation for optical disk disks) for optical disk drives.
try:
remove_output = (subprocess.check_output(["eject " + disk_path], stderr=subprocess.STDOUT, shell=True)).decode().strip()
remove_output = (subprocess.check_output(["eject", disk_path], stderr=subprocess.STDOUT, shell=False)).decode().strip()
except subprocess.CalledProcessError as e:
storage_disk_action_warning_dialog(e.output.decode("utf-8").strip())
return
if "loop" not in disk_name and "sr" not in disk_name: # "Remove" operation ("power off" operation) for non-virtual (loop devices) disks and non-optical disk drives. This operations method is used for USB disks, external HDDs/SSDs, etc.
try:
remove_output = (subprocess.check_output(["udisksctl power-off -b " + disk_path], stderr=subprocess.STDOUT, shell=True)).decode().strip()
remove_output = (subprocess.check_output(["udisksctl", "power-off", "-b", disk_path], stderr=subprocess.STDOUT, shell=False)).decode().strip()
except subprocess.CalledProcessError as e:
storage_disk_action_warning_dialog(e.output.decode("utf-8").strip())
return
......@@ -219,7 +219,7 @@ def storage_disk_has_no_mountable_file_system_error_dialog():
error_dialog4102.destroy()
# ----------------------------------- Storage - Storage Disk Action Warning Dialog Function (shows a warning dialog when a n output text is obtained during disk actions (mount, unmount, remove, etc.)) -----------------------------------
# ----------------------------------- Storage - Storage Disk Action Warning Dialog Function (shows a warning dialog when an output text is obtained during disk actions (mount, unmount, remove, etc.)) -----------------------------------
def storage_disk_action_warning_dialog(dialog_text):
warning_dialog4101 = Gtk.MessageDialog(transient_for=MainGUI.window1, title=_tr("Warning"), flags=0, message_type=Gtk.MessageType.WARNING,
......
......@@ -83,18 +83,29 @@ def storage_rename_gui_func():
if new_label == "":
new_label = '""' # Not string can not be used for deleting labels because of the its applications. "" have to be used in the commandline for deleting labels. '""' value is used for deleting labels of the file systems if no text is get from the entry.
try:
disk_filesystem = (subprocess.check_output("lsblk /dev/" + disk_name + " -no FSTYPE", shell=True).strip()).decode().lower() # Get disk file system for determining which application will be used for renaming operation. Different applications (commands) are used for renaming disks with different file systems.
if disk_filesystem == "ntfs":
os.system("pkexec sudo ntfslabel /dev/" + disk_name + " " + new_label) # "pkexec" is used for running application as root by using polkit authentication window. "pkexec" is used with "sudo" because some applications such as "ntfslabel" do not work without "sudo" is used.
if disk_filesystem == "ex2" or disk_filesystem == "ex3" or disk_filesystem == "ex4":
os.system("pkexec sudo e2label /dev/" + disk_name + " " + new_label)
if disk_filesystem == "mkswap":
os.system("pkexec sudo mkswap -L " + new_label + " /dev/" + disk_name) # For renaming labels of "swap"disks
if disk_filesystem == "exfat":
os.system("pkexec sudo exfatlabel /dev/" + disk_name + " " + new_label)
if disk_filesystem == "fat" or disk_filesystem == "vfat":
os.system("pkexec sudo fatlabel /dev/" + disk_name + " " + new_label)
except subprocess.CalledProcessError:
disk_for_file_system = "/dev/" + disk_name
disk_file_system = (subprocess.check_output(["lsblk", disk_for_file_system, "-no", "FSTYPE"], shell=False)).decode().strip().lower() # Get disk file system for determining which application will be used for renaming operation. Different applications (commands) are used for renaming disks with different file systems.
if disk_file_system == "ntfs":
action_output = (subprocess.check_output(["pkexec", "sudo", "ntfslabel", disk_for_file_system, new_label], stderr=subprocess.STDOUT, shell=False))