This commit is contained in:
2026-03-31 20:13:15 +08:00
parent 48044e957d
commit 08c513b995
1155 changed files with 79920 additions and 0 deletions

View File

@ -0,0 +1,58 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
configDir=$HOME/.config/apdatifier
config=$configDir/config.conf
test -d $configDir || mkdir -p $configDir
test -f $config || touch $config
source $(dirname "$0")/vars
for dir in $iconsDir $notifDir; do
test -d $dir || mkdir -p $dir
done
for icon in $icon1 $icon2 $icon3 $icon4; do
test -f $iconsDir/$icon || cp $appletDir/contents/ui/assets/icons/$icon $iconsDir
done
test -d $notifDir && cat > $notifDir/$notif << EOF
[Global]
IconName=apdatifier-plasmoid
Comment=Apdatifier
[Event/updates]
Name=New updates
Comment=Event when updates notification enabled without sound
Action=Popup
[Event/updatesSound]
Name=New updates (with sound)
Comment=Event when updates notification enabled with sound
Action=Popup|Sound
Sound=service-login
[Event/error]
Name=Error
Comment=Event when error notification enabled without sound
Action=Popup
[Event/errorSound]
Name=Error (with sound)
Comment=Event when errors notification enabled with sound
Action=Popup|Sound
Sound=dialog-error-serious
[Event/news]
Name=News
Comment=Event when news notification without sound
Action=Popup
[Event/newsSound]
Name=News (with sound)
Comment=Event when news notification with sound
Action=Popup|Sound
Sound=dialog-information
EOF

View File

@ -0,0 +1,174 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
source "$(dirname "$0")/utils"
trap '' SIGINT
[ "$1" ] && selected="$1" || selected=0
[[ $aur != true || -z $wrapper ]] && wrapper="pacman"
wrapper="${wrapper##*/}"; wrapper_sudo=$wrapper
[[ $wrapper = "pacman" ]] && wrapper_sudo="$sudoBin pacman"
returnMenu() {
printReturn
showOptions $selected
exit
}
options=(
"${ICO_MNG_OPT_01}${MNG_OPT_01}"
"${ICO_MNG_OPT_02}${MNG_OPT_02}"
"${ICO_MNG_OPT_03}${MNG_OPT_03}"
"${ICO_MNG_OPT_04}${MNG_OPT_04}"
"${ICO_MNG_OPT_05}${MNG_OPT_05}"
"${ICO_MNG_OPT_06}${MNG_OPT_06}"
"${ICO_MNG_OPT_07}${MNG_OPT_07}"
"${ICO_MNG_OPT_08}${MNG_OPT_08}"
"${ICO_MNG_OPT_09}${MNG_OPT_09}"
"${ICO_MNG_OPT_10}${MNG_OPT_10}"
"${ICO_MNG_OPT_11}${MNG_OPT_11}"
"${ICO_MNG_OPT_12}${MNG_OPT_12}"
)
showOptions() {
while true; do
clear; tput civis
for i in "${!options[@]}"; do
if [[ $i -eq $selected ]]; then
echo -e "$(colorize red bold $ICO_SELECT) $(colorize green bold ${options[$i]})"
else
echo -e " ${options[$i]}"
fi
done
read -rsn1 input
case $input in
A) ((selected--));;
B) ((selected++));;
"") break;;
esac
if [[ $selected -lt 0 ]]; then
selected=$(( ${#options[@]} - 1 ))
elif [ $selected -ge ${#options[@]} ]; then
selected=0
fi
done
clear; tput cnorm
case $selected in
0) fzfPreview Slq;;
1) fzfPreview Qq;;
2) fzfPreview Qqe;;
3) fzfPreview Qqet;;
4) fzfPreview Qqtd;;
5) uninstallOrphans;;
6) downgradePackage;;
7) printExec -Scc; $wrapper_sudo -Scc; returnMenu;;
8) printExec -Sc; $wrapper_sudo -Sc; returnMenu;;
9) rebuildPython;;
10) $scriptDir/mirrorlist true $selected;;
11) exit;;
esac
}
fzfPreview() {
dependencies "fzf" true
case $1 in
Slq) fzfExec -$1 -Si -Syu;;
*) fzfExec -$1 -Qil -Rsn;;
esac
}
fzfExec() {
packages=$($wrapper $1 | fzf $fzf_settings --preview "$wrapper $2 {}")
if [[ -z "$packages" ]]; then
showOptions $selected
else
packages=$(echo "$packages" | oneLine)
printExec $3 "$packages"
$wrapper_sudo $3 $packages
returnMenu
fi
}
uninstallOrphans() {
if [[ -n $($wrapper -Qdt) ]]; then
printExec -Rsn "$($wrapper -Qqtd | oneLine)"
printImportant "$MNG_WARN"; echo
$wrapper_sudo -Rsn $($wrapper -Qqtd)
else
printDone "$MNG_DONE"
fi
returnMenu
}
downgradePackage() {
dependencies "fzf" true
pacman_cache_dir="$(pacman-conf CacheDir)"
wrapper_cache_dir="$HOME/.cache/$wrapper"
files=$(find "$pacman_cache_dir" "$wrapper_cache_dir" -type f -name "*.pkg.tar.zst" -printf "%f\n" 2>/dev/null | \
fzf --exact --multi --layout=reverse)
if [[ -z "$files" ]]; then
showOptions "$selected"
return
fi
file_paths=()
for file in $files; do
if [ -f "${pacman_cache_dir}${file}" ]; then
file_paths+=("${pacman_cache_dir}${file}")
else
path=$(find "$wrapper_cache_dir" -type f -name "$file" 2>/dev/null)
[[ -n "$path" ]] && file_paths+=("$path")
fi
done
if [ ${#file_paths[@]} -gt 0 ]; then
cache="${file_paths[*]}"
printExec -U "$cache"
$wrapper_sudo -U $cache
fi
returnMenu
}
rebuildPython() {
[[ $wrapper = "pacman" ]] && { printDone "$MNG_DONE"; returnMenu; }
rebuild_dir=$(find /usr/lib -maxdepth 1 -type d -name "python*.*" | oneLine)
if [ $(echo "$rebuild_dir" | wc -w) -gt 1 ]; then
rebuild_dir="${rebuild_dir#* }"
rebuild_packages=$( { pacman -Qqo "$rebuild_dir" | pacman -Qqm - | oneLine; } 2>/dev/null)
if [[ -z "$rebuild_packages" ]]; then
printDone "$MNG_DONE"
else
printExec "-S --rebuild" "$rebuild_packages"
while true; do
printQuestion "$MNG_RESUME"; read -r answer
case "$answer" in
[Yy]*) echo; break;;
[Nn]*|"") echo; showOptions;;
*) ;;
esac
done
pacman -Qqo "$rebuild_dir" | pacman -Qqm - | $wrapper -S --rebuild -
fi
else
printDone "$MNG_DONE"
fi
returnMenu
}
showOptions

View File

