Last active
June 6, 2018 15:22
-
-
Save catvec/199680f33b32ed087ac667bf86fbf0d3 to your computer and use it in GitHub Desktop.
OSX Alarm Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # | |
| # Usage: alarm COMMAND [command positional arguments] | |
| # | |
| # Args: | |
| # - COMMAND: Action to run | |
| # - set: Set an alarm, positional arguments: | |
| # - MINUTES: Number of minutes until alarm should go off | |
| # - [SAY]: Text to print and speak when alarm is done, defaults to | |
| # "Alarm done" | |
| # - time: Set an alarm for a specific time | |
| # - ls: List set alarms | |
| # - rm: Remove set alarm, positional arguments: | |
| # - ALARM_NUM: Identifying alarm number | |
| # - wait: Wait for alarms to complete, automatically run after set is | |
| # called | |
| # Check GNU Date installed | |
| if ! which gdate > /dev/null; then | |
| echo "Error GNU date must be installed under the name \"gdate\"" >&2 | |
| exit 1 | |
| fi | |
| # Initialize alarm dir | |
| alarms_dir="$HOME/.alarms" | |
| alarm_time_file="time" | |
| alarm_say_file="say" | |
| mkdir -p "$alarms_dir" | |
| # Command constants | |
| wait_poll_time=10 | |
| wait_lock_file="$alarms_dir/WAIT.lock" | |
| # Helpers | |
| function exec_ls_alarms_dir() { # () | |
| out=$(ls -1 -a -d $alarms_dir/*/ 2> /dev/null | sort -n) | |
| } | |
| function get_alarms_dirs() { # () | |
| if ! exec_ls_alarms_dir; then | |
| return | |
| fi | |
| while read "d"; do | |
| basename "$d" | |
| done <<< "$out" | |
| } | |
| function get_last_alarm() { # () | |
| echo $(get_alarms_dirs | tail -n 1) | |
| } | |
| function get_next_alarm_num() { # () | |
| last_alarm="$(get_last_alarm)" | |
| if [ -z "$last_alarm" ]; then | |
| echo "1" | |
| else | |
| echo "$last_alarm + 1" | bc | |
| fi | |
| } | |
| function get_current_time() { # () | |
| echo $(date +%s) | |
| } | |
| function get_alarm_time() { # ( alarm_num ) | |
| # Arguments | |
| alarm_num="$1" | |
| if [ -z "$alarm_num" ]; then | |
| echo "Error - get_alarm_time: alarm_num argument must be provided" >&2 | |
| exit 1 | |
| fi | |
| # Get | |
| cat "$alarms_dir/$alarm_num/$alarm_time_file" | |
| } | |
| function get_alarm_say() { # ( alarm_num ) | |
| # Arguments | |
| alarm_num="$1" | |
| if [ -z "$alarm_num" ]; then | |
| echo "Error - get_alarm_say: alarm_num argument must be provided" >&2 | |
| exit 1 | |
| fi | |
| # Get | |
| cat "$alarms_dir/$alarm_num/$alarm_say_file" | |
| } | |
| function clean_wait_lock() { # () | |
| rm "$wait_lock_file" | |
| } | |
| function trigger_alarm() { # ( alarm_num ) | |
| # Arguments | |
| alarm_num="$1" | |
| if [ -z "$alarm_num" ]; then | |
| echo "Error - trigger_alarm: alarm_num argument must be provided" >&2 | |
| exit 1 | |
| fi | |
| # Trigger | |
| say="$(get_alarm_say $alarm_num)" | |
| echo " !Alarm #$alarm_num done: $say" | |
| say "$say" | |
| notify "$say" | |
| bloop | |
| } | |
| function unix_to_timestamp() { # (unix_time) | |
| # Arguments | |
| unix_time="$1" | |
| if [ -z "$unix_time" ]; then | |
| echo "Error - unix_to_timestamp: unix_time argument must be provided" >&2 | |
| exit 1 | |
| fi | |
| # Convert | |
| date -r "$unix_time" | |
| } | |
| # Commands | |
| function cmd_time() { # (timestamp, say) | |
| # Arguments | |
| timestamp="$1" | |
| shift | |
| if [ "$1" == "am" ] || [ "$1" == "AM" ] || [ "$1" == "pm" ] || [ "$1" == "PM" ]; then | |
| timestamp="$timestamp $1" | |
| shift | |
| fi | |
| if [ -z "$timestamp" ]; then | |
| echo "Timestamp argument must be provided" >&2 | |
| exit 1 | |
| fi | |
| say="$1" | |
| # Parse provided time | |
| timestamp_unix=$(gdate -d "$timestamp" "+%s") | |
| if [ "$?" != "0" ]; then | |
| echo "Error parsing timestamp into unix time" >&2 | |
| exit 1 | |
| fi | |
| # Get difference | |
| current_unix=$(get_current_time) | |
| if [ "$?" != "0" ]; then | |
| echo "Failed to get current unix time" >&2 | |
| exit 1 | |
| fi | |
| minutes=$(echo "scale=2; ($timestamp_unix - $current_unix) / 60" | bc) | |
| if [ "$?" != "0" ]; then | |
| echo "Error calculating difference between current time and provided time" >&2 | |
| exit 1 | |
| fi | |
| # Set | |
| echo "Setting alarm for $timestamp (In $minutes minutes)" | |
| cmd_set "$minutes" "$say" | |
| } | |
| function cmd_set() { # (time, say) | |
| # Arguments | |
| minutes="$1" | |
| if [ -z "$minutes" ]; then | |
| echo "Minutes argument must be provided" >&2 | |
| exit 1 | |
| fi | |
| say="$2" | |
| if [ -z "$say" ]; then | |
| say="Alarm done" | |
| fi | |
| # Calculate alarm params | |
| seconds=$(echo "$minutes * 60" | bc) | |
| alarm_time=$(echo "$(get_current_time) + $seconds" | bc) | |
| alarm_time=${alarm_time%.*} | |
| alarm_num=$(get_next_alarm_num) | |
| alarm_dir="$alarms_dir/$alarm_num" | |
| # Set alarm | |
| echo "Alarm #$alarm_num will go off in $minutes minutes at $(unix_to_timestamp $alarm_time) ($seconds seconds)" | |
| mkdir -p "$alarm_dir" | |
| echo "$alarm_time" > "$alarm_dir/$alarm_time_file" | |
| echo "$say" > "$alarm_dir/$alarm_say_file" | |
| echo "" | |
| cmd_wait | |
| } | |
| function cmd_ls() { # () | |
| ds=$(get_alarms_dirs) | |
| if [ -z "$ds" ]; then | |
| echo "No alarms" | |
| else | |
| echo "Alarms:" | |
| while read "alarm_num"; do | |
| alarm_time="$(get_alarm_time $alarm_num)" | |
| alarm_time="$(unix_to_timestamp $alarm_time)" | |
| alarm_say="$(get_alarm_say $alarm_num)" | |
| echo " - $alarm_num: $alarm_time, \"$alarm_say\"" | |
| done <<< "$ds" | |
| fi | |
| } | |
| function cmd_rm() { # ( alarm_num ) | |
| # Arguments | |
| alarm_num="$1" | |
| if [ -z "$alarm_num" ]; then | |
| echo "Error - rm: alarm_num argument must be provided" >&2 | |
| exit 1 | |
| fi | |
| # Remove | |
| rm -rf "$alarms_dir/$alarm_num" | |
| } | |
| function cmd_wait() { # () | |
| # Wait lock | |
| if [ -f "$wait_lock_file" ]; then | |
| echo "Error: wait is already running, stop or delete $wait_lock_file" >&2 | |
| exit 1 | |
| fi | |
| trap clean_wait_lock EXIT | |
| touch "$wait_lock_file" | |
| # Wait | |
| temp_poll_time="" | |
| while true; do | |
| echo "Checking alarms" | |
| current_time="$(get_current_time)" | |
| # Loop through alarms and check | |
| ds=$(get_alarms_dirs) | |
| if [ -z "$ds" ]; then | |
| echo " No alarms" | |
| sleep "$wait_poll_time" | |
| else | |
| while read "alarm_num"; do | |
| alarm_time="$(get_alarm_time $alarm_num)" | |
| # If alarm done | |
| if (( "$current_time" > "$alarm_time" )); then | |
| trigger_alarm "$alarm_num" | |
| echo " Press any key to acknowledge alarm #$alarm_num" | |
| read -t 3 -n 1 "in" </dev/tty | |
| if [ ! -z "$in" ]; then | |
| in="" | |
| cmd_rm "$alarm_num" | |
| echo " Alarm #$alarm_num removed" | |
| else | |
| echo "$in" | |
| temp_poll_time="1" | |
| fi | |
| if [ -z "$(get_alarms_dirs)" ]; then | |
| echo "No more alarms" | |
| exit 1 | |
| fi | |
| else | |
| # If alarm waiting | |
| delta=$(echo "$alarm_time - $current_time" | bc) | |
| echo " Alarm #$alarm_num has $delta seconds left" | |
| # If delta to alarm being done is less than poll interval | |
| if (( "$delta" < "$wait_poll_time" )); then | |
| # If delta is smaller than any temp poll time we have | |
| if [ -z "$temp_poll_time" ] || (( "$delta" < "$temp_poll_time" )); then | |
| temp_poll_time=$(echo "$delta + 1" | bc) | |
| fi | |
| fi | |
| fi | |
| done <<< "$ds" | |
| fi | |
| # Wait till next check | |
| sleep_time="$wait_poll_time" | |
| if [ ! -z "$temp_poll_time" ]; then | |
| sleep_time="$temp_poll_time" | |
| temp_poll_time="" | |
| fi | |
| sleep "$sleep_time" | |
| echo "" | |
| done | |
| } | |
| # Parse command | |
| cmd="$1" | |
| shift | |
| case "$cmd" in | |
| time) | |
| cmd_time "$@" | |
| ;; | |
| set) | |
| cmd_set "$@" | |
| ;; | |
| ls) | |
| cmd_ls | |
| ;; | |
| rm) | |
| cmd_rm "$@" | |
| ;; | |
| wait) | |
| cmd_wait | |
| ;; | |
| *) | |
| echo "Error: unknown command $cmd" >&2 | |
| exit 1 | |
| ;; | |
| esac | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| afplay /System/Library/Sounds/Funk.aiff |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| terminal-notifier -message "$1" -title "Terminal Notification" | |
| bloop |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment