From 46b81fae7e894d95dfcd76b9ee4a31df322603f7 Mon Sep 17 00:00:00 2001 From: Abhiraj Roy <157954129+iconized@users.noreply.github.com> Date: Mon, 3 Jun 2024 03:44:26 +0530 Subject: [PATCH] :wrench: chore(remove): clean code Signed-off-by: Abhiraj Roy <157954129+iconized@users.noreply.github.com> --- .github/workflows/commitizen.yml | 33 - .gitignore | 2 - LICENSE | 21 - commits.sh | 32 - functions.py | 1707 ------------------------------ kernel.py | 51 - push.sh | 21 - snigdhaos-kernel-manager.css | 167 --- snigdhaos-kernel-manager.py | 107 -- ui/AboutDialog.py | 67 -- ui/FlowBox.py | 638 ----------- ui/KernelStack.py | 631 ----------- ui/ManagerGUI.py | 516 --------- ui/MenuButton.py | 45 - ui/MessageWindow.py | 95 -- ui/ProgressWindow.py | 632 ----------- ui/SettingsWindow.py | 715 ------------- ui/SplashScreen.py | 30 - ui/Stack.py | 30 - 19 files changed, 5540 deletions(-) delete mode 100644 .github/workflows/commitizen.yml delete mode 100644 .gitignore delete mode 100644 LICENSE delete mode 100755 commits.sh delete mode 100644 functions.py delete mode 100644 kernel.py delete mode 100755 push.sh delete mode 100644 snigdhaos-kernel-manager.css delete mode 100644 snigdhaos-kernel-manager.py delete mode 100644 ui/AboutDialog.py delete mode 100644 ui/FlowBox.py delete mode 100644 ui/KernelStack.py delete mode 100644 ui/ManagerGUI.py delete mode 100644 ui/MenuButton.py delete mode 100644 ui/MessageWindow.py delete mode 100644 ui/ProgressWindow.py delete mode 100644 ui/SettingsWindow.py delete mode 100644 ui/SplashScreen.py delete mode 100644 ui/Stack.py diff --git a/.github/workflows/commitizen.yml b/.github/workflows/commitizen.yml deleted file mode 100644 index 8286582..0000000 --- a/.github/workflows/commitizen.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Commitizen Check - -on: - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - commitizen_check: - name: Check Commitizen Commit on Push - runs-on: ubuntu-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v2 - - - name: Install Node.js - uses: actions/setup-node@v3 - with: - node-version: '14' - - - name: Install Commitizen - run: npm install -g commitizen - - - name: Verify Commitizen Commit - run: | - if git log --format='%s' ${{ github.event.before }}..${{ github.sha }} | grep -v '^(feat|fix|docs|style|refactor|perf|test|chore)(\(.+\))?: .+'; then - echo "Invalid commit message found. Please use Commitizen convention." - exit 1 - fi \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0e5ac79..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.venv -__pycache__ \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 90da770..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 SNIGDHA OS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/commits.sh b/commits.sh deleted file mode 100755 index d4cc733..0000000 --- a/commits.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# Author : Eshan Roy -# URI : https://eshanized.github.io - -# NOTE: If you are on Snigdha OS, -# you can install commitizen-go with `sudo pacman -S commitizen-go` -# or `s commitizen-go`. Else you need to install `yay` or `yay-bin` -# to install commitizen. I have written this script only for *Arch Linux. - -# Function to check if Commitizen is installed -check_commitizen() { - if ! pacman -Qq better-commits &> /dev/null; then - echo "Better Commits is not installed. Please install it using 'yay -S commitizen-go'." >&2 - exit 1 - fi -} - -# Function to stage, commit, and push changes -push_to_github() { - git add . - better-commits - git push origin master -} - -# Main Function -main() { - check_commitizen - push_to_github -} - -main \ No newline at end of file diff --git a/functions.py b/functions.py deleted file mode 100644 index 16a3983..0000000 --- a/functions.py +++ /dev/null @@ -1,1707 +0,0 @@ -import logging -import shutil -import sys -import os -import distro -from os import makedirs -import requests -import threading -import re -import time -import subprocess -import gi -import datetime -import psutil -import queue -import pathlib -import tomlkit -from tomlkit import dumps, load -from datetime import timedelta -from logging.handlers import TimedRotatingFileHandler -from threading import Thread -from queue import Queue -from ui.MessageWindow import MessageWindow -from kernel import Kernel, InstalledKernel, CommunityKernel - -gi.require_version("Gtk", "4.0") -from gi.repository import GLib - - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - -latest_archlinux_package_search_url = ( - "https://archlinux.org/packages/search/json?name=${PACKAGE_NAME}" -) -archlinux_mirror_archive_url = "https://archive.archlinux.org" -headers = {"Content-Type": "text/plain;charset=UTF-8"} - -dist_id = distro.id() -dist_name = distro.name() - -cache_days = 5 -fetched_kernels_dict = {} -cached_kernels_list = [] -community_kernels_list = [] -supported_kernels_dict = {} -community_kernels_dict = {} -pacman_repos_list = [] -process_timeout = 200 - -sudo_username = os.getlogin() -home = "/home/" + str(sudo_username) - -# pacman log file -pacman_logfile = "/var/log/pacman.log" - -# pacman lock file -pacman_lockfile = "/var/lib/pacman/db.lck" - -# pacman conf file -pacman_conf_file = "/etc/pacman.conf" - -# thread names -thread_get_kernels = "thread_get_kernels" -thread_get_community_kernels = "thread_get_community_kernels" -thread_install_community_kernel = "thread_install_community_kernel" -thread_install_archive_kernel = "thread_install_archive_kernel" -thread_check_kernel_state = "thread_check_kernel_state" -thread_uninstall_kernel = "thread_uninstall_kernel" -thread_monitor_messages = "thread_monitor_messages" -thread_refresh_cache = "thread_refresh_cache" -thread_refresh_ui = "thread_refresh_ui" - -cache_dir = "%s/.cache/snigdhaos-kernel-manager" % home -cache_file = "%s/kernels.toml" % cache_dir -cache_update = "%s/update" % cache_dir - -log_dir = "/var/log/snigdhaos-kernel-manager" -event_log_file = "%s/event.log" % log_dir - - -config_file_default = "%s/defaults/config.toml" % base_dir -config_dir = "%s/.config/snigdhaos-kernel-manager" % home -config_file = "%s/.config/snigdhaos-kernel-manager/config.toml" % home - -logger = logging.getLogger("logger") - -# create console handler and set level to debug -ch = logging.StreamHandler() - - -logger.setLevel(logging.DEBUG) -ch.setLevel(logging.DEBUG) - -# create formatter -formatter = logging.Formatter( - "%(asctime)s:%(levelname)s > %(message)s", "%Y-%m-%d %H:%M:%S" -) -# add formatter to ch -ch.setFormatter(formatter) - - -# add ch to logger -logger.addHandler(ch) - - -# ===================================================== -# CHECK FOR KERNEL UPDATES -# ===================================================== -def get_latest_kernel_updates(self): - logger.info("Getting latest kernel versions") - try: - last_update_check = None - fetch_update = False - cache_timestamp = None - - if os.path.exists(cache_file): - with open(cache_file, "r", encoding="utf-8") as f: - # data = tomlkit.load(f) - - data = f.readlines()[2] - - if len(data) == 0: - logger.error( - "%s is empty, delete it and open the app again" % cache_file - ) - - if len(data) > 0 and "timestamp" in data.strip(): - # cache_timestamp = data["timestamp"] - cache_timestamp = ( - data.split("timestamp = ")[1].replace('"', "").strip() - ) - - if not os.path.exists(cache_update): - last_update_check = datetime.datetime.now().strftime("%Y-%m-%d") - with open(cache_update, mode="w", encoding="utf-8") as f: - f.write("%s\n" % last_update_check) - - permissions(cache_dir) - - else: - with open(cache_update, mode="r", encoding="utf-8") as f: - last_update_check = f.read().strip() - - with open(cache_update, mode="w", encoding="utf-8") as f: - f.write("%s\n" % datetime.datetime.now().strftime("%Y-%m-%d")) - - permissions(cache_dir) - - logger.info( - "Linux package update last fetched on %s" - % datetime.datetime.strptime(last_update_check, "%Y-%m-%d").date() - ) - - if ( - datetime.datetime.strptime(last_update_check, "%Y-%m-%d").date() - < datetime.datetime.now().date() - ): - - logger.info("Fetching Linux package update data") - - response = requests.get( - latest_archlinux_package_search_url.replace( - "${PACKAGE_NAME}", "linux" - ), - headers=headers, - allow_redirects=True, - timeout=60, - stream=True, - ) - - if response.status_code == 200: - if response.json() is not None: - if len(response.json()["results"]) > 0: - if response.json()["results"][0]["last_update"]: - logger.info( - "Linux kernel package last update = %s" - % datetime.datetime.strptime( - response.json()["results"][0]["last_update"], - "%Y-%m-%dT%H:%M:%S.%f%z", - ).date() - ) - if ( - datetime.datetime.strptime( - response.json()["results"][0]["last_update"], - "%Y-%m-%dT%H:%M:%S.%f%z", - ).date() - ) > ( - datetime.datetime.strptime( - cache_timestamp, "%Y-%m-%d %H-%M-%S" - ).date() - ): - logger.info( - "Linux kernel package updated, cache refresh required" - ) - - refresh_cache(self) - - return True - - else: - logger.info( - "Linux kernel package not updated, cache refresh not required" - ) - - return False - - else: - logger.info("Kernel update check not required") - - return False - - else: - logger.info("No cache file present, refresh required") - if not os.path.exists(cache_update): - last_update_check = datetime.datetime.now().strftime("%Y-%m-%d") - with open(cache_update, mode="w", encoding="utf-8") as f: - f.write("%s\n" % last_update_check) - - permissions(cache_dir) - - return False - - except Exception as e: - logger.error("Exception in get_latest_kernel_updates(): %s" % e) - return True - - -# ===================================================== -# CACHE LAST MODIFIED -# ===================================================== -def get_cache_last_modified(): - try: - if os.path.exists(cache_file): - timestamp = datetime.datetime.fromtimestamp( - pathlib.Path(cache_file).stat().st_mtime, tz=datetime.timezone.utc - ) - - return "%s %s" % ( - timestamp.date(), - str(timestamp.time()).split(".")[0], - ) - - else: - return "Cache file does not exist" - except Exception as e: - logger.error("Exception in get_cache_last_modified(): %s" % e) - - -# ===================================================== -# LOG DIRECTORY -# ===================================================== - -try: - if not os.path.exists(log_dir): - makedirs(log_dir) -except Exception as e: - logger.error("Exception in make log directory(): %s" % e) - - -# rotate the events log every Friday -tfh = TimedRotatingFileHandler(event_log_file, encoding="utf-8", delay=False, when="W4") -tfh.setFormatter(formatter) -logger.addHandler(tfh) - -# ===================================================== -# PERMISSIONS -# ===================================================== - - -def permissions(dst): - try: - groups = subprocess.run( - ["sh", "-c", "id " + sudo_username], - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) - for x in groups.stdout.decode().split(" "): - if "gid" in x: - g = x.split("(")[1] - group = g.replace(")", "").strip() - subprocess.call(["chown", "-R", sudo_username + ":" + group, dst], shell=False) - - except Exception as e: - logger.error("Exception in permissions(): %s" % e) - - -def setup_config(self): - try: - if not os.path.exists(config_dir): - makedirs(config_dir) - - if not os.path.exists(config_file): - shutil.copy(config_file_default, config_dir) - permissions(config_dir) - - return read_config(self) - - except Exception as e: - logger.error("Exception in setup_config(): %s" % e) - - -def update_config(config_data, bootloader): - try: - logger.info("Updating config data") - - with open(config_file, "w") as f: - tomlkit.dump(config_data, f) - - return True - - except Exception as e: - logger.error("Exception in update_config(): %s" % e) - return False - - -def read_config(self): - try: - logger.debug("Config file = %s" % config_file) - logger.info("Reading in config file") - config_data = None - with open(config_file, "rb") as f: - config_data = tomlkit.load(f) - - for official_kernel in config_data["kernels"]["official"]: - supported_kernels_dict[official_kernel["name"]] = ( - official_kernel["description"], - official_kernel["headers"], - ) - - for community_kernel in config_data["kernels"]["community"]: - community_kernels_dict[community_kernel["name"]] = ( - community_kernel["description"], - community_kernel["headers"], - community_kernel["repository"], - ) - - return config_data - except Exception as e: - logger.error("Exception in read_config(): %s" % e) - sys.exit(1) - - -def create_cache_dir(): - try: - if not os.path.exists(cache_dir): - makedirs(cache_dir) - - logger.info("Cache directory = %s" % cache_dir) - - permissions(cache_dir) - except Exception as e: - logger.error("Exception in create_cache_dir(): %s" % e) - - -def create_log_dir(): - try: - if not os.path.exists(log_dir): - makedirs(log_dir) - - logger.info("Log directory = %s" % log_dir) - except Exception as e: - logger.error("Exception in create_log_dir(): %s" % e) - - -def write_cache(): - try: - if len(fetched_kernels_dict) > 0: - with open(cache_file, "w", encoding="utf-8") as f: - f.write('title = "Arch Linux Kernels"\n\n') - f.write( - 'timestamp = "%s"\n' - % datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S") - ) - f.write('source = "%s"\n\n' % archlinux_mirror_archive_url) - - for kernel in fetched_kernels_dict.values(): - f.write("[[kernel]]\n") - f.write( - 'name = "%s"\nheaders = "%s"\nversion = "%s"\nsize = "%s"\nfile_format = "%s"\nlast_modified = "%s"\n\n' - % ( - kernel.name, - kernel.headers, - kernel.version, - kernel.size, - kernel.file_format, - kernel.last_modified, - ) - ) - permissions(cache_file) - except Exception as e: - logger.error("Exception in write_cache(): %s" % e) - - -# install from the ALA -def install_archive_kernel(self): - try: - install_cmd_str = [ - "pacman", - "-U", - self.official_kernels[0], - self.official_kernels[1], - "--noconfirm", - "--needed", - ] - - wait_for_pacman_process() - - logger.info("Running %s" % install_cmd_str) - - event = "%s [INFO]: Running %s\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - " ".join(install_cmd_str), - ) - - event_log = [] - self.messages_queue.put(event) - - with subprocess.Popen( - install_cmd_str, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - bufsize=1, - universal_newlines=True, - ) as process: - while True: - if process.poll() is not None: - break - for line in process.stdout: - print(line.strip()) - self.messages_queue.put(line) - event_log.append(line.lower().strip()) - - time.sleep(0.3) - - error = None - - if ( - "installation finished. no error reported." - or "initcpio image generation successful" in event_log - ): - error = False - - else: - if error is None: - # check errors and indicate to user install failed - for log in event_log: - # if "installation finished. no error reported." in log: - # error = False - # break - if "error" in log or "errors" in log: - event = ( - "%s [ERROR]: Errors have been encountered during installation\n" - % (datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")) - ) - - logger.error(log) - - self.messages_queue.put(event) - - self.errors_found = True - - error = True - - GLib.idle_add( - show_mw, - self, - "System changes", - f"Kernel {self.action} failed\n" - f"There have been errors, please review the logs\n", - "images/48x48/akm-warning.png", - priority=GLib.PRIORITY_DEFAULT, - ) - - break - - # query to check if kernel installed - - if check_kernel_installed(self.kernel.name + "-headers") and error is False: - - self.kernel_state_queue.put((0, "install", self.kernel.name + "-headers")) - - event = "%s [INFO]: Installation of %s-headers completed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - ) - - self.messages_queue.put(event) - - else: - self.kernel_state_queue.put((1, "install", self.kernel.name + "-headers")) - - event = "%s [ERROR]: Installation of %s-headers failed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - ) - - self.errors_found = True - self.messages_queue.put(event) - - if check_kernel_installed(self.kernel.name) and error is False: - self.kernel_state_queue.put((0, "install", self.kernel.name)) - - event = "%s [INFO]: Installation of kernel %s completed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - ) - - self.messages_queue.put(event) - - else: - self.kernel_state_queue.put((1, "install", self.kernel.name)) - - event = "%s [ERROR]: Installation of kernel %s failed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - ) - - self.messages_queue.put(event) - - # signal to say end reached - self.kernel_state_queue.put(None) - - except Exception as e: - logger.error("Exception in install_archive_kernel(): %s" % e) - - GLib.idle_add( - show_mw, - self, - "System changes", - f"Kernel {self.action} failed\n" - f"There have been errors, please review the logs\n", - "images/48x48/akm-warning.png", - priority=GLib.PRIORITY_DEFAULT, - ) - - -def refresh_cache(self): - if os.path.exists(cache_file): - os.remove(cache_file) - get_official_kernels(self) - write_cache() - - -def read_cache(self): - try: - self.timestamp = None - with open(cache_file, "rb") as f: - data = tomlkit.load(f) - - if len(data) == 0: - logger.error( - "%s is empty, delete it and open the app again" % cache_file - ) - - name = None - headers = None - version = None - size = None - last_modified = None - file_format = None - - if len(data) > 0: - self.timestamp = data["timestamp"] - - self.cache_timestamp = data["timestamp"] - - # check date of cache, if it's older than 5 days - refresh - - if self.timestamp: - self.timestamp = datetime.datetime.strptime( - self.timestamp, "%Y-%m-%d %H-%M-%S" - ) - - delta = datetime.datetime.now() - self.timestamp - - if delta.days >= cache_days: - logger.info("Cache is older than 5 days, refreshing ..") - refresh_cache(self) - else: - - if delta.days > 0: - logger.debug("Cache is %s days old" % delta.days) - else: - logger.debug("Cache is newer than 5 days") - - kernels = data["kernel"] - - if len(kernels) > 1: - for k in kernels: - - # any kernels older than 2 years - # (currently linux v4.x or earlier) are deemed eol so ignore them - - # if ( - # datetime.datetime.now().year - # - datetime.datetime.strptime( - # k["last_modified"], "%d-%b-%Y %H:%M" - # ).year - # <= 2 - # ): - cached_kernels_list.append( - Kernel( - k["name"], - k["headers"], - k["version"], - k["size"], - k["last_modified"], - k["file_format"], - ) - ) - - name = None - headers = None - version = None - size = None - last_modified = None - file_format = None - - if len(cached_kernels_list) > 0: - sorted(cached_kernels_list) - logger.info("Kernels cache data processed") - else: - logger.error( - "Cached file is invalid, remove it and try again" - ) - - else: - logger.error("Failed to read cache file") - - except Exception as e: - logger.error("Exception in read_cache(): %s" % e) - - -# get latest versions of the official kernels -def get_latest_versions(self): - try: - kernel_versions = {} - for kernel in supported_kernels_dict: - check_cmd_str = ["pacman", "-Si", kernel] - - process_kernel_query = subprocess.Popen( - check_cmd_str, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - - out, err = process_kernel_query.communicate(timeout=process_timeout) - - if process_kernel_query.returncode == 0: - for line in out.decode("utf-8").splitlines(): - if line.startswith("Version :"): - kernel_versions[kernel] = line.split("Version :")[1] - break - - self.kernel_versions_queue.put(kernel_versions) - - except Exception as e: - logger.error("Exception in get_latest_versions(): %s" % e) - - -def parse_archive_html(response, linux_kernel): - for line in response.splitlines(): - if " 0: - if "-x86_64" in files[0]: - version = files[0].split("-x86_64")[0] - file_format = files[0].split("-x86_64")[1] - - url = ( - "/packages/l/%s" % archlinux_mirror_archive_url - + "/%s" % linux_kernel - + "/%s" % files[0] - ) - - if ".sig" not in file_format: - if len(line.rstrip().split(" ")) > 0: - size = line.strip().split(" ").pop().strip() - - last_modified = line.strip().split("").pop() - for x in last_modified.split(" "): - if len(x.strip()) > 0 and ":" in x.strip(): - # 02-Mar-2023 21:12 - # %d-%b-Y %H:%M - last_modified = x.strip() - - headers = "%s%s" % ( - supported_kernels_dict[linux_kernel][1], - version.replace(linux_kernel, ""), - ) - - if ( - version is not None - and url is not None - and headers is not None - and datetime.datetime.now().year - - datetime.datetime.strptime( - last_modified, "%d-%b-%Y %H:%M" - ).year - <= 2 # ignore kernels <=2 years old - ): - ke = Kernel( - linux_kernel, - headers, - version, - size, - last_modified, - file_format, - ) - - fetched_kernels_dict[version] = ke - - version = None - file_format = None - url = None - size = None - last_modified = None - - -def wait_for_response(response_queue): - while True: - # time.sleep(0.1) - items = response_queue.get() - - # error break from loop - if items is None: - break - - # we have all kernel data break - if len(supported_kernels_dict) == len(items): - break - - -def get_response(session, linux_kernel, response_queue, response_content): - response = session.get( - "%s/packages/l/%s" % (archlinux_mirror_archive_url, linux_kernel), - headers=headers, - allow_redirects=True, - timeout=60, - stream=True, - ) - - if response.status_code == 200: - logger.debug("Response is 200") - if response.text is not None: - response_content[linux_kernel] = response.text - response_queue.put(response_content) - else: - logger.error("Something went wrong with the request") - logger.error(response.text) - response_queue.put(None) - - -def get_official_kernels(self): - try: - if not os.path.exists(cache_file) or self.refresh_cache is True: - session = requests.session() - response_queue = Queue() - response_content = {} - # loop through linux kernels - for linux_kernel in supported_kernels_dict: - logger.info( - "Fetching data from %s/packages/l/%s" - % (archlinux_mirror_archive_url, linux_kernel) - ) - Thread( - target=get_response, - args=( - session, - linux_kernel, - response_queue, - response_content, - ), - daemon=True, - ).start() - - wait_for_response(response_queue) - session.close() - - for kernel in response_content: - parse_archive_html(response_content[kernel], kernel) - - if len(fetched_kernels_dict) > 0: # and self.refresh_cache is True: - write_cache() - read_cache(self) - - self.queue_kernels.put(cached_kernels_list) - # elif self.refresh_cache is False: - # logger.info("Cache already processed") - # read_cache(self) - # self.queue_kernels.put(cached_kernels_list) - - else: - logger.error("Failed to retrieve Linux Kernel list") - self.queue_kernels.put(None) - else: - logger.debug("Reading cache file = %s" % cache_file) - # read cache file - read_cache(self) - self.queue_kernels.put(cached_kernels_list) - - except Exception as e: - logger.error("Exception in get_official_kernels(): %s" % e) - - -def wait_for_cache(self): - while True: - if not os.path.exists(cache_file): - time.sleep(0.2) - else: - read_cache(self) - break - - -# ===================================================== -# THREADING -# ===================================================== - - -# check if the named thread is running -def is_thread_alive(thread_name): - for thread in threading.enumerate(): - if thread.name == thread_name and thread.is_alive(): - return True - - return False - - -# print all threads -def print_all_threads(): - for thread in threading.enumerate(): - logger.info("Thread = %s and state is %s" % (thread.name, thread.is_alive())) - - -# ===================================================== -# UPDATE TEXTVIEW IN PROGRESS WINDOW -# ===================================================== - - -def update_progress_textview(self, line): - try: - if len(line) > 0: - self.textbuffer.insert_markup( - self.textbuffer.get_end_iter(), " %s" % line, len(" %s" % line) - ) - except Exception as e: - logger.error("Exception in update_progress_textview(): %s" % e) - finally: - self.messages_queue.task_done() - text_mark_end = self.textbuffer.create_mark( - "end", self.textbuffer.get_end_iter(), False - ) - # scroll to the end of the textview - self.textview.scroll_mark_onscreen(text_mark_end) - - -# ===================================================== -# MESSAGES QUEUE: MONITOR THEN UPDATE TEXTVIEW -# ===================================================== - - -def monitor_messages_queue(self): - try: - while True: - message = self.messages_queue.get() - - GLib.idle_add( - update_progress_textview, - self, - message, - priority=GLib.PRIORITY_DEFAULT, - ) - except Exception as e: - logger.error("Exception in monitor_messages_queue(): %s" % e) - - -# ===================================================== -# CHECK IF KERNEL INSTALLED -# ===================================================== - - -def check_kernel_installed(name): - try: - logger.info("Checking kernel package %s is installed" % name) - check_cmd_str = ["pacman", "-Q", name] - logger.debug("Running cmd = %s" % check_cmd_str) - process_kernel_query = subprocess.Popen( - check_cmd_str, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - - out, err = process_kernel_query.communicate(timeout=process_timeout) - - logger.debug(out.decode("utf-8")) - - if process_kernel_query.returncode == 0: - for line in out.decode("utf-8").splitlines(): - if line.split(" ")[0] == name: - return True - else: - return False - - return False - except Exception as e: - logger.error("Exception in check_kernel_installed(): %s" % e) - - -def wait_for_pacman_process(): - - timeout = 120 - i = 0 - while check_pacman_lockfile(): - time.sleep(0.1) - logger.debug("Pacman lockfile found .. waiting") - i += 1 - if i == timeout: - logger.info("Timeout reached") - break - - -# ===================================================== -# REMOVE KERNEL -# ===================================================== - - -def uninstall(self): - try: - kernel_installed = check_kernel_installed(self.kernel.name) - logger.info("Kernel installed = %s" % kernel_installed) - kernel_headers_installed = check_kernel_installed(self.kernel.name + "-headers") - logger.info("Kernel headers installed = %s" % kernel_headers_installed) - - uninstall_cmd_str = None - event_log = [] - - if kernel_installed is True and kernel_headers_installed is True: - uninstall_cmd_str = [ - "pacman", - "-Rs", - self.kernel.name, - self.kernel.name + "-headers", - "--noconfirm", - ] - - if kernel_installed is True and kernel_headers_installed is False: - uninstall_cmd_str = ["pacman", "-Rs", self.kernel.name, "--noconfirm"] - - if kernel_installed == 0: - logger.info("Kernel is not installed, uninstall not required") - self.kernel_state_queue.put((0, "uninstall", self.kernel.name)) - - logger.debug("Uninstall cmd = %s" % uninstall_cmd_str) - - # check if kernel, and kernel header is actually installed - if uninstall_cmd_str is not None: - - wait_for_pacman_process() - - logger.info("Running %s" % uninstall_cmd_str) - - event = "%s [INFO]: Running %s\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - " ".join(uninstall_cmd_str), - ) - self.messages_queue.put(event) - - with subprocess.Popen( - uninstall_cmd_str, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - bufsize=1, - universal_newlines=True, - ) as process: - while True: - if process.poll() is not None: - break - for line in process.stdout: - self.messages_queue.put(line) - print(line.strip()) - event_log.append(line.lower().strip()) - - # self.pacmanlog_queue.put(line) - # process_stdout_lst.append(line) - - time.sleep(0.3) - - self.errors_found = False - for log in event_log: - if "error" in log: - self.errors_found = True - - # query to check if kernel installed - if "headers" in uninstall_cmd_str: - if check_kernel_installed(self.kernel.name + "-headers") is True: - self.kernel_state_queue.put( - (1, "uninstall", self.kernel.name + "-headers") - ) - - event = ( - "%s [ERROR]: Uninstall failed\n" - % datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") - ) - - self.messages_queue.put(event) - - else: - self.kernel_state_queue.put((0, "uninstall", self.kernel.name)) - - event = ( - "%s [INFO]: Uninstall completed\n" - % datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") - ) - - self.messages_queue.put(event) - - else: - if check_kernel_installed(self.kernel.name) is True: - self.kernel_state_queue.put((1, "uninstall", self.kernel.name)) - - event = ( - "%s [ERROR]: Uninstall failed\n" - % datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") - ) - - self.messages_queue.put(event) - - else: - self.kernel_state_queue.put((0, "uninstall", self.kernel.name)) - - event = ( - "%s [INFO]: Uninstall completed\n" - % datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") - ) - - self.messages_queue.put(event) - - # signal to say end reached - self.kernel_state_queue.put(None) - - except Exception as e: - logger.error("Exception in uninstall(): %s" % e) - - -# ===================================================== -# LIST COMMUNITY KERNELS -# ===================================================== - - -def get_community_kernels(self): - try: - logger.info("Fetching package information for community based kernels") - for community_kernel in sorted(community_kernels_dict): - if community_kernels_dict[community_kernel][2] in pacman_repos_list: - pacman_repo = community_kernels_dict[community_kernel][2] - headers = community_kernels_dict[community_kernel][1] - name = community_kernel - - # fetch kernel info - query_cmd_str = [ - "pacman", - "-Si", - "%s/%s" % (pacman_repo, name), - ] - - # logger.debug("Running %s" % query_cmd_str) - process_kernel_query = subprocess.Popen( - query_cmd_str, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - out, err = process_kernel_query.communicate(timeout=process_timeout) - version = None - install_size = None - build_date = None - if process_kernel_query.returncode == 0: - for line in out.decode("utf-8").splitlines(): - if line.startswith("Version :"): - version = line.split("Version :")[1].strip() - if line.startswith("Installed Size :"): - install_size = line.split("Installed Size :")[1].strip() - if "MiB" in install_size: - install_size = round( - float(install_size.replace("MiB", "").strip()) - * 1.048576, - ) - - if line.startswith("Build Date :"): - build_date = line.split("Build Date :")[1].strip() - - if name and version and install_size and build_date: - community_kernels_list.append( - CommunityKernel( - name, - headers, - pacman_repo, - version, - build_date, - install_size, - ) - ) - - self.queue_community_kernels.put(community_kernels_list) - - except Exception as e: - logger.error("Exception in get_community_kernels(): %s" % e) - - -# ===================================================== -# INSTALL COMMUNITY KERNELS -# ===================================================== -def install_community_kernel(self): - try: - error = False - install_cmd_str = [ - "pacman", - "-S", - "%s/%s" % (self.kernel.repository, self.kernel.name), - "%s/%s" % (self.kernel.repository, "%s-headers" % self.kernel.name), - "--noconfirm", - "--needed", - ] - - logger.info("Running %s" % install_cmd_str) - - event = "%s [INFO]: Running %s\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - " ".join(install_cmd_str), - ) - - event_log = [] - - self.messages_queue.put(event) - - with subprocess.Popen( - install_cmd_str, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - bufsize=1, - universal_newlines=True, - ) as process: - while True: - if process.poll() is not None: - break - for line in process.stdout: - print(line.strip()) - self.messages_queue.put(line) - event_log.append(line.lower().strip()) - - time.sleep(0.3) - - for log in event_log: - if "installation finished. no error reported." in log: - error = False - break - - if "error" in log: - error = True - - if check_kernel_installed(self.kernel.name) and error is False: - logger.info("Kernel = installed") - - self.kernel_state_queue.put((0, "install", self.kernel.name)) - - event = "%s [INFO]: Installation of %s completed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - ) - - self.messages_queue.put(event) - - else: - logger.error("Kernel = install failed") - - self.kernel_state_queue.put((1, "install", self.kernel.name)) - - event = "%s [ERROR]: Installation of %s failed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - ) - - self.errors_found = True - self.messages_queue.put(event) - - # signal to say end reached - self.kernel_state_queue.put(None) - except Exception as e: - logger.error("Exception in install_community_kernel(): %s " % e) - - -# ===================================================== -# CHECK PACMAN LOCK FILE EXISTS -# ===================================================== - - -# check pacman lockfile -def check_pacman_lockfile(): - return os.path.exists(pacman_lockfile) - - -# ====================================================================== -# GET PACMAN REPOS -# ====================================================================== - - -def get_pacman_repos(): - if os.path.exists(pacman_conf_file): - list_repos_cmd_str = ["pacman-conf", "-l"] - with subprocess.Popen( - list_repos_cmd_str, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - bufsize=1, - universal_newlines=True, - ) as process: - while True: - if process.poll() is not None: - break - for line in process.stdout: - pacman_repos_list.append(line.strip()) - - else: - logger.error("Failed to locate %s, are you on an ArchLinux based system ?") - - -# ====================================================================== -# GET INSTALLED KERNEL INFO -# ====================================================================== - - -def get_installed_kernel_info(package_name): - query_str = ["pacman", "-Qi", package_name] - - try: - process_kernel_query = subprocess.Popen( - query_str, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - out, err = process_kernel_query.communicate(timeout=process_timeout) - install_size = None - install_date = None - if process_kernel_query.returncode == 0: - for line in out.decode("utf-8").splitlines(): - if line.startswith("Installed Size :"): - install_size = line.split("Installed Size :")[1].strip() - if "MiB" in install_size: - install_size = round( - float(install_size.replace("MiB", "").strip()) * 1.048576, - ) - if line.startswith("Install Date :"): - install_date = line.split("Install Date :")[1].strip() - return install_size, install_date - except Exception as e: - logger.error("Exception in get_installed_kernel_info(): %s" % e) - - -# ====================================================================== -# GET INSTALLED KERNELS -# ====================================================================== - - -def get_installed_kernels(): - query_str = ["pacman", "-Q"] - installed_kernels = [] - - try: - process_kernel_query = subprocess.Popen( - query_str, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - - out, err = process_kernel_query.communicate(timeout=process_timeout) - if process_kernel_query.returncode == 0: - for line in out.decode("utf-8").splitlines(): - if line.lower().strip().startswith("linux"): - package_name = line.split(" ")[0] - package_version = line.split(" ")[1] - - if ( - package_name in supported_kernels_dict - or package_name in community_kernels_dict - ): - install_size, install_date = get_installed_kernel_info( - package_name - ) - installed_kernel = InstalledKernel( - package_name, - package_version, - install_date, - install_size, - ) - - installed_kernels.append(installed_kernel) - - return installed_kernels - except Exception as e: - logger.error("Exception in get_installed_kernels(): %s" % e) - - -# ====================================================================== -# GET ACTIVE KERNEL -# ====================================================================== - - -def get_active_kernel(): - logger.info("Getting active Linux kernel") - query_str = ["uname", "-rs"] - - try: - process_kernel_query = subprocess.Popen( - query_str, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - - out, err = process_kernel_query.communicate(timeout=process_timeout) - - if process_kernel_query.returncode == 0: - for line in out.decode("utf-8").splitlines(): - if len(line.strip()) > 0: - kernel = line.strip() - _version = "-".join(kernel.split("-")[:-1]) - _type = kernel.split("-")[-1] - - logger.info("Active kernel = %s" % kernel) - - return kernel - except Exception as e: - logger.error("Exception in get_active_kernel(): %s" % e) - - -# ===================================================== -# PACMAN SYNC PACKAGE DB -# ===================================================== -def sync_package_db(): - try: - sync_str = ["pacman", "-Sy"] - logger.info("Synchronizing pacman package databases") - process_sync = subprocess.run( - sync_str, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - timeout=process_timeout, - ) - - if process_sync.returncode == 0: - return None - else: - if process_sync.stdout: - out = str(process_sync.stdout.decode("utf-8")) - logger.error(out) - - return out - - except Exception as e: - logger.error("Exception in sync_package_db(): %s" % e) - - -def get_boot_loader(): - try: - logger.info("Getting bootloader") - cmd = ["bootctl", "status"] - logger.debug("Running %s" % " ".join(cmd)) - process = subprocess.run( - cmd, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - timeout=process_timeout, - universal_newlines=True, - bufsize=1, - ) - - if process.returncode == 0: - for line in process.stdout.splitlines(): - if line.strip().startswith("Product:"): - product = line.strip().split("Product:")[1].strip() - if "grub" in product.lower(): - logger.info("bootctl product reports booted with grub") - return "grub" - if "systemd-boot" in product.lower(): - logger.info("bootcl product reports booted with systemd-boot") - return "systemd-boot" - elif line.strip().startswith("Not booted with EFI"): # noqa - # bios - logger.info( - "bootctl - not booted with EFI, setting bootloader to grub" - ) - return "grub" - else: - logger.error("Failed to run %s" % " ".join(cmd)) - logger.error(process.stdout) - except Exception as e: - logger.error("Exception in get_boot_loader(): %s" % e) - - -# ====================================================================== -# GET INSTALLED KERNEL VERSION -# ====================================================================== - - -def get_kernel_version(kernel): - cmd = ["pacman", "-Qli", kernel] - # pacman_kernel_version = None - kernel_modules_path = None - try: - logger.debug("Running %s" % " ".join(cmd)) - process = subprocess.run( - cmd, - shell=False, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - timeout=process_timeout, - universal_newlines=True, - bufsize=1, - ) - - if process.returncode == 0: - for line in process.stdout.splitlines(): - # if line.startswith("Version :"): - # pacman_kernel_version = line.split("Version :")[1].strip() - # print(pacman_kernel_version) - - if "/usr/lib/modules/" in line: - if "kernel" in line.split(" ")[1]: - kernel_modules_path = line.split(" ")[1] - break - - if kernel_modules_path is not None: - return ( - kernel_modules_path.split("/usr/lib/modules/")[1] - .strip() - .split("/kernel/")[0] - .strip() - ) - else: - return None - - except Exception as e: - logger.error("Exception in get_kernel_version(): %s" % e) - - -def run_process(self): - error = False - - logger.debug("Running process = %s" % " ".join(self.cmd)) - with subprocess.Popen( - self.cmd, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - bufsize=1, - universal_newlines=True, - ) as process: - while True: - if process.poll() is not None: - break - for line in process.stdout: - self.messages_queue.put(line) - self.stdout_lines.append(line.lower().strip()) - print(line.strip()) - - for log in self.stdout_lines: - if "error" in log or "errors" in log: - self.errors_found = True - - error = True - - if error is True: - self.label_notify_revealer.set_text("%s failed" % " ".join(self.cmd)) - self.reveal_notify() - - logger.error("%s failed" % " ".join(self.cmd)) - else: - self.label_notify_revealer.set_text("%s completed" % " ".join(self.cmd)) - self.reveal_notify() - - logger.info("%s completed" % " ".join(self.cmd)) - - # time.sleep(0.3) - - -# ====================================================================== -# UPDATE BOOTLOADER ENTRIES -# ====================================================================== - - -# grub - grub-mkconfig /boot/grub/grub.cfg -# systemd-boot - bootctl update -def update_bootloader(self): - cmds = [] - error = False - self.stdout_lines = [] - - if self.action == "install": - image = "images/48x48/akm-install.png" - - if self.installed_kernel_version is not None: - - for self.cmd in [ - ["kernel-install", "add-all"], - ["kernel-install", "remove", self.installed_kernel_version], - ]: - run_process(self) - - else: - self.cmd = ["kernel-install", "add-all"] - run_process(self) - - else: - image = "images/48x48/akm-remove.png" - if self.installed_kernel_version is not None: - self.cmd = ["kernel-install", "remove", self.installed_kernel_version] - run_process(self) - - try: - - """ - kernel-install -add-all - kernel-install remove $kernel_version - this is for systems which do not have any pacman hooks in place - useful for vanilla arch installs - """ - - self.label_notify_revealer.set_text("Updating bootloader %s" % self.bootloader) - self.reveal_notify() - - logger.info("Current bootloader = %s" % self.bootloader) - - cmd = None - - if self.bootloader == "grub": - if self.bootloader_grub_cfg is not None: - cmd = ["grub-mkconfig", "-o", self.bootloader_grub_cfg] - else: - logger.error("Bootloader grub config file not specified") - - event = "%s [INFO]: Running %s\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - " ".join(cmd), - ) - self.messages_queue.put(event) - - elif self.bootloader == "systemd-boot": - # cmd = ["bootctl", "update"] - # graceful update systemd-boot - cmd = ["bootctl", "--no-variables", "--graceful", "update"] - event = "%s [INFO]: Running %s\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - " ".join(cmd), - ) - self.messages_queue.put(event) - else: - logger.error("Bootloader is empty / not supported") - - if cmd is not None: - self.stdout_lines = [] - logger.info("Running %s" % " ".join(cmd)) - with subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - bufsize=1, - universal_newlines=True, - ) as process: - while True: - if process.poll() is not None: - break - for line in process.stdout: - self.stdout_lines.append(line.strip()) - self.messages_queue.put(line) - print(line.strip()) - - # time.sleep(0.3) - - if process.returncode == 0: - self.label_notify_revealer.set_text( - "Bootloader %s updated" % self.bootloader - ) - self.reveal_notify() - - logger.info("%s update completed" % self.bootloader) - - event = "%s [INFO]: %s update completed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.bootloader, - ) - self.messages_queue.put(event) - - logger.info("Linux packages have changed a reboot is recommended") - event = "%s [INFO]: #### Linux packages have changed a reboot is recommended ####\n" % datetime.datetime.now().strftime( - "%Y-%m-%d-%H-%M-%S" - ) - self.messages_queue.put(event) - - if self.restore is False: - GLib.idle_add( - show_mw, - self, - "System changes", - f"Kernel {self.action} completed\n" - f"This window can now be closed\n", - image, - priority=GLib.PRIORITY_DEFAULT, - ) - else: - if ( - "Skipping" - or "same boot loader version in place already." in self.stdout_lines - ): - logger.info("%s update completed" % self.bootloader) - - event = "%s [INFO]: %s update completed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.bootloader, - ) - self.messages_queue.put(event) - - if self.restore is False: - GLib.idle_add( - show_mw, - self, - "System changes", - f"Kernel {self.action} completed\n" - f"This window can now be closed\n", - image, - priority=GLib.PRIORITY_DEFAULT, - ) - - else: - self.label_notify_revealer.set_text( - "Bootloader %s update failed" % self.bootloader - ) - self.reveal_notify() - - event = "%s [ERROR]: %s update failed\n" % ( - datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.bootloader, - ) - - logger.error("%s update failed" % self.bootloader) - logger.error(str(self.stdout_lines)) - self.messages_queue.put(event) - - GLib.idle_add( - show_mw, - self, - "System changes", - f"Kernel {self.action} failed .. attempting kernel restore\n" - f"There have been errors, please review the logs\n", - image, - priority=GLib.PRIORITY_DEFAULT, - ) - - else: - logger.error("Bootloader update failed") - - GLib.idle_add( - show_mw, - self, - "System changes", - f"Kernel {self.action} failed\n" - f"There have been errors, please review the logs\n", - image, - priority=GLib.PRIORITY_DEFAULT, - ) - # else: - # logger.error("Bootloader update cannot continue, failed to set command.") - except Exception as e: - logger.error("Exception in update_bootloader(): %s" % e) - - -# ====================================================================== -# SHOW MESSAGE WINDOW AFTER BOOTLOADER UPDATE -# ====================================================================== -def show_mw(self, title, msg, image): - mw = MessageWindow( - title=title, - message=msg, - image_path=image, - detailed_message=False, - transient_for=self, - ) - - mw.present() - - -# ====================================================================== -# CHECKS PACMAN PROCESS -# ====================================================================== -def check_pacman_process(self): - try: - process_found = False - for proc in psutil.process_iter(): - try: - pinfo = proc.as_dict(attrs=["pid", "name", "create_time"]) - - if pinfo["name"] == "pacman": - process_found = True - - except (psutil.NoSuchProcess, psutil.AccessDenied): - continue - - if process_found is True: - logger.info("Pacman process is running") - return True - else: - return False - except Exception as e: - logger.error("Exception in check_pacman_process() : %s" % e) \ No newline at end of file diff --git a/kernel.py b/kernel.py deleted file mode 100644 index e8350fc..0000000 --- a/kernel.py +++ /dev/null @@ -1,51 +0,0 @@ -# Store kernel data taken from -import datetime -from datetime import datetime - - -class Kernel: - def __init__(self, name, headers, version, size, last_modified, file_format): - self.name = name - self.headers = headers - self.version = version - self.size = size - self.last_modified = last_modified - self.file_format = file_format - - def __gt__(self, other): - datetime_value_self = ( - datetime.strptime(self.last_modified, "%d-%b-%Y %H:%M") - .replace(tzinfo=None) - .date() - ) - - datetime_value_other = ( - datetime.strptime(other.last_modified, "%d-%b-%Y %H:%M") - .replace(tzinfo=None) - .date() - ) - - if datetime_value_other > datetime_value_self: - return datetime_value_other - - -class CommunityKernel: - def __init__(self, name, headers, repository, version, build_date, install_size): - self.name = name - self.headers = headers - self.repository = repository - self.version = version - self.build_date = build_date - self.install_size = install_size - - def __gt__(self, other): - if other.name > self.name: - return other - - -class InstalledKernel: - def __init__(self, name, version, date, size): - self.name = name - self.version = version - self.date = date - self.size = size \ No newline at end of file diff --git a/push.sh b/push.sh deleted file mode 100755 index 7e3faa7..0000000 --- a/push.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Iconized - -pull_from_github(){ - git pull -} - -push_to_github() { - # git pull - git add . - ezcommits - git push -u origin master -} - -main(){ - pull_from_github - push_to_github -} - -main \ No newline at end of file diff --git a/snigdhaos-kernel-manager.css b/snigdhaos-kernel-manager.css deleted file mode 100644 index ae080b6..0000000 --- a/snigdhaos-kernel-manager.css +++ /dev/null @@ -1,167 +0,0 @@ -box#box{ - padding: 5px 5px 5px 5px; -} - -box#main{ - padding-left: 20px; - padding-right: 20px; - padding-bottom: 20px; - padding-top: 10px; -} - -box#box_padding_left{ - padding-left: 5px; -} - -box#vbox_flowbox_message { - padding: 10px 10px 10px 10px; -} - -box#vbox_active_kernel{ - padding: 5px 5px 5px 5px; -} - -box#hbox_notify_revealer{ - padding: 10px 10px 10px 10px; - border-radius: 10px; - border-spacing: 5px; - background-color: #3fe1b0; - color: #0e1313; - border-color: transparent; -} - -box#box_row{ - padding-left: 20px; - padding-top: 8px; - padding-bottom: 8px; -} - -box#hbox_kernel{ - background-color: @theme_base_color; - padding-bottom: 8px; - /*box-shadow: -6px 8px 10px rgba(81,41,10,0.1),0px 2px 2px rgba(81,41,10,0.2);*/ -} - -box#vbox_header{ - background-color: @theme_base_color; - border-top: 1px solid @borders; - border-bottom: 1px solid @borders; - border-left: 1px solid @borders; - border-right: 1px solid @borders; - padding: 5px 5px 5px 5px; - border-radius: 100px; - border-spacing: 5px; - font-weight: bold; - font-family: 'Noto Sans', 'Helvetica', sans-serif; - /*box-shadow: -6px 8px 10px rgba(81,41,10,0.1),0px 2px 2px rgba(81,41,10,0.2);*/ -} - -box#hbox_warning{ - background-color: #4c8bf5; - color: white; - font-family: 'Noto Sans', 'Helvetica', sans-serif; - padding: 5px 5px 5px 5px; -} - -label#label_notify_revealer{ - background-color: #3fe1b0; - color: #0e1313; - font-family: 'Noto Sans', 'Helvetica', sans-serif; - font-weight: bold; -} - -label#label_active_kernel { - font-family: 'Noto Sans', 'Helvetica', sans-serif; - font-size: 11px; -} - -label#label_stack_kernel { - font-size: 20px; - font-weight: 600; - border-top: 1px solid @borders; - border-bottom: 1px solid @borders; - border-left: 1px solid @borders; - border-right: 1px solid @borders; - padding: 5px 5px 5px 5px; - border-radius: 100px; - border-spacing: 5px; - font-family: 'Noto Sans', 'Helvetica', sans-serif; - color: #fcfcfc; - background-color: @theme_base_color; -} - -label#label_stack_desc { - font-size: 12.5px; - font-weight: 600; - padding: 5px 5px 5px 5px; - font-style: italic; - font-family: 'Noto Sans', 'Helvetica', sans-serif; -} - -label#label_community_warning { - font-size: 12.5px; - padding: 5px 5px 5px 5px; - font-family: 'Noto Sans', 'Helvetica', sans-serif; -} - -label#label_error{ - font-size: 12.5px; - font-weight: 600; - padding: 5px 5px 5px 5px; - color: #fcfcfc; - background-color: #E42217; - font-family: 'Noto Sans', 'Helvetica', sans-serif; - border-top: 1px solid @borders; - border-bottom: 1px solid @borders; - border-left: 1px solid @borders; - border-right: 1px solid @borders; - padding: 5px 5px 5px 5px; - border-radius: 10px; - border-spacing: 5px; -} - -label#label_stack_count { - font-size: 12px; - font-weight: 500; - padding: 5px 5px 5px 5px; - font-style: italic; - font-family: 'Noto Sans', 'Helvetica', sans-serif; -} - -label#label_kernel_version { - padding: 5px 5px 5px 5px; - font-size: 12px; - font-family: 'Noto Sans', 'Helvetica', sans-serif; -} - -label#label_kernel_flowbox { - padding: 5px 5px 5px 5px; - font-size: 11px; - font-family: 'Noto Sans', 'Helvetica', sans-serif; -} - -label#label_about { - padding: 5px 5px 5px 5px; - font-size: 11px; - font-family: 'Noto Sans', 'Helvetica', sans-serif; -} - -button#button_uninstall_kernel{ - font-weight: 600; -} - -.sidebar label{ - font-size: 12.5px; - font-weight: 500; - padding: 10px 10px 10px 10px; -} - -#textview_log text{ - background-color: #232627; - color: #fcfcfc; - font-family: 'Noto Sans', 'Helvetica', sans-serif; - border-top: 1px solid @borders; - border-bottom: 1px solid @borders; - border-left: 1px solid @borders; - border-right: 1px solid @borders; -} \ No newline at end of file diff --git a/snigdhaos-kernel-manager.py b/snigdhaos-kernel-manager.py deleted file mode 100644 index 0c96ef8..0000000 --- a/snigdhaos-kernel-manager.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/python - -import os -import functions as fn -from ui import ManagerGUI -import gi -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio, GLib - -base_dir = fn.os.path.dirname(fn.os.path.realpath(__file__)) - -app_name = "Snigdha OS Kernel Manager" -app_version = "${app_version}" -app_name_dir = "snigdhaos-kernel-manager" -app_id = "org.snigdhaos.kernelmanager" -lock_file = "/tmp/sokm.lock" -pid_file = "/tmp/sokm.pid" - - -class Main(Gtk.Application): - def __init__(self): - super().__init__(application_id=app_id, flags=Gio.ApplicationFlags.FLAGS_NONE) - - def do_activate(self): - default_context = GLib.MainContext.default() - win = self.props.active_window - if not win: - win = ManagerGUI( - application=self, - app_name=app_name, - default_context=default_context, - app_version=app_version, - ) - - display = Gtk.Widget.get_display(win) - - # sourced from /usr/share/icons/hicolor/scalable/apps - win.set_icon_name("snigdhaos-kernel-manager-tux") - provider = Gtk.CssProvider.new() - css_file = Gio.file_new_for_path(base_dir + "/snigdhaos-kernel-manager.css") - provider.load_from_file(css_file) - Gtk.StyleContext.add_provider_for_display( - display, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION - ) - win.present() - - def do_startup(self): - Gtk.Application.do_startup(self) - - def do_shutdown(self): - Gtk.Application.do_shutdown(self) - if os.path.exists(lock_file): - os.remove(lock_file) - if os.path.exists(pid_file): - os.remove(pid_file) - - -def signal_handler(sig, frame): - Gtk.main_quit(0) - - -# These should be kept as it ensures that multiple installation instances can't be run concurrently. -if __name__ == "__main__": - try: - # signal.signal(signal.SIGINT, signal_handler) - - if not fn.os.path.isfile(lock_file): - with open(pid_file, "w") as f: - f.write(str(fn.os.getpid())) - - # splash = SplashScreen() - - app = Main() - app.run(None) - else: - md = Gtk.MessageDialog( - parent=Main(), - flags=0, - message_type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.YES_NO, - text="%s Lock File Found" % app_name, - ) - md.format_secondary_markup( - "A %s lock file has been found. This indicates there is already an instance of %s running.\n\ - Click 'Yes' to remove the lock file and try running again" - % (lock_file, app_name) - ) # noqa - - result = md.run() - md.destroy() - - if result in (Gtk.ResponseType.OK, Gtk.ResponseType.YES): - pid = "" - if fn.os.path.exists(pid_file): - with open(pid_file, "r") as f: - line = f.read() - pid = line.rstrip().lstrip() - - else: - # in the rare event that the lock file is present, but the pid isn't - fn.os.unlink(lock_file) - fn.sys.exit(1) - else: - fn.sys.exit(1) - except Exception as e: - # fn.logger.error("Exception in __main__: %s" % e) - print("Exception in __main__: %s" % e) \ No newline at end of file diff --git a/ui/AboutDialog.py b/ui/AboutDialog.py deleted file mode 100644 index 49972d8..0000000 --- a/ui/AboutDialog.py +++ /dev/null @@ -1,67 +0,0 @@ -# This class stores static information about the app, and is displayed in the about window -import os -import gi -import functions as fn - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio, Gdk - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - - -class AboutDialog(Gtk.AboutDialog): - def __init__(self, manager_gui, **kwargs): - super().__init__(**kwargs) - - website = "http://arcolinux.info/" - authors = ["Erik Dubois", "Fennec"] - program_name = "Arch Linux Kernel Manager" - comments = ( - f"Add/Remove Officially supported Linux kernels on Arch based systems\n" - f"Powered by the Arch Linux Archive (a.k.a ALA)\n" - f"Community based Linux kernels are also supported\n" - f"Developed in Python with GTK 4\n" - ) - - icon_name = "akm-tux" - - self.set_transient_for(manager_gui) - self.set_modal(True) - self.set_authors(authors) - self.set_program_name(program_name) - self.set_comments(comments) - self.set_website(website) - - self.set_logo_icon_name(icon_name) - self.set_version("Version %s" % manager_gui.app_version) - - self.connect("activate-link", self.on_activate_link) - - tux_icon = Gdk.Texture.new_from_file( - file=Gio.File.new_for_path( - os.path.join(base_dir, "images/96x96/akm-tux.png") - ) - ) - - self.set_logo(tux_icon) - - def on_activate_link(self, about_dialog, uri): - try: - cmd = ["sudo", "-u", fn.sudo_username, "xdg-open", uri] - - proc = fn.subprocess.Popen( - cmd, - shell=False, - stdout=fn.subprocess.PIPE, - stderr=fn.subprocess.STDOUT, - universal_newlines=True, - ) - - out, err = proc.communicate(timeout=50) - - fn.logger.warning(out) - - except Exception as e: - fn.logger.error("Exception in activate_link(): %s" % e) - - return True \ No newline at end of file diff --git a/ui/FlowBox.py b/ui/FlowBox.py deleted file mode 100644 index 8c44ccf..0000000 --- a/ui/FlowBox.py +++ /dev/null @@ -1,638 +0,0 @@ -import datetime - -import gi -import os -import functions as fn -from ui.ProgressWindow import ProgressWindow -from ui.MessageWindow import MessageWindow - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio, GLib - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - - -class FlowBox(Gtk.FlowBox): - def __init__( - self, - kernel, - active_kernel, - manager_gui, - source, - ): - super(FlowBox, self).__init__() - - self.manager_gui = manager_gui - - # self.set_row_spacing(1) - # self.set_column_spacing(1) - # self.set_name("hbox_kernel") - # self.set_activate_on_single_click(True) - # self.connect("child-activated", self.on_child_activated) - self.set_valign(Gtk.Align.START) - - self.set_selection_mode(Gtk.SelectionMode.NONE) - - # self.set_homogeneous(True) - - self.set_max_children_per_line(2) - self.set_min_children_per_line(2) - self.kernel_count = 0 - - self.active_kernel_found = False - self.kernels = [] - - self.kernel = kernel - self.source = source - - if self.source == "official": - self.flowbox_official() - - if self.source == "community": - self.flowbox_community() - - def flowbox_community(self): - for community_kernel in self.kernel: - self.kernels.append(community_kernel) - - self.kernel_count += 1 - - if len(self.kernels) > 0: - installed = False - - for cache in self.kernels: - fb_child = Gtk.FlowBoxChild() - fb_child.set_name( - "%s %s %s" % (cache.name, cache.version, cache.repository) - ) - - vbox_kernel_widgets = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=0 - ) - vbox_kernel_widgets.set_name("vbox_kernel_widgets") - vbox_kernel_widgets.set_homogeneous(True) - - switch_kernel = Gtk.Switch() - switch_kernel.set_halign(Gtk.Align.START) - - hbox_kernel_switch = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=0 - ) - - hbox_kernel_switch.append(switch_kernel) - - label_kernel_size = Gtk.Label(xalign=0, yalign=0) - label_kernel_size.set_name("label_kernel_flowbox") - - label_kernel_name = Gtk.Label(xalign=0, yalign=0) - label_kernel_name.set_name("label_kernel_version") - label_kernel_name.set_markup( - "%s %s %s" - % (cache.name, cache.version, cache.repository) - ) - label_kernel_name.set_selectable(True) - - vbox_kernel_widgets.append(label_kernel_name) - - tux_icon = Gtk.Picture.new_for_file( - file=Gio.File.new_for_path( - os.path.join(base_dir, "images/48x48/akm-tux.png") - ) - ) - tux_icon.set_can_shrink(True) - - for installed_kernel in self.manager_gui.installed_kernels: - if "{}-{}".format( - installed_kernel.name, installed_kernel.version - ) == "{}-{}".format(cache.name, cache.version): - installed = True - - if cache.name == installed_kernel.name: - if ( - cache.version > installed_kernel.version - or cache.version != installed_kernel.version - ): - fn.logger.info( - "Kernel upgrade available - %s %s" - % (cache.name, cache.version) - ) - - tux_icon = Gtk.Picture.new_for_file( - file=Gio.File.new_for_path( - os.path.join( - base_dir, "images/48x48/akm-update.png" - ) - ) - ) - tux_icon.set_can_shrink(True) - - label_kernel_name.set_markup( - "*%s %s %s" - % (cache.name, cache.version, cache.repository) - ) - - if installed is True: - switch_kernel.set_state(True) - switch_kernel.set_active(True) - - else: - switch_kernel.set_state(False) - switch_kernel.set_active(False) - - tux_icon.set_content_fit(content_fit=Gtk.ContentFit.SCALE_DOWN) - tux_icon.set_halign(Gtk.Align.START) - - installed = False - switch_kernel.connect("state-set", self.kernel_toggle_state, cache) - - hbox_kernel = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) - hbox_kernel.set_name("hbox_kernel") - - label_kernel_size.set_text("%sM" % str(cache.install_size)) - - vbox_kernel_widgets.append(label_kernel_size) - - label_kernel_build_date = Gtk.Label(xalign=0, yalign=0) - label_kernel_build_date.set_name("label_kernel_flowbox") - label_kernel_build_date.set_text(cache.build_date) - - vbox_kernel_widgets.append(label_kernel_build_date) - - vbox_kernel_widgets.append(hbox_kernel_switch) - - hbox_kernel.append(tux_icon) - hbox_kernel.append(vbox_kernel_widgets) - - fb_child.set_child(hbox_kernel) - - self.append(fb_child) - - def flowbox_official(self): - for official_kernel in self.manager_gui.official_kernels: - if official_kernel.name == self.kernel: - self.kernels.append(official_kernel) - self.kernel_count += 1 - - if len(self.kernels) > 0: - installed = False - - latest = sorted(self.kernels)[:-1][0] - - for cache in sorted(self.kernels): - fb_child = Gtk.FlowBoxChild() - fb_child.set_name("%s %s" % (cache.name, cache.version)) - if cache == latest: - tux_icon = Gtk.Picture.new_for_file( - file=Gio.File.new_for_path( - os.path.join(base_dir, "images/48x48/akm-new.png") - ) - ) - - else: - tux_icon = Gtk.Picture.new_for_file( - file=Gio.File.new_for_path( - os.path.join(base_dir, "images/48x48/akm-tux.png") - ) - ) - - tux_icon.set_content_fit(content_fit=Gtk.ContentFit.SCALE_DOWN) - tux_icon.set_halign(Gtk.Align.START) - - vbox_kernel_widgets = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=0 - ) - vbox_kernel_widgets.set_homogeneous(True) - - hbox_kernel_switch = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=0 - ) - - switch_kernel = Gtk.Switch() - switch_kernel.set_halign(Gtk.Align.START) - - hbox_kernel_switch.append(switch_kernel) - - label_kernel_version = Gtk.Label(xalign=0, yalign=0) - label_kernel_version.set_name("label_kernel_version") - label_kernel_version.set_selectable(True) - - label_kernel_size = Gtk.Label(xalign=0, yalign=0) - label_kernel_size.set_name("label_kernel_flowbox") - - if self.manager_gui.installed_kernels is None: - self.manager_gui.installed_kernels = fn.get_installed_kernels() - - for installed_kernel in self.manager_gui.installed_kernels: - if ( - "{}-{}".format(installed_kernel.name, installed_kernel.version) - == cache.version - ): - installed = True - - if installed is True: - switch_kernel.set_state(True) - switch_kernel.set_active(True) - - else: - switch_kernel.set_state(False) - switch_kernel.set_active(False) - - installed = False - switch_kernel.connect("state-set", self.kernel_toggle_state, cache) - - label_kernel_version.set_markup("%s" % cache.version) - - hbox_kernel = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) - hbox_kernel.set_name("hbox_kernel") - - label_kernel_size.set_text(cache.size) - - vbox_kernel_widgets.append(label_kernel_version) - vbox_kernel_widgets.append(label_kernel_size) - - label_kernel_modified = Gtk.Label(xalign=0, yalign=0) - label_kernel_modified.set_name("label_kernel_flowbox") - label_kernel_modified.set_text(cache.last_modified) - - vbox_kernel_widgets.append(label_kernel_modified) - - vbox_kernel_widgets.append(hbox_kernel_switch) - - hbox_kernel.append(tux_icon) - hbox_kernel.append(vbox_kernel_widgets) - - fb_child.set_child(hbox_kernel) - - self.append(fb_child) - - else: - fn.logger.error("Failed to read in kernels.") - - def kernel_toggle_state(self, switch, data, kernel): - fn.logger.debug( - "Switch toggled, kernel selected = %s %s" % (kernel.name, kernel.version) - ) - message = None - title = None - - if fn.check_pacman_lockfile() is False: - # switch widget is currently toggled off - if switch.get_state() is False: # and switch.get_active() is True: - for inst_kernel in fn.get_installed_kernels(): - if inst_kernel.name == kernel.name: - if self.source == "official": - if ( - inst_kernel.version - > kernel.version.split("%s-" % inst_kernel.name)[1] - ): - title = "Downgrading %s kernel" % kernel.name - else: - title = "Upgrading %s kernel" % kernel.name - - break - - if title is None: - title = "Kernel install" - - if self.source == "community": - message = "This will install %s-%s - Is this ok ?" % ( - kernel.name, - kernel.version, - ) - elif self.source == "official": - message = ( - "This will install %s - Is this ok ?" % kernel.version - ) - - message_window = FlowBoxMessageWindow( - title=title, - message=message, - action="install", - kernel=kernel, - transient_for=self.manager_gui, - textview=self.manager_gui.textview, - textbuffer=self.manager_gui.textbuffer, - switch=switch, - source=self.source, - manager_gui=self.manager_gui, - ) - message_window.present() - return True - - # switch widget is currently toggled on - # if widget.get_state() == True and widget.get_active() == False: - if switch.get_state() is True: - # and switch.get_active() is False: - installed_kernels = fn.get_installed_kernels() - - if len(installed_kernels) > 1: - - if self.source == "community": - message = "This will remove %s-%s - Is this ok ?" % ( - kernel.name, - kernel.version, - ) - elif self.source == "official": - message = ( - "This will remove %s - Is this ok ?" % kernel.version - ) - - message_window = FlowBoxMessageWindow( - title="Kernel uninstall", - message=message, - action="uninstall", - kernel=kernel, - transient_for=self.manager_gui, - textview=self.manager_gui.textview, - textbuffer=self.manager_gui.textbuffer, - switch=switch, - source=self.source, - manager_gui=self.manager_gui, - ) - message_window.present() - return True - else: - switch.set_state(True) - # switch.set_active(False) - fn.logger.warn( - "You only have 1 kernel installed, and %s-%s is currently running, uninstall aborted." - % (kernel.name, kernel.version) - ) - msg_win = MessageWindow( - title="Warning: Uninstall aborted", - message=f"You only have 1 kernel installed\n" - f"{kernel.name} {kernel.version} is currently active\n", - image_path="images/48x48/akm-remove.png", - transient_for=self.manager_gui, - detailed_message=False, - ) - msg_win.present() - return True - - else: - fn.logger.error( - "Pacman lockfile found, is another pacman process running ?" - ) - - msg_win = MessageWindow( - title="Warning", - message="Pacman lockfile found, which indicates another pacman process is running", - transient_for=self.manager_gui, - detailed_message=False, - image_path="images/48x48/akm-warning.png", - ) - msg_win.present() - return True - - # while self.manager_gui.default_context.pending(): - # self.manager_gui.default_context.iteration(True) - - -class FlowBoxInstalled(Gtk.FlowBox): - def __init__(self, installed_kernels, manager_gui, **kwargs): - super().__init__(**kwargs) - - self.set_selection_mode(Gtk.SelectionMode.NONE) - - self.set_homogeneous(True) - self.set_max_children_per_line(2) - self.set_min_children_per_line(2) - - self.manager_gui = manager_gui - - for installed_kernel in installed_kernels: - tux_icon = Gtk.Picture.new_for_file( - file=Gio.File.new_for_path( - os.path.join(base_dir, "images/48x48/akm-tux.png") - ) - ) - - fb_child = Gtk.FlowBoxChild() - fb_child.set_name( - "%s %s" % (installed_kernel.name, installed_kernel.version) - ) - - tux_icon.set_content_fit(content_fit=Gtk.ContentFit.SCALE_DOWN) - tux_icon.set_halign(Gtk.Align.START) - - label_installed_kernel_version = Gtk.Label(xalign=0, yalign=0) - label_installed_kernel_version.set_name("label_kernel_version") - label_installed_kernel_version.set_markup( - "%s %s" % (installed_kernel.name, installed_kernel.version) - ) - label_installed_kernel_version.set_selectable(True) - - hbox_installed_version = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=0 - ) - - hbox_installed_version.append(label_installed_kernel_version) - - label_installed_kernel_size = Gtk.Label(xalign=0, yalign=0) - label_installed_kernel_size.set_name("label_kernel_flowbox") - label_installed_kernel_size.set_text("%sM" % str(installed_kernel.size)) - - label_installed_kernel_date = Gtk.Label(xalign=0, yalign=0) - label_installed_kernel_date.set_name("label_kernel_flowbox") - label_installed_kernel_date.set_text("%s" % installed_kernel.date) - - btn_uninstall_kernel = Gtk.Button.new_with_label("Remove") - - btn_context = btn_uninstall_kernel.get_style_context() - btn_context.add_class("destructive-action") - - vbox_uninstall_button = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=0 - ) - vbox_uninstall_button.set_name("box_padding_left") - - btn_uninstall_kernel.set_hexpand(False) - btn_uninstall_kernel.set_halign(Gtk.Align.CENTER) - btn_uninstall_kernel.set_vexpand(False) - btn_uninstall_kernel.set_valign(Gtk.Align.CENTER) - - vbox_uninstall_button.append(btn_uninstall_kernel) - - btn_uninstall_kernel.connect( - "clicked", self.button_uninstall_kernel, installed_kernel - ) - - vbox_kernel_widgets = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=0 - ) - - vbox_kernel_widgets.append(hbox_installed_version) - vbox_kernel_widgets.append(label_installed_kernel_size) - vbox_kernel_widgets.append(label_installed_kernel_date) - vbox_kernel_widgets.append(vbox_uninstall_button) - - hbox_kernel = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) - hbox_kernel.set_name("hbox_kernel") - - hbox_kernel.append(tux_icon) - hbox_kernel.append(vbox_kernel_widgets) - - fb_child.set_child(hbox_kernel) - - self.append(fb_child) - - def button_uninstall_kernel(self, button, installed_kernel): - installed_kernels = fn.get_installed_kernels() - - if len(installed_kernels) > 1: - fn.logger.info( - "Selected kernel to remove = %s %s" - % (installed_kernel.name, installed_kernel.version) - ) - - message_window = FlowBoxMessageWindow( - title="Kernel uninstall", - message="This will remove %s-%s - Is this ok ?" - % (installed_kernel.name, installed_kernel.version), - action="uninstall", - kernel=installed_kernel, - transient_for=self.manager_gui, - textview=self.manager_gui.textview, - textbuffer=self.manager_gui.textbuffer, - switch=None, - source=None, - manager_gui=self.manager_gui, - ) - message_window.present() - else: - fn.logger.warn( - "You only have 1 kernel installed %s %s, uninstall aborted." - % (installed_kernel.name, installed_kernel.version) - ) - msg_win = MessageWindow( - title="Warning: Uninstall aborted", - message=f"You only have 1 kernel installed\n" - f"{installed_kernel.name} {installed_kernel.version}\n", - image_path="images/48x48/akm-remove.png", - transient_for=self.manager_gui, - detailed_message=False, - ) - msg_win.present() - - -class FlowBoxMessageWindow(Gtk.Window): - def __init__( - self, - title, - message, - action, - kernel, - textview, - textbuffer, - switch, - source, - manager_gui, - **kwargs, - ): - super().__init__(**kwargs) - - self.set_title(title=title) - self.set_modal(modal=True) - self.set_resizable(False) - self.set_icon_name("archlinux-kernel-manager-tux") - - header_bar = Gtk.HeaderBar() - header_bar.set_show_title_buttons(False) - - label_title = Gtk.Label(xalign=0.5, yalign=0.5) - label_title.set_markup("%s" % title) - - self.set_titlebar(header_bar) - - header_bar.set_title_widget(label_title) - - self.textview = textview - self.textbuffer = textbuffer - self.manager_gui = manager_gui - self.kernel = kernel - self.action = action - self.switch = switch - self.source = source - - vbox_flowbox_message = Gtk.Box.new( - orientation=Gtk.Orientation.VERTICAL, spacing=10 - ) - vbox_flowbox_message.set_name("vbox_flowbox_message") - - self.set_child(child=vbox_flowbox_message) - - label_flowbox_message = Gtk.Label(xalign=0, yalign=0) - label_flowbox_message.set_markup("%s" % message) - label_flowbox_message.set_name("label_flowbox_message") - - vbox_flowbox_message.set_halign(Gtk.Align.CENTER) - - # Widgets. - button_yes = Gtk.Button.new_with_label("Yes") - button_yes.set_size_request(100, 30) - button_yes.set_halign(Gtk.Align.END) - button_yes_context = button_yes.get_style_context() - button_yes_context.add_class("destructive-action") - button_yes.connect("clicked", self.on_button_yes_clicked) - - button_no = Gtk.Button.new_with_label("No") - button_no.set_size_request(100, 30) - button_no.set_halign(Gtk.Align.END) - button_no.connect("clicked", self.on_button_no_clicked) - - hbox_buttons = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL, spacing=15) - hbox_buttons.set_halign(Gtk.Align.CENTER) - hbox_buttons.append(button_yes) - hbox_buttons.append(button_no) - - vbox_flowbox_message.append(label_flowbox_message) - vbox_flowbox_message.append(hbox_buttons) - - def on_button_yes_clicked(self, button): - self.hide() - self.destroy() - progress_window = None - if fn.check_pacman_lockfile() is False: - if self.action == "uninstall": - progress_window = ProgressWindow( - title="Removing kernel", - action="uninstall", - textview=self.textview, - textbuffer=self.textbuffer, - kernel=self.kernel, - switch=self.switch, - source=self.source, - manager_gui=self.manager_gui, - transient_for=self.manager_gui, - ) - - if self.action == "install": - progress_window = ProgressWindow( - title="Installing kernel", - action="install", - textview=self.textview, - textbuffer=self.textbuffer, - kernel=self.kernel, - switch=self.switch, - source=self.source, - manager_gui=self.manager_gui, - transient_for=self.manager_gui, - ) - else: - fn.logger.error( - "Pacman lockfile found, is another pacman process running ?" - ) - - def on_button_no_clicked(self, button): - if self.action == "uninstall": - if self.switch is not None: - self.switch.set_state(True) - - elif self.action == "install": - if self.switch is not None: - self.switch.set_state(False) - - self.hide() - self.destroy() - - return True \ No newline at end of file diff --git a/ui/KernelStack.py b/ui/KernelStack.py deleted file mode 100644 index 73b1598..0000000 --- a/ui/KernelStack.py +++ /dev/null @@ -1,631 +0,0 @@ -import gi -import os -import functions as fn -from ui.FlowBox import FlowBox, FlowBoxInstalled -from ui.Stack import Stack -from kernel import Kernel, InstalledKernel, CommunityKernel - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio, Gdk - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - - -class KernelStack: - def __init__( - self, - manager_gui, - **kwargs, - ): - super().__init__(**kwargs) - self.manager_gui = manager_gui - self.flowbox_stacks = [] - self.search_entries = [] - - def add_installed_kernels_to_stack(self, reload): - vbox_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - vbox_header.set_name("vbox_header") - - lbl_heading = Gtk.Label(xalign=0.5, yalign=0.5) - lbl_heading.set_name("label_flowbox_message") - lbl_heading.set_text("%s" % "Installed kernels".upper()) - - lbl_padding = Gtk.Label(xalign=0.0, yalign=0.0) - lbl_padding.set_text(" ") - - grid_banner_img = Gtk.Grid() - - image_settings = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-install.png") - ) - - image_settings.set_icon_size(Gtk.IconSize.LARGE) - image_settings.set_halign(Gtk.Align.START) - - grid_banner_img.attach(image_settings, 0, 1, 1, 1) - grid_banner_img.attach_next_to( - lbl_padding, - image_settings, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - grid_banner_img.attach_next_to( - lbl_heading, - lbl_padding, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - vbox_header.append(grid_banner_img) - - label_installed_desc = Gtk.Label(xalign=0, yalign=0) - label_installed_desc.set_text("Installed Linux kernel and modules") - label_installed_desc.set_name("label_stack_desc") - - label_installed_count = Gtk.Label(xalign=0, yalign=0) - - label_installed_count.set_name("label_stack_count") - - vbox_search_entry = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - - search_entry_installed = Gtk.SearchEntry() - search_entry_installed.set_name("search_entry_installed") - search_entry_installed.set_placeholder_text("Search installed kernels...") - search_entry_installed.connect("search_changed", self.flowbox_filter_installed) - - vbox_search_entry.append(search_entry_installed) - - if reload is True: - if self.manager_gui.vbox_installed_kernels is not None: - for widget in self.manager_gui.vbox_installed_kernels: - if widget.get_name() == "label_stack_count": - widget.set_markup( - "%s Installed kernels" - % len(self.manager_gui.installed_kernels) - ) - - if widget.get_name() == "scrolled_window_installed": - self.manager_gui.vbox_installed_kernels.remove(widget) - - scrolled_window_installed = Gtk.ScrolledWindow() - scrolled_window_installed.set_name("scrolled_window_installed") - scrolled_window_installed.set_policy( - Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC - ) - scrolled_window_installed.set_propagate_natural_height(True) - scrolled_window_installed.set_propagate_natural_width(True) - - self.flowbox_installed = FlowBoxInstalled( - installed_kernels=self.manager_gui.installed_kernels, - manager_gui=self.manager_gui, - ) - vbox_installed_flowbox = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=12 - ) - - # vbox_installed_flowbox.set_halign(align=Gtk.Align.FILL) - - vbox_installed_flowbox.append(self.flowbox_installed) - - scrolled_window_installed.set_child(vbox_installed_flowbox) - - self.manager_gui.vbox_installed_kernels.append(scrolled_window_installed) - - if self.manager_gui.vbox_active_installed_kernel is not None: - self.manager_gui.vbox_installed_kernels.reorder_child_after( - self.manager_gui.vbox_active_installed_kernel, - scrolled_window_installed, - ) - else: - self.manager_gui.vbox_installed_kernels = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=5 - ) - self.manager_gui.vbox_installed_kernels.set_name("vbox_installed_kernels") - - self.manager_gui.vbox_active_installed_kernel = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=5 - ) - self.manager_gui.vbox_active_installed_kernel.set_name("vbox_active_kernel") - - label_active_installed_kernel = Gtk.Label(xalign=0.5, yalign=0.5) - label_active_installed_kernel.set_name("label_active_kernel") - label_active_installed_kernel.set_selectable(True) - - label_active_installed_kernel.set_markup( - "Active kernel: %s" % self.manager_gui.active_kernel - ) - label_active_installed_kernel.set_halign(Gtk.Align.START) - self.manager_gui.vbox_active_installed_kernel.append( - label_active_installed_kernel - ) - - scrolled_window_installed = Gtk.ScrolledWindow() - scrolled_window_installed.set_name("scrolled_window_installed") - scrolled_window_installed.set_policy( - Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC - ) - scrolled_window_installed.set_propagate_natural_height(True) - scrolled_window_installed.set_propagate_natural_width(True) - - label_installed_count.set_markup( - "%s Installed kernels" % len(self.manager_gui.installed_kernels) - ) - - self.flowbox_installed = FlowBoxInstalled( - installed_kernels=self.manager_gui.installed_kernels, - manager_gui=self.manager_gui, - ) - vbox_installed_flowbox = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=12 - ) - - # vbox_installed_flowbox.set_halign(align=Gtk.Align.FILL) - - vbox_installed_flowbox.append(self.flowbox_installed) - - scrolled_window_installed.set_child(vbox_installed_flowbox) - - # self.manager_gui.vbox_installed_kernels.append(label_installed_title) - self.manager_gui.vbox_installed_kernels.append(vbox_header) - self.manager_gui.vbox_installed_kernels.append(label_installed_desc) - self.manager_gui.vbox_installed_kernels.append(label_installed_count) - self.manager_gui.vbox_installed_kernels.append(vbox_search_entry) - self.manager_gui.vbox_installed_kernels.append(scrolled_window_installed) - self.manager_gui.vbox_installed_kernels.append( - self.manager_gui.vbox_active_installed_kernel - ) - - self.manager_gui.stack.add_titled( - self.manager_gui.vbox_installed_kernels, "Installed", "Installed" - ) - - def add_official_kernels_to_stack(self, reload): - if reload is True: - self.flowbox_stacks.clear() - for kernel in fn.supported_kernels_dict: - vbox_flowbox = None - stack_child = self.manager_gui.stack.get_child_by_name(kernel) - - if stack_child is not None: - for stack_widget in stack_child: - if stack_widget.get_name() == "scrolled_window_official": - scrolled_window_official = stack_widget - vbox_flowbox = ( - scrolled_window_official.get_child().get_child() - ) - - for widget in vbox_flowbox: - widget.remove_all() - - self.flowbox_official_kernel = FlowBox( - kernel, - self.manager_gui.active_kernel, - self.manager_gui, - "official", - ) - self.flowbox_stacks.append(self.flowbox_official_kernel) - - vbox_flowbox.append(self.flowbox_official_kernel) - - # while self.manager_gui.default_context.pending(): - # self.manager_gui.default_context.iteration(True) - else: - for kernel in fn.supported_kernels_dict: - self.manager_gui.vbox_kernels = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=5 - ) - - self.manager_gui.vbox_kernels.set_name("stack_%s" % kernel) - - hbox_sep_kernels = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=10 - ) - - hsep_kernels = Gtk.Separator(orientation=Gtk.Orientation.VERTICAL) - - vbox_active_kernel = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=5 - ) - vbox_active_kernel.set_name("vbox_active_kernel") - - label_active_kernel = Gtk.Label(xalign=0.5, yalign=0.5) - label_active_kernel.set_name("label_active_kernel") - label_active_kernel.set_selectable(True) - label_active_kernel.set_markup( - "Active kernel: %s" % self.manager_gui.active_kernel - ) - label_active_kernel.set_halign(Gtk.Align.START) - - label_bottom_padding = Gtk.Label(xalign=0, yalign=0) - label_bottom_padding.set_text(" ") - - hbox_sep_kernels.append(hsep_kernels) - - self.flowbox_official_kernel = FlowBox( - kernel, self.manager_gui.active_kernel, self.manager_gui, "official" - ) - - self.flowbox_stacks.append(self.flowbox_official_kernel) - - vbox_flowbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) - vbox_flowbox.set_name("vbox_flowbox_%s" % kernel) - # vbox_flowbox.set_halign(align=Gtk.Align.FILL) - vbox_flowbox.append(self.flowbox_official_kernel) - - scrolled_window_official = Gtk.ScrolledWindow() - scrolled_window_official.set_name("scrolled_window_official") - scrolled_window_official.set_policy( - Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC - ) - scrolled_window_official.set_propagate_natural_height(True) - scrolled_window_official.set_propagate_natural_width(True) - - label_title = Gtk.Label(xalign=0.5, yalign=0.5) - label_title.set_text(kernel.upper()) - label_title.set_name("label_stack_kernel") - - label_desc = Gtk.Label(xalign=0, yalign=0) - label_desc.set_text(fn.supported_kernels_dict[kernel][0]) - label_desc.set_name("label_stack_desc") - - label_count = Gtk.Label(xalign=0, yalign=0) - label_count.set_markup( - "%s Available kernels" - % self.flowbox_official_kernel.kernel_count - ) - - label_count.set_name("label_stack_count") - - vbox_search_entry = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=5 - ) - - search_entry_official = Gtk.SearchEntry() - search_entry_official.set_name(kernel) - search_entry_official.set_placeholder_text( - "Search %s kernels..." % kernel - ) - search_entry_official.connect( - "search_changed", self.flowbox_filter_official - ) - - self.search_entries.append(search_entry_official) - - vbox_search_entry.append(search_entry_official) - - vbox_active_kernel.append(label_active_kernel) - - vbox_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - vbox_header.set_name("vbox_header") - - lbl_heading = Gtk.Label(xalign=0.5, yalign=0.5) - lbl_heading.set_name("label_flowbox_message") - lbl_heading.set_text( - "%s - Verified and official kernels" % kernel.upper() - ) - - lbl_padding = Gtk.Label(xalign=0.0, yalign=0.0) - lbl_padding.set_text(" ") - - grid_banner_img = Gtk.Grid() - - image_settings = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-verified.png") - ) - - image_settings.set_icon_size(Gtk.IconSize.LARGE) - image_settings.set_halign(Gtk.Align.START) - - grid_banner_img.attach(image_settings, 0, 1, 1, 1) - grid_banner_img.attach_next_to( - lbl_padding, - image_settings, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - grid_banner_img.attach_next_to( - lbl_heading, - lbl_padding, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - vbox_header.append(grid_banner_img) - - # vbox_kernels.append(label_title) - self.manager_gui.vbox_kernels.append(vbox_header) - # self.manager_gui.vbox_kernels.append(label_title) - self.manager_gui.vbox_kernels.append(label_desc) - self.manager_gui.vbox_kernels.append(label_count) - self.manager_gui.vbox_kernels.append(vbox_search_entry) - self.manager_gui.vbox_kernels.append(hbox_sep_kernels) - - scrolled_window_official.set_child(vbox_flowbox) - self.manager_gui.vbox_kernels.append(scrolled_window_official) - self.manager_gui.vbox_kernels.append(vbox_active_kernel) - - kernel_sidebar_title = None - - if kernel == "linux": - kernel_sidebar_title = "Linux" - elif kernel == "linux-lts": - kernel_sidebar_title = "Linux-LTS" - elif kernel == "linux-zen": - kernel_sidebar_title = "Linux-ZEN" - elif kernel == "linux-hardened": - kernel_sidebar_title = "Linux-Hardened" - elif kernel == "linux-rt": - kernel_sidebar_title = "Linux-RT" - elif kernel == "linux-rt-lts": - kernel_sidebar_title = "Linux-RT-LTS" - - self.manager_gui.stack.add_titled( - self.manager_gui.vbox_kernels, kernel, kernel_sidebar_title - ) - - def flowbox_filter_official(self, search_entry): - def filter_func(fb_child, text): - if search_entry.get_name() == fb_child.get_name().split(" ")[0]: - if text in fb_child.get_name(): - return True - else: - return False - else: - return True - - text = search_entry.get_text() - - for flowbox in self.flowbox_stacks: - flowbox.set_filter_func(filter_func, text) - - def flowbox_filter_community(self, search_entry): - def filter_func(fb_child, text): - if search_entry.get_name() == "search_entry_community": - if text in fb_child.get_name(): - return True - else: - return False - else: - return True - - text = search_entry.get_text() - - self.flowbox_community.set_filter_func(filter_func, text) - - def flowbox_filter_installed(self, search_entry): - def filter_func(fb_child, text): - if search_entry.get_name() == "search_entry_installed": - if text in fb_child.get_name(): - return True - else: - return False - else: - return True - - text = search_entry.get_text() - - self.flowbox_installed.set_filter_func(filter_func, text) - - def add_community_kernels_to_stack(self, reload): - vbox_active_kernel = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - vbox_active_kernel.set_name("vbox_active_kernel") - vbox_kernels = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - hbox_sep_kernels = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) - hsep_kernels = Gtk.Separator(orientation=Gtk.Orientation.VERTICAL) - hbox_sep_kernels.append(hsep_kernels) - - label_active_kernel = Gtk.Label(xalign=0.5, yalign=0.5) - label_active_kernel.set_name("label_active_kernel") - label_active_kernel.set_selectable(True) - label_active_kernel.set_markup( - "Active kernel: %s" % self.manager_gui.active_kernel - ) - label_active_kernel.set_halign(Gtk.Align.START) - - label_count = Gtk.Label(xalign=0, yalign=0) - label_count.set_name("label_stack_count") - - vbox_search_entry = None - - search_entry_community = Gtk.SearchEntry() - search_entry_community.set_name("search_entry_community") - search_entry_community.set_placeholder_text( - "Search %s kernels..." % "community based" - ) - search_entry_community.connect("search_changed", self.flowbox_filter_community) - - hbox_warning_message = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=5 - ) - hbox_warning_message.set_name("hbox_warning_message") - - label_pacman_warning = Gtk.Label(xalign=0, yalign=0) - label_pacman_warning.set_name("label_community_warning") - - image_warning = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-warning.png") - ) - image_warning.set_name("image_warning") - - image_warning.set_icon_size(Gtk.IconSize.LARGE) - image_warning.set_halign(Gtk.Align.CENTER) - - hbox_warning = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbox_warning.set_name("hbox_warning") - - hbox_warning.append(image_warning) - # hbox_warning.append(label_pacman_warning) - - label_warning = Gtk.Label(xalign=0, yalign=0) - label_warning.set_name("label_community_warning") - label_warning.set_markup( - f"These are user produced content\n" - f"Any use of the provided files is at your own risk" - ) - - hbox_warning.append(label_warning) - - if reload is True: - vbox_flowbox = None - stack_child = self.manager_gui.stack.get_child_by_name("Community Kernels") - - if stack_child is not None: - for stack_widget in stack_child: - if stack_widget.get_name() == "label_stack_count": - stack_widget.set_markup( - "%s Available kernels" - % len(self.manager_gui.community_kernels) - ) - if stack_widget.get_name() == "vbox_search_entry": - if len(self.manager_gui.community_kernels) == 0: - for search_entry in stack_widget: - search_entry.set_visible(False) - else: - for search_entry in stack_widget: - search_entry.set_visible(True) - - if stack_widget.get_name() == "scrolled_window_community": - scrolled_window_community = stack_widget - vbox_flowbox = scrolled_window_community.get_child().get_child() - - for widget in vbox_flowbox: - if widget.get_name() != "vbox_no_community": - widget.remove_all() - else: - if len(self.manager_gui.community_kernels) > 0: - # widget.hide() - for box_widget in widget: - box_widget.hide() - - vbox_search_entry = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=5 - ) - - vbox_search_entry.append(search_entry_community) - # widget.append(hbox_warning) - widget.append(vbox_search_entry) - - self.flowbox_community = FlowBox( - self.manager_gui.community_kernels, - self.manager_gui.active_kernel, - self.manager_gui, - "community", - ) - vbox_flowbox.append(self.flowbox_community) - - while self.manager_gui.default_context.pending(): - # fn.time.sleep(0.1) - self.manager_gui.default_context.iteration(True) - else: - self.flowbox_community = None - - vbox_flowbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) - # vbox_flowbox.set_halign(align=Gtk.Align.FILL) - - if len(self.manager_gui.community_kernels) == 0: - label_count.set_markup("%s Available kernels" % 0) - else: - self.flowbox_community = FlowBox( - self.manager_gui.community_kernels, - self.manager_gui.active_kernel, - self.manager_gui, - "community", - ) - - vbox_flowbox.append(self.flowbox_community) - - label_count.set_markup( - "%s Available kernels" % self.flowbox_community.kernel_count - ) - - vbox_search_entry = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=5 - ) - - vbox_search_entry.set_name("vbox_search_entry") - - vbox_search_entry.append(search_entry_community) - - if reload is False: - scrolled_window_community = Gtk.ScrolledWindow() - scrolled_window_community.set_name("scrolled_window_community") - scrolled_window_community.set_policy( - Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC - ) - scrolled_window_community.set_propagate_natural_height(True) - scrolled_window_community.set_propagate_natural_width(True) - - label_title = Gtk.Label(xalign=0.5, yalign=0.5) - label_title.set_text("Community Kernels") - label_title.set_name("label_stack_kernel") - - label_desc = Gtk.Label(xalign=0, yalign=0) - label_desc.set_text("Community Linux kernel and modules") - label_desc.set_name("label_stack_desc") - - vbox_active_kernel.append(label_active_kernel) - - vbox_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - vbox_header.set_name("vbox_header") - - lbl_heading = Gtk.Label(xalign=0.5, yalign=0.5) - lbl_heading.set_name("label_flowbox_message") - - lbl_heading.set_text( - "%s - Unofficial kernels" % "Community based".upper() - ) - - lbl_padding = Gtk.Label(xalign=0.0, yalign=0.0) - lbl_padding.set_text(" ") - - grid_banner_img = Gtk.Grid() - - image_settings = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-community.png") - ) - - image_settings.set_icon_size(Gtk.IconSize.LARGE) - image_settings.set_halign(Gtk.Align.START) - - grid_banner_img.attach(image_settings, 0, 1, 1, 1) - grid_banner_img.attach_next_to( - lbl_padding, - image_settings, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - grid_banner_img.attach_next_to( - lbl_heading, - lbl_padding, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - vbox_header.append(grid_banner_img) - - vbox_kernels.append(vbox_header) - vbox_kernels.append(label_desc) - vbox_kernels.append(hbox_warning) - vbox_kernels.append(label_count) - - if vbox_search_entry is not None: - vbox_kernels.append(vbox_search_entry) - vbox_kernels.append(hbox_sep_kernels) - - scrolled_window_community.set_child(vbox_flowbox) - - vbox_kernels.append(scrolled_window_community) - vbox_kernels.append(vbox_active_kernel) - - self.manager_gui.stack.add_titled( - vbox_kernels, "Community Kernels", "Community" - ) \ No newline at end of file diff --git a/ui/ManagerGUI.py b/ui/ManagerGUI.py deleted file mode 100644 index 2b2f409..0000000 --- a/ui/ManagerGUI.py +++ /dev/null @@ -1,516 +0,0 @@ -import gi -import os -from ui.MenuButton import MenuButton -from ui.Stack import Stack -from ui.KernelStack import KernelStack -from ui.FlowBox import FlowBox, FlowBoxInstalled -from ui.AboutDialog import AboutDialog -from ui.SplashScreen import SplashScreen -from ui.MessageWindow import MessageWindow -from ui.SettingsWindow import SettingsWindow -import functions as fn - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio, Gdk, GLib - - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - - -class ManagerGUI(Gtk.ApplicationWindow): - def __init__(self, app_name, default_context, app_version, **kwargs): - super().__init__(**kwargs) - - self.default_context = default_context - - self.app_version = app_version - - if self.app_version == "${app_version}": - self.app_version = "dev" - - fn.logger.info("Version = %s" % self.app_version) - - self.set_title(app_name) - self.set_resizable(True) - self.set_default_size(950, 650) - - # get list of kernels from the arch archive website, aur, then cache - self.official_kernels = [] - self.community_kernels = [] - - # splashscreen queue for threading - self.queue_load_progress = fn.Queue() - - # official kernels queue for threading - self.queue_kernels = fn.Queue() - - # community kernels queue for threading - self.queue_community_kernels = fn.Queue() - - hbox_notify_revealer = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=20 - ) - hbox_notify_revealer.set_name("hbox_notify_revealer") - hbox_notify_revealer.set_halign(Gtk.Align.CENTER) - - self.notify_revealer = Gtk.Revealer() - self.notify_revealer.set_reveal_child(False) - self.label_notify_revealer = Gtk.Label(xalign=0, yalign=0) - self.label_notify_revealer.set_name("label_notify_revealer") - - self.notify_revealer.set_child(hbox_notify_revealer) - - hbox_notify_revealer.append(self.label_notify_revealer) - - self.splash_screen = SplashScreen(app_name) - - try: - fn.Thread( - target=self.wait_for_gui_load, - daemon=True, - ).start() - except Exception as e: - fn.logger.error(e) - - while self.default_context.pending(): - fn.time.sleep(0.1) - self.default_context.iteration(True) - - self.bootloader = None - self.bootloader_grub_cfg = None - - # self.bootloader = fn.get_boot_loader() - - config_data = fn.setup_config(self) - - if "bootloader" in config_data.keys(): - if config_data["bootloader"]["name"] is not None: - self.bootloader = config_data["bootloader"]["name"].lower() - - if self.bootloader == "grub": - if config_data["bootloader"]["grub_config"] is not None: - self.bootloader_grub_cfg = config_data["bootloader"][ - "grub_config" - ] - elif self.bootloader != "systemd-boot" or self.bootloader != "grub": - fn.logger.warning( - "Invalid bootloader config found it should only be systemd-boot or grub" - ) - - fn.logger.warning("Using bootctl to determine current bootloader") - self.bootloader = None - - if self.bootloader is not None or self.bootloader_grub_cfg is not None: - fn.logger.info("User provided bootloader options read from config file") - fn.logger.info("User bootloader option = %s " % self.bootloader) - if self.bootloader_grub_cfg is not None: - fn.logger.info( - "User bootloader Grub config = %s " % self.bootloader_grub_cfg - ) - else: - # no config setting found for bootloader use default method - self.bootloader = fn.get_boot_loader() - if self.bootloader == "grub": - self.bootloader_grub_cfg = "/boot/grub/grub.cfg" - - if self.bootloader is not None: - fn.create_cache_dir() - fn.create_log_dir() - fn.get_pacman_repos() - - self.stack = Stack(transition_type="OVER_DOWN") - self.kernel_stack = KernelStack(self) - - header_bar = Gtk.HeaderBar() - - label_title = Gtk.Label(xalign=0.5, yalign=0.5) - label_title.set_markup("%s" % app_name) - - header_bar.set_title_widget(label_title) - header_bar.set_show_title_buttons(True) - - self.set_titlebar(header_bar) - - menu_outerbox = Gtk.Box(spacing=6, orientation=Gtk.Orientation.VERTICAL) - header_bar.pack_end(menu_outerbox) - - menu_outerbox.show() - - menubutton = MenuButton() - - menu_outerbox.append(menubutton) - - menubutton.show() - - action_about = Gio.SimpleAction(name="about") - action_about.connect("activate", self.on_about) - - action_settings = Gio.SimpleAction(name="settings") - action_settings.connect("activate", self.on_settings, fn) - - self.add_action(action_settings) - - self.add_action(action_about) - - action_refresh = Gio.SimpleAction(name="refresh") - action_refresh.connect("activate", self.on_refresh) - - self.add_action(action_refresh) - - action_quit = Gio.SimpleAction(name="quit") - action_quit.connect("activate", self.on_quit) - - self.add_action(action_quit) - - # add shortcut keys - - event_controller_key = Gtk.EventControllerKey.new() - event_controller_key.connect("key-pressed", self.key_pressed) - - self.add_controller(event_controller_key) - - # overlay = Gtk.Overlay() - # self.set_child(child=overlay) - - self.vbox = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=10) - self.vbox.set_name("main") - - self.set_child(child=self.vbox) - - self.vbox.append(self.notify_revealer) - - self.installed_kernels = fn.get_installed_kernels() - - self.active_kernel = fn.get_active_kernel() - - fn.logger.info("Installed kernels = %s" % len(self.installed_kernels)) - - self.refresh_cache = False - - self.refresh_cache = fn.get_latest_kernel_updates(self) - - self.start_get_kernels_threads() - - self.load_kernels_gui() - - # validate bootloader - if self.bootloader_grub_cfg and not os.path.exists( - self.bootloader_grub_cfg - ): - mw = MessageWindow( - title="Grub config file not found", - message=f"The specified Grub config file: {self.bootloader_grub_cfg} does not exist\n" - f"This will cause an issue when updating the bootloader\n" - f"Update the configuration file/use the Advanced Settings to change this\n", - image_path="images/48x48/akm-error.png", - detailed_message=False, - transient_for=self, - ) - - mw.present() - if self.bootloader == "systemd-boot": - if not os.path.exists( - "/sys/firmware/efi/fw_platform_size" - ) or not os.path.exists("/sys/firmware/efi/efivars"): - mw = MessageWindow( - title="Legacy boot detected", - message=f"Cannot select systemd-boot, UEFI boot mode is not available\n" - f"Update the configuration file\n" - f"Or use the Advanced Settings to change this\n", - image_path="images/48x48/akm-warning.png", - detailed_message=False, - transient_for=self, - ) - - mw.present() - - else: - fn.logger.error("Failed to set bootloader, application closing") - fn.sys.exit(1) - - def key_pressed(self, keyval, keycode, state, userdata): - shortcut = Gtk.accelerator_get_label( - keycode, keyval.get_current_event().get_modifier_state() - ) - - # quit application - if shortcut in ("Ctrl+Q", "Ctrl+Mod2+Q"): - self.destroy() - - def open_settings(self, fn): - settings_win = SettingsWindow(fn, self) - settings_win.present() - - def timeout(self): - self.hide_notify() - - def hide_notify(self): - self.notify_revealer.set_reveal_child(False) - if self.timeout_id is not None: - GLib.source_remove(self.timeout_id) - self.timeout_id = None - - def reveal_notify(self): - # reveal = self.notify_revealer.get_reveal_child() - self.notify_revealer.set_reveal_child(True) - self.timeout_id = GLib.timeout_add(3000, self.timeout) - - def start_get_kernels_threads(self): - if self.refresh_cache is False: - fn.logger.info("Starting get official Linux kernels thread") - try: - fn.Thread( - name=fn.thread_get_kernels, - target=fn.get_official_kernels, - daemon=True, - args=(self,), - ).start() - - except Exception as e: - fn.logger.error("Exception in thread fn.get_official_kernels(): %s" % e) - finally: - self.official_kernels = self.queue_kernels.get() - self.queue_kernels.task_done() - - else: - self.official_kernels = self.queue_kernels.get() - self.queue_kernels.task_done() - - fn.logger.info("Starting pacman db synchronization thread") - self.queue_load_progress.put("Starting pacman db synchronization") - - self.pacman_db_sync() - - fn.logger.info("Starting get community kernels thread") - self.queue_load_progress.put("Getting community based Linux kernels") - - try: - thread_get_community_kernels = fn.Thread( - name=fn.thread_get_community_kernels, - target=fn.get_community_kernels, - daemon=True, - args=(self,), - ) - - thread_get_community_kernels.start() - - except Exception as e: - fn.logger.error("Exception in thread_get_community_kernels: %s" % e) - finally: - self.community_kernels = self.queue_community_kernels.get() - self.queue_community_kernels.task_done() - - # ===================================================== - # PACMAN DB SYNC - # ===================================================== - - def pacman_db_sync(self): - sync_err = fn.sync_package_db() - - if sync_err is not None: - fn.logger.error("Pacman db synchronization failed") - - print( - "---------------------------------------------------------------------------" - ) - - GLib.idle_add( - self.show_sync_db_message_dialog, - sync_err, - priority=GLib.PRIORITY_DEFAULT, - ) - - else: - fn.logger.info("Pacman DB synchronization completed") - - def show_sync_db_message_dialog(self, sync_err): - mw = MessageWindow( - title="Error - Pacman db synchronization", - message=f"Pacman db synchronization failed\n" - f"Failed to run 'pacman -Syu'\n" - f"{sync_err}\n", - image_path="images/48x48/akm-warning.png", - transient_for=self, - detailed_message=True, - ) - - mw.present() - - # keep splash screen open, until main gui is loaded - def wait_for_gui_load(self): - while True: - fn.time.sleep(0.2) - status = self.queue_load_progress.get() - if status == 1: - GLib.idle_add( - self.splash_screen.destroy, - priority=GLib.PRIORITY_DEFAULT, - ) - break - - def on_settings(self, action, param, fn): - self.open_settings(fn) - - def on_about(self, action, param): - about_dialog = AboutDialog(self) - about_dialog.present() - - def on_refresh(self, action, param): - if not fn.is_thread_alive(fn.thread_refresh_ui): - fn.Thread( - name=fn.thread_refresh_ui, - target=self.refresh_ui, - daemon=True, - ).start() - - def refresh_ui(self): - fn.logger.debug("Refreshing UI") - - self.label_notify_revealer.set_text("Refreshing UI started") - GLib.idle_add( - self.reveal_notify, - priority=GLib.PRIORITY_DEFAULT, - ) - fn.pacman_repos_list = [] - fn.get_pacman_repos() - - fn.cached_kernels_list = [] - fn.community_kernels_list = [] - - self.official_kernels = None - - self.community_kernels = None - - self.installed_kernels = None - - self.start_get_kernels_threads() - - self.installed_kernels = fn.get_installed_kernels() - - self.label_notify_revealer.set_text("Refreshing official kernels") - GLib.idle_add( - self.reveal_notify, - priority=GLib.PRIORITY_DEFAULT, - ) - - GLib.idle_add( - self.kernel_stack.add_official_kernels_to_stack, - True, - priority=GLib.PRIORITY_DEFAULT, - ) - - self.label_notify_revealer.set_text("Refreshing community kernels") - GLib.idle_add( - self.reveal_notify, - priority=GLib.PRIORITY_DEFAULT, - ) - - GLib.idle_add( - self.kernel_stack.add_community_kernels_to_stack, - True, - priority=GLib.PRIORITY_DEFAULT, - ) - - self.label_notify_revealer.set_text("Refreshing installed kernels") - GLib.idle_add( - self.reveal_notify, - priority=GLib.PRIORITY_DEFAULT, - ) - - GLib.idle_add( - self.kernel_stack.add_installed_kernels_to_stack, - True, - priority=GLib.PRIORITY_DEFAULT, - ) - - while self.default_context.pending(): - fn.time.sleep(0.3) - self.default_context.iteration(False) - - # fn.time.sleep(0.5) - - fn.logger.debug("Refresh UI completed") - - self.label_notify_revealer.set_text("Refreshing UI completed") - GLib.idle_add( - self.reveal_notify, - priority=GLib.PRIORITY_DEFAULT, - ) - - def on_quit(self, action, param): - self.destroy() - fn.logger.info("Application quit") - - def on_button_quit_response(self, widget): - self.destroy() - fn.logger.info("Application quit") - - def load_kernels_gui(self): - hbox_sep = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) - hsep = Gtk.Separator(orientation=Gtk.Orientation.VERTICAL) - hbox_sep.append(hsep) - - # handle error here with message - if self.official_kernels is None: - fn.logger.error("Failed to retrieve kernel list") - - stack_sidebar = Gtk.StackSidebar() - stack_sidebar.set_name("stack_sidebar") - stack_sidebar.set_stack(self.stack) - - hbox_stack_sidebar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) - hbox_stack_sidebar.set_name("hbox_stack_sidebar") - hbox_stack_sidebar.append(stack_sidebar) - hbox_stack_sidebar.append(self.stack) - - self.vbox.append(hbox_stack_sidebar) - - button_quit = Gtk.Button.new_with_label("Quit") - # button_quit.set_size_request(100, 30) - button_quit.connect( - "clicked", - self.on_button_quit_response, - ) - - btn_context = button_quit.get_style_context() - btn_context.add_class("destructive-action") - - grid_bottom_panel = Gtk.Grid() - grid_bottom_panel.set_halign(Gtk.Align.END) - grid_bottom_panel.set_row_homogeneous(True) - - grid_bottom_panel.attach(button_quit, 0, 1, 1, 1) - - self.vbox.append(grid_bottom_panel) - - self.textbuffer = Gtk.TextBuffer() - - self.textview = Gtk.TextView() - self.textview.set_property("editable", False) - self.textview.set_property("monospace", True) - - self.textview.set_vexpand(True) - self.textview.set_hexpand(True) - - self.textview.set_buffer(self.textbuffer) - - fn.logger.info("Creating kernel UI") - - # add official kernel flowbox - - fn.logger.debug("Adding official kernels to UI") - self.kernel_stack.add_official_kernels_to_stack(reload=False) - - fn.logger.debug("Adding community kernels to UI") - self.kernel_stack.add_community_kernels_to_stack(reload=False) - - fn.logger.debug("Adding installed kernels to UI") - self.kernel_stack.add_installed_kernels_to_stack(reload=False) - - while self.default_context.pending(): - self.default_context.iteration(True) - - fn.time.sleep(0.3) - - self.queue_load_progress.put(1) - fn.logger.info("Kernel manager UI loaded") \ No newline at end of file diff --git a/ui/MenuButton.py b/ui/MenuButton.py deleted file mode 100644 index 3d14c58..0000000 --- a/ui/MenuButton.py +++ /dev/null @@ -1,45 +0,0 @@ -import gi - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk - -# Gtk.Builder xml for the application menu -APP_MENU = """ - - - -
- - _About - win.about - - - _Settings - win.settings - - - _Refresh - win.refresh - - - _Quit - win.quit - -
-
-
-""" - - -class MenuButton(Gtk.MenuButton): - """ - Wrapper class for at Gtk.Menubutton with a menu defined - in a Gtk.Builder xml string - """ - - def __init__(self, icon_name="open-menu-symbolic"): - super(MenuButton, self).__init__() - builder = Gtk.Builder.new_from_string(APP_MENU, -1) - menu = builder.get_object("app-menu") - self.set_menu_model(menu) - self.set_icon_name(icon_name) \ No newline at end of file diff --git a/ui/MessageWindow.py b/ui/MessageWindow.py deleted file mode 100644 index 5c57885..0000000 --- a/ui/MessageWindow.py +++ /dev/null @@ -1,95 +0,0 @@ -import gi -import os -import functions as fn - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio, GLib - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - - -class MessageWindow(Gtk.Window): - def __init__(self, title, message, image_path, detailed_message, **kwargs): - super().__init__(**kwargs) - - # self.set_title(title=title) - self.set_modal(modal=True) - self.set_resizable(False) - icon_name = "akm-tux" - self.set_icon_name(icon_name) - - header_bar = Gtk.HeaderBar() - header_bar.set_show_title_buttons(True) - - hbox_title = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) - - label_title = Gtk.Label(xalign=0.5, yalign=0.5) - label_title.set_markup("%s" % title) - - hbox_title.append(label_title) - header_bar.set_title_widget(hbox_title) - - self.set_titlebar(header_bar) - - vbox_message = Gtk.Box.new(orientation=Gtk.Orientation.VERTICAL, spacing=10) - vbox_message.set_name("vbox_flowbox_message") - - image = Gtk.Picture.new_for_filename(os.path.join(base_dir, image_path)) - - image.set_content_fit(content_fit=Gtk.ContentFit.SCALE_DOWN) - image.set_halign(Gtk.Align.START) - - hbox_image = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - - # hbox_image.append(image) - - self.set_child(child=vbox_message) - - if detailed_message is True: - scrolled_window = Gtk.ScrolledWindow() - - textview = Gtk.TextView() - textview.set_property("editable", False) - textview.set_property("monospace", True) - - textview.set_vexpand(True) - textview.set_hexpand(True) - - msg_buffer = textview.get_buffer() - msg_buffer.insert( - msg_buffer.get_end_iter(), - "Event timestamp = %s\n" - % fn.datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), - ) - msg_buffer.insert(msg_buffer.get_end_iter(), "%s\n" % message) - - scrolled_window.set_child(textview) - - hbox_image.append(scrolled_window) - - self.set_size_request(700, 500) - self.set_resizable(True) - else: - label_message = Gtk.Label(xalign=0, yalign=0) - label_message.set_markup("%s" % message) - label_message.set_name("label_flowbox_message") - - hbox_image.append(image) - hbox_image.append(label_message) - - vbox_message.append(hbox_image) - - button_ok = Gtk.Button.new_with_label("OK") - button_ok.set_size_request(100, 30) - button_ok.set_halign(Gtk.Align.END) - button_ok.connect("clicked", self.on_button_ok_clicked) - - hbox_buttons = Gtk.Box.new(orientation=Gtk.Orientation.HORIZONTAL, spacing=20) - hbox_buttons.set_halign(Gtk.Align.END) - hbox_buttons.append(button_ok) - - vbox_message.append(hbox_buttons) - - def on_button_ok_clicked(self, button): - self.hide() - self.destroy() \ No newline at end of file diff --git a/ui/ProgressWindow.py b/ui/ProgressWindow.py deleted file mode 100644 index 315d64d..0000000 --- a/ui/ProgressWindow.py +++ /dev/null @@ -1,632 +0,0 @@ -import sys -import gi -import os -import functions as fn -from ui.MessageWindow import MessageWindow -from gi.repository import Gtk, Gio, GLib - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - - -class ProgressWindow(Gtk.Window): - def __init__( - self, - title, - action, - textview, - textbuffer, - kernel, - switch, - source, - manager_gui, - **kwargs, - ): - super().__init__(**kwargs) - - self.set_title(title=title) - self.set_modal(modal=True) - self.set_resizable(True) - self.set_size_request(700, 400) - self.connect("close-request", self.on_close) - - self.textview = textview - self.textbuffer = textbuffer - - self.kernel_state_queue = fn.Queue() - self.messages_queue = fn.Queue() - self.kernel = kernel - self.timeout_id = None - self.errors_found = False - - self.action = action - self.switch = switch - - self.restore = False - - self.source = source - self.manager_gui = manager_gui - - self.bootloader = self.manager_gui.bootloader - self.bootloader_grub_cfg = self.manager_gui.bootloader_grub_cfg - - vbox_progress = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - vbox_progress.set_name("main") - - self.set_child(child=vbox_progress) - - header_bar = Gtk.HeaderBar() - self.label_title = Gtk.Label(xalign=0.5, yalign=0.5) - - header_bar.set_show_title_buttons(True) - - self.set_titlebar(header_bar) - - self.label_title.set_markup("%s" % title) - header_bar.set_title_widget(self.label_title) - - vbox_icon_settings = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - vbox_icon_settings.set_name("vbox_icon_settings") - - lbl_heading = Gtk.Label(xalign=0.5, yalign=0.5) - lbl_heading.set_name("label_flowbox_message") - - lbl_padding = Gtk.Label(xalign=0.0, yalign=0.0) - lbl_padding.set_text(" ") - - grid_banner_img = Gtk.Grid() - - image_settings = None - - if action == "install": - image_settings = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-install.png") - ) - lbl_heading.set_markup( - "Installing %s version %s " - % (self.kernel.name, self.kernel.version) - ) - if action == "uninstall": - image_settings = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-remove.png") - ) - lbl_heading.set_markup( - "Removing %s version %s " - % (self.kernel.name, self.kernel.version) - ) - - # get kernel version from pacman - self.installed_kernel_version = fn.get_kernel_version(self.kernel.name) - - if self.installed_kernel_version is not None: - fn.logger.debug( - "Installed kernel version = %s" % self.installed_kernel_version - ) - else: - fn.logger.debug("Nothing to remove .. previous kernel not installed") - - image_settings.set_halign(Gtk.Align.START) - image_settings.set_icon_size(Gtk.IconSize.LARGE) - - hbox_header = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbox_header.set_name("vbox_header") - - hbox_header.append(image_settings) - hbox_header.append(lbl_heading) - - vbox_progress.append(hbox_header) - - self.spinner = Gtk.Spinner() - self.spinner.set_spinning(True) - - image_warning = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-warning.png") - ) - - image_warning.set_icon_size(Gtk.IconSize.LARGE) - image_warning.set_halign(Gtk.Align.START) - - hbox_progress_warning = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=5 - ) - hbox_progress_warning.set_name("hbox_warning") - - hbox_progress_warning.append(image_warning) - - self.label_progress_window_desc = Gtk.Label(xalign=0, yalign=0) - - self.label_progress_window_desc.set_markup( - f"Do not close this window while a kernel {self.action} activity is in progress\n" - f"Progress can be monitored in the log below\n" - f"A reboot is recommended when Linux packages have changed" - ) - - hbox_progress_warning.append(self.label_progress_window_desc) - - self.label_status = Gtk.Label(xalign=0, yalign=0) - - button_close = Gtk.Button.new_with_label("Close") - button_close.set_size_request(100, 30) - button_close.set_halign(Gtk.Align.END) - - button_close.connect( - "clicked", - self.on_button_close_response, - ) - - self.label_spinner_progress = Gtk.Label(xalign=0, yalign=0) - if self.action == "install": - self.label_spinner_progress.set_markup( - "Please wait kernel %s is in progress" % "installation" - ) - elif self.action == "uninstall": - self.label_spinner_progress.set_markup( - "Please wait kernel %s is in progress" % "removal" - ) - - self.hbox_spinner = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - self.hbox_spinner.append(self.label_spinner_progress) - self.hbox_spinner.append(self.spinner) - - vbox_padding = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20) - vbox_padding.set_valign(Gtk.Align.END) - - label_padding = Gtk.Label(xalign=0, yalign=0) - label_padding.set_valign(Gtk.Align.END) - vbox_padding.append(label_padding) - - hbox_button_close = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=20) - - hbox_button_close.append(button_close) - hbox_button_close.set_halign(Gtk.Align.END) - - self.scrolled_window = Gtk.ScrolledWindow() - self.scrolled_window.set_propagate_natural_height(True) - self.scrolled_window.set_propagate_natural_width(True) - self.scrolled_window.set_policy( - Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC - ) - - hbox_notify_revealer = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=20 - ) - - hbox_notify_revealer.set_name("hbox_notify_revealer") - hbox_notify_revealer.set_halign(Gtk.Align.CENTER) - - self.notify_revealer = Gtk.Revealer() - self.notify_revealer.set_reveal_child(False) - self.label_notify_revealer = Gtk.Label(xalign=0, yalign=0) - self.label_notify_revealer.set_name("label_notify_revealer") - - self.notify_revealer.set_child(hbox_notify_revealer) - - hbox_notify_revealer.append(self.label_notify_revealer) - - if self.textview.get_buffer() is not None: - self.textview = Gtk.TextView() - self.textview.set_property("editable", False) - self.textview.set_property("monospace", True) - - self.textview.set_vexpand(True) - self.textview.set_hexpand(True) - - self.textview.set_buffer(self.textbuffer) - self.scrolled_window.set_child(self.textview) - - self.scrolled_window.set_size_request(300, 300) - - vbox_progress.append(hbox_progress_warning) - vbox_progress.append(self.notify_revealer) - vbox_progress.append(self.scrolled_window) - vbox_progress.append(self.hbox_spinner) - vbox_progress.append(self.label_status) - vbox_progress.append(vbox_padding) - vbox_progress.append(hbox_button_close) - - self.present() - - self.linux_headers = None - - if ( - self.source == "official" - and action == "install" - or action == "uninstall" - and self.source == "official" - ): - if kernel.name == "linux": - self.linux_headers = "linux-headers" - if kernel.name == "linux-rt": - self.linux_headers = "linux-rt-headers" - if kernel.name == "linux-rt-lts": - self.linux_headers = "linux-rt-lts-headers" - if kernel.name == "linux-hardened": - self.linux_headers = "linux-hardened-headers" - if kernel.name == "linux-zen": - self.linux_headers = "linux-zen-headers" - if kernel.name == "linux-lts": - self.linux_headers = "linux-lts-headers" - - self.official_kernels = [ - "%s/packages/l/%s/%s-x86_64%s" - % ( - fn.archlinux_mirror_archive_url, - kernel.name, - kernel.version, - kernel.file_format, - ), - "%s/packages/l/%s/%s-x86_64%s" - % ( - fn.archlinux_mirror_archive_url, - self.linux_headers, - kernel.headers, - kernel.file_format, - ), - ] - - # in the event an install goes wrong, fallback and reinstall previous kernel - - if self.source == "official": - self.restore_kernel = None - - for inst_kernel in fn.get_installed_kernels(): - if inst_kernel.name == self.kernel.name: - - self.restore_kernel = inst_kernel - break - - if self.restore_kernel: - fn.logger.info("Restore kernel = %s" % self.restore_kernel.name) - fn.logger.info( - "Restore kernel version = %s" % self.restore_kernel.version - ) - else: - fn.logger.info("No previous %s kernel installed" % self.kernel.name) - else: - fn.logger.info("Community kernel, no kernel restore available") - - if fn.check_pacman_lockfile() is False: - th_monitor_messages_queue = fn.threading.Thread( - name=fn.thread_monitor_messages, - target=fn.monitor_messages_queue, - daemon=True, - args=(self,), - ) - - th_monitor_messages_queue.start() - - if fn.is_thread_alive(fn.thread_monitor_messages): - self.textbuffer.delete( - self.textbuffer.get_start_iter(), self.textbuffer.get_end_iter() - ) - - if not fn.is_thread_alive(fn.thread_check_kernel_state): - th_check_kernel_state = fn.threading.Thread( - name=fn.thread_check_kernel_state, - target=self.check_kernel_state, - daemon=True, - ) - th_check_kernel_state.start() - - if action == "install" and self.source == "community": - self.label_notify_revealer.set_text( - "Installing from %s" % kernel.repository - ) - self.reveal_notify() - event = ( - "%s [INFO]: Installing kernel from repository %s, kernel = %s-%s\n" - % ( - fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.repository, - self.kernel.name, - self.kernel.version, - ) - ) - self.messages_queue.put(event) - - if not fn.is_thread_alive(fn.thread_install_community_kernel): - th_install_ch = fn.threading.Thread( - name=fn.thread_install_community_kernel, - target=fn.install_community_kernel, - args=(self,), - daemon=True, - ) - - th_install_ch.start() - - if action == "install" and self.source == "official": - self.label_notify_revealer.set_text("Installing kernel packages ...") - - self.reveal_notify() - - event = "%s [INFO]: Installing kernel = %s | version = %s\n" % ( - fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - self.kernel.version, - ) - self.messages_queue.put(event) - - if not fn.is_thread_alive(fn.thread_install_archive_kernel): - th_install = fn.threading.Thread( - name=fn.thread_install_archive_kernel, - target=fn.install_archive_kernel, - args=(self,), - daemon=True, - ) - - th_install.start() - - if action == "uninstall": - if fn.check_pacman_lockfile() is False: - self.label_notify_revealer.set_text("Removing kernel packages ...") - self.reveal_notify() - - event = "%s [INFO]: Uninstalling kernel %s %s\n" % ( - fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.name, - self.kernel.version, - ) - self.messages_queue.put(event) - - if not fn.is_thread_alive(fn.thread_uninstall_kernel): - th_uninstall_kernel = fn.threading.Thread( - name=fn.thread_uninstall_kernel, - target=self.uninstall_kernel, - daemon=True, - ) - - th_uninstall_kernel.start() - else: - self.label_notify_revealer.set_text( - "Pacman lockfile found cannot continue ..." - ) - - self.reveal_notify() - - fn.logger.error( - "Pacman lockfile found, is another pacman process running ?" - ) - - def timeout(self): - self.hide_notify() - - def hide_notify(self): - self.notify_revealer.set_reveal_child(False) - if self.timeout_id is not None: - GLib.source_remove(self.timeout_id) - self.timeout_id = None - - def reveal_notify(self): - # reveal = self.notify_revealer.get_reveal_child() - self.notify_revealer.set_reveal_child(True) - self.timeout_id = GLib.timeout_add(3000, self.timeout) - - def on_button_close_response(self, widget): - if fn.check_pacman_process(self): - mw = MessageWindow( - title="Pacman process running", - message="Pacman is busy processing a transaction .. please wait", - image_path="images/48x48/akm-progress.png", - transient_for=self, - detailed_message=False, - ) - - mw.present() - else: - self.destroy() - - def on_close(self, data): - if fn.check_pacman_process(self): - mw = MessageWindow( - title="Pacman process running", - message="Pacman is busy processing a transaction .. please wait", - image_path="images/48x48/akm-progress.png", - transient_for=self, - detailed_message=False, - ) - - mw.present() - - return True - return False - - def check_kernel_state(self): - returncode = None - kernel = None - while True: - items = self.kernel_state_queue.get() - - try: - if items is not None: - returncode, action, kernel = items - - if returncode == 0: - self.label_notify_revealer.set_text( - "Kernel %s completed" % action - ) - self.reveal_notify() - - fn.logger.info("Kernel %s completed" % action) - - if returncode == 1: - self.errors_found = True - - self.label_notify_revealer.set_text("Kernel %s failed" % action) - self.reveal_notify() - - fn.logger.error("Kernel %s failed" % action) - - event = "%s [ERROR]: Kernel %s failed\n" % ( - fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - action, - ) - self.messages_queue.put(event) - - self.label_status.set_markup( - "Kernel %s failed - see logs above" - % action - ) - - # undo action here if action == install - - event = ( - "%s [INFO]: Attempting to undo previous Linux package changes\n" - % ( - fn.datetime.datetime.now().strftime( - "%Y-%m-%d-%H-%M-%S" - ), - ) - ) - - self.messages_queue.put(event) - - if action == "install" and self.restore_kernel is not None: - self.restore = True - fn.logger.info( - "Installation failed, attempting removal of previous Linux package changes" - ) - self.set_title("Kernel installation failed") - - self.label_spinner_progress.set_markup( - "Please wait restoring kernel %s" - % self.restore_kernel.version - ) - - fn.uninstall(self) - - fn.logger.info( - "Restoring previously installed kernel %s" - % self.restore_kernel.version - ) - - self.official_kernels = [ - "%s/packages/l/%s/%s-%s-x86_64%s" - % ( - fn.archlinux_mirror_archive_url, - self.restore_kernel.name, - self.restore_kernel.name, - self.restore_kernel.version, - ".pkg.tar.zst", - ), - "%s/packages/l/%s/%s-%s-x86_64%s" - % ( - fn.archlinux_mirror_archive_url, - self.linux_headers, - self.linux_headers, - self.restore_kernel.version, - ".pkg.tar.zst", - ), - ] - self.errors_found = False - fn.install_archive_kernel(self) - self.set_title("Kernel installation failed") - self.label_status.set_markup( - f"Kernel %s failed - see logs above\n" - % action - ) - - # self.spinner.set_spinning(False) - # self.hbox_spinner.hide() - # - # self.label_progress_window_desc.set_markup( - # f"This window can be now closed\n" - # f"A reboot is recommended when Linux packages have changed" - # ) - - # break - else: - if ( - returncode == 0 - and "-headers" in kernel - or action == "uninstall" - or action == "install" - and self.errors_found is False - ): - - fn.update_bootloader(self) - self.update_installed_list() - self.update_official_list() - - if len(self.manager_gui.community_kernels) > 0: - self.update_community_list() - - if self.restore == False: - self.label_title.set_markup( - "Kernel %s completed" % action - ) - - self.label_status.set_markup( - "Kernel %s completed" - % action - ) - - self.spinner.set_spinning(False) - self.hbox_spinner.hide() - - self.label_progress_window_desc.set_markup( - f"This window can be now closed\n" - f"A reboot is recommended when Linux packages have changed" - ) - else: - self.label_title.set_markup( - "Kernel %s failed" % action - ) - - self.label_status.set_markup( - "Kernel %s failed" - % action - ) - - self.spinner.set_spinning(False) - self.hbox_spinner.hide() - - self.label_progress_window_desc.set_markup( - f"This window can be now closed\n" - f"Previous kernel restored due to failure\n" - f"A reboot is recommended when Linux packages have changed" - ) - - # # else: - # self.spinner.set_spinning(False) - # self.hbox_spinner.hide() - # - # self.label_progress_window_desc.set_markup( - # f"This window can be now closed\n" - # f"A reboot is recommended when Linux packages have changed" - # ) - - break - except Exception as e: - fn.logger.error("Exception in check_kernel_state(): %s" % e) - - finally: - self.kernel_state_queue.task_done() - - def update_installed_list(self): - self.manager_gui.installed_kernels = fn.get_installed_kernels() - GLib.idle_add( - self.manager_gui.kernel_stack.add_installed_kernels_to_stack, True - ) - - def update_official_list(self): - self.manager_gui.installed_kernels = fn.get_installed_kernels() - GLib.idle_add( - self.manager_gui.kernel_stack.add_official_kernels_to_stack, - True, - ) - - def update_community_list(self): - self.manager_gui.installed_kernels = fn.get_installed_kernels() - GLib.idle_add( - self.manager_gui.kernel_stack.add_community_kernels_to_stack, - True, - ) - - def uninstall_kernel(self): - event = "%s [INFO]: Uninstalling kernel %s\n" % ( - fn.datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), - self.kernel.version, - ) - - self.messages_queue.put(event) - - fn.uninstall(self) \ No newline at end of file diff --git a/ui/SettingsWindow.py b/ui/SettingsWindow.py deleted file mode 100644 index de6ecc9..0000000 --- a/ui/SettingsWindow.py +++ /dev/null @@ -1,715 +0,0 @@ -import gi -import os -from ui.Stack import Stack -from ui.MessageWindow import MessageWindow -import functions as fn - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio, GLib, GObject - -base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) - - -class SettingsWindow(Gtk.Window): - def __init__(self, fn, manager_gui, **kwargs): - super().__init__(**kwargs) - - self.set_title("Arch Linux Kernel Manager - Settings") - self.set_resizable(False) - self.set_size_request(600, 600) - stack = Stack(transition_type="CROSSFADE") - - self.set_icon_name("akm-tux") - self.manager_gui = manager_gui - self.set_modal(True) - self.set_transient_for(self.manager_gui) - - self.queue_kernels = self.manager_gui.queue_kernels - - header_bar = Gtk.HeaderBar() - - header_bar.set_show_title_buttons(True) - - self.set_titlebar(header_bar) - - hbox_main = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - hbox_main.set_name("box") - self.set_child(child=hbox_main) - - vbox_header = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - vbox_header.set_name("vbox_header") - - lbl_heading = Gtk.Label(xalign=0.5, yalign=0.5) - lbl_heading.set_name("label_flowbox_message") - lbl_heading.set_text("Preferences") - - lbl_padding = Gtk.Label(xalign=0.0, yalign=0.0) - lbl_padding.set_text(" ") - - grid_banner_img = Gtk.Grid() - - image_settings = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-settings.png") - ) - - image_settings.set_icon_size(Gtk.IconSize.LARGE) - image_settings.set_halign(Gtk.Align.START) - - grid_banner_img.attach(image_settings, 0, 1, 1, 1) - grid_banner_img.attach_next_to( - lbl_padding, - image_settings, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - grid_banner_img.attach_next_to( - lbl_heading, - lbl_padding, - Gtk.PositionType.RIGHT, - 1, - 1, - ) - - vbox_header.append(grid_banner_img) - - hbox_main.append(vbox_header) - - stack_switcher = Gtk.StackSwitcher() - stack_switcher.set_orientation(Gtk.Orientation.HORIZONTAL) - stack_switcher.set_stack(stack) - - button_close = Gtk.Button(label="Close") - button_close.connect("clicked", self.on_close_clicked) - - hbox_stack_sidebar = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) - hbox_stack_sidebar.set_name("box") - - hbox_stack_sidebar.append(stack_switcher) - hbox_stack_sidebar.append(stack) - - hbox_main.append(hbox_stack_sidebar) - - vbox_button = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) - vbox_button.set_halign(Gtk.Align.END) - vbox_button.set_name("box") - - vbox_button.append(button_close) - - hbox_stack_sidebar.append(vbox_button) - - vbox_settings = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - vbox_settings.set_name("box") - - label_official_kernels = Gtk.Label(xalign=0, yalign=0) - label_official_kernels.set_markup( - "Latest Official kernels (%s)" % len(fn.supported_kernels_dict) - ) - - label_community_kernels = Gtk.Label(xalign=0, yalign=0) - label_community_kernels.set_markup( - "Latest Community based kernels (%s)" - % len(self.manager_gui.community_kernels) - ) - - vbox_settings_listbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - - self.listbox_official_kernels = Gtk.ListBox() - self.listbox_official_kernels.set_selection_mode(Gtk.SelectionMode.NONE) - - self.label_loading_kernels = Gtk.Label(xalign=0, yalign=0) - self.label_loading_kernels.set_text("Loading ...") - - self.listbox_official_kernels.append(self.label_loading_kernels) - - listbox_community_kernels = Gtk.ListBox() - listbox_community_kernels.set_selection_mode(Gtk.SelectionMode.NONE) - - scrolled_window_community = Gtk.ScrolledWindow() - scrolled_window_official = Gtk.ScrolledWindow() - - scrolled_window_community.set_policy( - Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC - ) - - scrolled_window_official.set_policy( - Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC - ) - - scrolled_window_community.set_size_request(0, 150) - scrolled_window_official.set_size_request(0, 150) - - scrolled_window_official.set_child(self.listbox_official_kernels) - vbox_community_warning = None - - self.kernel_versions_queue = fn.Queue() - fn.Thread( - target=fn.get_latest_versions, - args=(self,), - daemon=True, - ).start() - - fn.Thread(target=self.check_official_version_queue, daemon=True).start() - - if len(self.manager_gui.community_kernels) > 0: - for community_kernel in self.manager_gui.community_kernels: - row_community_kernel = Gtk.ListBoxRow() - hbox_community_kernel = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=5 - ) - hbox_community_kernel.set_name("box_row") - - hbox_row_official_kernel_row = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=10 - ) - - label_community_kernel = Gtk.Label(xalign=0, yalign=0) - label_community_kernel.set_text("%s" % community_kernel.name) - - label_community_kernel_version = Gtk.Label(xalign=0, yalign=0) - label_community_kernel_version.set_text("%s" % community_kernel.version) - - hbox_row_official_kernel_row.append(label_community_kernel) - hbox_row_official_kernel_row.append(label_community_kernel_version) - - hbox_community_kernel.append(hbox_row_official_kernel_row) - - row_community_kernel.set_child(hbox_community_kernel) - listbox_community_kernels.append(row_community_kernel) - scrolled_window_community.set_child(listbox_community_kernels) - else: - vbox_community_warning = Gtk.Box( - orientation=Gtk.Orientation.VERTICAL, spacing=10 - ) - vbox_community_warning.set_name("box") - - image_warning = Gtk.Image.new_from_file( - os.path.join(base_dir, "images/48x48/akm-warning.png") - ) - - image_warning.set_icon_size(Gtk.IconSize.LARGE) - image_warning.set_halign(Gtk.Align.START) - - hbox_warning = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbox_warning.set_name("box") - - hbox_warning.append(image_warning) - - label_pacman_no_community = Gtk.Label(xalign=0, yalign=0) - label_pacman_no_community.set_markup( - f"Cannot find any supported unofficial pacman repository's\n" - f"Add unofficial pacman repository's to use community based kernels" - ) - - hbox_warning.append(label_pacman_no_community) - - vbox_community_warning.append(hbox_warning) - - vbox_settings_listbox.append(label_official_kernels) - vbox_settings_listbox.append(scrolled_window_official) - vbox_settings_listbox.append(label_community_kernels) - - if len(self.manager_gui.community_kernels) > 0: - vbox_settings_listbox.append(scrolled_window_community) - else: - vbox_settings_listbox.append(vbox_community_warning) - - vbox_settings.append(vbox_settings_listbox) - - vbox_settings_adv = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - - vbox_settings_adv.set_name("box") - - self.listbox_settings_adv = Gtk.ListBox() - self.listbox_settings_adv.set_selection_mode(Gtk.SelectionMode.NONE) - - row_settings_adv = Gtk.ListBoxRow() - self.listbox_settings_adv.append(row_settings_adv) - - hbox_bootloader_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbox_bootloader_row.set_name("box_row") - hbox_bootloader_row.set_halign(Gtk.Align.START) - - self.hbox_bootloader_grub_row = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=5 - ) - self.hbox_bootloader_grub_row.set_name("box_row") - self.hbox_bootloader_grub_row.set_halign(Gtk.Align.START) - - self.text_entry_bootloader_file = Gtk.Entry() - - hbox_switch_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbox_switch_row.set_name("box_row") - hbox_switch_row.set_halign(Gtk.Align.START) - - hbox_log_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbox_log_row.set_name("box_row") - hbox_log_row.set_halign(Gtk.Align.START) - - label_bootloader = Gtk.Label(xalign=0, yalign=0) - label_bootloader.set_markup("Bootloader") - - hbox_warning = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5) - hbox_warning.set_name("hbox_warning") - - label_bootloader_warning = Gtk.Label(xalign=0, yalign=0) - label_bootloader_warning.set_markup( - f"Only change this setting if you know what you are doing\n" - f"The selected Grub/Systemd-boot bootloader entry will be updated\n" - f"This may break your system" - ) - - hbox_warning.append(label_bootloader_warning) - - label_settings_bootloader_title = Gtk.Label(xalign=0.5, yalign=0.5) - label_settings_bootloader_title.set_markup("Current Bootloader") - - self.label_settings_bootloader_file = Gtk.Label(xalign=0.5, yalign=0.5) - self.label_settings_bootloader_file.set_text("GRUB config file") - - self.button_override_bootloader = Gtk.Button( - label="Override bootloader settings" - ) - self.button_override_bootloader.connect("clicked", self.on_override_clicked) - self.hbox_bootloader_override_row = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=20 - ) - self.hbox_bootloader_override_row.set_name("box_row") - self.hbox_bootloader_override_row.append(self.button_override_bootloader) - - boot_loaders = {0: "grub", 1: "systemd-boot"} - - # Set up the factory - factory = Gtk.SignalListItemFactory() - factory.connect("setup", self._on_factory_setup) - factory.connect("bind", self._on_factory_bind) - - self.model = Gio.ListStore(item_type=Bootloader) - for bootloader_id in boot_loaders.keys(): - self.model.append( - Bootloader( - id=bootloader_id, - name=boot_loaders[bootloader_id], - ) - ) - - self.dropdown_bootloader = Gtk.DropDown( - model=self.model, factory=factory, hexpand=True - ) - - self.dropdown_bootloader.set_sensitive(False) - - self.selected_bootloader = None - - self._bootloader_grub_config = "/boot/grub/grub.cfg" - - row_settings_override_grub = Gtk.ListBoxRow() - row_settings_grub = Gtk.ListBoxRow() - self.listbox_settings_adv.append(row_settings_grub) - - self.listbox_settings_adv.append(row_settings_override_grub) - - self.text_entry_bootloader_file.connect("changed", self.on_entry_changed) - self.text_entry_bootloader_file.props.editable = False - text_entry_buffer_file = Gtk.EntryBuffer() - - if self.manager_gui.bootloader_grub_cfg is not None: - text_entry_buffer_file.set_text( - self.manager_gui.bootloader_grub_cfg, - len(self.manager_gui.bootloader_grub_cfg), - ) - else: - text_entry_buffer_file.set_text( - self._bootloader_grub_config, - len(self._bootloader_grub_config), - ) - - self.text_entry_bootloader_file.set_buffer(text_entry_buffer_file) - self.text_entry_bootloader_file.set_halign(Gtk.Align.END) - self.text_entry_bootloader_file.set_sensitive(False) - - label_grub_file_path = Gtk.Label(xalign=0.5, yalign=0.5) - label_grub_file_path.set_markup("Grub file path") - - self.hbox_bootloader_grub_row.append(label_grub_file_path) - self.hbox_bootloader_grub_row.append(self.text_entry_bootloader_file) - - row_settings_grub.set_child(self.hbox_bootloader_grub_row) - - if manager_gui.bootloader == "grub": - self.dropdown_bootloader.set_selected(0) - self.selected_bootloader = 0 - self.hbox_bootloader_grub_row.set_visible(True) - - row_settings_override_grub.set_child(self.hbox_bootloader_override_row) - - if manager_gui.bootloader == "systemd-boot": - - self.selected_bootloader = 1 - - self.dropdown_bootloader.set_selected(1) - row_settings_override_systemd = Gtk.ListBoxRow() - self.listbox_settings_adv.append(row_settings_override_systemd) - row_settings_override_systemd.set_child(self.hbox_bootloader_override_row) - - self.hbox_bootloader_grub_row.set_visible(False) - - self.dropdown_bootloader.connect( - "notify::selected-item", self._on_selected_item_notify - ) - - hbox_bootloader_row.append(label_settings_bootloader_title) - hbox_bootloader_row.append(self.dropdown_bootloader) - - row_settings_adv.set_child(hbox_bootloader_row) - - vbox_settings_adv.append(label_bootloader) - vbox_settings_adv.append(hbox_warning) - vbox_settings_adv.append(self.listbox_settings_adv) - - listbox_settings_cache = Gtk.ListBox() - listbox_settings_cache.set_selection_mode(Gtk.SelectionMode.NONE) - - row_settings_cache = Gtk.ListBoxRow() - listbox_settings_cache.append(row_settings_cache) - - label_cache = Gtk.Label(xalign=0, yalign=0) - label_cache.set_markup("Refresh data from Arch Linux Archive") - - label_cache_update = Gtk.Label(xalign=0.5, yalign=0.5) - label_cache_update.set_text("Update (this will take some time)") - - self.label_cache_update_status = Gtk.Label(xalign=0.5, yalign=0.5) - - switch_refresh_cache = Gtk.Switch() - switch_refresh_cache.connect("state-set", self.refresh_toggle) - - label_cache_file = Gtk.Label(xalign=0, yalign=0) - label_cache_file.set_text(fn.cache_file) - label_cache_file.set_selectable(True) - - self.label_cache_lastmodified = Gtk.Label(xalign=0, yalign=0) - self.label_cache_lastmodified.set_markup( - "Last modified date: %s" % fn.get_cache_last_modified() - ) - - hbox_switch_row.append(label_cache_update) - hbox_switch_row.append(switch_refresh_cache) - hbox_switch_row.append(self.label_cache_update_status) - - row_settings_cache.set_child(hbox_switch_row) - - label_logfile = Gtk.Label(xalign=0, yalign=0) - label_logfile.set_markup("Log file") - - button_logfile = Gtk.Button(label="Open event log file") - button_logfile.connect("clicked", self.on_button_logfile_clicked) - - label_logfile_location = Gtk.Label(xalign=0.5, yalign=0.5) - label_logfile_location.set_text(fn.event_log_file) - label_logfile_location.set_selectable(True) - hbox_log_row.append(button_logfile) - hbox_log_row.append(label_logfile_location) - - listbox_settings_log = Gtk.ListBox() - listbox_settings_log.set_selection_mode(Gtk.SelectionMode.NONE) - - row_settings_log = Gtk.ListBoxRow() - listbox_settings_log.append(row_settings_log) - - row_settings_log.set_child(hbox_log_row) - - vbox_settings_adv.append(label_cache) - vbox_settings_adv.append(self.label_cache_lastmodified) - vbox_settings_adv.append(label_cache_file) - vbox_settings_adv.append(listbox_settings_cache) - vbox_settings_adv.append(label_logfile) - vbox_settings_adv.append(listbox_settings_log) - - stack.add_titled(vbox_settings_adv, "Advanced Settings", "Advanced") - stack.add_titled(vbox_settings, "Kernels", "Kernel versions") - - def populate_official_kernels(self): - self.label_loading_kernels.hide() - for official_kernel in fn.supported_kernels_dict: - row_official_kernel = Gtk.ListBoxRow() - hbox_row_official = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=5) - - hbox_row_official_kernel_row = Gtk.Box( - orientation=Gtk.Orientation.HORIZONTAL, spacing=10 - ) - - hbox_row_official.set_name("box_row") - - label_kernel = Gtk.Label(xalign=0, yalign=0) - label_kernel.set_text("%s" % official_kernel) - - label_kernel_version = Gtk.Label(xalign=0, yalign=0) - label_kernel_version.set_text("%s" % self.kernel_versions[official_kernel]) - - hbox_row_official_kernel_row.append(label_kernel) - hbox_row_official_kernel_row.append(label_kernel_version) - - hbox_row_official.append(hbox_row_official_kernel_row) - - row_official_kernel.set_child(hbox_row_official) - - self.listbox_official_kernels.append(row_official_kernel) - - def check_official_version_queue(self): - while True: - self.kernel_versions = self.kernel_versions_queue.get() - - if self.kernel_versions is not None: - break - - self.kernel_versions_queue.task_done() - - GLib.idle_add(self.populate_official_kernels, priority=GLib.PRIORITY_DEFAULT) - - def on_entry_changed(self, entry): - if ( - len(entry.get_text()) > 0 - and entry.get_text() != self.manager_gui.bootloader_grub_cfg - ): - self.button_override_bootloader.get_child().set_text("Apply changes") - - def _on_factory_setup(self, factory, list_item): - label = Gtk.Label() - list_item.set_child(label) - - def _on_factory_bind(self, factory, list_item): - label = list_item.get_child() - bootloader = list_item.get_item() - label.set_text(bootloader.name) - - def on_override_clicked(self, widget): - if self.button_override_bootloader.get_child().get_text() == "Apply changes": - # validate bootloader - if self.dropdown_bootloader.get_selected() == 1: - if not os.path.exists( - "/sys/firmware/efi/fw_platform_size" - ) or not os.path.exists("/sys/firmware/efi/efivars"): - mw = MessageWindow( - title="Legacy boot detected", - message="Cannot select systemd-boot, UEFI boot mode is not available", - image_path="images/48x48/akm-warning.png", - transient_for=self, - detailed_message=False, - ) - - mw.present() - self.dropdown_bootloader.set_selected(0) - return - - config_data = fn.read_config(self) - - if config_data is not None: - # grub - - if ( - self.dropdown_bootloader.get_selected() == 0 - and len( - self.text_entry_bootloader_file.get_buffer().get_text().strip() - ) - > 0 - ): - if fn.os.path.exists( - self.text_entry_bootloader_file.get_buffer().get_text().strip() - ): - if "bootloader" in config_data.keys(): - config_data.remove("bootloader") - - bootloader = fn.tomlkit.table(True) - bootloader.update({"name": "grub"}) - bootloader.update( - { - "grub_config": self.text_entry_bootloader_file.get_buffer() - .get_text() - .strip() - } - ) - - config_data.append("bootloader", bootloader) - - if fn.update_config(config_data, "grub") is True: - self.manager_gui.bootloader = "grub" - self.manager_gui.bootloader_grub_cfg = ( - self.text_entry_bootloader_file.get_buffer() - .get_text() - .strip() - ) - else: - mw = MessageWindow( - title="Grub config file", - message="The specified Grub config file %s does not exist" - % self.text_entry_bootloader_file.get_buffer() - .get_text() - .strip(), - image_path="images/48x48/akm-warning.png", - transient_for=self, - detailed_message=False, - ) - - mw.present() - self.button_override_bootloader.get_child().set_text( - "Override bootloader settings" - ) - - elif ( - self.dropdown_bootloader.get_selected() == 1 - and self.selected_bootloader - != self.dropdown_bootloader.get_selected() - ): - if "bootloader" in config_data.keys(): - config_data.remove("bootloader") - - self.hbox_bootloader_grub_row.set_visible(True) - - bootloader = fn.tomlkit.table(True) - bootloader.update({"name": "systemd-boot"}) - - config_data.append("bootloader", bootloader) - - if fn.update_config(config_data, "systemd-boot") is True: - self.manager_gui.bootloader = "systemd-boot" - - else: - self.dropdown_bootloader.set_sensitive(True) - - if self.dropdown_bootloader.get_selected() == 0: - self.hbox_bootloader_grub_row.set_visible(True) - self.text_entry_bootloader_file.set_sensitive(True) - self.text_entry_bootloader_file.props.editable = True - elif self.dropdown_bootloader.get_selected() == 1: - self.hbox_bootloader_grub_row.set_visible(False) - - def _on_selected_item_notify(self, dd, _): - if self.dropdown_bootloader.get_selected() != self.selected_bootloader: - self.button_override_bootloader.get_child().set_text("Apply changes") - else: - self.button_override_bootloader.get_child().set_text( - "Override bootloader settings" - ) - if dd.get_selected() == 1: - if self.text_entry_bootloader_file is not None: - self.hbox_bootloader_grub_row.set_visible(False) - elif dd.get_selected() == 0: - if self.text_entry_bootloader_file is not None: - self.hbox_bootloader_grub_row.set_visible(True) - self.text_entry_bootloader_file.set_sensitive(True) - self.text_entry_bootloader_file.props.editable = True - - def monitor_kernels_queue(self, switch): - while True: - if len(fn.fetched_kernels_dict) > 0: - self.manager_gui.official_kernels = self.queue_kernels.get() - self.queue_kernels.task_done() - self.refreshed = True - if self.manager_gui.official_kernels is not None: - switch.set_sensitive(False) - self.update_official_list() - self.update_community_list() - self.update_timestamp() - self.label_cache_update_status.set_markup( - "Cache refresh completed" - ) - else: - self.label_cache_update_status.set_markup( - "Cache refresh failed" - ) - self.refreshed = False - self.update_timestamp() - break - else: - self.label_cache_update_status.set_markup( - "Cache refresh in progress" - ) - # fn.time.sleep(0.3) - - def refresh_toggle(self, switch, data): - if switch.get_active() is True: - # refresh cache - fn.logger.info("Refreshing cache file %s" % fn.cache_file) - switch.set_sensitive(False) - - try: - th_refresh_cache = fn.Thread( - name=fn.thread_refresh_cache, - target=fn.refresh_cache, - args=(self,), - daemon=True, - ) - - th_refresh_cache.start() - - # monitor queue - fn.Thread( - target=self.monitor_kernels_queue, daemon=True, args=(switch,) - ).start() - - except Exception as e: - fn.logger.error("Exception in refresh_toggle(): %s" % e) - self.label_cache_update_status.set_markup("Cache refresh failed") - - def update_timestamp(self): - if self.refreshed is True: - self.label_cache_lastmodified.set_markup( - "Last modified date: %s" - % fn.get_cache_last_modified() - ) - else: - self.label_cache_lastmodified.set_markup( - "Last modified date: %s" - % "Refresh failed" - ) - - def update_official_list(self): - self.manager_gui.installed_kernels = fn.get_installed_kernels() - GLib.idle_add( - self.manager_gui.kernel_stack.add_official_kernels_to_stack, - True, - ) - - def update_community_list(self): - self.manager_gui.installed_kernels = fn.get_installed_kernels() - - GLib.idle_add( - self.manager_gui.kernel_stack.add_community_kernels_to_stack, - True, - ) - - def on_close_clicked(self, widget): - self.destroy() - - def on_button_logfile_clicked(self, widget): - try: - cmd = ["sudo", "-u", fn.sudo_username, "xdg-open", fn.event_log_file] - fn.subprocess.Popen( - cmd, - shell=False, - stdout=fn.subprocess.PIPE, - stderr=fn.subprocess.STDOUT, - ) - - except Exception as e: - fn.logger.error("Exception in on_button_logfile_clicked(): %s" % e) - - -class Bootloader(GObject.Object): - __gtype_name__ = "Bootloader" - - def __init__(self, id, name): - super().__init__() - - self.id = id - self.name = name - - @GObject.Property - def bootloader_id(self): - return self.id - - @GObject.Property - def bootloader_name(self): - return self.name \ No newline at end of file diff --git a/ui/SplashScreen.py b/ui/SplashScreen.py deleted file mode 100644 index 73639b7..0000000 --- a/ui/SplashScreen.py +++ /dev/null @@ -1,30 +0,0 @@ -import gi -import functions as fn - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk, Gio - -base_dir = fn.os.path.abspath(fn.os.path.join(fn.os.path.dirname(__file__), "..")) - - -class SplashScreen(Gtk.Window): - def __init__(self, app_name, **kwargs): - super().__init__(**kwargs) - self.set_decorated(False) - self.set_resizable(False) - self.set_default_size(600, 400) - - self.set_modal(True) - self.set_title(app_name) - self.set_icon_name("archlinux-kernel-manager-tux") - - tux_icon = Gtk.Picture.new_for_file( - file=Gio.File.new_for_path( - fn.os.path.join(base_dir, "images/600x400/akm-tux-splash.png") - ) - ) - - tux_icon.set_content_fit(content_fit=Gtk.ContentFit.FILL) - - self.set_child(child=tux_icon) - self.present() \ No newline at end of file diff --git a/ui/Stack.py b/ui/Stack.py deleted file mode 100644 index a5f5850..0000000 --- a/ui/Stack.py +++ /dev/null @@ -1,30 +0,0 @@ -import gi - -gi.require_version("Gtk", "4.0") -from gi.repository import Gtk - - -class Stack(Gtk.Stack): - def __init__(self, transition_type): - super(Stack, self).__init__() - - # self.set_transition_type(Gtk.StackTransitionType.ROTATE_LEFT) - if transition_type == "ROTATE_LEFT": - transition_type = Gtk.StackTransitionType.ROTATE_LEFT - if transition_type == "ROTATE_RIGHT": - transition_type = Gtk.StackTransitionType.ROTATE_RIGHT - if transition_type == "CROSSFADE": - transition_type = Gtk.StackTransitionType.CROSSFADE - if transition_type == "SLIDE_UP": - transition_type = Gtk.StackTransitionType.SLIDE_UP - if transition_type == "SLIDE_DOWN": - transition_type = Gtk.StackTransitionType.SLIDE_DOWN - if transition_type == "OVER_DOWN": - transition_type = Gtk.StackTransitionType.OVER_DOWN - - self.set_transition_type(transition_type) - self.set_hexpand(True) - self.set_vexpand(True) - self.set_transition_duration(250) - self.set_hhomogeneous(False) - self.set_vhomogeneous(False) \ No newline at end of file