@ -0,0 +1,53 @@
i18n("Upgrade in progress")
i18n("Full system upgrade")
i18n("Flatpak Upgrade")
i18n("Plasma Widgets Upgrade")
i18n("Upgrade")
i18n("Total execution time:")
i18n("Critical package(s) updated, reboot may be required:")
i18n("Do you want to reboot now?")
i18n("Press Enter to close")
i18n("Skipped...")
i18n("Fetching the latest filtered mirror list")
i18n("Ranking mirrors by their connection and opening speed")
i18n("Check your mirrorlist generator settings...")
i18n("was updated with the following servers:")
i18n("To write to the mirrorlist file, sudo privileges are required")
i18n("Your current mirrorlist:")
i18n("For some widgets you may need to Log Out or restart plasmashell after upgrade")
i18n("Checking widgets for updates")
i18n("Fetching data from the API")
i18n("Getting the download link")
i18n("Downloading package")
i18n("Proceed with upgrade?")
i18n("Restart plasmashell now?")
i18n("No description")
i18n("Too many API requests in the last 15 minutes from your IP address, please try again later")
i18n("Failed to retrieve data from the API")
i18n("Unkwnown error")
i18n("File metadata.json not found")
i18n("Errors in metadata.json file")
i18n("Unsupported file format")
i18n("No files for download")
i18n("No file tagged with version")
i18n("Multiple files are tagged with version")
i18n("Failed to download the package")
i18n("List all available packages in repositories")
i18n("List all installed packages")
i18n("List explicitly installed packages")
i18n("List explicitly installed packages and isn't a dependency of anything")
i18n("List installed dependencies that aren't needed anymore (orphans)")
i18n("Uninstall orphan packages")
i18n("Install (downgrade) a package from cache")
i18n("Remove ALL cached packages")
i18n("Remove cached packages that are not currently installed")
i18n("Rebuild AUR python packages after python upgrade")
i18n("Refresh mirrorlist")
i18n("Exit")
i18n("Review dependency warnings before removing")
i18n("Resume?")
i18n("Press Enter to return menu")
i18n("Search:")
i18n("Executed:")
i18n("Nothing to do")
i18n("Required installed")

View File

@ -0,0 +1,96 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
source "$(dirname "$0")/utils"
[[ "$1" == "true" ]] && MENU=1 || MENU=0
selected=$2
returnMenu() {
printReturn
$scriptDir/management $selected
exit
}
mirrorfile="/etc/pacman.d/mirrorlist"
OUTDATED=false
[[ ! -f "$mirrorfile" ]] && {
NORM_TIME="(no file)"
OUTDATED=true
} || {
FILE_TIME=$(date -r "$mirrorfile" +%s)
NORM_TIME=$(date -d @"$FILE_TIME" +"%d %b %H:%M:%S")
CURR_TIME=$(date +%s)
[[ "$mirrors" == "age" && $MENU -eq 0 ]] && {
(( CURR_TIME - FILE_TIME >= mirrorsAge * 86400 )) && OUTDATED=true || exit
}
}
[[ "$mirrors" != "force" || $MENU -eq 1 ]] && {
printImportant "$MIRROR_TIME" "$NORM_TIME"
while true; do
printQuestion "$MNG_OPT_11?"; read -r answer
case "$answer" in
[Yy]*) echo; break;;
[Nn]*|"") (( MENU )) && { returnMenu; } || { echo; exit; };;
*) ;;
esac
done
}
dependencies "rankmirrors" true
rankmirrors -V &>/dev/null || {
countries=$(echo "$dynamicUrl" | grep -oP '(?<=country=)[^&]+')
countries=$(echo "$countries" | tr '\n' ' ')
countries=$(echo "$countries" | sed 's/ *$//')
if [ -z "$countries" ]; then
printError "$MIRRORS_ERR"
else
echo "Selected countries: $countries"
${sudoBin} rankmirrors -c ${countries}
echo
fi
(( MENU )) && returnMenu || exit
}
tempfile=$(mktemp)
tput sc; curl -m 60 -s -o $tempfile "$dynamicUrl" 2>/dev/null &
spinner $! "$MIRRORS_FETCH"; tput rc; tput ed
if [[ -s "$tempfile" && $(head -n 1 "$tempfile" | grep -c "^##") -gt 0 ]]; then
printDone "$MIRRORS_FETCH"
else
printError "$MIRRORS_FETCH"
printError "$MIRRORS_ERR"
(( MENU )) && returnMenu || exit
fi
sed -i -e "s/^#Server/Server/" -e "/^#/d" "$tempfile"
tempfile2=$(mktemp)
tput sc; rankmirrors -n "$mirrorCount" "$tempfile" > "$tempfile2" &
spinner $! "$MIRRORS_RANK"; tput rc; tput ed
if [[ -s "$tempfile2" && $(head -n 1 "$tempfile2" | grep -c "^# S") -gt 0 ]]; then
printDone "$MIRRORS_RANK"
else
printError "$MIRRORS_RANK"
(( MENU )) && returnMenu || exit
fi
sed -i '1d' "$tempfile2"
sed -i "1s/^/##\n## Arch Linux repository mirrorlist\n## Generated on $(date '+%Y-%m-%d %H:%M:%S')\n##\n\n/" "$tempfile2"
${sudoBin} -n true 2>/dev/null || { printImportant "$MIRRORS_SUDO"; }
cat $tempfile2 | ${sudoBin} tee $mirrorfile > /dev/null
if [ $? -eq 0 ]; then
printDone "$mirrorfile $MIRRORS_UPD"
echo -e "$y$(tail -n +6 $mirrorfile | sed 's/Server = //g')$c\n"
rm $tempfile; rm $tempfile2
(( MENU )) && returnMenu
else
printError "$MIRRORS_SUDO"
(( MENU )) && returnMenu || exit
fi

View File

@ -0,0 +1,57 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
source "$(dirname "$0")/utils"
declare -A termArg=( ["gnome-terminal"]="--" ["ptyxis"]="--" ["terminator"]="-x" )
name="${1^}"
sess="Apdatifier"
term="$(basename $terminal)"
termArg="${termArg[$term]:-"-e"}"
scr="$(dirname "$0")/$1"
arg="${@:2}"
# Ghostty requires additional quotes
[[ $term = ghostty ]] && Q="'"
_attach="${Q}tmux attach-session -t $sess \; select-window -t $name${Q}"
_script="${Q}$scr $arg${Q}"
[[ $tmuxSession = "true" && -x $(command -v tmux) ]] && _TMUX=1
run_terminal() {
$term $termArg bash -c "$1"
}
run_yakuake() {
qdbusCMD sessions runCommandInTerminal $session "bash -c '$1'"
}
create_tmux_session() {
! tmux has-session -t "$sess" 2>/dev/null && {
tmux new-session -d -s "$sess" -n "$name" "bash -c '$scr $arg'"
} || {
! tmux list-windows -t "$sess" | grep -wq "$name" && {
tmux new-window -t "$sess:" -n "$name" "bash -c '$scr $arg'"
}
}
}
if [[ $term = "yakuake" ]]; then
session=$(qdbusCMD sessions addSession)
visible=$(qdbusCMD MainWindow_1 org.qtproject.Qt.QWidget.visible)
qdbusCMD tabs org.kde.yakuake.setTabTitle $session $name
if (( _TMUX )); then
create_tmux_session
run_yakuake "$_attach"
else
run_yakuake "tput sc; clear; $_script"
fi
[[ $visible = "false" ]] && qdbusCMD window org.kde.yakuake.toggleWindowState
elif (( _TMUX )); then
create_tmux_session
run_terminal "$_attach"
else
run_terminal "$_script"
fi

