Skip to content

Instantly share code, notes, and snippets.

@gammy
Last active May 6, 2016 12:33
Show Gist options
  • Save gammy/1c7a6a5f85d099e850239338532fba30 to your computer and use it in GitHub Desktop.
Save gammy/1c7a6a5f85d099e850239338532fba30 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# Diox' Alarm, first draft
# Warning: Requires both bash and possibly also GNU date
read_timeout=10 # Must be in seconds
snooze_time="10 minutes"
human_format="%A%e, %H:%M"
ansi_red="\e[1;31m" # bold + red
ansi_green="\e[1;32m" # bold + green
ansi_yellow="\e[1;33m" # bold + yellow
ansi_clr_line="\e[K"
ansi_clr_colors="\e[0m"
ansi_save_cursor="\e[s"
ansi_restore_cursor="\e[u"
if [ -z "$BASH_VERSION" ]; then
echo "Bash is required"! >&2
exit 1
fi
print_remaining() {
local total_seconds=$1
local dd hh mm ss ut
let dd="$total_seconds / 60 / 60 / 24"
let hh="$total_seconds / 60 / 60 % 24"
let mm="($total_seconds / 60 % 60)"
let ss="$total_seconds % 60"
if [ $dd -ne 0 ]; then
ut[1]="$dd day"
[[ $dd -gt 1 ]] && ut[0]+="s"
fi
if [ $hh -ne 0 ]; then
ut[1]="$hh hour"
[[ $hh -gt 1 ]] && ut[1]+="s"
fi
if [ $mm -ne 0 ]; then
ut[2]="$mm minute"
[[ $mm -gt 1 ]] && ut[2]+="s"
else
if [ $dd -eq 0 -a $hh -eq 0 ]; then
if [ $ss -lt 1 ]; then
ut[2]="now"
else
ut[2]="less than 1 minute"
fi
fi
fi
echo -en "${ut[@]}"
}
wakeup() {
$arg_script &
local bg_pid=$!
local user_input
echo -en "\n[${ansi_green}q${ansi_clr_colors}] to stop, "
echo -en "[${ansi_yellow}s${ansi_clr_colors}] to snooze\n\n"
read -N 1 -t ${read_timeout} user_input
pkill -P $bg_pid
case "$user_input" in
"q")
echo
exit
;;
"s")
unixtime_alarm=$(date +"%s" -d "$snooze_time")
human_alarm="$(date +"${human_format}" -d "$snooze_time")"
clear
;;
esac
alrm
}
alrm() {
local let seconds=2 # Anything greater than 1
while [ $seconds -gt 1 ]
do
unixtime_now="$(date +%s)"
human_now="$(date +"${human_format}")"
let seconds="$unixtime_alarm - $unixtime_now"
echo -en "${ansi_restore_cursor}"
echo -e "${human_now}${ansi_clr_line}\n${ansi_clr_line}"
echo -e "$arg_script will run for ${read_timeout}s on${ansi_clr_line}"
echo -en "${ansi_red}${human_alarm}${ansi_clr_colors} "
echo -n '('; print_remaining $seconds; echo -e ")${ansi_clr_line}"
sleep 1
done
wakeup
}
if [ $# -ne 2 ]; then
me="$(basename $0)"
echo "Usage: $me <script filename> <time>"
echo
echo "Examples:"
echo " $me ./test.bash 06:30"
echo " $me ./test.bash \"Friday 13:00\""
echo " $me \$(which ls) \"1 minute 10 seconds\""
echo
echo "^C exits"
exit 0
fi
arg_script="$1"
arg_time="$2"
# Sanity checks
if [ ! -x "$arg_script" ]; then
echo "\"$arg_script\": not executable, or doesn't exist" >&2
exit 1
fi
date +"${human_format}" -d "$arg_time" > /dev/null 2>&1 || {
echo -n "Failed to run \`date\` command: " >&2
echo "date +\"${human_format}\" -d \"$arg_time\"" >&2
date --version 2>&1 | head -n1 >&2
exit 1
}
which pkill || exit 1
unixtime_alarm=$(date +"%s" -d "$arg_time")
human_alarm="$(date +"${human_format}" -d "$arg_time")"
clear
echo -e "${ansi_save_cursor}"
alrm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment