The bare $HOME repo is gone. This is now the rice: install.sh, rice-* scripts in bin/, configs in home/ linked into $HOME, theme templates, st and the particle wallpaper. Clone to ~/rice and run install.sh.
107 lines
4.2 KiB
Bash
Executable file
107 lines
4.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# rice-reminder - desktop reminders backed by systemd user timers.
|
|
#
|
|
# rice-reminder new ask in rofi
|
|
# rice-reminder add <when> <text> when: 20m | 1h30m | 15:30 | "tomorrow 9:00" | "2026-09-15 09:00"
|
|
# rice-reminder list upcoming reminders as a notification
|
|
# rice-reminder json upcoming reminders as JSON (calendar panel)
|
|
# rice-reminder cancel <id> | clear
|
|
#
|
|
# In rofi, type "20m tea", "15:30 standup" or "tomorrow 9:00 | dentist".
|
|
# Reminders use app name "rice", so they still show during do-not-disturb.
|
|
set -uo pipefail
|
|
|
|
self="$(readlink -f "$0")"
|
|
run="${XDG_RUNTIME_DIR:-/tmp}/rice"
|
|
mkdir -p "$run"
|
|
poke() { date +%s%N > "$run/reminder.rev"; }
|
|
say() { notify-send -a rice -u low -i alarm-symbolic "$@"; }
|
|
|
|
# Resolve a "when" into epoch seconds, or fail.
|
|
resolve() {
|
|
local when="$1" now t
|
|
now=$(date +%s)
|
|
if [[ $when =~ ^([0-9]+[smhd])+$ ]]; then
|
|
local secs=0 part
|
|
for part in $(grep -oE '[0-9]+[smhd]' <<<"$when"); do
|
|
case "${part: -1}" in
|
|
s) secs=$((secs + ${part%?})) ;;
|
|
m) secs=$((secs + ${part%?} * 60)) ;;
|
|
h) secs=$((secs + ${part%?} * 3600)) ;;
|
|
d) secs=$((secs + ${part%?} * 86400)) ;;
|
|
esac
|
|
done
|
|
echo $((now + secs)); return
|
|
fi
|
|
if [[ $when =~ ^[0-9]{1,2}:[0-9]{2}$ ]]; then
|
|
t=$(date -d "today $when" +%s 2>/dev/null) || return 1
|
|
(( t <= now )) && t=$(date -d "tomorrow $when" +%s)
|
|
echo "$t"; return
|
|
fi
|
|
t=$(date -d "$when" +%s 2>/dev/null) || return 1
|
|
(( t > now )) || return 1
|
|
echo "$t"
|
|
}
|
|
|
|
add() {
|
|
local when="$1" text="${2:-Reminder}" at unit
|
|
at=$(resolve "$when") || { say "Reminder" "Couldn't read \"$when\" as a time"; return 1; }
|
|
unit="rice-reminder-$(date +%s%N)"
|
|
systemd-run --user --quiet --collect --unit="$unit" --description="$text" \
|
|
--on-calendar="$(date -d "@$at" '+%Y-%m-%d %H:%M:%S')" \
|
|
--timer-property=AccuracySec=1s \
|
|
-- "$self" fire "$text" || { say "Reminder" "Could not schedule it"; return 1; }
|
|
say "Reminder set" "$text · $(date -d "@$at" '+%a %H:%M')"
|
|
poke
|
|
}
|
|
|
|
upcoming() {
|
|
local unit next
|
|
systemctl --user list-timers 'rice-reminder-*' --all -o json 2>/dev/null |
|
|
jq -r '.[] | [.unit, (.next / 1000000 | floor)] | @tsv' |
|
|
while IFS=$'\t' read -r unit next; do
|
|
(( next > 0 )) || continue
|
|
printf '%s\t%s\t%s\n' "${unit%.timer}" "$next" "$(systemctl --user show -p Description --value "$unit")"
|
|
done | sort -t$'\t' -k2,2n
|
|
}
|
|
|
|
case "${1:-}" in
|
|
new)
|
|
input=$(rofi -dmenu -theme "$HOME/.config/rofi/prompt.rasi" -p "Reminder" \
|
|
-mesg "20m tea · 15:30 standup · tomorrow 9:00 | dentist") || exit 0
|
|
[[ -n $input ]] || exit 0
|
|
if [[ $input == *"|"* ]]; then
|
|
when="${input%%|*}"; text="${input#*|}"
|
|
else
|
|
when="${input%% *}"; text="${input#"$when"}"
|
|
fi
|
|
when="$(sed 's/^ *//; s/ *$//' <<<"$when")"; text="$(sed 's/^ *//; s/ *$//' <<<"$text")"
|
|
add "$when" "${text:-Reminder}"
|
|
;;
|
|
add) add "${2:?when}" "${3:-Reminder}" ;;
|
|
fire)
|
|
notify-send -a rice -u critical -i alarm-symbolic "Reminder" "${2:-Reminder}"
|
|
command -v paplay >/dev/null && [[ -f /usr/share/sounds/freedesktop/stereo/complete.oga ]] &&
|
|
paplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null
|
|
poke
|
|
;;
|
|
list)
|
|
body=$(upcoming | while IFS=$'\t' read -r _ next text; do printf '%s %s\n' "$(date -d "@$next" '+%a %H:%M')" "$text"; done)
|
|
say "Upcoming reminders" "${body:-Nothing scheduled}"
|
|
;;
|
|
json)
|
|
upcoming | jq -R -s -c 'split("\n") | map(select(length > 0) | split("\t")
|
|
| {id: .[0], at: (.[1] | tonumber), time: (.[1] | tonumber | strflocaltime("%H:%M")),
|
|
date: (.[1] | tonumber | strflocaltime("%Y-%m-%d")), text: .[2]})'
|
|
;;
|
|
cancel)
|
|
[[ ${2:-} =~ ^rice-reminder-[0-9]+$ ]] || { echo "rice-reminder: cancel takes a reminder id" >&2; exit 2; }
|
|
systemctl --user stop "$2.timer" && poke
|
|
;;
|
|
clear)
|
|
systemctl --user list-timers 'rice-reminder-*' --all --no-legend 2>/dev/null | awk '{ for (i = 1; i <= NF; i++) if ($i ~ /\.timer$/) print $i }' |
|
|
xargs -r systemctl --user stop
|
|
say "Reminders" "All cleared"; poke
|
|
;;
|
|
*) sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'; exit 2 ;;
|
|
esac
|