#!/usr/bin/env bash # this script enables water tracking in tmux status bar via a simple command usage() { cat < full DYNAMIC_SYMBOL=( '\uf58d' '\uf579' '\uf57a' '\uf57b' '\uf57c' '\uf57d' '\uf57e' '\uf57f' '\uf580' '\uf581' '\uf578' ) get_current_amt() { # gets the current water intake if [[ ! -f "$WATERFILE" ]] ; then # no waterfile # archiving old file mv ${WATER_DIR}/*.csv ${WATER_DIR}/archive # creating new file for the day printf 'Time, Change, Running Total\n' > "$WATERFILE" printf '%s, 0, 0\n' "$TIME" >> "$WATERFILE" else # waterfile exists CURRENT_WATER=$(cat $WATERFILE | tail -n 1 | awk '{print $3}') fi } reminder() { # checks and creates a reminder if [[ -z "$TMUX" ]] ; then echo "TMUX required for reminder!" exit 1 fi # this will round up goal_incr=$((($GOAL_AMT + ${#GOALS[@]}-1) / ${#GOALS[@]})) # index of the time to check in $GOALS cur_indx=$(($CURRENT_WATER / $goal_incr)) if [[ $CURRENT_WATER -lt $GOAL_AMT ]] ; then # goals not finished, check pace time_unix=$(date -d "$TIME" +%s) # expired is goaltime - current time expired=$(( $(date -d "${GOALS[$cur_indx]}" +%s) - $time_unix)) if [[ $expired -lt 0 ]] ; then # goal missed, check snooze source "$WATER_DIR/.reminder" 2>/dev/null # check elapsed if [[ $time_unix -gt $REMINDER_SNOOZE ]] ; then # trigger reminder goal=$(( ($GOAL_AMT * ($cur_indx + 1)) / ${#GOALS[@]})) fmt_time=$(date -d "${GOALS[$cur_indx]}" "+%l:%M %P") rem_info=$(printf 'You have only drank %d fl. oz. while your goal is to drink %d fl. oz. by %s!\n\nThis reminder will reappear in %d minutes unless you consume fluids!\n\nOptionally, mute this reminder until tomorrow' $CURRENT_WATER $goal "$fmt_time" $SNOOZE) tmux display-popup -E\ dialog\ --title 'DEHYDRATION ALERT'\ --yes-label 'Dismiss'\ --no-label 'Mute'\ --yesno \ "$rem_info" 0 0 # check for mute if [[ $? == 1 ]] ; then # muted until tomorrow TTS=$(date -d "tomorrow 00:00:00" +%s) else TTS=$(date -d "+ $SNOOZE minutes" +%s) fi # update last_reminder printf 'REMINDER_SNOOZE=%d\n' $TTS > "$WATER_DIR/.reminder" fi fi fi } update_water() { # updates water based on $WATER_CHANGE CURRENT_WATER=$(($CURRENT_WATER + $WATER_CHANGE)) # putting in file printf '%s, %d, %d\n' "$TIME" $WATER_CHANGE $CURRENT_WATER >> "$WATERFILE" } undo_changes() { # removes specifed entries # gets the lines of entries WATER_LINES=$(($(wc -l < "$WATERFILE") - 2)) if [[ $WATER_LINES -gt 0 ]] ; then # removing entries if [[ "$1" == "all" || "$1" == "ALL" ]] ; then # force a reset REMOVAL=$WATER_LINES elif [[ $1 =~ ^[0-9]+$ ]] ; then # remove $1 changes if [[ $1 -gt $WATER_LINES ]] ; then printf 'Only %d entries\n' $WATER_LINES REMOVAL=$WATER_LINES else REMOVAL=$1 fi else printf 'Arguement %s not recognized\n' "$1" usage exit 1 fi choice=$(bash -c "read -p 'Are you sure you want to remove $REMOVAL entries? (y/n)' -n 1 -r c; echo \$c") echo "" if [[ $choice =~ ^[Yy]$ ]] ; then # remove if [[ $WATER_LINES -gt $REMOVAL ]] ; then # removing specified lines last_line=$(($WATER_LINES - $REMOVAL + 3)) # account for offset sed -i "$last_line ,$ d" "$WATERFILE" else # essentially a reset printf 'Time, Change, Running Total\n' > "$WATERFILE" printf '%s, 0, 0\n' "$TIME" >> "$WATERFILE" fi # updating amount get_current_amt fi echo "Removed $REMOVAL entries!" else echo "Nothing to remove!" fi } colorize() { # sends water intake level through conditionals to be colorized if [[ $1 -lt 32 ]] ; then color="$RED" elif [[ $1 -lt 64 ]] ; then color="$YELLOW" elif [[ $1 -lt 96 ]] ; then color="$LIGHT_YELLOW" elif [[ $1 -lt 128 ]] ; then color="$LIGHT_GREEN" else color="$GREEN" fi # avoids newlines printf '%s' "$color" } print_water() { # formats and prints $CURRENT_WATER if [ "$SYMBOL" == "dynamic" ] ; then # getting dynamic symbol # rounding down symb_indx=$(echo "scale=1; indx=($CURRENT_WATER / $GOAL_AMT) * ${#DYNAMIC_SYMBOL[@]}; scale=0; indx/1" | bc) if [[ $symb_indx -ge ${#DYNAMIC_SYMBOL[@]} ]] ; then # trimming symb_indx=$((${#DYNAMIC_SYMBOL[@]}-1)) fi # if colors are enabled, colorize the symbol if [ "$COLORIZE" = true ] ; then clr="$BLUE" fi printf '%s%s ' "$clr" $(echo -e "${DYNAMIC_SYMBOL[$symb_indx]}") elif [[ "$SYMBOL" == "static" ]] ; then # space for double wide printf '%s ' "$STATIC_SYMBOL" fi if [ "$COLORIZE" = true ] ; then dflt="#[default]" printf '%s' "$(colorize $CURRENT_WATER)" fi printf '%d%s\n' $CURRENT_WATER "$dflt" # checks for a reminder if [[ "$REMINDER" = true ]] ; then # reminders enabled reminder fi } # make dir on fresh installs if [[ ! -d "${WATER_DIR}/archive" ]] ; then mkdir -p "${WATER_DIR}/archive" fi # get the current amount get_current_amt # transform long form args for arg in "$@"; do shift case "$arg" in '--help') set -- "$@" "-h" ;; '--colorize') set -- "$@" "-c" ;; '--reminder') set -- "$@" "-r" ;; '--undo') set -- "$@" "-u" ;; '--symbol') set -- "$@" "-s" ;; *) set -- "$@" "$arg" ;; esac done # parsing args while getopts "hcrsSuU:" opt ; do case "$opt" in 'c' ) COLORIZE=true ;; 's' ) [ -n "$SYMBOL" ] && usage 1 || SYMBOL="static" ;; 'S' ) [ -n "$SYMBOL" ] && usage 1 || SYMBOL="dynamic" ;; 'u' ) [ -n "$UNDO" ] && usage 1 || UNDO=1 ;; 'U' ) [ -n "$UNDO" ] && usage 1 || UNDO="$OPTARG" ;; 'r' ) REMINDER=true ;; 'h' ) usage ;; '?' ) usage 1 >&2 ;; esac done # check for undo first if [[ ! -z "$UNDO" ]] ; then undo_changes "$UNDO" fi # get the change (if any) shift $(($OPTIND - 1)) WATER_CHANGE=$1 # update totals if [[ ! -z "$WATER_CHANGE" ]] ; then # prevent empty/0 updates update_water fi # return the new total # Could make this an opt, but it seems to be a good default behavior print_water