View File

@ -0,0 +1,185 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
source "$(dirname "$0")/utils"
trap 'echo -e "\n\n$(colorize red bold $ICO_WARN "CTRL+C. $UPGRADE_SKIPPED")"' SIGINT
run() {
[[ -z $2 ]] && printExec "$1"
if [ "$idleInhibit" = true ]; then
# (( !OSD )) && {
# OSD=1
# qdbus6 org.kde.plasmashell /org/kde/osdService org.kde.osdService.showText \
# system-suspend-inhibited "Idle inhibition is active during upgrade"
# }
read -ra cmd <<< "$1"
systemd-inhibit --what=idle:sleep:shutdown --who="Apdatifier" --why="$UPGRADE_PROGRESS" "${cmd[@]}"
else
eval ${1}
fi
}
bin="$sudoBin pacman"; [ "$aur" = true ] && bin=$wrapper
fullSystemUpgrade() {
startTime=$(date +%s)
critical_updated=()
critical_installed=()
critical_packages=(
"amd-ucode"
"intel-ucode"
"cryptsetup"
"linux"
"linux-hardened"
"linux-lts"
"linux-zen"
"linux-rt"
"linux-rt-lts"
"linux-firmware*"
"linux-cachyos*"
"linux-cacule*"
"nvidia"
"nvidia-dkms"
"nvidia-*xx-dkms"
"nvidia-*xx"
"nvidia-*lts-dkms"
"nvidia*-lts"
"mkinitcpio*"
"booster*"
"mesa"
"systemd*"
"wayland"
"virtualbox-guest-utils"
"virtualbox-host-dkms"
"virtualbox-host-modules-arch"
"egl-wayland"
"xf86-video-*"
"xorg-server*"
"xorg-fonts*"
"winesync-dkms"
)
if [ "$arch" = true ]; then
printMsg "$UPGRADE_FULL_ARCH"
echo
[ "$mirrors" != "false" ] && $scriptDir/mirrorlist
if [ -n "$preExec" ]; then
run "$preExec"
printf '\n\033[32m'; printf '%.0s:' {1..48}; printf '\033[0m\n\n'
fi
if [ "$rebootSystem" = true ]; then
for package in "${critical_packages[@]}"; do
matches=$(pacman -Qq | grep -E "^${package//\*/.*}$")
[ -n "$matches" ] && critical_installed+=($matches)
done
declare -A beforeVersions
for pkg in "${critical_installed[@]}"; do
beforeVersions[$pkg]=$(pacman -Q $pkg | awk '{print $2}')
done
fi
test -f "$configDir/env.sh" && source "$configDir/env.sh"
run "$bin -Syu $archFlags"
for pkg in "${critical_installed[@]}"; do
afterVersion=$(pacman -Q $pkg | awk '{print $2}')
if [ "${beforeVersions[$pkg]}" != "$afterVersion" ]; then
critical_updated+=("$pkg")
fi
done
fi
if [ "$flatpak" = true ]; then
printMsg "$UPGRADE_FULL_FLATPAK"
echo
run "flatpak update $flatpakFlags"
if [ "$flatpakRemoveUnused" = true ]; then
echo
run "flatpak uninstall --unused $flatpakFlags"
fi
fi
if [ "$widgets" = true ]; then
printMsg "$UPGRADE_FULL_WIDGETS"
echo
run "$scriptDir/widgets upgradeAll" noPrint
fi
if [ -n "$postExec" ]; then
printf '\n\033[32m'; printf '%.0s:' {1..48}; printf '\033[0m\n\n'
run "$postExec"
fi
trap ' ' SIGINT
endTime=$(date +%s)
runTime=$((endTime-startTime))
echo
printImportant "$UPGRADE_EXECTIME" "$(printf "%02dh:%02dm:%02ds" $((runTime / 3600)) $(( (runTime % 3600) / 60 )) $((runTime % 60)))"
# if [ "$idleInhibit" = true ]; then
# qdbus6 org.kde.plasmashell /org/kde/osdService org.kde.osdService.showText \
# system-suspend-uninhibited "Idle inhibition has been disabled"
# fi
if [ ${#critical_updated[@]} -gt 0 ]; then
echo
printImportant "$UPGRADE_CRITICAL" "${critical_updated[*]}"
while true; do
printQuestion "$UPGRADE_REBOOT"; read -r answer
case "$answer" in
[Yy]*) qdbus6 org.kde.Shutdown /Shutdown logoutAndReboot;;
[Nn]*|"") break;;
*) ;;
esac
done
fi
printClose
}
flatpak_package() {
printMsg "$UPGRADE_PACKAGE: $2"
echo
printExec "flatpak update" "$1 $flatpakFlags"
flatpak update $1 $flatpakFlags
printClose
}
widget_package() {
printMsg "$UPGRADE_PACKAGE: $2"
echo
$scriptDir/widgets upgrade $1 $2
printClose
}
postUpgrade() {
local list=""
[ "$arch" = true ] && list+=$(pacman -Q | awk '{print "{\"NM\": \"" $1 "\", \"VO\": \"" $2 "\"},"}')
[ "$flatpak" = true ] && list+=$(flatpak list --app --columns=name,version,active | awk -F'\t' '{print "{\"NM\": \"" $1 "\", \"VO\": \"" $2 $3 "\"},"}')
[ "$widgets" = true ] && list+=$($scriptDir/widgets list)
echo "[${list%,}]"
}
case "$1" in
"full") fullSystemUpgrade ;;
"flatpak") shift; flatpak_package $1 $2;;
"widget") shift; widget_package $1 $2;;
"postUpgrade") postUpgrade ;;
*) exit;;
esac

View File

