#!/bin/sh [[ -e /opt/bssdtk/core ]] && . /opt/bssdtk/core || { echo Requires bssdtk to be installed. exit 1 } requireOnce colors DATAFILE="${HOME}/.todo-list" DATE_FORMAT="%Y-%m-%d %H:%M" MINUTE=60 HOUR=$(( $MINUTE * 60)) DAY=$(( $HOUR * 24)) WEEK=$(( $DAY * 7 )) MONTH=$(( $WEEK * 4 )) YEAR=$(( $WEEK * 52 )) function SaveNewToDo () { [[ -e "${DATAFILE}.temp" ]] && mv "${DATAFILE}.temp" "${DATAFILE}" } function Plural () { [[ "$3" != "1" ]] && echo "$3 $2" || echo "$3 $1" } function ToSeconds () { if [[ "$(uname)" == "Darwin" ]] ; then # Mac Version date -j -f "%a %b %d %T %Z %Y" "$1" "+%s" else date --date "`date`" "+%s" fi; } function FromSeconds () { if [[ "$(uname)" == "Darwin" ]] ; then # Mac Version date -r "$1" +"$DATE_FORMAT" else # Linux Version date -d @"$1" +"$DATE_FORMAT" fi } function DayName () { if [[ "$(uname)" == "Darwin" ]] ; then # Mac Version local when=$(date -r "$1") else # Linux Version local when=$(date -d @"$1") fi local name=$(echo $when | cut -d " " -f 1) local day=$(echo $when | cut -d " " -f 3) case day in 1|21|31) local suffix=st ;; 2|22) local suffix=nd ;; 3|23) local suffix=rd ;; *) local suffix=th esac echo $name the ${day}${suffix} } function SetRemainingText () { if [[ "$status" == "C" ]] ; then remaining="$(FromSeconds $due)" remaining_text=Completed else remaining=$(( $due - $(ToSeconds "$(date)") )) remaining_text="$remaining" if [[ $remaining -lt 0 ]] ; then remaining_text=Overdue elif [[ $remaining -lt $DAY ]] ; then remaining_text="Today by $(echo $(FromSeconds $due) | cut -d ' ' -f 2)" elif [[ $remaining -lt $WEEK ]] ; then remaining_text="In $(Plural day days $(( $remaining / $DAY )) ) on $(DayName $due)" else remaining_text="In $(Plural week weeks $(( $remaining / $WEEK ))) on $(echo $(FromSeconds $due) | cut -d ' ' -f 1)" fi fi } function SetPriorityText () { case $priority in L) priorty_text=Low ;; H) priorty_text=High ;; *) priorty_text=Medium esac } function DoToDo () { local task=$1 shift index=0 while read -r line ; do [[ "$(echo $line)" == "" ]] && continue status=$(echo $line|cut -d , -f 1| tr "[:lower:]" "[:upper:]") priority=$(echo $line|cut -d , -f 2| tr "[:lower:]" "[:upper:]") SetPriorityText added=$(echo $line|cut -d , -f 3) due=$(echo $line|cut -d , -f 4) SetRemainingText message=$(echo $line|cut -d , -f 5-) $task (( index++ )) done<"$DATAFILE" } function ShowItem () { echoNoBreak "#$index ($priorty_text), ${remaining_text}, ${message}" } function SaveItem () { echo "$status,$priority,$added,$due,$message">>"${DATAFILE}.temp" } function ShowAllOfType () { local class=$1 shift if [[ "$class" == "*" ]] || [[ "${class//$status/}" != "$class" ]] ; then ShowItem fi } function ShowIncomplete () { ShowAllOfType I } function PushToDo () { if [[ "$number" == "*" ]] || [[ "$number" == "$index" ]] ; then case $(echo $delayinc | tr "[:upper:]" "[:lower:]") in day|days) local pushby=$(( $delayby * $DAY )) ;; week|weeks) local pushby=$(( $delayby * $WEEK )) ;; month|months) local pushby=$(( $delayby * $MONTH )) ;; year|years) local pushby=$(( $delayby * $YEAR)) ;; *) local pushby=$(( $delayby * $HOUR )) esac setColor red ShowItem due=$(( $due + $pushby )) setColor green SetRemainingText ShowItem setColor default fi SaveItem } function MarkComplete () { if [[ "$number" == "*" ]] || [[ "$number" == "$index" ]] ; then setColor green now=$(ToSeconds "$(date)") due=$now status=C SetPriorityText SetRemainingText ShowItem setColor default fi SaveItem } while [[ "${1}" != "" ]] ; do case "${1}" in help) echoNoBreak "Usage: ${0##*/} option [parameters...]" echoNoBreak echoNoBreak " help show help" echoNoBreak " add M add a new todo with Message" echoNoBreak " done N todo Number is complete" echoNoBreak " push N T [F] push Number is out by Time [hour,day,week..]" echoNoBreak " list list todo items." echoNoBreak exit 0 ;; add|new) message="$2" shift while [[ "$2" != "" ]] ; do message="$message $2" shift done now=$(ToSeconds "$(date)") message="I,M,$now,$(($now + $WEEK)),$message" echo "$message">>"$DATAFILE" echoNoBreak "Added new item: \`$(echo $message | cut -d , -f 5-)'" echoNoBreak "Due by $(FromSeconds $(echo $message | cut -d , -f 4))" ;; done|finish|finished|complete|completed) number="$2" shift DoToDo MarkComplete SaveNewToDo ;; push|delay) number="$2" shift delayinc="days" delayby="$2" shift if [[ "$2" != "" ]] ; then delayinc="$2" shift fi DoToDo PushToDo SaveNewToDo ;; list) [[ ! -e "$DATAFILE" ]] && { echo "No To-Do list present." exit 0 } DoToDo ShowIncomplete ;; *) echo "Error: \`${1}' is an invalid option." exit 1 esac shift done