diff --git a/install.py b/install.py index a7e0c6b..1c2f84c 100644 --- a/install.py +++ b/install.py @@ -33,10 +33,11 @@ def main(): if args.remove or args.reinstall: installer.remove() - else: + + if not args.remove: installer.install() - if not args.gdm and args.remove == args.reinstall: + if not args.gdm and not args.remove: apply_gnome_theme() diff --git a/scripts/gdm.py b/scripts/gdm.py index ad4601a..947245b 100644 --- a/scripts/gdm.py +++ b/scripts/gdm.py @@ -2,8 +2,9 @@ import os import subprocess from .theme import Theme -from .utils import label_files, remove_properties, remove_keywords, gnome +from .utils import remove_properties, remove_keywords, gnome from . import config +from .utils.files_labeler import FilesLabeler class ThemePrepare: @@ -11,7 +12,7 @@ class ThemePrepare: Theme object prepared for installation """ - def __init__(self, theme, theme_file, should_label=False): + def __init__(self, theme: Theme, theme_file, should_label=False): self.theme = theme self.theme_file = theme_file self.should_label = should_label @@ -38,7 +39,7 @@ class GlobalTheme: self.backup_file = f"{self.destination_file}.backup" self.backup_trigger = "\n/* Marble theme */\n" # trigger to check if theme is installed - self.extracted_theme = os.path.join(self.temp_folder, config.extracted_gdm_folder) + self.extracted_theme: str = os.path.join(self.temp_folder, config.extracted_gdm_folder) self.gst = os.path.join(self.destination_folder, self.destination_file) # use backup file if theme is installed self.themes: list[ThemePrepare] = [] @@ -46,7 +47,7 @@ class GlobalTheme: self.mode = mode - def __create_theme(self, theme_type, mode=None, should_label=False, is_filled=False): + def __create_theme(self, theme_type: str, mode=None, should_label=False, is_filled=False): """Helper to create theme objects""" theme = Theme(theme_type, self.colors_json, self.theme_folder, self.extracted_theme, self.temp_folder, @@ -111,16 +112,18 @@ class GlobalTheme: :param sat: color saturation """ - for theme in self.themes: - if theme.should_label: - label_files(theme.theme.temp_folder, "light", theme.theme.main_styles) + for theme_prepare in self.themes: + if theme_prepare.should_label: + temp_folder = theme_prepare.theme.temp_folder + main_styles = theme_prepare.theme.main_styles + FilesLabeler(temp_folder, main_styles).append_label("light") - remove_keywords(theme.theme_file, "!important") - remove_properties(theme.theme_file, "background-color", "color", "box-shadow", "border-radius") + remove_keywords(theme_prepare.theme_file, "!important") + remove_properties(theme_prepare.theme_file, "background-color", "color", "box-shadow", "border-radius") - self.__add_gnome_styles(theme.theme) + self.__add_gnome_styles(theme_prepare.theme) - theme.theme.install(hue, color, sat, destination=self.extracted_theme) + theme_prepare.theme.install(hue, color, sat, destination=self.extracted_theme) def __backup(self): diff --git a/scripts/install/global_theme_installer.py b/scripts/install/global_theme_installer.py index 2f75fc1..993b273 100644 --- a/scripts/install/global_theme_installer.py +++ b/scripts/install/global_theme_installer.py @@ -20,9 +20,13 @@ class GlobalThemeInstaller(ThemeInstaller): gdm_temp, mode=self.args.mode, is_filled=self.args.filled) def _install_theme(self, hue, theme_name, sat): - self.theme.prepare() self.theme.install(hue, sat) def _apply_tweaks_to_theme(self): for theme in self.theme.themes: - self._apply_tweaks(theme.theme) \ No newline at end of file + self._apply_tweaks(theme.theme) + + def _after_install(self): + print("\nGDM theme installed successfully.") + print("You need to restart gdm.service to apply changes.") + print("Run \"systemctl restart gdm.service\" to restart GDM.") \ No newline at end of file diff --git a/scripts/install/local_theme_installer.py b/scripts/install/local_theme_installer.py index 7409e5f..1d20451 100644 --- a/scripts/install/local_theme_installer.py +++ b/scripts/install/local_theme_installer.py @@ -10,12 +10,8 @@ class LocalThemeInstaller(ThemeInstaller): theme: Theme def remove(self): - args = self.args colors = self.colors.colors - if args.remove or args.reinstall: - remove_files(args, colors) - if not args.reinstall: - return + remove_files(self.args, colors) def _define_theme(self): theme_folder = os.path.join(config.raw_theme_folder, config.gnome_folder) @@ -28,4 +24,7 @@ class LocalThemeInstaller(ThemeInstaller): self.theme.install(hue, theme_name, sat) def _apply_tweaks_to_theme(self): - self._apply_tweaks(self.theme) \ No newline at end of file + self._apply_tweaks(self.theme) + + def _after_install(self): + print("\nTheme installed successfully.") \ No newline at end of file diff --git a/scripts/install/theme_installer.py b/scripts/install/theme_installer.py index d525436..eef91d4 100644 --- a/scripts/install/theme_installer.py +++ b/scripts/install/theme_installer.py @@ -1,11 +1,13 @@ import argparse +from abc import ABC, abstractmethod from scripts.install.colors_definer import ColorsDefiner from scripts.theme import Theme from scripts.tweaks_manager import TweaksManager -class ThemeInstaller: +class ThemeInstaller(ABC): + """Base class for theme installers""" theme: Theme def __init__(self, args: argparse.Namespace, colors: ColorsDefiner): @@ -14,24 +16,39 @@ class ThemeInstaller: self.stop_after_first_installed_color = False self._define_theme() + @abstractmethod def remove(self): + """Method for removing already installed themes""" pass def install(self): self.theme.prepare() self._apply_tweaks_to_theme() self._apply_colors() + self._after_install() + @abstractmethod def _define_theme(self): + """Here is the place to define the theme object""" pass - def _install_theme(self, hue, theme_name, sat): - pass - + @abstractmethod def _apply_tweaks_to_theme(self): + """Should apply the tweaks for prepared theme""" + pass + + @abstractmethod + def _install_theme(self, hue, theme_name, sat): + """Should say how to install the defined theme""" + pass + + @abstractmethod + def _after_install(self): + """Method to be called after the theme is installed. Can be used for logging or other actions""" pass def _apply_tweaks(self, theme): + """This method should be called in the _apply_tweaks_to_theme method""" tweaks_manager = TweaksManager() tweaks_manager.apply_tweaks(self.args, theme, self.colors) diff --git a/scripts/utils/__init__.py b/scripts/utils/__init__.py index 2ae0305..786b174 100644 --- a/scripts/utils/__init__.py +++ b/scripts/utils/__init__.py @@ -3,7 +3,6 @@ from .copy_files import copy_files from .destinaiton_return import destination_return from .generate_file import generate_file from .hex_to_rgba import hex_to_rgba -from .label_files import label_files from .remove_files import remove_files from .remove_keywords import remove_keywords from .remove_properties import remove_properties diff --git a/scripts/utils/files_labeler.py b/scripts/utils/files_labeler.py new file mode 100644 index 0000000..1b23514 --- /dev/null +++ b/scripts/utils/files_labeler.py @@ -0,0 +1,51 @@ +import os + +type LabeledFileGroup = tuple[str, str] + +class FilesLabeler: + def __init__(self, directory: str, *args: str): + """ + Initialize the working directory and files to change + """ + self.directory = directory + self.files = args + + def append_label(self, label: str): + """ + Append a label to all files in the directory + and update references in the files + """ + labeled_files = self._label_files(label) + self._update_references(labeled_files) + + def _label_files(self, label: str) -> list[LabeledFileGroup]: + labeled_files = [] + for filename in os.listdir(self.directory): + if label in filename: continue + + name, extension = os.path.splitext(filename) + new_filename = f"{name}-{label}{extension}" + + old_filepath = os.path.join(self.directory, filename) + new_filepath = os.path.join(self.directory, new_filename) + os.rename(old_filepath, new_filepath) + + labeled_files.append((filename, new_filename)) + return labeled_files + + def _update_references(self, labeled_files: list[LabeledFileGroup]): + for file_path in self.files: + with open(file_path, 'r') as file: + file_content = file.read() + + file_content = self._update_references_in_file(file_content, labeled_files) + + with open(file_path, 'w') as file: + file.write(file_content) + + @staticmethod + def _update_references_in_file(file_content: str, labeled_files: list[LabeledFileGroup]) -> str: + replaced_content = file_content + for old_name, new_name in labeled_files: + replaced_content = replaced_content.replace(old_name, new_name) + return replaced_content \ No newline at end of file diff --git a/scripts/utils/label_files.py b/scripts/utils/label_files.py deleted file mode 100644 index 801b4d5..0000000 --- a/scripts/utils/label_files.py +++ /dev/null @@ -1,44 +0,0 @@ -import os - -def label_files(directory, label, *args): - """ - Add a label to all files in a directory - :param directory: folder where files are located - :param label: label to add - :param args: files to change links to labeled files - :return: - """ - - # Open all files - files = [open(file, 'r') for file in args] - read_files = [] - - filenames = [] - - for filename in os.listdir(directory): - # Skip if the file is already labeled - if label in filename: - continue - - # Split the filename into name and extension - name, extension = os.path.splitext(filename) - - # Form the new filename and rename the file - new_filename = f"{name}-{label}{extension}" - os.rename(os.path.join(directory, filename), os.path.join(directory, new_filename)) - - filenames.append((filename, new_filename)) - - # Replace the filename in all files - for i, file in enumerate(files): - read_file = file.read() - read_file.replace(filenames[i][0], filenames[i][1]) - read_files.append(read_file) - file.close() - - write_files = [open(file, 'w') for file in args] - - # Write the changes to the files and close them - for i, file in enumerate(write_files): - file.write(read_files[i]) - file.close()