@ -0,0 +1,382 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
source "$(dirname "$0")/vars"
cleanup() {
[ -d $tempDir ] && rm -rf $tempDir
}
makeTempDir() {
cleanup
mkdir $tempDir
}
colorize() {
local red="\033[31m"
local green="\033[32m"
local blue="\033[34m"
local yellow="\033[33m"
local white="\033[37m"
local clear="\033[0m"
local bold="\033[1m"
local color="$1"; shift
local style=""
if [[ "$1" == "bold" ]]; then
style="${!1}"
shift
fi
echo -ne "${!color}${style}$*${clear}"
}
printDone() {
echo -e "$(colorize green bold "$ICO_DONE $1")"
}
printError() {
echo -e "$(colorize red bold "$ICO_ERR $1")"
}
printImportant() {
echo -e "$(colorize yellow bold "$ICO_WARN $1") $2"
}
printQuestion() {
echo -en "$(colorize yellow bold "$ICO_QUESTION $1") [y/N]: "
}
printExec() {
echo -e "$(colorize blue bold "$ICO_EXEC $MNG_EXEC") $(colorize white $wrapper_sudo $1 $2) \n"
}
printMsg() {
local text="$1"
local padding=$(( (48 - ${#text} - 2) / 2 ))
local l=$(printf ":%.0s" {1..48})
local s=$(printf ":%.0s" $(seq 1 $padding))
local p=${s}$( (( ${#text} % 2 )) && echo ":" )
echo
echo -e "$(colorize green bold $l)"
echo -e "$(colorize green bold $s) $(colorize white bold $text) $(colorize green bold $p)"
echo -e "$(colorize green bold $l)"
}
printReturn() {
tput civis
echo
echo -e "$(colorize blue bold $ICO_RETURN $MNG_RETURN)"
read -r
tput cnorm
}
printClose() {
tput civis
printMsg "$UPGRADE_ENTER"
read -r
tput cnorm
[[ $(basename $terminal) = "yakuake" ]] && qdbusCMD sessions removeSession $(qdbusCMD sessions activeSessionId)
}
printWhile() {
tput sc
pid=$1
spinner $pid "$2"
wait $pid
exitCode=$?
tput rc
tput ed
[[ $exitCode -eq 0 ]] && printDone "$2" || printError "$2"
if [[ "$2" = "$WIDGETS_FETCH" ]]; then
case $exitCode in
1) printError "$WIDGETS_ERR_API_FAIL" ;;
2) printError "$WIDGETS_ERR_API" ;;
3) printError "$WIDGETS_ERR_UNKNOWN" ;;
esac
elif [[ "$2" = "$WIDGETS_LINK" ]]; then
case $exitCode in
1) printError "$WIDGETS_ERR_NOFILES. $UPGRADE_SKIPPED" ;;
2) printError "$WIDGETS_ERR_NOTAGGED $latestVer. $UPGRADE_SKIPPED" ;;
3) printError "$WIDGETS_ERR_TAGGED $latestVer. $UPGRADE_SKIPPED" ;;
esac
elif [[ "$2" = "$WIDGETS_DOWNLOADING" ]]; then
case $exitCode in
1) printError "$WIDGETS_ERR_PACKAGE_FAIL" ;;
2) printError "$WIDGETS_ERR_EXT" ;;
3) printError "$WIDGETS_ERR_NO_JSON" ;;
4) printError "$WIDGETS_ERR_JSON" ;;
esac
fi
}
qdbusCMD() {
qdbus6 org.kde.yakuake /yakuake/$1 "${@:2}"
}
dependencies() {
for cmd in ${1}; do
if ! command -v "$cmd" >/dev/null; then
printError "${CMD_ERR} ${cmd}"
[ $2 ] && returnMenu || exit
fi
done
}
oneLine() {
tr '\n' ' ' | sed 's/ $//'
}
spinner() {
local spin="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
while kill -0 $1 2>/dev/null; do
i=$(( (i+1) %10 ))
printf "\r$(colorize red ${spin:$i:1}) $(colorize blue bold "$2...")"
sleep .2
done
}
clearVer() {
local ver="${1}"
ver="${ver//[^0-9.]/.}"
while [[ "$ver" == *".."* ]]; do
ver="${ver//../.}"
done
ver="${ver#.}"
ver="${ver%.}"
echo "${ver}"
}
compareVer() {
[[ $1 == $2 ]] && return 0
local IFS=.; local i ver1=($1) ver2=($2)
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done
for ((i=0; i<${#ver1[@]}; i++)); do
[[ -z ${ver2[i]} ]] && ver2[i]=0
((10#${ver1[i]} > 10#${ver2[i]})) && return 1
((10#${ver1[i]} < 10#${ver2[i]})) && return 2
done
return 0
}
getId() {
[[ $1 =~ ^[0-9]+$ ]] && f=2 || f=1
grep $1 "$(dirname "$0")/widgets-id" | cut -d' ' -f$f
}
restartPlasmashell() {
if [[ "$restartShell" = true ]]; then
sleep 1
while true; do
printQuestion "$WIDGETS_RESTART"; read -r answer
case "$answer" in
[Yy]*) break;;
[Nn]*|"") exit;;
*) ;;
esac
done
eval ${restartCommand}
else
printImportant "$WIDGETS_WARN"
fi
}
combineFiles() {
sleep 1
[ -f "$1" ] && rm "$1"
for cache in $(find $configDir -name "updates.json_*" | sort); do
cat "$cache" >> "$1"; rm "$cache"
done
}
updateJson() {
cat <<< "$2" > "$1.tmp" && mv "$1.tmp" "$1"
}
rss() {
command -v jq >/dev/null || { echo "${CMD_ERR} jq" >&2; return 127; }
makeTempDir
trap cleanup EXIT
local newsFile="$configDir/news.json"
if [[ ! -s "$newsFile" ]] \
|| ! jq -e '.' "$newsFile" >/dev/null 2>&1 \
|| ! jq -e '[.[] | .date | strptime("%d.%m.%Y | %H:%M")] | length == length' "$newsFile" >/dev/null 2>&1; then
echo '[]' > "$newsFile"
fi
for url in "$@"; do
local rssFile=$(mktemp "$tempDir/XXXXXX.xml")
curl -s -o "$rssFile" --connect-timeout 5 --retry 2 --max-time 60 --url "$url" 2>/dev/null
xmllint --noout "$rssFile" 2>/dev/null || { echo $url; exit 1; }
local title=$(xmllint --xpath "string(/rss/channel/title)" $rssFile)
local article=$(xmllint --xpath "string(/rss/channel/item[1]/title)" $rssFile)
local date=$(date -d "$(xmllint --xpath 'string(/rss/channel/item[1]/pubDate)' $rssFile)" +"%d.%m.%Y | %H:%M")
local link=$(xmllint --xpath "string(/rss/channel/item[1]/link)" $rssFile)
[[ -z "$title" || -z "$article" || -z "$date" || -z "$link" ]] && { echo $url; exit 1; }
while (( $(jq "[.[] | select(.title == \"$title\")] | length" "$newsFile") > newsKeep )); do
index=$(jq --arg title "$title" 'to_entries | reverse | map(select(.value.title == $title)) | .[0].key' $newsFile)
updateJson $newsFile "$(jq --argjson index "$index" "del(.[$index])" $newsFile)"
done
if ! jq -e ".[] | select(.link == \"$link\")" $newsFile > /dev/null; then
local item=$(jq -n --arg t "$title" --arg a "$article" --arg d "$date" --arg l "$link" '{title: $t, article: $a, date: $d, link: $l, removed: false}')
updateJson $newsFile "$(jq "[$item] + ." $newsFile)"
fi
done
updateJson $newsFile "$(jq 'sort_by(.date | strptime("%d.%m.%Y | %H:%M") | mktime) | reverse' $newsFile)"
jq . $newsFile
}
install_devel() {
printMsg "Downloading devel"
echo
required="git jq"
for cmd in ${required}; do command -v "$cmd" >/dev/null || { printError "Required installed ${cmd}"; printClose; exit; }; done;
commit=$(curl -s https://api.github.com/repos/exequtic/apdatifier/commits/main | jq -r '.sha' | cut -c1-7)
if [[ "github commit: $commit" = "$(jq -r '.KPlugin.Description' $appletDir/metadata.json)" ]]; then
printDone "Up to date"
printClose
exit
fi
savedir=$(pwd)
clonedir=$(mktemp -d)
cd $clonedir
{ git clone -n --depth=10 --filter=tree:0 -b main https://github.com/exequtic/apdatifier 2>/dev/null
} & printWhile $! "Clone main branch"
[[ $exitCode -ne 0 ]] && { printClose; exit; }
cd apdatifier
{ git sparse-checkout set --no-cone package 2>/dev/null && git checkout 2>/dev/null
} & printWhile $! "Checkout package directory"
[[ $exitCode -ne 0 ]] && { printClose; exit; }
if command -v less &>/dev/null; then
echo
printImportant "Last 10 commits:"
git log --oneline
sleep 2
fi
echo
printMsg "Upgrading Apdatifier"
echo
cd package || exit 1
updateJson metadata.json "$(jq --arg new_value "github commit: $commit" '.KPlugin.Description = $new_value' metadata.json)"
[[ $trayEnabledByDefault == "true" ]] && updateJson $metadata "$(jq '.KPlugin.EnabledByDefault = true' $metadata)"
while true; do
printQuestion "Do you want build translations?"; read -r answer
case "$answer" in
[Yy]*) cd translate; bash build; cd ..; break;;
[Nn]*|"") break;;
*) ;;
esac
done
echo
tar --exclude=./apdatifier.tar -cf apdatifier.tar .
kpackagetool6 -t Plasma/Applet -u apdatifier.tar 2>/dev/null
echo
cd $savedir
[ ! -d $clonedir ] || rm -rf $clonedir
restartShell=true
restartPlasmashell
printClose
exit
}
install_stable() {
if [[ "$(jq -r '.KPlugin.Description' $appletDir/metadata.json)" = "Arch Update Notifier" ]]; then
while true; do
printImportant "It looks like you already have the stable version."
printQuestion "Do you still want to proceed?"; read -r answer
case "$answer" in
[Yy]*) break;;
[Nn]*|"") printClose; exit;;
*) ;;
esac
done
fi
$scriptDir/upgrade widget "2135796" "apdatifier"
}
uninstall() {
printMsg "Uninstall Apdatifier"
echo
while true; do
printQuestion "Continue?"; read -r answer
case "$answer" in
[Yy]*) break;;
[Nn]*|"") printClose; exit;;
*) ;;
esac
done
echo
showCommand() {
echo -e "$(colorize yellow bold "$ICO_EXEC Command:") $1"
}
printImportant "Remove icons"
for icon in $icon1 $icon2 $icon3 $icon4; do
showCommand "rm $iconsDir/$icon"
test -f "$iconsDir/$icon" && rm "$iconsDir/$icon"
done
showCommand "rmdir -p --ignore-fail-on-non-empty $iconsDir"
test -d "$iconsDir" && rmdir -p --ignore-fail-on-non-empty "$iconsDir"
sleep 1; echo
printImportant "Remove notification"
showCommand "rm $notifDir/$notif"
test -f "$notifDir/$notif" && rm "$notifDir/$notif"
showCommand "rmdir -p --ignore-fail-on-non-empty $notifDir"
test -d "$notifDir" && rmdir -p --ignore-fail-on-non-empty "$notifDir"
sleep 1; echo
printImportant "Remove configuration"
showCommand "rm -rf $configDir"
test -d "$configDir" && rm -rf "$configDir"
sleep 1; echo
printImportant "Uninstall plasmoid"
showCommand "kpackagetool6 -t Plasma/Applet -r $applet"
kpackagetool6 -t Plasma/Applet -r $applet 2>/dev/null
sleep 1; echo
echo "Bye :("; sleep 1
printClose
exit
}
case "$1" in
"rss") shift; rss "$@" ;;
"combineFiles") shift; combineFiles $1 ;;
"installDev") install_devel ;;
"installStable") install_stable ;;
"uninstall") uninstall ;;
esac

