mirror of
https://github.com/imarkoff/Marble-shell-theme.git
synced 2025-09-18 01:07:55 -07:00
Reworked uninstallation process
- Support uninstalling all themes and specified colors/modes only; - For reinstallation should be specified -ri argument; - Fixed theme removal in /root directory; - Fixed --help; - Closes #36.
This commit is contained in:
@@ -1,48 +1,122 @@
|
||||
# TODO: Less verbose output for the user and simplify the code
|
||||
# TODO: Add ability to delete custom colors
|
||||
# TODO: Create an interface where the user can select which themes to delete
|
||||
# TODO: Add a flag to skip the confirmation prompt
|
||||
|
||||
import argparse
|
||||
import shutil
|
||||
from collections import defaultdict
|
||||
|
||||
from .. import config
|
||||
import os
|
||||
|
||||
def remove_files():
|
||||
"""
|
||||
Delete already installed Marble theme
|
||||
"""
|
||||
def remove_files(args: argparse.Namespace, colors: dict[str, str]):
|
||||
"""Delete already installed Marble theme"""
|
||||
themes = detect_themes(config.themes_folder)
|
||||
|
||||
paths = (config.themes_folder, "~/.local/share/themes")
|
||||
filtered_themes = themes
|
||||
|
||||
print("💡 You do not need to delete files if you want to update theme.\n")
|
||||
if args.all:
|
||||
filtered_themes = themes
|
||||
if not args.all:
|
||||
args_dict = vars(args)
|
||||
arguments = [color for color in colors.keys() if args_dict.get(color)]
|
||||
filtered_themes = themes.filter(arguments)
|
||||
|
||||
confirmation = input(f"Do you want to delete all \"Marble\" folders in {' and in '.join(paths)}? (y/N) ").lower()
|
||||
if not filtered_themes:
|
||||
print("No matching themes found.")
|
||||
return
|
||||
|
||||
if confirmation == "y":
|
||||
for path in paths:
|
||||
colors = [color for (color, modes) in filtered_themes]
|
||||
print(f"The following themes will be deleted: {', '.join(colors)}.")
|
||||
if args.mode:
|
||||
print(f"Theme modes to be deleted: {args.mode}.")
|
||||
|
||||
# Check if the path exists
|
||||
if os.path.exists(os.path.expanduser(path)):
|
||||
if input(f"Proceed? (y/N) ").lower() == "y":
|
||||
filtered_themes.remove(args.mode)
|
||||
print("Themes deleted successfully.")
|
||||
else:
|
||||
print("Operation cancelled.")
|
||||
|
||||
# Get the list of folders in the path
|
||||
folders = os.listdir(os.path.expanduser(path))
|
||||
|
||||
# toggle if folder has no marble theme
|
||||
found_folder = False
|
||||
def detect_themes(path: str) -> 'Themes':
|
||||
"""Detect themes in a given path"""
|
||||
abs_path = os.path.expanduser(path)
|
||||
themes = Themes()
|
||||
|
||||
for folder in folders:
|
||||
if folder.startswith("Marble"):
|
||||
folder_path = os.path.join(os.path.expanduser(path), folder)
|
||||
print(f"Deleting folder {folder_path}...", end='')
|
||||
if not os.path.exists(abs_path):
|
||||
return themes
|
||||
|
||||
try:
|
||||
os.system(f"rm -r {folder_path}")
|
||||
folders = os.listdir(abs_path)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error deleting folder {folder_path}: {e}")
|
||||
for folder in folders:
|
||||
parsed = parse_folder(folder)
|
||||
if parsed:
|
||||
(color, mode) = parsed
|
||||
theme_mode = ThemeMode(mode=mode, path=os.path.join(abs_path, folder))
|
||||
themes.add_theme(color, theme_mode)
|
||||
|
||||
else:
|
||||
found_folder = True
|
||||
print("Done.")
|
||||
return themes
|
||||
|
||||
if not found_folder:
|
||||
print(f"No folders starting with \"Marble\" found in {path}.")
|
||||
|
||||
else:
|
||||
print(f"The path {path} does not exist.")
|
||||
def parse_folder(folder: str) -> tuple[str, str] | None:
|
||||
"""Parse a folder name into color and mode"""
|
||||
folder_arr = folder.split("-")
|
||||
|
||||
if len(folder_arr) < 2 or folder_arr[0] != "Marble":
|
||||
return None
|
||||
|
||||
color = "-".join(folder_arr[1:-1])
|
||||
mode = folder_arr[-1]
|
||||
|
||||
return color, mode
|
||||
|
||||
|
||||
class ThemeMode:
|
||||
"""Concrete theme with mode and path"""
|
||||
mode: str
|
||||
path: str
|
||||
|
||||
def __init__(self, mode: str, path: str):
|
||||
self.mode = mode
|
||||
self.path = path
|
||||
|
||||
def remove(self):
|
||||
try:
|
||||
shutil.rmtree(self.path)
|
||||
except Exception as e:
|
||||
print(f"Error deleting {self.path}: {e}")
|
||||
|
||||
|
||||
class Themes:
|
||||
"""Collection of themes grouped by color"""
|
||||
def __init__(self):
|
||||
self.by_color: dict[str, list[ThemeMode]] = defaultdict(list) # color: list[ThemeMode]
|
||||
|
||||
def add_theme(self, color: str, theme_mode: ThemeMode):
|
||||
self.by_color[color].append(theme_mode)
|
||||
|
||||
def filter(self, colors: list[str]):
|
||||
"""
|
||||
Filter themes by colors.
|
||||
Returns a new Themes object.
|
||||
"""
|
||||
filtered = Themes()
|
||||
|
||||
for color in colors:
|
||||
if color in self.by_color:
|
||||
filtered.by_color[color] = self.by_color[color].copy()
|
||||
|
||||
return filtered
|
||||
|
||||
def remove(self, mode: str | None = None):
|
||||
for modes in self.by_color.values():
|
||||
for theme_mode in modes:
|
||||
if mode is None or theme_mode.mode == mode:
|
||||
theme_mode.remove()
|
||||
|
||||
def __bool__(self):
|
||||
return bool(self.by_color)
|
||||
|
||||
def __iter__(self):
|
||||
for color, modes in self.by_color.items():
|
||||
yield color, modes
|
||||
|
Reference in New Issue
Block a user