New update notification for if I38 is out of date.

This commit is contained in:
Storm Dragon
2026-05-16 18:10:19 -04:00
parent 3a9c2ab6f1
commit 9859cc348b
3 changed files with 144 additions and 1 deletions
+15
View File
@@ -382,6 +382,21 @@ To reconfigure I38 completely, run the `i38.sh` script again.
*GNOME/MATE comparison:* Much more text-based configuration compared to the graphical settings dialogs in GNOME/MATE. *GNOME/MATE comparison:* Much more text-based configuration compared to the graphical settings dialogs in GNOME/MATE.
## Updating I38
I38 checks for updates in the background during your desktop session. If a newer version is found, I38 sends one notification and then stops checking for the rest of that session. If the server is unavailable or your network is down, I38 stays quiet and tries again later.
To update I38 on this system:
1. Open a terminal with `MODKEY` + `Return`.
2. Type `cd "I38CHECKOUTPATH"` and press Enter.
3. Type `git pull` and press Enter.
4. Type `./i38.sh` and press Enter.
Running `./i38.sh` regenerates your I38 configuration and refreshes the installed scripts. Your personal shortcuts in `~/.config/i3/customizations` are preserved.
If you only need to copy the latest scripts and do not want to regenerate the full i3 configuration, you can use `./i38.sh -u` instead.
## Getting Help ## Getting Help
If you need assistance with I38, you can: If you need assistance with I38, you can:
+23 -1
View File
@@ -14,6 +14,8 @@
i3Path="${XDG_CONFIG_HOME:-$HOME/.config}/i3" i3Path="${XDG_CONFIG_HOME:-$HOME/.config}/i3"
i3msg="i3-msg" i3msg="i3-msg"
configFile="${PWD}/I38_preferences.conf" configFile="${PWD}/I38_preferences.conf"
i38VersionFile="${i3Path}/i38-version"
i38CheckoutPath="${PWD}"
# Dialog accessibility # Dialog accessibility
export DIALOGOPTS='--no-lines --visit-items' export DIALOGOPTS='--no-lines --visit-items'
@@ -449,6 +451,7 @@ update_scripts() {
existingPinHash="$screenlockPinHash" existingPinHash="$screenlockPinHash"
fi fi
cp -rv scripts/ "${i3Path}/" | dialog --backtitle "I38" --progressbox "Updating scripts..." -1 -1 cp -rv scripts/ "${i3Path}/" | dialog --backtitle "I38" --progressbox "Updating scripts..." -1 -1
write_i38_version
write_desktop_shortcuts_template write_desktop_shortcuts_template
if [[ -n "$existingPinHash" ]]; then if [[ -n "$existingPinHash" ]]; then
screenlockPinHash="$existingPinHash" screenlockPinHash="$existingPinHash"
@@ -521,6 +524,22 @@ EOF
return 0 return 0
} }
i38_current_commit() {
if ! command -v git &> /dev/null; then
return 1
fi
git -C "$PWD" rev-parse --verify HEAD 2> /dev/null
}
write_i38_version() {
mkdir -p "${i3Path}"
if i38Commit="$(i38_current_commit)"; then
printf '%s\n' "$i38Commit" > "$i38VersionFile"
else
rm -f "$i38VersionFile"
fi
}
# Array of command line arguments # Array of command line arguments
declare -A command=( declare -A command=(
@@ -859,6 +878,7 @@ write_waytray_config
# Create the i3 configuration directory. # Create the i3 configuration directory.
mkdir -p "${i3Path}" mkdir -p "${i3Path}"
write_i38_version
write_desktop_shortcuts_template write_desktop_shortcuts_template
# Move scripts into place # Move scripts into place
cp -rv scripts/ "${i3Path}/" | dialog --backtitle "I38" --progressbox "Moving scripts into place and writing config..." -1 -1 cp -rv scripts/ "${i3Path}/" | dialog --backtitle "I38" --progressbox "Moving scripts into place and writing config..." -1 -1
@@ -1254,6 +1274,7 @@ if command -v waytray-daemon &> /dev/null ; then
fi fi
echo "exec_always --no-startup-id ${i3Path}/scripts/i38-clipboard.py --daemon" echo "exec_always --no-startup-id ${i3Path}/scripts/i38-clipboard.py --daemon"
echo "exec_always --no-startup-id ${i3Path}/scripts/desktop.sh" echo "exec_always --no-startup-id ${i3Path}/scripts/desktop.sh"
echo "exec --no-startup-id ${i3Path}/scripts/i38-update-check.sh"
if [[ $dex -eq 0 ]]; then if [[ $dex -eq 0 ]]; then
echo '# Start XDG autostart .desktop files using dex. See also' echo '# Start XDG autostart .desktop files using dex. See also'
echo '# https://wiki.archlinux.org/index.php/XDG_Autostart' echo '# https://wiki.archlinux.org/index.php/XDG_Autostart'
@@ -1474,7 +1495,8 @@ sed -i -e "s|BROWSER|${webBrowser}|g" \
-e "s|SCREENREADER|${screenReader}|g" \ -e "s|SCREENREADER|${screenReader}|g" \
-e "s|RATPOISONKEY|${escapeKey}|g" \ -e "s|RATPOISONKEY|${escapeKey}|g" \
-e "s|TEXTEDITOR|${textEditor}|g" \ -e "s|TEXTEDITOR|${textEditor}|g" \
-e "s|FILEBROWSER|${fileBrowser}|g" "${i3Path}/I38.html" -e "s|FILEBROWSER|${fileBrowser}|g" \
-e "s|I38CHECKOUTPATH|${i38CheckoutPath}|g" "${i3Path}/I38.html"
# Create the firstrun file # Create the firstrun file
touch "${i3Path}/firstrun" touch "${i3Path}/firstrun"
+106
View File
@@ -0,0 +1,106 @@
#!/usr/bin/env bash
# This file is part of I38.
#
# I38 is free software: you can redistribute it and/or modify it under the terms
# of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
set -u
remoteUrl="${I38_UPDATE_REMOTE_URL:-https://git.stormux.org/storm/I38}"
remoteRef="${I38_UPDATE_REMOTE_REF:-refs/heads/master}"
initialDelay="${I38_UPDATE_INITIAL_DELAY:-90}"
checkInterval="${I38_UPDATE_CHECK_INTERVAL:-21600}"
notifyInterval="${I38_UPDATE_NOTIFY_INTERVAL:-604800}"
networkTimeout="${I38_UPDATE_NETWORK_TIMEOUT:-20}"
scriptDir="$(unset CDPATH; cd -- "$(dirname -- "$0")" && pwd)"
i3Dir="$(dirname -- "$scriptDir")"
versionFile="${I38_VERSION_FILE:-${i3Dir}/i38-version}"
stateDir="${XDG_STATE_HOME:-${HOME}/.local/state}/I38"
notifyState="${stateDir}/update-check-notified"
valid_commit() {
[[ "${1:-}" =~ ^[0-9a-fA-F]{40}$ ]]
}
read_installed_commit() {
local commit
[[ -r "$versionFile" ]] || return 1
IFS= read -r commit < "$versionFile" || return 1
valid_commit "$commit" || return 1
printf '%s\n' "$commit"
}
read_remote_commit() {
local output commit
if command -v timeout > /dev/null; then
output="$(timeout "$networkTimeout" git ls-remote "$remoteUrl" "$remoteRef" 2> /dev/null)" || return 1
else
output="$(git ls-remote "$remoteUrl" "$remoteRef" 2> /dev/null)" || return 1
fi
commit="${output%%[[:space:]]*}"
valid_commit "$commit" || return 1
printf '%s\n' "$commit"
}
already_notified() {
local remoteCommit="$1"
local lastCommit lastTime now
[[ -r "$notifyState" ]] || return 1
{
IFS= read -r lastCommit
IFS= read -r lastTime
} < "$notifyState" || return 1
[[ "$lastCommit" == "$remoteCommit" ]] || return 1
[[ "$lastTime" =~ ^[0-9]+$ ]] || return 1
now="$(date +%s)"
(( now - lastTime < notifyInterval ))
}
remember_notification() {
local remoteCommit="$1"
mkdir -p "$stateDir" || return 0
{
printf '%s\n' "$remoteCommit"
date +%s
} > "$notifyState" 2> /dev/null || true
}
send_update_notification() {
local remoteCommit="$1"
notify-send \
"I38 update available" \
"A newer I38 version is available. Update your checkout, then run i38.sh -u or rerun i38.sh to refresh your setup." \
2> /dev/null || return 1
remember_notification "$remoteCommit"
}
if ! command -v git > /dev/null || ! command -v notify-send > /dev/null; then
exit 0
fi
sleep "$initialDelay"
while :; do
installedCommit="$(read_installed_commit)" || exit 0
remoteCommit="$(read_remote_commit)"
remoteStatus=$?
if [[ $remoteStatus -eq 0 && "$remoteCommit" != "$installedCommit" ]]; then
if ! already_notified "$remoteCommit"; then
send_update_notification "$remoteCommit"
exit 0
fi
fi
sleep "$checkInterval"
done