View File

@ -0,0 +1,125 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
scriptDir=`cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd`
applet="com.github.exequtic.apdatifier"
configDir="$HOME/.config/apdatifier"
localDir="$HOME/.local/share"
iconsDir="$localDir/icons/breeze/status/24"
notifDir="$localDir/knotifications6"
appletDir="$localDir/plasma/plasmoids/$applet"
tempDir="/tmp/apdatifier"
config="$configDir/config.conf"
icon1="apdatifier-plasmoid.svg"
icon2="apdatifier-packages.svg"
icon3="apdatifier-package.svg"
icon4="apdatifier-flatpak.svg"
notif="apdatifier.notifyrc"
export TEXTDOMAINDIR="$scriptDir/../../locale"
export TEXTDOMAIN="plasma_applet_${applet}"
source $config
declare -a var_names=(
UPGRADE_PROGRESS
UPGRADE_FULL_ARCH
UPGRADE_FULL_FLATPAK
UPGRADE_FULL_WIDGETS
UPGRADE_PACKAGE
UPGRADE_EXECTIME
UPGRADE_CRITICAL
UPGRADE_REBOOT
UPGRADE_ENTER
UPGRADE_SKIPPED
MIRRORS_FETCH
MIRRORS_RANK
MIRRORS_ERR
MIRRORS_UPD
MIRRORS_SUDO
MIRROR_TIME
WIDGETS_WARN
WIDGETS_CHECK
WIDGETS_FETCH
WIDGETS_LINK
WIDGETS_DOWNLOADING
WIDGETS_PROCEED
WIDGETS_RESTART
WIDGETS_NODESC
WIDGETS_ERR_API
WIDGETS_ERR_API_FAIL
WIDGETS_ERR_UNKNOWN
WIDGETS_ERR_NO_JSON
WIDGETS_ERR_JSON
WIDGETS_ERR_EXT
WIDGETS_ERR_NOFILES
WIDGETS_ERR_NOTAGGED
WIDGETS_ERR_TAGGED
WIDGETS_ERR_PACKAGE_FAIL
MNG_OPT_01
MNG_OPT_02
MNG_OPT_03
MNG_OPT_04
MNG_OPT_05
MNG_OPT_06
MNG_OPT_07
MNG_OPT_08
MNG_OPT_09
MNG_OPT_10
MNG_OPT_11
MNG_OPT_12
MNG_WARN
MNG_RESUME
MNG_RETURN
MNG_SEARCH
MNG_EXEC
MNG_DONE
CMD_ERR
)
i=0
while IFS= read -r line && [ $i -lt ${#var_names[@]} ]; do
i=$((i+1))
text=$(echo "$line" | grep -oP '(?<=\().*(?=\))' | sed 's/"//g')
eval "${var_names[$((i-1))]}=\"$(gettext "$text")\""
done < "$scriptDir/messages"
if [[ $termFont = "true" ]]; then
ICO_MNG_OPT_01="󱝩 "
ICO_MNG_OPT_02="󱝫 "
ICO_MNG_OPT_03="󱝭 "
ICO_MNG_OPT_04="󱝭 "
ICO_MNG_OPT_05="󱝧 "
ICO_MNG_OPT_06=" "
ICO_MNG_OPT_07="󱝥 "
ICO_MNG_OPT_08="󱝝 "
ICO_MNG_OPT_09="󱝝 "
ICO_MNG_OPT_10="󰌠 "
ICO_MNG_OPT_11="󱘴 "
ICO_MNG_OPT_12=" "
ICO_ERR=""
ICO_DONE=""
ICO_WARN="󱇎"
ICO_QUESTION=""
ICO_EXEC="󰅱"
ICO_RETURN="󰄽"
ICO_SELECT="󰄾"
else
ICO_ERR="✘"
ICO_DONE="✔"
ICO_WARN="::"
ICO_QUESTION="::"
ICO_EXEC="::"
ICO_RETURN="<<"
ICO_SELECT=">"
fi
fzf_settings="--preview-window "right:70%" --height=100% \
--layout=reverse --info=right --border=none \
--multi --track --exact --margin=0 --padding=0 \
--cycle --prompt=$MNG_SEARCH --marker=•"

View File

@ -0,0 +1,346 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2024 Evgeny Kazantsev <exequtic@gmail.com>
# SPDX-License-Identifier: MIT
source "$(dirname "$0")/utils"
fetch_api_data() {
echo '<?xml version="1.0" encoding="UTF-8"?><data>' > "$XML"
local page=0
local pagesize=100
while true; do
pageXML=$(mktemp "$tempDir/XXXXXX.xml")
api_url="https://api.kde-look.org/ocs/v1/content/data?categories=705x715x719x720&sort=new&page=$page&pagesize=$pagesize"
curl -s -o "$pageXML" --connect-timeout 5 --retry 2 --max-time 60 --request GET --url "$api_url"
! xmllint --noout "$pageXML" 2>/dev/null && return 1
totalitems=$(xmllint --xpath "string(//ocs/meta/totalitems)" $pageXML)
statuscode=$(xmllint --xpath "string(//ocs/meta/statuscode)" $pageXML)
case $statuscode in
100)
xmllint --xpath "//content[@details='summary']" $pageXML >> $XML
items=$(((page + 1) * pagesize))
if [[ $totalitems > $items ]]; then
((page++))
else
echo '</data>' >> "$XML"
break
fi
;;
200) return 2 ;;
*) return 3 ;;
esac
done
return 0
}
get_packages() {
packages=($(find \
"$localDir/kwin/effects" \
"$localDir/kwin/scripts" \
"$localDir/plasma/plasmoids" \
"$localDir/plasma/wallpapers" \
-mindepth 1 -maxdepth 1 -type d 2>/dev/null))
[ ${#packages[@]} -eq 0 ] && exit
}
get_package_type() {
case $(xmllint --xpath "string(//id[text()='$contentId']/../typeid)" $XML) in
"715") echo "Plasma/Wallpaper";;
"719") echo "KWin/Effect";;
"720") echo "KWin/Script";;
*) echo "Plasma/Applet";;
esac
}
get_package_info() {
local id=$(basename "$package")
local metadata="$package/metadata.json"
[[ -s "$metadata" ]] || return 1
jq . $metadata >/dev/null 2>&1 || return 2
local originName=$(jq -r '.KPlugin.Name' $metadata)
name=$(echo "$originName" | sed 's/ /-/g; s/.*/\L&/')
local quotedOriginName='"'$(echo "$originName" | sed 's/"/\\"/g')'"'
contentId=$(xmllint --xpath "string(//name[text()=$quotedOriginName]/../id)" "$XML")
if [[ -z "$contentId" ]]; then
knsregistry=("plasmoids" "kwinscripts" "kwineffect" "wallpaperplugin")
for kns in "${knsregistry[@]}"; do
kns="$HOME/.local/share/knewstuff3/$kns.knsregistry"
[[ -s "$kns" ]] && contentId=$(xmllint --xpath "string(//installedfile[contains(text(), '/$id')]/../id)" $kns)
[[ -n "$contentId" ]] && break
done
fi
[[ -z "$contentId" ]] && contentId="$(getId "$id" | head -n 1)"
[[ -z "$contentId" ]] && return 3
currentVer=$(clearVer "$(jq -r '.KPlugin.Version' "$metadata")")
latestVer=$(clearVer "$(xmllint --xpath "string(//id[text()='$contentId']/../version)" $XML)")
[ -z "$currentVer" ] || [ -z "$latestVer" ] && return 4
compareVer "$currentVer" "$latestVer"
[[ $? != 2 ]] && return 5
description=$(jq -r '.KPlugin.Description' $metadata | sed 's/"/\\"/g' | tr -d '\n')
[ -z "$description" ] || [ "$description" = "null" ] && description="$WIDGETS_NODESC"
author=$(jq -r '.KPlugin.Authors[].Name' $metadata | paste -sd "," - | sed 's/,/, /g')
[ -z "$author" ] || [ "$author" = "null" ] && author="?"
icon=$(jq -r '.KPlugin.Icon' $metadata)
local fallbackIcon="start-here-kde-plasma-symbolic"
if [ -z "$icon" ]; then
icon=$fallbackIcon
else
local iconTheme=$(kreadconfig6 --file kdeglobals --group Icons --key Theme)
local themeDir1="/usr/share/icons/$iconTheme/"
local themeDir2="$HOME/.local/share/icons/$iconTheme/"
local themeDir3="$HOME/.icons/$iconTheme/"
! find -L "$themeDir1" "$themeDir2" "$themeDir3" \
-type f -name "$icon.svg" -print -quit 2>/dev/null | grep -q . \
&& icon=$fallbackIcon
fi
url="https://store.kde.org/p/$contentId"
repo="kde-store"
type=$(get_package_type)
if ! jq -e ".KPackageStructure == \"$type\"" "$metadata" >/dev/null 2>&1; then
updateJson $metadata "$(jq ". + { \"KPackageStructure\": \"$type\" }" $metadata)"
fi
return 0
}
get_download_link() {
local signed=()
local files=0
while read -r download_version; do
((files++))
if [[ "$latestVer" == "$(clearVer "$(xmllint --xpath "string(//id[text()='$contentId']/../$download_version)" $XML)")" ]]; then
signed+=("${download_version#download_version}")
fi
done < <(xmllint --xpath "//content[id='$contentId']/*" $XML | grep -o 'download_version[0-9]\+' | uniq)
if [[ $files -eq 1 || ${#signed[@]} -eq 1 ]]; then
echo $(xmllint --xpath "string(//id[text()='$contentId']/../downloadlink${signed[0]:-1})" $XML) > $tempDir/link
return 0
else
[[ $files -eq 0 ]] && return 1
[[ ${#signed[@]} -eq 0 ]] && return 2
(( ${#signed[@]} > 1 )) && return 3
fi
}
make_updates_list() {
local out=""
for package in "${packages[@]}"; do
get_package_info
[[ $? -ne 0 ]] && continue
out+="{\"NM\": \"${name}\","
out+="\"RE\": \"${repo}\","
out+="\"TP\": \"${type}\","
out+="\"CN\": \"${contentId}\","
out+="\"IN\": \"${icon}\","
out+="\"DE\": \"${description}\","
out+="\"AU\": \"${author}\","
out+="\"VO\": \"${currentVer}\","
out+="\"VN\": \"${latestVer}\","
out+="\"LN\": \"${url}\"}",
done
echo -e "[${out%,}]" > $updatesList
}
check_packages_updates() {
command -v jq >/dev/null || { echo 127; exit; }
makeTempDir
XML="$tempDir/api.kde-look.xml"
updatesList="$tempDir/update.list.json"
trap cleanup EXIT
declare -a packages
get_packages
fetch_api_data
case $? in
1) echo 1; exit ;;
2) echo 2; exit ;;
3) echo 3; exit ;;
esac
make_updates_list
jq . $updatesList
}
download_package() {
mkdir -p $tempDir/$name/unpacked
link=$(cat $tempDir/link)
package="$tempDir/$name/$(basename "${link}")"
curl -s -o $package --connect-timeout 5 --retry 2 --max-time 120 --request GET --location --url "$link" 2>/dev/null
[ ! -s "$package" ] && return 1
bsdtar -xf "$package" -C "$tempDir/$name/unpacked" || return 2
metadata=$(find $tempDir/$name/unpacked -name metadata.json)
[ -z "metadata" ] && return 3
jq . $metadata >/dev/null 2>&1 || return 4
if ! jq -e ".KPackageStructure == \"$type\"" "$metadata" >/dev/null 2>&1; then
updateJson $metadata "$(jq ". + { \"KPackageStructure\": \"$type\" }" $metadata)"
fi
updateJson $metadata "$(jq --arg new_value "$latestVer" '.KPlugin.Version = $new_value' $metadata)"
if [[ $name == "apdatifier" && $trayEnabledByDefault == "true" ]]; then
if jq -e '.KPlugin.EnabledByDefault == false' "$metadata" > /dev/null; then
updateJson $metadata "$(jq '.KPlugin.EnabledByDefault = true' $metadata)"
fi
fi
return 0
}
upgrade_all_packages() {
dependencies "jq"
makeTempDir
XML="$tempDir/api.kde-look.xml"
updatesList="$tempDir/update.list.json"
trap cleanup EXIT
declare -a packages
get_packages
fetch_api_data & printWhile $! "$WIDGETS_FETCH"
[[ $exitCode -ne 0 ]] && exit
make_updates_list & printWhile $! "$WIDGETS_CHECK"
if [[ -s "$updatesList" ]] && jq -e '(. | length) > 0' "$updatesList" > /dev/null 2>&1; then
echo
jq -c 'sort_by(.NM)[]' "$updatesList" | while read -r info; do
echo -e "$(colorize white bold $(echo "$info" | jq -r '.NM')) \t \
$(colorize yellow bold $(echo "$info" | jq -r '.TP')) \t \
$(colorize red bold $(echo "$info" | jq -r '.VO')) \t \
$(colorize white "->") \t \
$(colorize green bold $(echo "$info" | jq -r '.VN'))"
done | column -t
echo
if [[ $widgetConfirmation = true ]]; then
while true; do
printQuestion "$WIDGETS_PROCEED"; read -r answer
case "$answer" in
[Yy]*) echo; break;;
[Nn]*|"") return 0;;
*) ;;
esac
done
fi
updated=false
while read -r info; do
name=$(echo "$info" | jq -r '.NM')
contentId=$(echo "$info" | jq -r '.CN')
latestVer=$(echo "$info" | jq -r '.VN')
type=$(echo "$info" | jq -r '.TP')
echo "$(colorize blue bold "$ICO_EXEC $name ($latestVer)")"
get_download_link & printWhile $! "$WIDGETS_LINK"
[[ $exitCode -ne 0 ]] && { echo; continue; }
download_package & printWhile $! "$WIDGETS_DOWNLOADING"
[[ $exitCode -ne 0 ]] && { echo; continue; }
kpackagetool6 -t $type -u $(dirname $(find $tempDir/$name -name "metadata.json")) 2>/dev/null
updated=true
sleep 1
echo
done < <(jq -c 'sort_by(.NM)[]' "$updatesList")
[[ $updated = true ]] && restartPlasmashell
else
printDone "$MNG_DONE"
fi
}
upgrade_package() {
[ -n "$1" ] && contentId="$1" || exit
[ -n "$2" ] && name="$2" || exit
dependencies "jq"
mkdir -p $tempDir/$name/unpacked
XML="$tempDir/$name/api.kde-look.xml"
trap cleanup EXIT
{
curl -s -o $XML --connect-timeout 5 --retry 2 --max-time 60 --request GET --url "https://api.kde-look.org/ocs/v1/content/data/$contentId" 2>/dev/null
if xmllint --noout $XML 2>/dev/null; then
statuscode=$(xmllint --xpath "string(//ocs/meta/statuscode)" $XML)
case $statuscode in
100) return 0 ;;
200) return 2 ;;
*) return 3 ;;
esac
else
return 1
fi
} & printWhile $! "$WIDGETS_FETCH"
[[ $exitCode -ne 0 ]] && exit
latestVer=$(clearVer "$(xmllint --xpath "string(//id[text()='$contentId']/../version)" $XML)")
type=$(get_package_type)
get_download_link & printWhile $! "$WIDGETS_LINK"
[[ $exitCode -ne 0 ]] && exit
download_package & printWhile $! "$WIDGETS_DOWNLOADING"
[[ $exitCode -ne 0 ]] && exit
kpackagetool6 -t $type -u $(dirname $(find $tempDir/$name -name "metadata.json")) 2>/dev/null
sleep 1
echo
restartPlasmashell
}
list_current_packages() {
declare -a packages
get_packages
local out=""
for package in "${packages[@]}"; do
local json="$package/metadata.json"; [ -s "$json" ] || continue
local name="$(jq -r '.KPlugin.Name' $json)"; [ -z "$name" ] && continue
local currentVer=$(clearVer "$(jq -r '.KPlugin.Version' "$json")"); [ -z "$currentVer" ] && continue
out+="{\"NM\": \"${name}\","
out+="\"VO\": \"${currentVer}\"},\n"
done
echo -e $out
}
case "$1" in
"list") list_current_packages;;
"check") check_packages_updates;;
"upgrade") shift; upgrade_package $1 $2;;
"upgradeAll") upgrade_all_packages;;
*) exit;;
esac

