loader image

Reply To: How to update Linux through the terminal, Debian based.

What makes us different from other similar websites? Forums Tech How to update Linux through the terminal, Debian based. Reply To: How to update Linux through the terminal, Debian based.

#8405
thumbtak
Moderator

Here is a python script to update the system. It should be fine, but run it at your own risk.
Save as System_Update.py and run as $ python3 System_Update.py

import tkinter as tk
from tkinter import ttk, scrolledtext
import subprocess
import threading
import time

class PacmanUpdater:
def __init__(self, root):
self.root = root
self.root.title("Xubuntu Maintenance Pro")
self.root.geometry("1000x900")
self.root.configure(bg="#121212")

self.style = ttk.Style()
self.style.theme_use('clam')
self.style.configure("TFrame", background="#121212")
self.style.configure("TLabel", background="#121212", foreground="#ffffff", font=("Segoe UI", 10))
self.style.configure("Header.TLabel", font=("Segoe UI", 18, "bold"), foreground="#ffffff")
self.style.configure("TButton", font=("Segoe UI", 9, "bold"), background="#333333", foreground="#ffffff", padding=8)
self.style.map("TButton", background=[('active', '#ff66cc'), ('disabled', '#222222')])

self.raw_commands = [
("APT Update", "apt update"),
("APT Upgrade", "apt upgrade -y"),
("APT Dist-Upgrade", "apt dist-upgrade -y"),
("APT Autoremove", "apt autoremove -y"),
("Flatpak Upgrade", "flatpak upgrade -y"),
("Flatpak Update", "flatpak update -y"),
("Flatpak Cleanup", "flatpak uninstall --unused -y"),
("Snap Refresh", "snap refresh")
]

self.is_running_all = False
self.create_widgets()

def create_widgets(self):
header = ttk.Frame(self.root, padding=(40, 20))
header.pack(fill="x")
ttk.Label(header, text="System Maintenance Console", style="Header.TLabel").pack(side="left")

btn_container = ttk.Frame(header)
btn_container.pack(side="right")
self.run_all_btn = ttk.Button(btn_container, text="RUN FULL MAINTENANCE", command=self.start_run_all)
self.run_all_btn.pack(side="left", padx=5)
ttk.Button(btn_container, text="CLEAR LOG", command=self.clear_terminal).pack(side="left", padx=5)

self.pac_canvas = tk.Canvas(self.root, width=850, height=80, bg="#000000", highlightthickness=2, highlightbackground="#333333")
self.pac_canvas.pack(pady=10)
self.draw_static_dots()

grid_container = ttk.Frame(self.root, padding=(40, 10))
grid_container.pack(fill="x")
for i, (label, _) in enumerate(self.raw_commands):
col, row_idx = (0, i) if i < 4 else (1, i-4)
lbl = ttk.Label(grid_container, text=f"• {label}")
lbl.grid(row=row_idx, column=col, sticky="w", padx=20, pady=5)

footer = ttk.Frame(self.root, padding=(40, 20))
footer.pack(fill="both", expand=True)
self.terminal = scrolledtext.ScrolledText(footer, bg="#000000", fg="#ff66cc", insertbackground="white", font=("Consolas", 10), borderwidth=0)
self.terminal.pack(fill="both", expand=True)

def draw_static_dots(self):
self.pac_canvas.delete("all")
for x in range(50, 850, 40):
self.pac_canvas.create_oval(x-3, 40-3, x+3, 40+3, fill="#ffffff", tags="dot")
self.pacman = self.pac_canvas.create_arc(10, 10, 70, 70, start=30, extent=300, fill="#FFFF00", outline="black")

def update_pacman(self, progress):
x_target = 10 + (progress * 7.5)
self.pac_canvas.coords(self.pacman, x_target, 10, x_target + 60, 70)
dots = self.pac_canvas.find_withtag("dot")
for dot in dots:
coords = self.pac_canvas.coords(dot)
if coords and coords[0] < x_target + 30:
self.pac_canvas.delete(dot)

