KDE - Theme (complete) snapshotting script

#!/bin/bash

Check if a keyword is provided

if [ -z “$1” ]; then
echo “Error: Please provide a keyword for the backup filenames.”
echo “Usage: $0 ”
exit 1
fi

KEYWORD=“$1”
BASE_DIR=“/home/greg/Documents/backup/desktops”
BACKUP_DIR=“$BASE_DIR/plasma_backup_${KEYWORD}”

Check if backup directory already exists

if [ -d “$BACKUP_DIR” ]; then
read -p "Backup directory $BACKUP_DIR already exists. Overwrite? [y|n]: " ANSWER
if [ “$ANSWER” = “y” ] || [ “$ANSWER” = “Y” ]; then
rm -rf “$BACKUP_DIR” || { echo “Error: Failed to delete existing backup directory $BACKUP_DIR”; exit 1; }
echo “Deleted existing backup directory $BACKUP_DIR”
else
echo “Backup aborted. Directory $BACKUP_DIR already exists.”
exit 1
fi
fi

Create backup directory

mkdir -p “$BACKUP_DIR” || { echo “Error: Failed to create backup directory $BACKUP_DIR”; exit 1; }

List of files and directories to back up

CONFIG_FILES=(
“$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc”
“$HOME/.config/kdeglobals”
“$HOME/.config/plasmarc”
“$HOME/.config/kwinrc”
“$HOME/.config/kscreenrc”
“$HOME/.local/share/plasma”
“$HOME/.local/share/plasma/desktoptheme”
“$HOME/.local/share/icons”
“$HOME/.local/share/applications”
)

Copy files with keyword prefix

for ITEM in “${CONFIG_FILES[@]}”; do
if [ -e “$ITEM” ]; then
# Get the basename of the file or directory
BASENAME=$(basename “$ITEM”)
# Destination path with keyword prefix
DEST=“$BACKUP_DIR/${KEYWORD}_${BASENAME}”
cp -r “$ITEM” “$DEST” && echo “Backed up $ITEM to $DEST” || echo “Error: Failed to back up $ITEM”
else
echo “Warning: $ITEM does not exist, skipping…”
fi
done

Specifically back up application launcher icon settings

LAUNCHER_CONFIG=“$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc”
if [ -f “$LAUNCHER_CONFIG” ]; then

Try multiple possible launcher applets

for PLUGIN in “org.kde.plasma.kickoff” “org.kde.plasma.kicker” “org.kde.plasma.kickerdash”; do
grep -A 20 -B 5 “plugin=$PLUGIN” “$LAUNCHER_CONFIG” > “$BACKUP_DIR/${KEYWORD}launcher_icon_settings${PLUGIN}.txt” 2>/dev/null
if [ -s “$BACKUP_DIR/${KEYWORD}launcher_icon_settings${PLUGIN}.txt” ]; then
echo “Backed up $PLUGIN launcher settings to $BACKUP_DIR/${KEYWORD}launcher_icon_settings${PLUGIN}.txt”
else
rm -f “$BACKUP_DIR/${KEYWORD}launcher_icon_settings${PLUGIN}.txt”
fi
done
if ! ls “$BACKUP_DIR”/${KEYWORD}launcher_icon_settings*.txt >/dev/null 2>&1; then
echo “Warning: No launcher settings found for known applets in $LAUNCHER_CONFIG”
fi
fi

echo “Backup completed. Files saved to $BACKUP_DIR”

#!/bin/bash

Check if a keyword is provided

if [ -z “$1” ]; then
echo “Error: Please provide the backup keyword.”
echo “Usage: $0 ”
exit 1
fi

KEYWORD=“$1”
BACKUP_DIR=“/home/greg/Documents/backup/desktops/plasma_backup_${KEYWORD}”

Check if backup directory exists

if [ ! -d “$BACKUP_DIR” ]; then
echo “Error: Backup directory $BACKUP_DIR does not exist.”
exit 1
fi

List of expected files/directories with their original paths

