#! /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) # # TODO support minus time # trap 'exit 1' SIGUSR1 trap 'which rsync_retry.sh &>/dev/null && setsid rsync_retry.sh $LOG_FILE &>/dev/null &' EXIT LOG_FILE=~/.context && touch $LOG_FILE PLAN_FILE=~/log/plan.context.md PROC=$$ 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:]') [ -z "$hour$min$sec" ] && kill -10 $PROC echo "${hour:-0}*3600 + ${min:-0}*60 + ${sec:-0}" | bc | xargs printf '%.0f\n' } # Get formated string from given seconds _format_seconds() { hour=$(( $1 / 3600 )) min=$(( ($1 % 3600) / 60 )) sec=$(( $1 % 60 )) echo ${hour}h${min}m${sec}s } _save_spend_time_to_dic() { while read -r ctx sec; do [ -z "$ctx" ] && continue SPEND[$ctx]=$sec done <$LOG_FILE } _desktop_notify() { which notify-send &>/dev/null && notify-send "$context +$1" } # 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")" _desktop_notify "$(_format_seconds "${given_seconds}")" # Get total time of given time and current context time while read -r ctx sec; do if [ "$ctx" = "$context" ]; then total=$(( "$sec" + "$given_seconds" )) if [ "$SET" = true ]; then sed -i -E "/^${context}.*/d" $LOG_FILE break else sed -i -E "s/^${context}.*/${context}\t${total}/" $LOG_FILE exit 0 fi 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 [ "$context" = "$ctx" ] && echo -ne '\e[33;1m' echo -ne "$ctx\t\t" date -u -d @"$sec" +%H:%M | tr -d '\n' echo -n "/" date -u -d @"$seconds_of_plan" +%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 echo -ne "\e[31m" number_of_exceed=${number_of_remaining#-} printf "%0.s\b" $(seq "$number_of_exceed") 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