diff --git a/scripts/core/sxmo_alarmclock.sh b/scripts/core/sxmo_alarmclock.sh new file mode 100755 index 0000000..69be2bd --- /dev/null +++ b/scripts/core/sxmo_alarmclock.sh @@ -0,0 +1,219 @@ +#!/usr/bin/env sh + +# include common definitions +# shellcheck source=scripts/core/sxmo_common.sh +. "$(dirname "$0")/sxmo_common.sh" + +RTCWAKE="$(which sxmo_rtcwake.sh)" +ALARMCLOCK="$(which sxmo_alarmclock.sh)" + + +ALARMS="$HOME/.config/sxmo/alarms.tsv" +NOTIFICATION="${DEFAULT_ALARM:-/usr/share/sxmo/ring.ogg}" + +alarms() { + cat "$ALARMS" | cut -d $'\t' -f 1,2 | sed -E "s/^([^#].*)/\1 $icon_chk/; s/^#//" +} + +playalarm(){ + message="$1" + notification="${2:-$NOTIFICATION}" + echo mpv --quiet --no-video --loop "$notification" & + mpvid="$!" + CHOICE="$( + printf %b " + Snooze + Dismiss + " | + awk '{$1=$1};1' | grep '\w' | dmenu -p "$message" + )" + case "$CHOICE" in + Snooze) + notify-send "Still need to implement" + ;; + Dismiss) + kill "$mpvid" + ;; + esac +} + +# First argument should be the string like nyyyyyn +dayscron(){ + list="$1" + cronlist="" + for i in $(seq 0 6); do + if [ "${list:$i:1}" = "y" ]; then + cronlist="$cronlist$i," + fi + done + # Remove trailing , + cronlist="$(echo "$cronlist" | sed 's/,$//')" + # If no days were given, assume any day + [ -z "$cronlist" ] && cronlist="*" + printf %s "$cronlist" +} + +alarmcrons(){ + cat "$ALARMS" | sed '/^#/d' | while read line; do + hour="$(echo "$line" | awk -F '(\t|:)' '{print $1}')" + minute="$(echo "$line" | awk -F '(\t|:)' '{print $2}')" + message="$(echo "$line" | awk -F '(\t|:)' '{print $3}')" + days="$(echo "$line" | awk -F '(\t|:)' '{print $4}')" + alarm="$(echo "$line" | awk -F '(\t|:)' '{print $5}')" + printf "%s\n" "$minute $hour * * $(dayscron "$days") $RTCWAKE $ALARMCLOCK playalarm \"$message\" \"$alarm\"" + done +} + +setcrons(){ + ( + # All of the crons that aren't to do with the alarm clock + crontab -l | grep -v sxmo_alarmclock + # The alarm clock cron entries + alarmcrons + ) | crontab - +} + +togglealarm() { + alarm="$1" + time="$(echo "$alarm" | cut -d ' ' -f 1)" + description="$(echo "$alarm" | cut -d ' ' -f 2- | sed "s/ $icon_chk//")" + if echo "$alarm" | grep -q "$icon_chk\$"; then + # If the alarm contains the check, it needs to be disabled + sed -i -E "s/^($time\t$description)/#\1/" "$ALARMS" + else + # If the alarm doesn't contain the check, it needs to be enabled + sed -i -E "s/^#($time\t$description)/\1/" "$ALARMS" + fi + setcrons +} + +deletealarm() { + CHOICE="$( + printf %b "Close Menu\n$(alarms)" | awk '{$1=$1};1' | grep '\w' | + dmenu -p "Delete Alarm" + )" + if [ "$CHOICE" = "Close Menu" ]; then + return + else + time="$(echo "$CHOICE" | cut -d ' ' -f 1)" + description="$(echo "$CHOICE" | cut -d ' ' -f 2- | sed "s/ $icon_chk//")" + if echo "$CHOICE" | grep -q "$icon_chk\$"; then + # If the alarm contains the check, then the line to delete will start time\tdescription + sed -i -E "/^($time\t$description)/d" "$ALARMS" + else + # If the alarm doesn't contain the check, then the line to delete will a hash + sed -i -E "/^#($time\t$description)/d" "$ALARMS" + fi + setcrons + fi +} + +daylist(){ + list="$1" + echo "Sunday $( [ "${list:0:1}" = "y" ] && echo "$icon_chk" )" + echo "Monday $( [ "${list:1:1}" = "y" ] && echo "$icon_chk" )" + echo "Tuesday $( [ "${list:2:1}" = "y" ] && echo "$icon_chk" )" + echo "Wednesday $( [ "${list:3:1}" = "y" ] && echo "$icon_chk" )" + echo "Thursday $( [ "${list:4:1}" = "y" ] && echo "$icon_chk" )" + echo "Friday $( [ "${list:5:1}" = "y" ] && echo "$icon_chk" )" + echo "Saturday $( [ "${list:6:1}" = "y" ] && echo "$icon_chk" )" +} + +listtodays(){ + sed "/$icon_chk/ s/.*/y/; s/...*/n/" | tr -d '\n' +} + +toggleDay(){ + # The 7 long string eg nyyyyyn + days="$1" + # The number to change (0 indexed) + item="$2" + nextItem="$(( item + 1 ))" + pre="${days:0:item}" + post="${days:nextItem}" + current="${days:item:1}" + if [ "$current" = "y" ]; then + new="n" + else + new="y" + fi + echo "$pre$new$post" +} + +newalarm() { + time="$( + echo "Cancel" | + sxmo_dmenu_with_kb.sh -p "Time:" + )" + [ "$time" = "Cancel" ] && return + + description="$( + echo "Cancel" | + sxmo_dmenu_with_kb.sh -p "Description:" + )" + [ "$description" = "Cancel" ] && return + + days="nnnnnnn" + + while true; do + daytoggle="$( + printf %b "$(daylist "$days")\nSave\nCancel" | sxmo_dmenu.sh -p "Days:" + )" + [ "$daytoggle" = "Save" ] && break + [ "$daytoggle" = "Cancel" ] && return + case "$daytoggle" in + "Save" ) break ;; + "Cancel" ) return ;; + "Sunday"* ) days="$(toggleDay "$days" 0)" ;; + "Monday"* ) days="$(toggleDay "$days" 1)" ;; + "Tuesday"* ) days="$(toggleDay "$days" 2)" ;; + "Wednesday"* ) days="$(toggleDay "$days" 3)" ;; + "Thursday"* ) days="$(toggleDay "$days" 4)" ;; + "Friday"* ) days="$(toggleDay "$days" 5)" ;; + "Saturday"* ) days="$(toggleDay "$days" 6)" ;; + esac + done + + printf %b "$time\t$description\t$days\n" >> "$ALARMS" + + setcrons +} + +alarmclockmenu() { + while true; do + CHOICE="$( + printf %b " + $(alarms) + New Alarm + Delete Alarm + System Menu + Close Menu + " | + awk '{$1=$1};1' | grep '\w' | dmenu -p 'Alarms' + )" + [ -z "$CHOICE" ] && exit 1 + case "$CHOICE" in + "System Menu" ) + sxmo_appmenu.sh sys && exit + ;; + "Close Menu" ) + exit + ;; + "New Alarm" ) + newalarm + ;; + "Delete Alarm" ) + deletealarm + ;; + *) + togglealarm "$CHOICE" + ;; + esac + done +} + +if [ $# -gt 0 ]; then + "$@" +else + alarmclockmenu +fi