View File

@ -0,0 +1,189 @@
998890 com.bxabi.bumblebee-indicator
998913 org.kde.plasma.awesomewidget
1155946 com.dschopf.plasma.qalculate
1288430 org.kde.plasma.shutdownorswitch
1377704 org.kde.mediabar
1384066 org.kde.workraveApplet
1396415 com.github.solant.plasmataker
1627256 com.github.xyz32.timekeeper
1804745 com.github.heqro.day-night-switcher
1898708 org.nielsvm.plasma.menupager
2079446 dev.vili.sahkoporssi
2100417 org.kde.mcwsremote
2100418 org.kde.olib.thermalmonitor
2107649 org.kde.panel.transparency.toggle
2112443 com.github.tilorenz.compact_pager
2113872 com.github.korapp.cloudflare-warp
2114471 de.davidhi.ddcci-brightness
2115883 org.kde.plasma.simplekickoff
2117117 com.dv.fokus
2118132 com.github.stepan-zubkov.days-to-new-year
2118492 com.github.korapp.nordvpn
2126775 com.github.tilorenz.timeprogressbar
2128047 luisbocanegra.panelspacer.extended
2128143 plasmusic-toolbar
2128477 luisbocanegra.intel.gpu.monitor
2129423 org.kde.windowtitle
2130222 luisbocanegra.panel.modes.switcher
2130541 org.kde.archupdatechecker
2130967 luisbocanegra.panel.colorizer
2131364 com.github.korapp.homeassistant
2131462 org.kde.plasma.plasm6desktopindicator
2132405 com.github.dhruv8sh.year-progress-mod
2132554 com.himdek.kde.plasma.overview
2132555 com.himdek.kde.plasma.runcommand
2134470 a2n.archupdate.plasmoid
2135509 com.github.antroids.application-title-bar
2135511 org.kde.placesWidget
2135552 org.kde.plasma.yesplaymusic-lyrics
2135642 com.github.prayag2.minimalistclock
2135653 com.github.prayag2.modernclock
2135796 com.github.exequtic.apdatifier
2135799 com.github.k-donn.plasmoid-wunderground
2135898 com.dv.uswitcher
2136288 org.kde.Big.Clock
2136291 zayron.chaac.weather
2136295 Clock.Asitoki.Color
2136299 CircleClock
2136302 zayron.almanac
2136307 Minimal.chaac.weather
2136321 com.Petik.clock
2136329 weather.bicolor.widget
2136505 org.kde.netspeedWidget
2136546 com.nemmayan.clock
2136631 com.github.scriptinator
2136636 com.github.zren.commandoutput
2136852 org.kde.latte.separator
2136860 com.github.zren.alphablackcontrol
2136933 org.kde.plasma.advancedradio
2136963 luisbocanegra.kdematerialyou.colors
2137016 org.kde.plasma.Beclock
2137185 com.github.zren.dailyforecast
2137197 com.github.zren.condensedweather
2137217 org.kde.plasma.scpmk
2137231 com.github.eatsu.spaceraspager
2137418 zayron.simple.separator
2137431 com.github.zren.simpleweather
2137675 com.gitlab.scias.advancedreboot
2137726 org.zayronxio.vector.clock
2137844 org.kde.plasma.catwalk
2138251 org.kpple.kppleMenu
2138283 ink.chyk.minimumMediaController
2138365 optimus-gpu-switcher
2138473 org.kde.plasma.videocard
2138476 lenovo-conservation-mode-switcher
2138485 com.github.boraerciyas.controlcentre
2138746 org.kde.plasma.pminhibition
2138853 org.kde.Date.Bubble.P6
2138907 org.kde.latte.spacer
2139337 split-clock
2139541 com.github.configurable_button
2139890 Plasma.Control.Hub
2140275 com.github.davide-sd.ip_address
2140856 d4rkwzd.colorpicker-tray
2141133 org.kde.MinimalMusic.P6
2142681 Audio.Wave.Widget
2142716 com.github.zren.tiledmenu
2143899 org.kde.plasma.resources-monitor
2144212 AndromedaLauncher
2144426 org.previewqt.previewqt.plasmoidpreviewqt
2144969 SoloDay.P6
2145065 com.github.liujed.rssfeeds
2145280 com.github.DenysMb.Kicker-AppsOnly
2145723 luisbocanegra.desktop.wallpaper.effects
2146553 org.kde.plasma.ginti
2147850 zayron.almanac.V2
2147871 org.kde.plasma.clearclock
2147882 org.kde.windowtitle.Fork
2148373 lyrics-on-panel-plasma6
2148469 thot.observer.ram
2148472 thot.observer.cpu
2150544 org.kde.plasma.composeEmail
2150610 com.gitlab.scias.plasmavantage
2150916 org.kde.paneltransparencybutton
2151247 org.kde.plasma.win7showdesktop
2151576 ppk.plasma6.hydrobot
2151585 com.samirgaire10.Brave-plasma6
2151600 com.samirgaire10.chatgpt-plasma6
2151622 com.samirgaire10.Deepl-plasma6
2151683 com.samirgaire10.google_gemini-plasma6
2151687 com.samirgaire10.Google-plasma6
2151694 com.samirgaire10.GoogleTranslater-plasma6
2151931 org.kde.windowbuttons
2151962 com.samirgaire10.perplexityAi-plasma6
2152642 com.samirgaire10.blackbox.AI_plasma6
2153869 org.kde.plasma.private.BusyTasksPlasmoid
2154331 com.softtechok.systemmonitorplasmoid
2154894 org.51n7.kMenu
2157390 org.latgardi.darwinmenu
2158349 Almanac.Asimetric
2158358 org.kde.losungen6
2159592 com.samirgaire10.Ollama-plasma6
2160638 com.softtechok.processmonitor
2161461 Weather.IntiSol.kde
2162586 org.kde.dwardor.fanspeedmonitor
2163165 OnlyText.Date.Kde
2163199 com.samirgaire10.DuckDuckGo-plasma6
2163340 ChatAI-Plasmoid
2163368 Circle.Music.Widget
2164459 org.kde.redshiftControl6
2164590 org.kde.plasma.mediacontroller.panel
2164679 com.github.chrtall.kppleMenu
2166656 Aligned.Music.Widget
2166934 adhe.runcommand
2167594 adhe.dittomenu
2167836 com.github.jonmagon.plasma-screendimmer
2168131 Date.Urban.kde
2168466 Rates.Mercurius.Widget
2169597 com.github.danielwjchen.folding-at-home-plasma-widget
2170656 com.samirgaire10.Github-plasma6
2171750 adhe.menu.11
2172470 org.magpie.sonomatic.separator
2173278 org.kde.plasma.powerusage
2174238 adhe.launchpadPlasma
2174265 Chaac.Complete.Weather
2175475 Redmi.Clock
2179264 org.magpie.nightglow.separator
2179317 Start.Next.Menu
2179829 com.kevinbburns.grammarly
2179833 Small.Weather.Plasma6
2180314 Soniq.Widget
2180887 DeepinMenu.Classic
2182964 adhe.menu.11 #Ignored, not a unique ID
2183258 Compact.Menu
2183752 luisbocanegra.cursor.eyes
2184730 OnlyText.Date.Kde.v2
2184747 ChatQT-Plasmoid
2185174 Seeua.Weather
2185549 org.kde.plasma.pipewiresettings
2185626 org.kde.plasma.dockio
2185931 asus-battery-health-switcher
2185962 Start.11.Simple
2186442 Music.Waves
2187344 MusicMini
2187962 MechanicalClock
2188275 com.junongx.kde.currentlyplaying
2188581 Lyndo.Kde
2189544 Plain.Circle.Weather
2189637 Solid.Plain.Music
2193670 qinvvv.qtodo.widget
2194992 org.kde.osymUpdates
2195583 org.ruiny.NowPlaying
2196105 KdeControlStation
2196149 ff.qtodo.widget
2196368 com.github.imoize.ollamacontrol
2199942 Bix.Plasma.Player
2200890 org.dhruv8sh.kara
2201084 Emulator.Spectrum.Audio
2202249 com.espaker.simpleradioplayer-plasma6
2204865 org.dr42.analogclock
2206628 runcommand.fork
2211264 com.ekaaty.vinyl-launcher
2216429 org.kde.plasma.ipaddress
2216432 org.kde.plasma.shamsi-calendar
2217171 Concepto.menu.12
2217301 hermes.observer.ram.P6
2217313 hermes.observer.cpu.P6
2224768 org.kde.plasma.dayprogress
2225123 org.kde.olib.pinpanel
2225378 material.clock