#! /bin/bash
### --------
### Todo-cli v. 0.777.persei8
### A Super Simple Todo on CLI
### Created by: Lazy
### --------
### INITIALIZE
OPTIND=1
redo=1
MON=0
DAT=0
MINT=0
HR=0
###### FIRST TIME?
# Prefered text editor to edit notes with (vim,gedit,sandy etc)
FEDITOR="vim"
# Locations
TODODIR="/home/$USER"
TODODB="$TODODIR/.TODODB"
#TODODIR=/User/$User ## OSX Filesystem
# HINT: can be used with dropbox for `cloud-based` task list
# TODODIR="/path/to/dropbox/dir"
# TODODB="$TODODIR/.TODODB"
####### END CUSTOM CONFIGURATION
if [[ -d $TODODB ]]; then
PM=1
else
## Create appropriate dirs
mkdir $TODODB
mkdir $TODODB/data
mkdir $TODODB/backup
mkdir "$TODODB/data/notes"
fi
if [[ -e "$TODODB/REMTMP" ]]; then
rm "$TODODB/REMTMP"
else
PM=2
fi
if [[ -e $TODODB/REMTMP1 ]]; then
rm "$TODODB/REMTMP1"
else
PM=2
fi
if [[ -d $TODODB ]]; then
PM=1
else
## Create appropriate dirs
mkdir $TODODB
mkdir $TODODB/data
mkdir $TODODB/backup
fi
## END INITIALIZE
## BEGIN DEFINING FUNCTIONS
HABITS () {
echo 'What habit? (todo)'
read habit
cale
echo 'How often? [min/hr/day/month/weekday]'
read recc
case recc in
hr)
errchance=0
while [[ $errchance -lt 3 ]]; do
echo "every (0-23) hours?"
read timeval
if [[ "$timeval" = *[![:digit:]]* ]]; then
TIMESCALE=2
DUECRANK
else
echo "Not valid. Try again."
let errchance=errchance+1
fi
done
;;
esac
}
DUECRANK () {
#designated cron handler
case TIMESCALE in
2)
"* */$timeval * * * notify-send "
;;
esac
}
TODORM () {
TASKNUM=`awk -F";" '{ print $1 }' $TODODIR/TODO | grep -w $OPTARG`
NOTEX=`awk -F";" '{ print $1 }' "$TODODIR/TODO" | grep -w $OPTARG | awk -F";" -v d=$OPTARG '{ if ( $1 == d ) print $6}' "$TODODIR/TODO"`
if [[ "$OPTARG" = "$TASKNUM" ]]; then
if [[ "$NOTEX" = "" ]]; then
ok=ok
else
if [[ -a "$TODODB/data/notes/note-$OPTARG" ]]; then
rm "$TODODB/data/notes/note-$OPTARG"
else
ok=ok
fi
fi
grep -wv "^${OPTARG}" $TODODIR/TODO > $TODODIR/TODO.bak
cp $TODODIR/TODO.bak $TODODIR/TODO
echo "Task No."$TASKNUM" succesfully removed"
else
echo "Error: Task $OPTARG does not exist"
exit
fi
}
INVALID () {
echo "Invalid option: -$OPTARG"
echo "-h for optionn" || exit 1
}
CLEAR () {
if [[ -a $TODODIR/TODO ]]; then
touch "$TODODIR/TODOALL.bak"
cp $TODODIR/TODO $TODODIR/TODOALL.bak
echo "Back up created:"
echo "$TODODIR/TODOALL.bak"
rm $TODODIR/TODO
elif [[ "$resp" = n || "$resp" = N ]]; then
echo "Okay."
exit
fi
}
RESTORE () {
echo "Restoring latest back up..."
if [[ -a ~/TODOALL.bak ]]; then
cp $TODODIR/TODOALL.bak $TODODIR/TODO
echo "Finished"
exit 0
else
echo "No recorded backups"
exit
fi
}
TODOLIST () {
if [[ -a $TODODIR/TODO ]]; then
case $OPTARG in
full)
column -t -s ":" "$TODODIR/TODO" | awk -F";" 'BEGIN { print " Created On To-do Notes"
print "================ =================================== =============================" }
{ print $2" "," "$1"."" ""("$4")["$5"] "$3" ",$6 }'
;;
q)
column -t -s ":" "$TODODIR/TODO" | awk -F";" ' { $8= 0; if ( $6 !="" ) $8 = "+"; else $8= "";
if ( $4 == "high" || $4 == "High" ) print "\033[1;37m" $1"." "\033[0m","\033[0;31m"$8 $3 "\033[0m" ;
else if ( $4 == "med" || $4 == "Med" ) print "\033[1;37m" $1".","\033[0;32m"$8 $3 "\033[0m" ;
else if ( $4 == "low" || $4 == "Low") print "\033[1;37m" $1".","\033[0;33m"$8 $3 "\033[0m" ;
else
print "\033[1;34m" $1"." "\033[0m",$8 $3 }; '
;;
tree)
tree=$( awk -F";" '{ print $5 }' "$TODODIR/TODO" | sort | uniq )
for i in $tree
do
echo -e "\e[1;33m[$i]\e[00m"
awk -F";" '{ $8="0"; $2=""; if ( $6 !="" ) $8 = "+"; else $8= ""; if ( $4 == "high" || $4 == "High") print "\033[1;37m" $1".","\033[0;31m"$8 $3 "\033[0m", $5;
else if ( $4 == "med" || $4 == "Med" ) print "\033[1;37m" $1".","\033[0;32m"$8 $3 "\033[0m", $5;
else if ( $4 == "low" || $4 == "Low" ) print "\033[1;37m" $1".","\033[0;33m"$8 $3 "\033[0m"m, $5;}' ~/TODO | grep $i | sed -r "s/(^.+) .+$/\1/g"
echo -e ""
done
;;
?)
echo "Invalid options. -full for full list. -q for quick list. -t tree list."
exit 0
;;
esac
else
echo TODO file does not exist. Create a new task first.
fi
}
TODOP () {
touch .TODOTMP; touch .TODOTMP2
TASKNUM=`awk -F";" '{ print $1 }' $TODODIR/TODO | grep -w "$OPTARG"`
if [[ "$OPTARG" = "$TASKNUM" ]]; then
if [[ "$PRI" = "low" || "$PRI" = "Low" || "$PRI" = "med" || "$PRI" = "Med" || "$PRI" = "high" || "$PRI" = "High" ]]; then
OLD=$(grep -w "$OPTARG" $TODODIR/TODO)
echo $OLD >> .TODOTMP
awk ' BEGIN { FS=":"; OFS=":" } { $4="'$PRI'" }1 ' .TODOTMP >.TODOTMP2
NEW=$(cat .TODOTMP2)
sed "s/$OLD/$NEW/g" $TODODIR/TODO > TODO.bak
cp TODO.bak $TODODIR/TODO
rm .TODOTMP .TODOTMP2
echo "Task #"$TASKNUM" succesfully reprioritized to $PRI"
else
echo "Error: Valid Priorities are Low, Med, High -- Try again."
exit 0
fi
else
echo "Error: Task $OPTARG does not exist" || exit 2
fi
}
anscheck () {
if [[ "$ans" == Y || "$ans" == y || "$redo" -lt "3" ]]; then
echo "FORMAT: Month/Date/Hour/Minute"
let redo=redo+1
timecheck
else
if [[ "$ans" == N || "$ans" == n ]]; then
echo "Reminder not set. (Try again... if you wish)"
fi
fi
}
retry () {
if [ "$P1" == "1" ] && [ "$P2" == "1" ] && [ "$P3" == "1" ] && [ "$P4" == "1" ]; then
FU="reminder"
echo "Retry $FU input? (Y/N)"
read ans
if [ y = "$ans" ] || [ Y = "$ans" ] && [ "$redo" -lt "3" ]; then
echo "New Reminder Input (Month/Date/Hour/Minute):"
let redo=redo+1
else
if [ "$ans" = n ] || [ "$ans" = n ]; then
echo "Reminder not set. (Try again... if you wish)"
exit 0
fi
fi
read newrem
TPARSE
else
if [[ $P1 == "1" ]]; then
FU=MON
echo "Month must be between (1-12). Retry month input?"
read ans
if [ y = "$ans" ] || [ Y = "$ans" ] && [ "$redo" -lt "3" ]; then
echo "New Month Input (1-12):"
let redo=redo+1
else
if [ "$ans" = n ] || [ "$ans" = n ]; then
echo "Reminder not set. (Try again... if you wish)"
exit 0
fi
fi
read MON
timecheck
else
if [[ $P2 == "1" ]]; then
FU=DAT
echo "Date must be between (1-31). Retry date input?"
read ans
if [ y = "$ans" ] || [ Y = "$ans" ] && [ "$redo" -lt "3" ]; then
echo "New Hour Input (0-23):"
let redo=redo+1
else
if [ "$ans" = n ] || [ "$ans" = n ]; then
echo "Reminder not set. (Try again... if you wish)"
exit 0
fi
fi
read DAT
timecheck
else
if [[ $P3 == "1" ]]; then
FU=HR
echo "$FU must be between (0-23). Retry $FU input?"
read ans
if [ y = "$ans" ] || [ Y = "$ans" ] && [ "$redo" -lt "3" ]; then
echo "New Hour Input (0-23):"
let redo=redo+1
else
if [ "$ans" = n ] || [ "$ans" = n ]; then
echo "Reminder not set. (Try again... if you wish)"
exit 0
else
exit 0
fi
fi
read HR
timecheck
else
if [[ $P4 == "1" ]]; then
FU=MINT
echo "$FU must be between (0-59). Retry $FU input?"
read ans
if [ y = "$ans" ] || [ Y = "$ans" ] && [ "$redo" -lt "3" ]; then
echo "New Minute Input (0-59):"
let redo=redo+1
else
if [ "$ans" = n ] || [ "$ans" = n ]; then
echo "Reminder not set. (Try again... if you wish)"
exit 0
else
exit 0
fi
fi
read MINT
timecheck
fi
fi
fi
fi
fi
}
timecheck () {
##checks if time values are sensible
## Gets input from either REMDUE or RETRY
if [ $MON -ge 1 ] && [ $MON -le 12 ]; then
P1="2"
else
P1="1"
fi
if [ $DAT -ge 1 ] && [ $DAT -le 31 ]; then
P2="2"
else
P2="1"
fi
if [ $HR -ge 0 ] && [ $HR -le 23 ]; then
P3="2"
else
P3="1"
fi
if [ $MINT -ge "0" ] && [ $MINT -le 59 ]; then
P4="2"
else
P4="1"
fi
if [ "$P1" == "2" ] && [ "$P2" == "2" ] && [ "$P3" == "2" ] && [ "$P4" == "2" ]; then
REMDUE
else
retry
fi
}
REMDUE () {
if [[ "$PRI" = high || "$PRI" = High ]]; then
urg=critical
else
if [[ "$PRI" = med || "$PRI" = Med ]]; then
urg=normal
else
if [[ "$PRI" = low || "$PRI" = Low ]]; then
urg=low
fi
fi
fi
#Set REMINDER value in crontab DUE=$(echo "$MON/$DAT/$HR/$MINT")
crontab -l > newcron
echo -e "$MINT $HR $DAT $MON * DISPLAY=:0 /usr/bin/notify-send -u $urg \"Task: $OPTARG - $NOTES\" \n" >> newcron
crontab newcron
rm newcron
}
TPARSE () {
if [[ $FU == "" ]]; then
#TPARSE=`awk -F";" '{ print $1, $7 }' "$TODODIR/REMTMP" | grep -w "$TEST" | awk '{ print $2 }'`
#echo $TPARSE >> $TODODB/REMTMP
MON=`awk -F"/" '{ print $1 }' $TODODB/REMTMP`
DAT=`awk -F"/" '{ print $2 }' $TODODB/REMTMP`
HR=`awk -F"/" '{ print $3 }' $TODODB/REMTMP`
MINT=`awk -F"/" '{ print $4 }' $TODODB/REMTMP`
#Check if time values are sensible
PM=1
rm $TODODB/REMTMP
timecheck
else
if [[ "$FU" == "reminder" ]]; then
echo $newrem >> $TODODB/REMTMP1
MON=`awk -F"/" '{ print $1 }' $TODODB/REMTMP1`
DAT=`awk -F"/" '{ print $2 }' $TODODB/REMTMP1`
HR=`awk -F"/" '{ print $3 }' $TODODB/REMTMP1`
MINT=`awk -F"/" '{ print $4 }' $TODODB/REMTMP1`
timecheck
rm $TODODB/REMTMP1
fi
fi
}
NOTEVU () {
#TASKNUM=`awk -F";" '{ print $1, ";"$6}' "$TODODIR/TODO"`
NOTZ=`awk -F";" '{ print $1, ";"}' "$TODODIR/TODO" | grep -w $NN | awk -F";" -v d=$NN '{ if ( $1 == d )print $6 }' "$TODODIR/TODO"`
if [[ "$NOTZ" = "" ]]; then
echo "ERROR: Note doesn't exist..."
else
if [[ "$NOTZ" = "+" ]]; then
NPARSE
else
echo $NOTZ
fi
fi
}
NPARSE () {
#MASTER
cat "$TODODB/data/notes/note-$NN"
}
NODIT () {
noTEST=`awk -F";" '{ print $1 }' "$TODODIR/TODO" | tail -n 1`
number=0
echo "Opening your favourite text editor...."
echo "Opening default template. Hint: This can be changed to you liking"
sleep 1s
#clear previous nunotes
if [[ "$number" = "no$TEST" ]]; then
notename=$noTEST
let 'notename += 1'
else
notename=$noTEST
let 'notename += 1'
fi
cp "$TODODB/data/notes/templates/default" "$TODODB/data/notes/note-$notename"
$FEDITOR "$TODODB/data/notes/note-$notename"
}
### END DEFINING FUNCTIONS ###
NOTEDIT () {
if [[ -a "$TODODB/data/notes/note-$NN" ]]; then
echo "Opening your favourite text editor..."
sleep 1s
$FEDITOR "$TODODB/data/notes/note-$NN"
else
NOTZ=`awk -F";" '{ print $1, ";"}' "$TODODIR/TODO" | grep -w $NN | awk -F";" -v d=$NN '{ if ( $1 == d )print $6 }' "$TODODIR/TODO"`
if [[ "$NOTZ" = "" ]]; then
echo "ERROR: Note doesn't exist..."
else
echo "Old note: $NOTZ"
echo "Enter new note:"
read nunote
sed -i "s/$NOTZ/$nunote/g" "$TODODIR/TODO"
fi
fi
}
#Megaman! Execute!
while getopts ":p:e:h?a:l:m:czv" OPTION
do
case $OPTION in
p)
PRI=$3
TODOP ;;
e)
NN=`echo $2`
NOTEDIT ;;
h)
echo "OPTIONS:"
echo 'todo -a ["Task goes here"] [PRIORITY=low,medium,high] [TREE= any category your task belongs in] [NOTES="+", for detailed additional notes using a text editor. "a quick note", or just use the command line to add note. ] [ REMINDER="MONTH/DATE/HR/MIN", creates a reminder on specified time using notification (email coming soon) ] -- add a task'
echo 'todo -l [OPTION]'
echo ' q -- shows a numbered list with Priority Colors'
echo ' full -- shows a full list with creation date'
echo 'todo -m [Task number] -- remove specified task'
echo 'todo -p [Task number] [PRIORITY=low,medium,high] -- reprioritize task'
echo 'todo -v [Task number] -- views task note/details'
echo 'todo -e [Task number] -- edit selected task note'
echo 'todo -c -- clears ALL tasks and makes backup at $TODODIR/TODOALL.BAK '
echo 'todo -z -- restores latest backup' || exit ;;
a)
PRI=$3
BRANCH=$4
DUE=$6
NOTES=$5
number=0
touch "$TODODIR/TODO"
date=`date +"%Y-%m-%d"`
TEST=`awk -F";" '{ print $1 }' "$TODODIR/TODO" | tail -n 1`
declare -i TEST
if [[ "$PRI" = "" ]]; then
PRI=low
else
if [[ "$PRI" = "low" || "$PRI" = "Low" || "$PRI" = "med" || "$PRI" = "Med" || "$PRI" = "high" || "$PRI" = "High" ]]; then
PRI=$PRI
else
echo 'Error: Valid Priorities are Low, Med, High -- Try again.'
exit 0
fi
fi
if [[ "$DUE" != "" ]]; then
echo "$DUE" >> "$TODODB/REMTMP"
TPARSE
fi
if [[ "$NOTES" == "+" ]]; then
NEDIT=1
NODIT
else
if [[ "$NOTES" != "+" ]]; then
NOTES=$5
fi
fi
if [[ "$number" = "$TEST" ]]; then
echo "$number;$date;$OPTARG;$PRI;$BRANCH;$NOTES;$DUE" >> "$TODODIR/TODO"
echo "Task No.$number ($PRI) created"
else
let 'TEST += 1'
echo "$TEST;$date;$OPTARG;$PRI;$BRANCH;$NOTES;$DUE" >> "$TODODIR/TODO"
echo "Task No.$TEST ($PRI) succesfully created"
fi
;;
l)
TODOLIST ;;
m)
TODORM ;;
c)
CLEAR ;;
z)
RESTORE ;;
v)
NN=`echo $2`
NOTEVU ;;
?)
INVALID ;;
:)
echo 'Option -$OPTARG requires an argument.'
echo '-h for usage options' || exit 1 ;;
esac
done