165 lines
5.0 KiB
Bash
Executable File
165 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# try to load the sleep builtin dynamically, because otherwise there's
|
|
# a *lot* of overhead (in terms of PID count)
|
|
if [[ $(</proc/cmdline) = *"nixos-system"* ]]; then
|
|
enable -f /run/current-system/sw/lib/bash/sleep sleep
|
|
else
|
|
enable -f /lib/bash/sleep sleep
|
|
fi
|
|
|
|
get_schedule_info () {
|
|
if [ -z "$schedule_state" ]; then
|
|
schedule_state="needs_init"
|
|
fi
|
|
|
|
case "$schedule_state" in
|
|
"needs_init")
|
|
readarray -t lines < <(
|
|
khal list today 1d --format '{categories}|{title}|{start-time}|{end-time}' |
|
|
grep '^school.*' |
|
|
sed 's/school|//g'
|
|
)
|
|
|
|
# calculate the start-of-date time without shelling out to the date utility
|
|
printf -v unix '%(%s)T'
|
|
printf -v hours '%(%H)T'
|
|
printf -v mins '%(%M)T'
|
|
printf -v seconds '%(%S)T'
|
|
hours=$((10#$hours))
|
|
mins=$((10#$mins))
|
|
seconds=$((10#$seconds))
|
|
today_offset=$((hours * 60 * 60 + mins * 60 + seconds))
|
|
today=$((unix - today_offset))
|
|
|
|
for ((i=0; i < ${#lines[@]}; i++)); do
|
|
readarray -t -d'|' line <<<"${lines[i]}"
|
|
class_names+=("${line[0]}")
|
|
starts=${line[1]}
|
|
ends=${line[2]}
|
|
|
|
# convert to unix time
|
|
class_starts_hours=${starts%%:*}
|
|
class_starts_hours=$((10#$class_starts_hours))
|
|
class_starts_hours=$((class_starts_hours * 3600))
|
|
class_starts_minutes=${starts##*:}
|
|
class_starts_minutes=$((10#$class_starts_minutes))
|
|
class_starts_minutes=$((class_starts_minutes * 60))
|
|
class_starts_offset=$((class_starts_hours + class_starts_minutes))
|
|
class_starts_final=$((today + class_starts_offset))
|
|
|
|
class_ends_hours=${ends%%:*}
|
|
class_ends_hours=$((10#$class_ends_hours))
|
|
class_ends_hours=$((class_ends_hours * 3600))
|
|
class_ends_minutes=${ends##*:}
|
|
class_ends_minutes=$((10#$class_ends_minutes))
|
|
class_ends_minutes=$((class_ends_minutes * 60))
|
|
class_ends_offset=$((class_ends_hours + class_ends_minutes))
|
|
class_ends_final=$((today + class_ends_offset))
|
|
|
|
class_starts+=("$class_starts_final")
|
|
class_ends+=("$class_ends_final")
|
|
done
|
|
|
|
schedule_state="needs_recalc"
|
|
;;
|
|
"needs_recalc")
|
|
schedule_enabled="no"
|
|
printf -v ctime '%(%s)T' -1
|
|
for ((i=0; i < ${#class_names[@]}; i++)); do
|
|
if [ $ctime -lt ${class_starts[$i]} ] && [ $ctime -gt ${class_ends[$(($i - 1))]} ]; then
|
|
class_secs_left=$((${class_starts[$i]} - $ctime))
|
|
current_class_until_event="$class_secs_left"
|
|
current_class_name="${class_names[$i]}"
|
|
current_class_status="waiting"
|
|
schedule_enabled="yes"
|
|
elif [ $ctime -gt ${class_starts[$i]} ] && [ $ctime -lt ${class_ends[$i]} ]; then
|
|
class_secs_left=$((${class_ends[$i]} - $ctime))
|
|
current_class_until_event="$class_secs_left"
|
|
current_class_name="${class_names[$i]}"
|
|
current_class_status="inside"
|
|
schedule_enabled="yes"
|
|
fi
|
|
done
|
|
|
|
if [ "$schedule_enabled" = "no" ]; then
|
|
current_class_status="finished"
|
|
fi
|
|
|
|
schedule_state="needs_dec"
|
|
;;
|
|
"needs_dec")
|
|
if [ "$current_class_status" = "inside" ]; then
|
|
if [ "$((current_class_until_event / 60))" -le 5 ]; then
|
|
printf -v schedule_status "%02d:%02d left in %s/" "$((current_class_until_event / 60))" "$((current_class_until_event % 60))" "$current_class_name"
|
|
else
|
|
printf -v schedule_status "%s minutes left in %s/" "$((current_class_until_event / 60))" "$current_class_name"
|
|
fi
|
|
elif [ "$current_class_status" = "outside" ]; then
|
|
if [ "$((current_class_until_event / 60))" -le 5 ]; then
|
|
printf -v schedule_status "%02d:%02d until %s/" "$((current_class_until_event / 60))" "$((current_class_until_event % 60))" "$current_class_name"
|
|
else
|
|
printf -v schedule_status "%s minutes until %s/" "$((current_class_until_event / 60))" "$current_class_name"
|
|
fi
|
|
elif [ "$current_class_status" = "finished" ]; then
|
|
printf -v schedule_status ""
|
|
return
|
|
fi
|
|
|
|
current_class_until_event=$((current_class_until_event - 1))
|
|
if [ "$current_class_until_event" -eq 0 ]; then
|
|
schedule_state="needs_recalc"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
get_loadavg_info () {
|
|
loadavg_status="$(</proc/loadavg)/"
|
|
}
|
|
|
|
get_cmus_info () {
|
|
if [ /dev/shm/status/cmus -nt /dev/shm/status/modified ]; then
|
|
cmus_status="$(</dev/shm/status/cmus)/"
|
|
touch /dev/shm/status/modified
|
|
fi
|
|
}
|
|
|
|
get_days_until_21 () {
|
|
if [ -z "$birthday" ]; then
|
|
birthday=$(cat ~/.config/birthdate)
|
|
twenty_one=$((birthday + (21 * 365 * 24 * 60 * 60)))
|
|
fi
|
|
|
|
printf -v now "%(%s)T"
|
|
|
|
days_until_21_status=$(((twenty_one - now) / 24 / 60 / 60))
|
|
days_until_21_status="$days_until_21_status/"
|
|
}
|
|
|
|
get_battery_info () {
|
|
battery_status=$(</sys/class/power_supply/BAT0/capacity)
|
|
}
|
|
|
|
get_time_info () {
|
|
printf -v date_status '%(%d(%a)-%m(%b)-%y)T %(%H)T:%(%M)T:%(%S)T/' -1
|
|
}
|
|
|
|
while true; do
|
|
# use /dev/shm to minimize the amount of i/o on disk
|
|
if [ ! -d /dev/shm/status ]; then
|
|
mkdir -p /dev/shm/status
|
|
touch /dev/shm/status/modified
|
|
fi
|
|
|
|
get_time_info
|
|
get_loadavg_info
|
|
get_days_until_21
|
|
get_battery_info
|
|
get_cmus_info
|
|
get_schedule_info
|
|
|
|
printf "%s%s%s%s%s%s\n" "$schedule_status" "$cmus_status" "$loadavg_status" "$days_until_21_status" "$date_status" "$battery_status"
|
|
sleep 1
|
|
done | dwm-setstatus
|