You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
325 lines
8.9 KiB
Bash
325 lines
8.9 KiB
Bash
2 years ago
|
#!/usr/bin/env bash
|
||
|
|
||
|
# this script enables water tracking in tmux status bar via a simple command
|
||
|
|
||
|
usage() {
|
||
|
cat <<EOF
|
||
|
usage: $0 [-chr][-s|S][-u|U QTY] [WATER]
|
||
|
|
||
|
Options:
|
||
|
-c, --colorize enables tmux color options
|
||
|
-s, --symbol enables static nerdfont compaitable symbol
|
||
|
-S enables dynamic nf symbol
|
||
|
-u, --undo removes the last entry
|
||
|
-U removes the last QTY entries.
|
||
|
use all as QTY to remove all entries
|
||
|
-r, --reminder creates a tmux pop up to remind you to hydrate
|
||
|
-h, --help display this message
|
||
|
|
||
|
The reminder works based on specified water goals
|
||
|
Defaults to 32 ounces by 10 am, 64 by 1 pm, 96 by 5 pm, and 128 by 8 pm
|
||
|
Goals are defined in the script itself.
|
||
|
If a sub goal is not reached, the reminder will trigger
|
||
|
Reminders have a dismiss option as well as an entry box to enter the water drank
|
||
|
Reminders will pop up every 30 minutes until the goal is reached
|
||
|
|
||
|
The WATER arguement is an integer and will be added to the current total.
|
||
|
If a mistake is made, -u can remove the faulty entry.
|
||
|
EOF
|
||
|
exit $1
|
||
|
}
|
||
|
|
||
|
DATE=$(date +%b_%d_%y)
|
||
|
TIME=$(date +%H:%M:%S)
|
||
|
|
||
|
WATER_DIR="$HOME/.dotfiles/bin/water"
|
||
|
WATERFILE="${WATER_DIR}/${DATE}.csv" # makes it easy to reset on each new day
|
||
|
|
||
|
|
||
|
# customize goal amt and timings.
|
||
|
# checks based on current input and then cross references with goals
|
||
|
# linear calc so in this example 32 by 10, 64 by 13 etc.
|
||
|
####################################
|
||
|
GOAL_AMT=128 # fl. oz.
|
||
|
GOALS=( "10:00" "13:00" "16:00" "20:00" )
|
||
|
SNOOZE=30 # time between reminders (minutes)
|
||
|
####################################
|
||
|
|
||
|
# Colors
|
||
|
RED='#[fg=color1]'
|
||
|
YELLOW='#[fg=color3]'
|
||
|
LIGHT_YELLOW='#[fg=color226]'
|
||
|
LIGHT_GREEN='#[fg=color112]'
|
||
|
GREEN='#[fg=color21]'
|
||
|
BLUE='#[fg=color33]'
|
||
|
|
||
|
# Symbols to use
|
||
|
STATIC_SYMBOL='\uf6aa'
|
||
|
# from empty -> 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
|