extent = 359 if int(time.time()*10) % 2 == 0 else 300
start = 0 if extent == 359 else 30
self.pac_canvas.itemconfig(self.pacman, extent=extent, start=start)

def show_steam_achievement(self):
"""Fixed Achievement Popup with forced rendering and positioning."""
popup = tk.Toplevel(self.root)
popup.overrideredirect(True)
popup.attributes("-topmost", True)
popup.configure(bg="#1b2838")

# Geometry setup
width, height = 320, 85
# Center it based on the main app window
x = self.root.winfo_x() + (self.root.winfo_width() // 2) - (width // 2)
y = self.root.winfo_y() + 50 # Show it near the top of the app
popup.geometry(f"{width}x{height}+{x}+{y}")

# Achievement Frame with Border
frame = tk.Frame(popup, bg="#1b2838", highlightthickness=2, highlightbackground="#66c0f4")
frame.pack(fill="both", expand=True)

# Content
icon_label = tk.Label(frame, text="🏆", font=("Segoe UI", 32), bg="#1b2838", fg="#ebebeb")
icon_label.pack(side="left", padx=15)

text_frame = tk.Frame(frame, bg="#1b2838")
text_frame.pack(side="left", fill="y", pady=12)

title_lbl = tk.Label(text_frame, text="ACHIEVEMENT UNLOCKED", font=("Segoe UI", 10, "bold"), bg="#1b2838", fg="#66c0f4")
title_lbl.pack(anchor="w")

desc_lbl = tk.Label(text_frame, text="System Purified: Level Max", font=("Segoe UI", 11), bg="#1b2838", fg="#ffffff")
desc_lbl.pack(anchor="w")

# Force UI update so text doesn't appear empty
popup.update_idletasks()

# Simple Fade-in effect
popup.attributes("-alpha", 0.0)
def fade_in():
alpha = popup.attributes("-alpha")
if alpha < 1.0:
popup.attributes("-alpha", alpha + 0.1)
self.root.after(30, fade_in)

fade_in()
self.root.after(6000, popup.destroy)

def draw_completion(self):
self.pac_canvas.create_text(820, 40, text="👻", font=("Arial", 30), fill="white", tags="ghost")
for i in range(100, 110):
self.update_pacman(i)
self.root.update()
time.sleep(0.05)

self.pac_canvas.delete("ghost")
self.show_steam_achievement()
self.terminal.insert(tk.END, "\n>>> [SYSTEM OPTIMIZED] LEVEL COMPLETE! <<<\n")
self.terminal.see(tk.END)

def clear_terminal(self):
self.terminal.delete('1.0', tk.END)
self.draw_static_dots()

def start_run_all(self):
if not self.is_running_all:
self.is_running_all = True
self.run_all_btn.configure(state="disabled")
self.draw_static_dots()
threading.Thread(target=self.run_all_sequential, daemon=True).start()

def run_all_sequential(self):
self.terminal.insert(tk.END, ">>> AUTHENTICATING FOR FULL MAINTENANCE...\n")
sequence = " && ".join([c[1] for c in self.raw_commands])
full_command = f'pkexec sh -c "{sequence}"'

process = subprocess.Popen(full_command, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, text=True, bufsize=1)

progress = 0
while True:
line = process.stdout.readline()
if not line and process.poll() is not None: break
if line:
self.terminal.insert(tk.END, f" {line}")
self.terminal.see(tk.END)
if progress < 98:
progress += 0.2
self.update_pacman(progress)

process.wait()
self.update_pacman(100)
self.draw_completion()
self.is_running_all = False
self.run_all_btn.configure(state="normal")

if __name__ == "__main__":
root = tk.Tk()
app = PacmanUpdater(root)
root.mainloop()
  • This reply was modified 1 week, 2 days ago by thumbtak. Reason: Updated to make it more fluid and better looking
TAKs Shack