1024 lines
37 KiB
Python
1024 lines
37 KiB
Python
|
"""
|
||
|
* Author: "PepDebian(peppermintosteam@proton.me)
|
||
|
*
|
||
|
* License: SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
*
|
||
|
* These are the functions for the xDaily GUI
|
||
|
"""
|
||
|
|
||
|
import os
|
||
|
import sqlite3
|
||
|
import subprocess
|
||
|
import platform
|
||
|
import threading
|
||
|
import tkinter as tk
|
||
|
import ttkbootstrap as ttk
|
||
|
import xdailyconf
|
||
|
|
||
|
|
||
|
home_folder = os.path.expanduser('~')
|
||
|
DATABASE_LOCATION = '.local/share/pmostools/peptools/welval.db'
|
||
|
database_path = os.path.join(home_folder, DATABASE_LOCATION)
|
||
|
|
||
|
# Password Dialog Settings
|
||
|
GLOBAL_FONT = ("Helvetica", 10)
|
||
|
HEIGHT= 230
|
||
|
WIDTH = 100
|
||
|
PWD_TITLE = "Authenticate"
|
||
|
ICON_PATH ="/usr/share/pixmaps/peppermint-old.png"
|
||
|
LABEL_TEXT ="Enter sudo password:"
|
||
|
BUTTON_TEXT = "Submit"
|
||
|
STYLE_TYPE = "danger"
|
||
|
CURSOR_ICON = "hand2"
|
||
|
|
||
|
def set_browser():
|
||
|
"""
|
||
|
Determine the system and set the browser type
|
||
|
"""
|
||
|
architecture = platform.architecture()[0]
|
||
|
if '64bit' in architecture:
|
||
|
browser_type = "min"
|
||
|
else:
|
||
|
browser_type = "luakit"
|
||
|
return browser_type
|
||
|
|
||
|
|
||
|
|
||
|
def submit_password(password_entry,
|
||
|
submit_callback):
|
||
|
"""
|
||
|
Handle the submission of the sudo password.
|
||
|
"""
|
||
|
password = password_entry.get()
|
||
|
if password:
|
||
|
submit_callback(password)
|
||
|
else:
|
||
|
tk.messagebox.showerror("Error", "Password cannot be empty.")
|
||
|
|
||
|
|
||
|
def getdata(password):
|
||
|
"""
|
||
|
Send update data to the update table.
|
||
|
"""
|
||
|
conn = sqlite3.connect(database_path)
|
||
|
cur = conn.cursor()
|
||
|
clean_appudeto = '''DELETE FROM appudeto;'''
|
||
|
cur.execute(clean_appudeto)
|
||
|
conn.commit()
|
||
|
see_upgrades = f'echo "{password}" | sudo -S apt list --upgradable'
|
||
|
try:
|
||
|
with subprocess.Popen(see_upgrades,
|
||
|
shell=True, stdout=subprocess.PIPE,
|
||
|
stderr=subprocess.PIPE, text=True
|
||
|
) as process:
|
||
|
output, _ = process.communicate()
|
||
|
packages_to_install = []
|
||
|
for line in output.split('\n'):
|
||
|
if (line.strip().startswith('Listing...') or
|
||
|
line.strip() == ''):
|
||
|
continue
|
||
|
package_name = line.strip()
|
||
|
package_type = ('security' if 'security' in
|
||
|
line.lower() else 'regular'
|
||
|
)
|
||
|
packages_to_install.append((package_name,
|
||
|
package_type)
|
||
|
)
|
||
|
for package, package_type in packages_to_install:
|
||
|
cur.execute("""INSERT INTO appudeto
|
||
|
(package, package_type)
|
||
|
VALUES (?, ?)""",
|
||
|
(package, package_type)
|
||
|
)
|
||
|
conn.commit()
|
||
|
conn.close()
|
||
|
print("Data inserted successfully.")
|
||
|
except sqlite3.Error as e_r:
|
||
|
print("SQLite error:", e_r)
|
||
|
conn.rollback()
|
||
|
conn.close()
|
||
|
|
||
|
|
||
|
def update_thumbnail_cache(process, output_text_maint):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window.
|
||
|
"""
|
||
|
clean_msg ="The thumnail cache has been cleared"
|
||
|
output_text_maint.insert(tk.END, clean_msg)
|
||
|
output_text_maint.see(tk.END)
|
||
|
error_output = process.stderr.read()
|
||
|
print(error_output)
|
||
|
|
||
|
|
||
|
def update_recently_used(process, output_text_maint):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window.
|
||
|
"""
|
||
|
clean_msg ="The recently used for the browser have been removed."
|
||
|
output_text_maint.insert(tk.END, clean_msg)
|
||
|
output_text_maint.see(tk.END)
|
||
|
|
||
|
|
||
|
def update_peppermint_branding(process, output_text_maint):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window.
|
||
|
"""
|
||
|
clean_msg =("The contents of /opt/pepconf/os-release and "
|
||
|
"/usr/lib/os-release and /etc/os-release have "
|
||
|
"been checked indicating the Peppermint branding "
|
||
|
"is correct."
|
||
|
)
|
||
|
output_text_maint.insert(tk.END, clean_msg)
|
||
|
output_text_maint.see(tk.END)
|
||
|
|
||
|
|
||
|
def update_ssd_trim(process, output_text_maint):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window.
|
||
|
"""
|
||
|
if process is None:
|
||
|
output_text_maint.insert(tk.END, "Error: Failed to execute TRIM command\n")
|
||
|
return
|
||
|
|
||
|
for line in process.stdout:
|
||
|
output_text_maint.insert(tk.END, line)
|
||
|
output_text_maint.see(tk.END)
|
||
|
output_text_maint.insert(tk.END, "Done\n")
|
||
|
error_output = process.stderr.read()
|
||
|
print(error_output)
|
||
|
if ("password" in error_output.lower()
|
||
|
and "WARNING: apt does not have a stable CLI interface"
|
||
|
not in error_output
|
||
|
):
|
||
|
message = "Incorrect password\n"
|
||
|
output_text_maint.insert(tk.END, message, "error")
|
||
|
output_text_maint.see(tk.END)
|
||
|
|
||
|
|
||
|
def update_caching_icons(process, output_text_maint):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window.
|
||
|
"""
|
||
|
if process is None:
|
||
|
output_text_maint.insert(tk.END, "Error: Failed to execute cachings command\n")
|
||
|
return
|
||
|
|
||
|
for line in process.stdout:
|
||
|
output_text_maint.insert(tk.END, line)
|
||
|
output_text_maint.see(tk.END)
|
||
|
output_text_maint.insert(tk.END, "Done\n")
|
||
|
error_output = process.stderr.read()
|
||
|
print(error_output)
|
||
|
if ("password" in error_output.lower()
|
||
|
and "WARNING: apt does not have a stable CLI interface"
|
||
|
not in error_output
|
||
|
):
|
||
|
message = "Incorrect password\n"
|
||
|
output_text_maint.insert(tk.END, message, "error")
|
||
|
output_text_maint.see(tk.END)
|
||
|
|
||
|
|
||
|
def update_output_clean(process, output_text):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window.
|
||
|
"""
|
||
|
clean_msg =("When you run sudo apt clean, the command clears out "
|
||
|
"the local repository of retrieved package files, but "
|
||
|
"it typically doesn't produce any output unless there's "
|
||
|
"an error. This is normal behavior for many terminal "
|
||
|
"commands in Linux. The clean command has been ran "
|
||
|
"successfully.")
|
||
|
output_text.insert(tk.END, clean_msg)
|
||
|
output_text.see(tk.END)
|
||
|
error_output = process.stderr.read()
|
||
|
print(error_output)
|
||
|
if ("password" in error_output.lower()
|
||
|
and "WARNING: apt does not have a stable CLI interface"
|
||
|
not in error_output
|
||
|
):
|
||
|
message = "Incorrect password\n"
|
||
|
output_text.insert(tk.END, message, "error")
|
||
|
output_text.see(tk.END)
|
||
|
|
||
|
|
||
|
def update_output(process, output_text):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window.
|
||
|
"""
|
||
|
for line in process.stdout:
|
||
|
output_text.insert(tk.END, line)
|
||
|
output_text.see(tk.END)
|
||
|
output_text.insert(tk.END, "Done\n")
|
||
|
error_output = process.stderr.read()
|
||
|
print(error_output)
|
||
|
if ("password" in error_output.lower()
|
||
|
and "WARNING: apt does not have a stable CLI interface"
|
||
|
not in error_output
|
||
|
):
|
||
|
message = "Incorrect password\n"
|
||
|
output_text.insert(tk.END, message, "error")
|
||
|
output_text.see(tk.END)
|
||
|
|
||
|
|
||
|
def update_output_view(process, output_text):
|
||
|
"""
|
||
|
Send the terminal output to the entry on the window. But this for
|
||
|
the Reveiw, updates section of the tabbing
|
||
|
"""
|
||
|
for line in process.stdout:
|
||
|
if 'amd64' in line:
|
||
|
line = line.split('amd64')[0] # Take only the part before '['
|
||
|
output_text.insert(tk.END, line.strip() + '\n')
|
||
|
output_text.see(tk.END)
|
||
|
error_output = process.stderr.read()
|
||
|
print(error_output)
|
||
|
if ("password" in error_output.lower()
|
||
|
and "WARNING: apt does not have a stable CLI interface"
|
||
|
not in error_output
|
||
|
):
|
||
|
message = "Incorrect password\n"
|
||
|
output_text.insert(tk.END, message, "error")
|
||
|
output_text.see(tk.END)
|
||
|
|
||
|
|
||
|
def toggle_group(event, tree):
|
||
|
""" create sthe toggle group areas in the entry box"""
|
||
|
item_id = tree.identify_row(event)
|
||
|
children = tree.get_children(item_id)
|
||
|
if children:
|
||
|
if tree.item(children[0], "open"):
|
||
|
tree.item(item_id, open=False)
|
||
|
else:
|
||
|
tree.item(item_id, open=True)
|
||
|
|
||
|
|
||
|
def currently_pending_updates(xd_intro):
|
||
|
"""
|
||
|
Load the grid to show the used what is there on the main tab
|
||
|
"""
|
||
|
database_connection = sqlite3.connect(database_path)
|
||
|
cursor = database_connection.cursor()
|
||
|
cursor.execute("""
|
||
|
SELECT
|
||
|
package_type,
|
||
|
SUBSTR(package, 1, INSTR(package, '/') - 1) AS package
|
||
|
FROM
|
||
|
appudeto
|
||
|
""")
|
||
|
records = cursor.fetchall()
|
||
|
database_connection.close()
|
||
|
grouped_records = {}
|
||
|
for row in records:
|
||
|
record_type = row[0]
|
||
|
if record_type not in grouped_records:
|
||
|
grouped_records[record_type] = {"count": 0, "packages": set()}
|
||
|
grouped_records[record_type]["count"] += 1
|
||
|
grouped_records[record_type]["packages"].add(row[1])
|
||
|
pedning_updates = ttk.Labelframe(xd_intro, width=50, height=25,
|
||
|
text="Currently Pending Updates"
|
||
|
)
|
||
|
pedning_updates.place(x=270, y=150)
|
||
|
tree = ttk.Treeview(pedning_updates, bootstyle='danger', height=6)
|
||
|
tree["columns"] = ("count", "package" )
|
||
|
tree["show"] = "tree"
|
||
|
tree.heading("#0", text="package_type")
|
||
|
tree.heading("count", text="Count")
|
||
|
tree.heading("package", text="package")
|
||
|
tree.column("#0", width=100)
|
||
|
tree.column("count", width=160)
|
||
|
tree.column("package", width=80)
|
||
|
vsb = ttk.Scrollbar(pedning_updates, orient="vertical",
|
||
|
command=tree.yview
|
||
|
)
|
||
|
vsb.pack(side="right", fill="y")
|
||
|
for record_type, data in grouped_records.items():
|
||
|
type_node = tree.insert("", "end", text=record_type)
|
||
|
for package in data["packages"]:
|
||
|
tree.insert(type_node, "end", values=(package, ""))
|
||
|
tree.set(type_node, "count", str(data["count"]))
|
||
|
|
||
|
tree.pack(expand=True, fill=tk.BOTH, padx=5.7, pady=5.7)
|
||
|
|
||
|
|
||
|
def get_update_records():
|
||
|
""" Query the current update sin the table"""
|
||
|
database_connection = sqlite3.connect(database_path)
|
||
|
cursor = database_connection.cursor()
|
||
|
cursor.execute("SELECT package, package_type from appudeto")
|
||
|
|
||
|
|
||
|
def center_screen(window_object, window_height, window_width):
|
||
|
""" gets the coordinates of the center of the screen """
|
||
|
screen_width = window_object.winfo_screenwidth()
|
||
|
screen_height = window_object.winfo_screenheight()
|
||
|
x_coordinate = int((screen_width / 2) - (window_width / 2))
|
||
|
y_coordinate = int((screen_height / 2) - (window_height / 2))
|
||
|
window_object.geometry(f"{window_width}x{window_height}+"
|
||
|
f"{x_coordinate}+{y_coordinate}")
|
||
|
|
||
|
|
||
|
def wbase(window_object):
|
||
|
"""Check to see what base is being loaded"""
|
||
|
if os.path.exists("/etc/devuan_version"):
|
||
|
window_object.title(xdailyconf.DEVUAN_TITLE)
|
||
|
elif os.path.exists("/etc/debian_version"):
|
||
|
window_object.title(xdailyconf.DEBIAN_TITLE)
|
||
|
|
||
|
|
||
|
def pep_docs():
|
||
|
"""Open Pep Docs"""
|
||
|
browser_type = set_browser()
|
||
|
url = "https://peppermint_os.codeberg.page/html/"
|
||
|
command = (
|
||
|
f'{browser_type} --new-window {url} &'
|
||
|
)
|
||
|
os.system(command)
|
||
|
|
||
|
|
||
|
def source_forge():
|
||
|
"""Open Sourceforge"""
|
||
|
browser_type = set_browser()
|
||
|
url ="https://sourceforge.net/p/peppermintos/pepos/"
|
||
|
command = (
|
||
|
f'{browser_type} --new-window {url} &'
|
||
|
)
|
||
|
os.system(command)
|
||
|
|
||
|
def manage_updates_tab(main_notebook, output_text, run_task_updates,xd_intro, manage_updates):
|
||
|
""" Move to the manage updates tab"""
|
||
|
main_notebook.select(1)
|
||
|
print("seeme")
|
||
|
output_text.config(state="disabled")
|
||
|
run_task_updates.focus_set()
|
||
|
print("xd_intro in manage_updates_tab:", xd_intro)
|
||
|
set_command_to_check_update(
|
||
|
run_task_updates, output_text, manage_updates, xd_intro
|
||
|
)
|
||
|
|
||
|
def on_manage_updates_clicked(event, run_task_updates, run_task_maintenance,
|
||
|
output_text, output_text_maint, system_maintenance, manage_updates,
|
||
|
xd_intro):
|
||
|
"""
|
||
|
This setthe starting button correctly when the tabs are
|
||
|
changed
|
||
|
"""
|
||
|
selected_tab = event.widget.tab(event.widget.select(), "text")
|
||
|
if selected_tab == "Manage Updates":
|
||
|
set_command_to_check_update(run_task_updates, output_text, manage_updates, xd_intro)
|
||
|
elif selected_tab == "System Maintenance":
|
||
|
set_command_to_thumnail_cache(run_task_maintenance, output_text_maint, system_maintenance)
|
||
|
|
||
|
|
||
|
def seeme(output_text, manage_updates, xd_intro):
|
||
|
print("you are one the Update tab")
|
||
|
|
||
|
|
||
|
def seemetoo():
|
||
|
print("you are on the main tab")
|
||
|
|
||
|
def system_maintenance_tab(main_notebook, output_text_maint,
|
||
|
run_task_maintenance):
|
||
|
""" Move to the systems updates tab"""
|
||
|
main_notebook.select(2)
|
||
|
output_text_maint.config(state="disabled")
|
||
|
run_task_maintenance.focus_set()
|
||
|
|
||
|
|
||
|
def update_label_text(label, text):
|
||
|
""" Sets the update label to the correct text"""
|
||
|
label.config(text=text)
|
||
|
|
||
|
|
||
|
def run_apt_update(output_text, manage_updates, xd_intro):
|
||
|
"""
|
||
|
Runs the update for the run button on the Check for updates section.
|
||
|
"""
|
||
|
try:
|
||
|
output_text.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(manage_updates)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.bind("<Return>",
|
||
|
lambda event: submit_password(password_entry,
|
||
|
submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
def submit_callback(password):
|
||
|
"""
|
||
|
This function is used, to pass to the submit password
|
||
|
to handle the sudo submission
|
||
|
"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
command = f'echo "{password}" | sudo -S apt update'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_output,
|
||
|
args=(process, output_text),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
getdata(password)
|
||
|
currently_pending_updates(xd_intro)
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
except Exception as exception:
|
||
|
output_text.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
def run_thumbnail_cache(output_text_maint, system_maintenance):
|
||
|
""" Clear the thumbnail cache on the system """
|
||
|
try:
|
||
|
output_text_maint.config(state="normal")
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
command = 'sh -c "cd ~/.cache/thumbnails && rm -r * 2>/dev/null"'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_thumbnail_cache,
|
||
|
args=(process, output_text_maint),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
except Exception as exception:
|
||
|
output_text_maint.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_recently_used(output_text_maint, system_maintenance):
|
||
|
""" Clear the recetly used applications """
|
||
|
try:
|
||
|
output_text_maint.config(state="normal")
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
command = 'truncate -s 0 ~/.local/share/recently-used.xbel'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_recently_used,
|
||
|
args=(process, output_text_maint),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
except Exception as exception:
|
||
|
output_text_maint.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_peppermint_branding(output_text_maint, system_maintenance):
|
||
|
""" Check and correct the Peppermint Branding """
|
||
|
try:
|
||
|
output_text_maint.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(system_maintenance)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
|
||
|
password_entry.focus_set()
|
||
|
pep_release = '/opt/pepconf/os-release'
|
||
|
sys_usr_release = '/usr/lib/os-release'
|
||
|
sys_os_release = '/etc/os-release'
|
||
|
check_files = [sys_usr_release, sys_os_release]
|
||
|
|
||
|
def submit_password(entry, callback):
|
||
|
password = entry.get()
|
||
|
callback(password)
|
||
|
def submit_callback(password):
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
for fcheck in check_files:
|
||
|
if os.path.isfile(pep_release) and os.path.isfile(fcheck):
|
||
|
command = f'echo "{password}" | '
|
||
|
f'sudo -S cmp -s {pep_release} {fcheck}'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE,
|
||
|
stderr=subprocess.PIPE,
|
||
|
universal_newlines=True)
|
||
|
stdout, stderr = process.communicate()
|
||
|
if process.returncode == 0:
|
||
|
print(f"The contents of {pep_release} and "
|
||
|
f"{fcheck} are identical.")
|
||
|
else:
|
||
|
copy_command = f'sudo cp {pep_release} {fcheck}'
|
||
|
subprocess.run(copy_command, shell=True)
|
||
|
print(f"The contents of {pep_release} and "
|
||
|
f"{fcheck} are different.")
|
||
|
else:
|
||
|
print("One or both of the files do not exist.")
|
||
|
password_dialog.destroy()
|
||
|
thread = threading.Thread(target=update_peppermint_branding,
|
||
|
args=(None, output_text_maint),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
password_entry.bind(
|
||
|
"<Return>",
|
||
|
lambda event: submit_password(password_entry,
|
||
|
submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
except Exception as exception:
|
||
|
output_text_maint.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_ssd_trim(output_text_maint, system_maintenance):
|
||
|
""" Trim the SSD based on the file system """
|
||
|
try:
|
||
|
output_text_maint.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(system_maintenance)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.focus_set()
|
||
|
def submit_password(entry, callback):
|
||
|
password = entry.get()
|
||
|
callback(password)
|
||
|
def submit_callback(password):
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
with open('/etc/mtab', 'r') as mtab_file:
|
||
|
for line in mtab_file:
|
||
|
parts = line.split()
|
||
|
mount_point = parts[1]
|
||
|
fs_type = parts[2]
|
||
|
if fs_type in ['ext2', 'ext3', 'ext4', 'xfs',
|
||
|
'btrfs', 'f2fs'
|
||
|
]:
|
||
|
trim_command = f'fstrim -v {mount_point}'
|
||
|
else:
|
||
|
continue
|
||
|
|
||
|
# Execute TRIM command with sudo
|
||
|
command = (f'echo "{password}" | '
|
||
|
f'sudo -S {trim_command}')
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE,
|
||
|
stderr=subprocess.PIPE,
|
||
|
universal_newlines=True)
|
||
|
output_text_maint.insert(tk.END,
|
||
|
f"TRIM operation in progress for {mount_point}...\n"
|
||
|
)
|
||
|
thread = threading.Thread(target=update_ssd_trim,
|
||
|
args=(process,
|
||
|
output_text_maint),
|
||
|
daemon=True)
|
||
|
thread.start()
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback),
|
||
|
cursor=CURSOR_ICON , bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
password_entry.bind("<Return>", lambda event: submit_password(
|
||
|
password_entry, submit_callback))
|
||
|
except Exception as exception:
|
||
|
output_text_maint.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_caching_icons(output_text_maint, system_maintenance):
|
||
|
""" The icons caching command """
|
||
|
try:
|
||
|
output_text_maint.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(system_maintenance)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.bind("<Return>",
|
||
|
lambda event: submit_password(
|
||
|
password_entry, submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
|
||
|
def submit_password(entry, callback):
|
||
|
password = entry.get()
|
||
|
callback(password)
|
||
|
|
||
|
def submit_callback(password):
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
command = (f'echo "{password}" | sudo -S '
|
||
|
f'update-icon-caches /usr/share/icons/*')
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE,
|
||
|
stderr=subprocess.PIPE,
|
||
|
bufsize=1,
|
||
|
universal_newlines=True)
|
||
|
thread = threading.Thread(target=update_caching_icons,
|
||
|
args=(process, output_text_maint),
|
||
|
daemon=True)
|
||
|
thread.start()
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(
|
||
|
password_entry, submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE)
|
||
|
submit_button.pack(pady=5)
|
||
|
except Exception as exception:
|
||
|
output_text_maint.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_apt_view_update(output_text, manage_updates, xd_intro):
|
||
|
"""
|
||
|
Runs the list of upgrades avialable, it also shortens the results.
|
||
|
To be a simple summary vice the full details
|
||
|
"""
|
||
|
try:
|
||
|
output_text.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(manage_updates)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.bind("<Return>",
|
||
|
lambda event: submit_password(password_entry,
|
||
|
submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
|
||
|
def submit_callback(password):
|
||
|
"""
|
||
|
This function is used, to pass to the submit password
|
||
|
to handle the sudo submission
|
||
|
"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
command = f'echo "{password}" | sudo -S apt list --upgradable'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_output_view,
|
||
|
args=(process, output_text),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
currently_pending_updates(xd_intro)
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
except Exception as exception:
|
||
|
output_text.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_apt_clean(output_text, manage_updates):
|
||
|
"""
|
||
|
Runs the clean command
|
||
|
"""
|
||
|
try:
|
||
|
output_text.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(manage_updates)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.bind("<Return>",
|
||
|
lambda event: submit_password(password_entry,
|
||
|
submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
|
||
|
def submit_callback(password):
|
||
|
"""
|
||
|
This function is used, to pass to the submit password
|
||
|
to handle the sudo submission
|
||
|
"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
command = f'echo "{password}" | sudo apt clean'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_output_clean,
|
||
|
args=(process, output_text),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
except Exception as exception:
|
||
|
output_text.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_apt_autoclean(output_text, manage_updates):
|
||
|
"""
|
||
|
Runs the auto clean command.
|
||
|
"""
|
||
|
try:
|
||
|
output_text.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(manage_updates)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.bind("<Return>",
|
||
|
lambda event: submit_password(password_entry,
|
||
|
submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
|
||
|
def submit_callback(password):
|
||
|
"""
|
||
|
This function is used, to pass to the submit password
|
||
|
to handle the sudo submission
|
||
|
"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
command = f'echo "{password}" | sudo -S apt autoclean'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_output,
|
||
|
args=(process, output_text),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
except Exception as exception:
|
||
|
output_text.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_apt_autoremove(output_text, manage_updates):
|
||
|
"""
|
||
|
Runs the auto clean command.
|
||
|
"""
|
||
|
try:
|
||
|
output_text.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(manage_updates)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.bind("<Return>",
|
||
|
lambda event: submit_password(password_entry,
|
||
|
submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
|
||
|
def submit_callback(password):
|
||
|
"""
|
||
|
This function is used, to pass to the submit password
|
||
|
to handle the sudo submission
|
||
|
"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
command = f'echo "{password}" | sudo -S apt autoremove -y'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_output,
|
||
|
args=(process, output_text),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
getdata(password)
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
except Exception as exception:
|
||
|
output_text.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_install_update(output_text, manage_updates, xd_intro):
|
||
|
"""
|
||
|
Runs the install updates command.
|
||
|
"""
|
||
|
try:
|
||
|
output_text.config(state="normal")
|
||
|
password_dialog = tk.Toplevel(manage_updates)
|
||
|
password_dialog.title(PWD_TITLE)
|
||
|
password_dialog.tk.call('wm', 'iconphoto', password_dialog,
|
||
|
tk.PhotoImage(file=ICON_PATH))
|
||
|
center_screen(password_dialog, WIDTH, HEIGHT)
|
||
|
font = GLOBAL_FONT
|
||
|
label = ttk.Label(password_dialog, text=LABEL_TEXT)
|
||
|
label.pack(pady=5)
|
||
|
password_entry = tk.Entry(password_dialog, show='*', font=font)
|
||
|
password_entry.pack(pady=5)
|
||
|
password_entry.bind("<Return>",
|
||
|
lambda event: submit_password(password_entry,
|
||
|
submit_callback)
|
||
|
)
|
||
|
password_entry.focus_set()
|
||
|
|
||
|
def submit_callback(password):
|
||
|
"""
|
||
|
This function is used, to pass to the submit password
|
||
|
to handle the sudo submission
|
||
|
"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
password_dialog.destroy()
|
||
|
command = f'echo "{password}" | sudo -S apt upgrade -y'
|
||
|
process = subprocess.Popen(command, shell=True,
|
||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||
|
bufsize=1, universal_newlines=True
|
||
|
)
|
||
|
thread = threading.Thread(target=update_output,
|
||
|
args=(process, output_text),
|
||
|
daemon=True
|
||
|
)
|
||
|
thread.start()
|
||
|
getdata(password)
|
||
|
currently_pending_updates(xd_intro)
|
||
|
submit_button = ttk.Button(password_dialog, text=BUTTON_TEXT,
|
||
|
command=lambda: submit_password(password_entry,
|
||
|
submit_callback
|
||
|
),
|
||
|
cursor=CURSOR_ICON, bootstyle=STYLE_TYPE
|
||
|
)
|
||
|
submit_button.pack(pady=5)
|
||
|
except Exception as exception:
|
||
|
output_text.insert(tk.END, str(exception))
|
||
|
|
||
|
|
||
|
def run_terminal_xdaily():
|
||
|
""" this wills start xDaily in a new terminal"""
|
||
|
try:
|
||
|
os.system('xfce4-terminal -e "bash -c \'sudo xDaily; exec bash\'"')
|
||
|
except Exception as e:
|
||
|
print(f"Error executing command: {e}")
|
||
|
|
||
|
|
||
|
def set_command_to_view_update(run_task_updates, output_text,
|
||
|
manage_updates, xd_intro):
|
||
|
""" Redirect the command for the view updates"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
run_task_updates.config(
|
||
|
command=lambda: run_apt_view_update(output_text, manage_updates
|
||
|
,xd_intro)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_to_check_update(run_task_updates, output_text,
|
||
|
manage_updates, xd_intro):
|
||
|
""" Redirect the command for the check updates"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
run_task_updates.config(
|
||
|
command=lambda: run_apt_update(output_text, manage_updates,
|
||
|
xd_intro)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_to_install_update(run_task_updates, output_text,
|
||
|
manage_updates, xd_intro):
|
||
|
""" Redirect the command for the install updates"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
run_task_updates.config(
|
||
|
command=lambda: run_install_update(output_text, manage_updates,
|
||
|
xd_intro)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_to_apt_clean(run_task_updates, output_text,
|
||
|
manage_updates):
|
||
|
""" Redirect the command for the clean"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
run_task_updates.config(
|
||
|
command=lambda: run_apt_clean(output_text, manage_updates)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_to_autoclean(run_task_updates, output_text,
|
||
|
manage_updates):
|
||
|
""" Redirect the command for the auto clean"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
run_task_updates.config(
|
||
|
command=lambda: run_apt_autoclean(output_text, manage_updates)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_to_autoremove(run_task_updates, output_text,
|
||
|
manage_updates):
|
||
|
""" Redirect the command for the autoremove"""
|
||
|
output_text.delete(1.0, tk.END)
|
||
|
run_task_updates.config(
|
||
|
command=lambda: run_apt_autoremove(output_text, manage_updates)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_to_thumnail_cache(run_task_maintenance, output_text_maint,
|
||
|
system_maintenance):
|
||
|
""" Redirect the command for the thumbnail cache"""
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
run_task_maintenance.config(
|
||
|
command=lambda: run_thumbnail_cache(output_text_maint, system_maintenance)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_recently_used(run_task_maintenance, output_text_maint,
|
||
|
system_maintenance):
|
||
|
""" Redirect the command for the recently used"""
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
run_task_maintenance.config(
|
||
|
command=lambda: run_recently_used(output_text_maint, system_maintenance)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_peppermint_branding(run_task_maintenance, output_text_maint,
|
||
|
system_maintenance):
|
||
|
""" Redirect the command for the peppermint branding"""
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
run_task_maintenance.config(
|
||
|
command=lambda: run_peppermint_branding(output_text_maint, system_maintenance)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_command_ssd_trim(run_task_maintenance, output_text_maint,
|
||
|
system_maintenance):
|
||
|
""" Redirect the command for the ssd trim """
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
run_task_maintenance.config(
|
||
|
command=lambda: run_ssd_trim(output_text_maint, system_maintenance)
|
||
|
)
|
||
|
|
||
|
|
||
|
def set_caching_icons(run_task_maintenance, output_text_maint,
|
||
|
system_maintenance):
|
||
|
""" Redirect the command for the caching icons """
|
||
|
output_text_maint.delete(1.0, tk.END)
|
||
|
run_task_maintenance.config(
|
||
|
command=lambda: run_caching_icons(output_text_maint,
|
||
|
system_maintenance)
|
||
|
)
|
||
|
|