declare -A CONFIG_FILES=(
[“plasma-org.kde.plasma.desktop-appletsrc”]=“$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc”
[“kdeglobals”]=“$HOME/.config/kdeglobals”
[“plasmarc”]=“$HOME/.config/plasmarc”
[“kwinrc”]=“$HOME/.config/kwinrc”
[“kscreenrc”]=“$HOME/.config/kscreenrc”
[“plasma”]=“$HOME/.local/share/plasma”
[“desktoptheme”]=“$HOME/.local/share/plasma/desktoptheme”
[“icons”]=“$HOME/.local/share/icons”
[“applications”]=“$HOME/.local/share/applications”
)

Restore files by removing the keyword prefix

for KEY in “${!CONFIG_FILES[@]}”; do
for FILE in “$BACKUP_DIR”/*_“$KEY”; do
if [ -e “$FILE” ]; then
DEST=“${CONFIG_FILES[$KEY]}”
mkdir -p “$(dirname “$DEST”)”
cp -r “$FILE” “$DEST” && echo “Restored $FILE to $DEST” || echo “Error: Failed to restore $FILE”
else
echo “Warning: No backup found for $KEY in $BACKUP_DIR”
fi
done
done

Restore application launcher icon settings

if ls “$BACKUP_DIR”/${KEYWORD}launcher_icon_settings.txt >/dev/null 2>&1; then
for LAUNCHER_SETTINGS in “$BACKUP_DIR”/${KEYWORD}launcher_icon_settings
.txt; do
echo “Found launcher settings at $LAUNCHER_SETTINGS”
# Extract icon setting
ICON=$(grep “icon=” “$LAUNCHER_SETTINGS” | cut -d’=’ -f2)
if [ -n “$ICON” ]; then
# Find the applet ID for org.kde.plasma.kickoff
APPLET_ID=$(grep -B 5 “plugin=org.kde.plasma.kickoff” “$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc” | grep -o “[Containments][[0-9]][Applets][[0-9]]” | head -1)
if [ -n “$APPLET_ID” ]; then
kwriteconfig5 --file “$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc” --group “$APPLET_ID” --group “Configuration” --group “General” --key “icon” “$ICON”
echo “Applied launcher icon: $ICON”
else
echo “Warning: Could not find applet ID for org.kde.plasma.kickoff. Manual merge into $HOME/.config/plasma-org.kde.plasma.desktop-appletsrc required.”
fi
else
echo “Warning: No icon setting found in $LAUNCHER_SETTINGS”
fi
done
else
echo “Warning: No launcher settings found in $BACKUP_DIR”
fi

Clear Plasma cache

rm -rf “$HOME/.cache/*” && echo “Cleared Plasma cache” || echo “Error: Failed to clear cache”

Extract and apply the global theme

GLOBAL_THEME=“”
if [ -f “$HOME/.config/kdeglobals” ]; then
GLOBAL_THEME=$(grep “LookAndFeelPackage=” “$HOME/.config/kdeglobals” | cut -d’=’ -f2)
fi
if [ -n “$GLOBAL_THEME” ] && command -v plasma-apply-lookandfeel >/dev/null 2>&1; then
echo “Found global theme: $GLOBAL_THEME”
plasma-apply-lookandfeel -a “$GLOBAL_THEME” && echo “Applied global theme: $GLOBAL_THEME” || echo “Error: Failed to apply global theme $GLOBAL_THEME”
else
echo “Warning: Could not determine global theme or plasma-apply-lookandfeel not found. Falling back to desktop theme.”

Try desktop theme as fallback

DESKTOP_THEME=“”
if [ -f “$HOME/.config/plasmarc” ]; then
DESKTOP_THEME=$(grep “theme=” “$HOME/.config/plasmarc” | cut -d’=’ -f2)
fi
if [ -z “$DESKTOP_THEME” ] && [ -f “$HOME/.config/kdeglobals” ]; then
DESKTOP_THEME=$(grep “plasmaTheme=” “$HOME/.config/kdeglobals” | cut -d’=’ -f2)
fi
if [ -n “$DESKTOP_THEME” ] && command -v plasma-apply-desktoptheme >/dev/null 2>&1; then
echo “Found desktop theme: $DESKTOP_THEME”
plasma-apply-desktoptheme “$DESKTOP_THEME” && echo “Applied desktop theme: $DESKTOP_THEME” || echo “Error: Failed to apply desktop theme $DESKTOP_THEME”
else
echo “Warning: Could not determine desktop theme or plasma-apply-desktoptheme not found. Try manually applying the theme via System Settings.”
fi
fi

Apply icon theme

ICON_THEME=“”
if [ -f “$HOME/.config/kdeglobals” ]; then
ICON_THEME=$(grep “Theme=” “$HOME/.config/kdeglobals” | grep -v “ColorScheme” | cut -d’=’ -f2)
fi
if [ -n “$ICON_THEME” ] && command -v plasma-apply-icontheme >/dev/null 2>&1; then
echo “Found icon theme: $ICON_THEME”
plasma-apply-icontheme “$ICON_THEME” && echo “Applied icon theme: $ICON_THEME” || echo “Error: Failed to apply icon theme $ICON_THEME”
elif [ -n “$ICON_THEME” ]; then
kwriteconfig5 --file “$HOME/.config/kdeglobals” --group “Icons” --key “Theme” “$ICON_THEME” && echo “Set icon theme via kwriteconfig5: $ICON_THEME” || echo “Error: Failed to set icon theme via kwriteconfig5”
else
echo “Warning: Could not determine icon theme or plasma-apply-icontheme not found”
fi

Apply cursor theme

CURSOR_THEME=“”
if [ -f “$HOME/.config/kdeglobals” ]; then
CURSOR_THEME=$(grep “cursorThemeName=” “$HOME/.config/kdeglobals” | cut -d’=’ -f2)
fi
if [ -n “$CURSOR_THEME” ] && command -v plasma-apply-cursortheme >/dev/null 2>&1; then
echo “Found cursor theme: $CURSOR_THEME”
plasma-apply-cursortheme “$CURSOR_THEME” && echo “Applied cursor theme: $CURSOR_THEME” || echo “Error: Failed to apply cursor theme $CURSOR_THEME”
elif [ -n “$CURSOR_THEME” ]; then
kwriteconfig5 --file “$HOME/.config/kdeglobals” --group “KDE” --key “cursorThemeName” “$CURSOR_THEME” && echo “Set cursor theme via kwriteconfig5: $CURSOR_THEME” || echo “Error: Failed to set cursor theme via kwriteconfig5”
else
echo “Warning: Could not determine cursor theme or plasma-apply-cursortheme not found”
fi

Restart Plasma

kquitapp5 plasmashell && echo “Stopped plasmashell” || echo “Error: Failed to stop plasmashell”
sleep 2
kstart5 plasmashell && echo “Restarted plasmashell” || echo “Error: Failed to restart plasmashell”

echo “Restore completed from $BACKUP_DIR”

A tool already exists. Specifically for KDE (but also others).

2 Likes

What’s the point of asking an idiot (AI) to make you something that already exists in much better condition?

nice but me i use plasma 6 :wink:

3 Likes

For quality reasons, we do not want answers generated by an AI.
:footprints:

6 Likes

Perhaps more accurately (as we do deeply mistrust Language Models with very good reason) - we wouldn’t want answers pasted from an AI which tends to behave a little like ‘pickup sticks’ in throwing some deductions together with very nicely formatted, but often seriously flawed results.

It certainly is not a bad idea to employ AI to generate ‘draft’ scripts which you can, yourself, enhance whilst at the same time offering that same AI some feedback and prompt it to take another approach and help you to hone a decent solution, but you still have to verify, testing it and ensuring that it is useful for other users… and then offering it up as a POSSIBLE solution.

However, as mentioned before, Konsave already does this rather well. It is also possible to personalise it’s scope via the configuration, and you should have brought this up with your proposition along with a detailed comparison, as well as a reason why anyone should be interested to not use konsave instead.

Sadly your post was also extremely badly formatted, showing that you do not even possess the skills to paste code, or - better still - HIDE your pasted code with a suitable heading:

For example, here is a script which someone in this forum developed and which does not take several posts to paste in plain text format:

Maclean
#!/usr/bin/env bash
#
# maclean
#
# A little script to automate some relatively safe cleaning activities
#
# <3 cscs <3
#
set -eu

##	Directories to be considered junk. Additional folders may be added.
##	One path on each line. Use Caution. Targets will be deleted.

_junk_dirs=( 
	# Ancient Adobe Flash
	~/.adobe/
	~/.macromedia/
)

## Begin Script ##

EXIT_CODE=0

## Exit if root ##

if [[ "$EUID" = 0 ]]; then
	echo "Do not run as root." ;
	exit
fi

## Help ##

_helpdiag() {
	echo
	echo " maclean"
	echo
	echo " A little script to automate some relatively safe cleaning activities"
	echo
	echo " Usage: maclean [option]"
	echo
	echo " Extra Options:"
	echo "   -h     Print this Help"
	echo "   -a     Automatically affirm all Cleanings"
	echo
}

## Extra Options ##

while getopts ":ah" option; do
	case $option in
		a) # automatic mode
			sudo -k; 
			echo -e "\nPerforming all cleanings automatically."; 
			echo -e "\nThis is the final warning.\n";
			if sudo -p "To continue enter the password for %p: " true; then
				echo ""
				yes | $0 ;
			fi
			exit;;
		h) # display Help
			_helpdiag ;
			exit;;
		\?) # invalid option
			echo "Error: Invalid option" ;
			exit;;
	esac
done

## Junk folders ##

_junker() {
	for dir in "${_junk_dirs[@]}"; do
		if [[ -d "${dir}" ]]; then
			echo -ne "\nClean up junk directories (y/N)? "

			read response
			if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
				rm -rf "${_junk_dirs[@]}" ;
				echo "Done"
			else
				echo "Skipped"
			fi
			return 0
		fi
	done
}
_junker

## Thumbnail cache ##

echo -ne "\nClean thumbnail cache of files not accessed for 2 weeks (y/N)? "

read response
if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
	find ~/.cache/thumbnails -mindepth 1 -type d ! \( -readable -executable \) -prune -o -type f -atime +14 -print0 | xargs -r0 rm -rf ;
	echo "Done"
else
	echo "Skipped"
fi

## $HOME cache ##

echo -ne "\nClean \$HOME cache of files not accessed for 2 weeks (y/N)? "

read response
if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
	_ign_dirs=(
		! -path '*/yay/*'
		! -path '*/vivaldi/*'
		! -path '*/trizen/*'
		! -path '*/pip/*'
		! -path '*/pikaur/*'
		! -path '*/paru/*'
		! -path '*/pamac/*'
		! -path '*/pacaur/*'
		! -path '*/thunderbird/*'
		! -path '*/manjaro-tools/*'
		! -path '*/mozilla/*'
		! -path '*/google-chrome/*'
		! -path '*/chromium/*'
		! -path '*/chroots/*'
		! -path '*/BraveSoftware/*'
	)
	find ~/.cache -mindepth 1 -type d ! \( -readable -executable \) -prune -o "${_ign_dirs[@]}" -type f -atime +14 -print0 | xargs -r0 rm -rf ;
	echo "Done"
else
	echo "Skipped"
fi

## Journal logs ##

if [[ $(LANG=C journalctl --until=-2w | awk 'NR==1 {print $2; exit}') != "No" ]]; then
	echo -ne "\nClean journal of all logs older than 2 weeks (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		journalctl --vacuum-time=2weeks >/dev/null 2>&1 ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## SNAP Data ##

if systemctl is-active --quiet snapd ; then
	echo -ne "\nClean old and disabled SNAP revisions (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		LANG=C snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do
			snap remove "$snapname" --revision="$revision" ;
		done ;
		echo "Done"
	else
		echo "Skipped"
	fi
elif [[ -d ~/.snap || -d ~/snap ]]; then
	echo -ne "\nClean ALL SNAP application data from \$HOME (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		rm -rf ~/.snap ~/snap ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## Flatpak Data ##

if command -v flatpak >/dev/null 2>&1 ; then
	echo -ne "\nClean unused Flatpak REFs and application data (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		flatpak uninstall --unused ;
		if [[ -d ~/.var/app ]]; then
			flatpak uninstall --delete-data ;
		fi
		sudo flatpak repair ;
		echo "Done"
	else
		echo "Skipped"
	fi
elif [[ -d ~/.var/app || -d ~/.local/share/flatpak ]]; then
	echo -ne "\nClean ALL Flatpak application data from \$HOME (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		rm -rf ~/.var/app ~/.local/share/flatpak ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## npm cache ##

if command -v npm >/dev/null 2>&1 ; then
	echo -ne "\nClean unneeded data and verify entegrity of npm packages (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		echo -ne "\nClean ALL data from npm cache as well (y/N)? "
		
		read response
		if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
			npm cache clean --force ;
		else
			echo -e "Skipped\n"
		fi
		npm cache verify ;
		echo "Done"
	else
		echo "Skipped"
	fi
elif [[ -d ~/.npm ]]; then
	echo -ne "\nClean ALL items from the npm cache (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		rm -rf ~/.npm ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## pip cache ##

if command -v pip >/dev/null 2>&1 ; then
	echo -ne "\nClean ALL items from the pip cache (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		pip cache purge ;
		echo "Done"
	else
		echo "Skipped"
	fi
elif [[ -d ~/.cache/pip ]]; then
	echo -ne "\nClean ALL items from the pip cache (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		rm -rf ~/.cache/pip ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## pkgfile cache ##

if ! command -v pkgfile >/dev/null 2>&1 && [[ -d /var/cache/pkgfile ]] ; then 
	echo -ne "\nClean ALL items from the pkgfile cache (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		sudo rm -rf /var/cache/pkgfile ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## PackageKit cache ##

if command -v pkcon >/dev/null 2>&1 ; then
	echo -ne "\nClean ALL items from the PackageKit cache (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		sudo rm -rf /var/cache/PackageKit ;
		sudo pkcon refresh force -c -1 ;
		echo "Done"
	else
		echo "Skipped"
	fi
elif [[ -d /var/cache/PackageKit ]]; then
	echo -ne "\nClean ALL items from the PackageKit cache (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		sudo rm -rf /var/cache/PackageKit ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## AUR Helper cache ##

echo -ne "\nClean AUR Helper cache of all build files (y/N)? "

read response
if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
	helpers=(
		pacaur
		pamac
		paru
		pikaur
		trizen
		yay
	)
	for a in "${helpers[@]}"; do
		if pacman -Qsq "$a" | grep "^$a" > /dev/null ; then
			ahelper="$a";
			echo ""
			if [[ $ahelper = "paru" ]]; then
				$ahelper -Sccda ;
			elif [[ $ahelper = "pacaur" || $ahelper = "pikaur" || $ahelper = "trizen" || $ahelper = "yay" ]]; then
				$ahelper -Scca ;
			elif [[ $ahelper = "pamac" ]]; then
				$ahelper clean -b ;
			fi
		fi
	done
	echo "Done"
else
	echo "Skipped"
fi

## Package cache ##

if [[ $(LANG=C paccache -duk0 | awk 'NR==1 {print $2; exit}') != "no" ]]; then
	echo -ne "\nClean package cache of all uninstalled packages (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		paccache -rvuk0 ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

if [[ $(LANG=C paccache -dk2 | awk 'NR==1 {print $2; exit}') != "no" ]]; then
	echo -ne "\nClean package cache of all but 2 latest instances (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		paccache -rvk2 ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## Orphan Packages ##

if [[ $(pacman -Qdtq | head -c1 | wc -c) != 0 ]]; then
	echo -ne "\nClean out orphan packages (y/N)? "

	read response
	if [[ $response =~ ^(yes|y|Y|Yes)$ ]]; then
		sudo pacman -Rns $(pacman -Qdtq) || EXIT_CODE=$? ;
		echo "Done"
	else
		echo "Skipped"
	fi
fi

## pacnew/pacsave files ##

if [[ $(pacdiff -o | head -c1 | wc -c) != 0 ]]; then
	echo -ne "\nAttention! Manual intervention required for the following files: \n"

	pacdiff -o
fi

## Exit Script ##

echo ""
exit 0
3 Likes