#! /bin/bash # Usage: # context 1h2m30s (Update current context with given time) # context -s 1h20m (Set current context with given time) # context (Check total time of each context) LOG_FILE=~/log/.context && touch $LOG_FILE PLAN_FILE=~/log/plan.context.md context="$(cat ~/.task/context)" [[ "$@" =~ '-s' ]] && SET=true && shift time="$1" # The unit of time display. For example: # If it is 900(seconds), then the minimal symbol of # time display is 15min UNIT=900 #BLOCK_CHAR= BLOCK_CHAR=▮ #▊◼ # This dictionary store the valid contexts and the time I plan to spend on declare -A SPEND # Get seconds from given string _get_seconds() { # Modify input to fit the format that `date` can read hour=$(grep -o '[0-9.]\+h' <<<"$1" | tr -d '[:alpha:]') min=$(grep -o '[0-9.]\+m' <<<"$1" | tr -d '[:alpha:]') sec=$(grep -o '[0-9.]\+s' <<<"$1" | tr -d '[:alpha:]') echo "${hour:-0}*3600 + ${min:-0}*60 + ${sec:-0}" | bc | xargs printf '%.0f\n' } _save_spend_time_to_dic() { while read ctx sec; do [ -z "$ctx" ] && continue SPEND[$ctx]=$sec done <$LOG_FILE } # Update spend time on current context _update_spend_time() { # If current conetxt is not given, exit with 1 if [ -z "$context" ] || [ "$context" = none ]; then exit 1 fi given_seconds="$(_get_seconds "$time")" # Get total time of given time and current context time while read -r ctx sec; do if [ "$ctx" = "$context" ]; then total=$(( "$sec" + "$given_seconds" )) [ "$SET" = true ] && break sed -i -E "s/^${context}.*/${context}\t${total}/" $LOG_FILE exit 0 fi # Update Log file done <$LOG_FILE echo -e "$context\t${given_seconds}" >>$LOG_FILE } # Print spend for each context _print_spend_time() { _save_spend_time_to_dic while read -r line; do [ -z "$line" ] && break ctx=$(awk '{print $1}' <<<"$line") time=$(awk '{print $2}' <<<"$line") seconds_of_plan=$(_get_seconds $time) sec=${SPEND[$ctx]}; sec=${sec:-0} # Print context and time I spend echo -ne "$ctx\t\t" date -u -d @"$sec" +%H:%M | tr -d '\n' number_of_spend=$(( $sec / $UNIT )) # Print block of time spend (green) echo -ne "\t\t\e[32m" [ ! "$number_of_spend" = 0 ] && printf "%0.s$BLOCK_CHAR" $(seq $number_of_spend) echo -en "\e[0m" if [ -n "$seconds_of_plan" ]; then number_of_plan=$(( ${seconds_of_plan} / $UNIT )) [ "$(( $seconds_of_plan % $UNIT ))" = 0 ] || (( number_of_plan++ )) number_of_remaining=$(( $number_of_plan - $number_of_spend )) # Print block of remaining time (normal) if (( "$number_of_remaining" > 0 )); then printf "%0.s$BLOCK_CHAR" $(seq $number_of_remaining) # Print block of exceed time (red) elif (( "$number_of_remaining" < 0 )); then number_of_exceed=${number_of_remaining#-} printf "%0.s\b" $(seq $number_of_exceed) echo -ne "\e[31m" printf "%0.s$BLOCK_CHAR" $(seq $number_of_exceed) echo -en "\e[0m" fi fi echo done <$PLAN_FILE } if [ -n "$1" ]; then _update_spend_time else _print_spend_time fi