mirror of
https://github.com/imarkoff/Marble-shell-theme.git
synced 2025-09-18 17:27: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:
37
README.md
37
README.md
@@ -75,6 +75,9 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
|
|||||||
> [!TIP]
|
> [!TIP]
|
||||||
> If you want to install only one color, use the `--red`, `--yellow`, `--green`, `--blue`, `--purple`, `--gray` option.
|
> If you want to install only one color, use the `--red`, `--yellow`, `--green`, `--blue`, `--purple`, `--gray` option.
|
||||||
|
|
||||||
|
See the [installation tweaks](#-installation-tweaks) section for more information.
|
||||||
|
|
||||||
|
If you want to remove the theme, see the [uninstallation](#-uninstallation--reinstallation) section.
|
||||||
|
|
||||||
## 🖥️ GDM theme
|
## 🖥️ GDM theme
|
||||||
|
|
||||||
@@ -205,3 +208,37 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
|
|||||||
| --red --green --sat=70 | red, green accent colors, 70% of the stock saturation |
|
| --red --green --sat=70 | red, green accent colors, 70% of the stock saturation |
|
||||||
| --hue=200 --name=grayblue --sat=50 --mode=dark | custom grayblue accent color, 50% of the stock saturation, dark mode |
|
| --hue=200 --name=grayblue --sat=50 --mode=dark | custom grayblue accent color, 50% of the stock saturation, dark mode |
|
||||||
| --gdm --blue --gdm-image /path/to/image.jpg --gdm-blur=40 | Install GDM theming in blue color with own GDM background image and blur |
|
| --gdm --blue --gdm-image /path/to/image.jpg --gdm-blur=40 | Install GDM theming in blue color with own GDM background image and blur |
|
||||||
|
|
||||||
|
|
||||||
|
## 🗑️ Uninstallation / Reinstallation
|
||||||
|
|
||||||
|
- To remove the theme, run the program with the `--remove` option:
|
||||||
|
```shell
|
||||||
|
python install.py -ra
|
||||||
|
```
|
||||||
|
- To reinstall the theme, run the program with the `--reinstall` option:
|
||||||
|
```shell
|
||||||
|
python install.py -ri -a # (other installation options)
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> If you want to remove the GDM theme, use the `--gdm` option with the `--remove` option.
|
||||||
|
|
||||||
|
|
||||||
|
The program allows you to specify the color of the theme and the mode to remove.
|
||||||
|
For example, to remove purple and green themes in light mode, use the command:
|
||||||
|
```shell
|
||||||
|
python install.py -r --purple --green --mode light
|
||||||
|
```
|
||||||
|
|
||||||
|
Also, you can use the command above to reinstall purple and green themes in light mode with the `--reinstall` option.
|
||||||
|
```shell
|
||||||
|
python install.py -ri --purple --green --mode light
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Options
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
|------------------|-----------------------|
|
||||||
|
| -r, --remove | Remove the theme |
|
||||||
|
| -ri, --reinstall | Reinstall the theme |
|
17
install.py
17
install.py
@@ -30,7 +30,7 @@ from scripts.theme import Theme
|
|||||||
from scripts.gdm import GlobalTheme
|
from scripts.gdm import GlobalTheme
|
||||||
|
|
||||||
|
|
||||||
def parse_args(colors):
|
def parse_args(colors) -> argparse.Namespace:
|
||||||
"""
|
"""
|
||||||
Parse command-line arguments
|
Parse command-line arguments
|
||||||
:return: parsed arguments
|
:return: parsed arguments
|
||||||
@@ -51,7 +51,8 @@ def parse_args(colors):
|
|||||||
'''))
|
'''))
|
||||||
|
|
||||||
# Default arguments
|
# Default arguments
|
||||||
parser.add_argument('-r', '--remove', action='store_true', help='remove all "Marble" themes')
|
parser.add_argument('-r', '--remove', action='store_true', help='remove Marble themes')
|
||||||
|
parser.add_argument('-ri', '--reinstall', action='store_true', help='reinstall Marble themes')
|
||||||
|
|
||||||
default_args = parser.add_argument_group('Install default theme')
|
default_args = parser.add_argument_group('Install default theme')
|
||||||
default_args.add_argument('-a', '--all', action='store_true', help='all available accent colors')
|
default_args.add_argument('-a', '--all', action='store_true', help='all available accent colors')
|
||||||
@@ -70,7 +71,7 @@ def parse_args(colors):
|
|||||||
color_tweaks = parser.add_argument_group('Optional theme tweaks')
|
color_tweaks = parser.add_argument_group('Optional theme tweaks')
|
||||||
color_tweaks.add_argument('--mode', choices=['light', 'dark'], help='select a specific theme mode to install')
|
color_tweaks.add_argument('--mode', choices=['light', 'dark'], help='select a specific theme mode to install')
|
||||||
color_tweaks.add_argument('--sat', type=int, choices=range(0, 251),
|
color_tweaks.add_argument('--sat', type=int, choices=range(0, 251),
|
||||||
help='custom color saturation (<100%% - reduce, >100%% - increase)', metavar='(0 - 250)%')
|
help='custom color saturation (<100%% - reduce, >100%% - increase)', metavar='(0 - 250)')
|
||||||
|
|
||||||
gdm_theming = parser.add_argument_group('GDM theming')
|
gdm_theming = parser.add_argument_group('GDM theming')
|
||||||
gdm_theming.add_argument('--gdm', action='store_true', help='install GDM theme. \
|
gdm_theming.add_argument('--gdm', action='store_true', help='install GDM theme. \
|
||||||
@@ -183,8 +184,10 @@ def local_theme(args, colors):
|
|||||||
:param colors: colors from colors.json
|
:param colors: colors from colors.json
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if args.remove:
|
if args.remove or args.reinstall:
|
||||||
remove_files()
|
remove_files(args, colors["colors"])
|
||||||
|
if not args.reinstall:
|
||||||
|
return
|
||||||
|
|
||||||
gnome_shell_theme = Theme("gnome-shell", colors, f"{config.raw_theme_folder}/{config.gnome_folder}",
|
gnome_shell_theme = Theme("gnome-shell", colors, f"{config.raw_theme_folder}/{config.gnome_folder}",
|
||||||
config.themes_folder, config.temp_folder,
|
config.themes_folder, config.temp_folder,
|
||||||
@@ -204,7 +207,9 @@ def main():
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
local_theme(args, colors)
|
local_theme(args, colors)
|
||||||
apply_gnome_theme()
|
|
||||||
|
if args.remove == args.reinstall:
|
||||||
|
apply_gnome_theme()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@@ -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
|
from .. import config
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def remove_files():
|
def remove_files(args: argparse.Namespace, colors: dict[str, str]):
|
||||||
"""
|
"""Delete already installed Marble theme"""
|
||||||
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":
|
colors = [color for (color, modes) in filtered_themes]
|
||||||
for path in paths:
|
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 input(f"Proceed? (y/N) ").lower() == "y":
|
||||||
if os.path.exists(os.path.expanduser(path)):
|
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
|
def detect_themes(path: str) -> 'Themes':
|
||||||
found_folder = False
|
"""Detect themes in a given path"""
|
||||||
|
abs_path = os.path.expanduser(path)
|
||||||
|
themes = Themes()
|
||||||
|
|
||||||
for folder in folders:
|
if not os.path.exists(abs_path):
|
||||||
if folder.startswith("Marble"):
|
return themes
|
||||||
folder_path = os.path.join(os.path.expanduser(path), folder)
|
|
||||||
print(f"Deleting folder {folder_path}...", end='')
|
|
||||||
|
|
||||||
try:
|
folders = os.listdir(abs_path)
|
||||||
os.system(f"rm -r {folder_path}")
|
|
||||||
|
|
||||||
except Exception as e:
|
for folder in folders:
|
||||||
print(f"Error deleting folder {folder_path}: {e}")
|
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:
|
return themes
|
||||||
found_folder = True
|
|
||||||
print("Done.")
|
|
||||||
|
|
||||||
if not found_folder:
|
|
||||||
print(f"No folders starting with \"Marble\" found in {path}.")
|
|
||||||
|
|
||||||
else:
|
def parse_folder(folder: str) -> tuple[str, str] | None:
|
||||||
print(f"The path {path} does not exist.")
|
"""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
|
||||||
|
@@ -9,7 +9,7 @@ def define_arguments(parser: ArgumentParser):
|
|||||||
gdm_args = parser.add_argument_group("GDM tweaks")
|
gdm_args = parser.add_argument_group("GDM tweaks")
|
||||||
gdm_args.add_argument("--gdm-image", type=str, nargs="?", help="Set GDM background image")
|
gdm_args.add_argument("--gdm-image", type=str, nargs="?", help="Set GDM background image")
|
||||||
gdm_args.add_argument("--gdm-blur", type=int, nargs="?", help="Blur GDM background image (px)")
|
gdm_args.add_argument("--gdm-blur", type=int, nargs="?", help="Blur GDM background image (px)")
|
||||||
gdm_args.add_argument("--gdm-darken", type=int, choices=range(0, 100), help="Darken GDM background image (%)", metavar="(0 - 100)")
|
gdm_args.add_argument("--gdm-darken", type=int, choices=range(0, 100), help="Darken GDM background image (%%)", metavar="(0 - 100)")
|
||||||
gdm_args.add_argument("--gdm-lighten", type=int, choices=range(0, 100), help="Lighten GDM background image", metavar="(0 - 100)")
|
gdm_args.add_argument("--gdm-lighten", type=int, choices=range(0, 100), help="Lighten GDM background image", metavar="(0 - 100)")
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user