913 lines
21 KiB
Bash
Executable File
913 lines
21 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
trap "exit 1" TERM
|
|
export MYPID=$$
|
|
|
|
|
|
|
|
|
|
# ANSI stuff
|
|
BOLD="\033[1m"
|
|
ITALIC="\033[3m"
|
|
STRIKE="\033[9m"
|
|
PLAIN="\033[0m"
|
|
|
|
UNDERLINE="\033[4m"
|
|
RED="\033[31m"
|
|
MAGENTA="\033[35m"
|
|
GREEN="\033[32m"
|
|
YELLOW="\033[33m"
|
|
BLUE="\033[34m"
|
|
CYAN="\033[36m"
|
|
GREY="\033[2;37m"
|
|
LINK="$BLUE$UNDERLINE"
|
|
brack="$CYAN"
|
|
HILITE="\033[43;1m"
|
|
|
|
TOPTITLE="\033[44;1m"
|
|
LEFTTITLE="\033[31;1m"
|
|
|
|
function die() {
|
|
kill -s TERM $MYPID
|
|
}
|
|
|
|
function getalts() {
|
|
local verb alt var x
|
|
verb=$1
|
|
alt=""
|
|
var="words_$verb"
|
|
IFS='|'
|
|
for x in ${!var}; do
|
|
if [[ $x != $verb ]]; then
|
|
[[ -z $alt ]] && alt=$x || alt="$alt,$x"
|
|
fi
|
|
done
|
|
IFS=' '
|
|
echo "$alt"
|
|
}
|
|
|
|
function usage() {
|
|
local titleformat format
|
|
local usage_var desc_var
|
|
format="%22s %-40s %s\n"
|
|
echo "usage: $0 COMMAND [commandopts]"
|
|
echo
|
|
printf "$format" "COMMAND" "DESCRIPTION" "SYNONYMS"
|
|
for x in $valid_modes; do
|
|
usage_var="usage_$x"
|
|
desc_var="desc_$x"
|
|
printf "$format" "${!usage_var}" "${!desc_var}" "$(getalts $x)"
|
|
done
|
|
}
|
|
|
|
function inc() {
|
|
indent=$((indent + $indentamt))
|
|
}
|
|
|
|
function dec() {
|
|
indent=$((indent - $indentamt))
|
|
}
|
|
|
|
function getuid_witherror() { # [noun]
|
|
local x rv noun
|
|
if [[ $$ -ge 2 ]]; then
|
|
noun=$2
|
|
else
|
|
noun="task"
|
|
fi
|
|
x=$(getuid $1)
|
|
rv=$?
|
|
if [[ $rv -ne 0 ]]; then
|
|
error "Specified $noun #$1 does not exist."
|
|
die
|
|
fi
|
|
echo "$x"
|
|
return $rv
|
|
}
|
|
|
|
function getuid() {
|
|
local res id uid
|
|
id=$1
|
|
res=""
|
|
for uid in ${!idmap[@]}; do
|
|
if [[ ${idmap[$uid]} == $id ]]; then
|
|
res=${uid}
|
|
break
|
|
fi
|
|
done
|
|
echo $res
|
|
if [[ -z $res ]]; then
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function getid() {
|
|
local res uid
|
|
uid=$1
|
|
res=${idmap[$uid]}
|
|
if [[ -z $res ]]; then
|
|
return 1
|
|
fi
|
|
echo $res
|
|
return 0
|
|
}
|
|
|
|
function getorgenid() {
|
|
local res uid
|
|
uid=$1
|
|
res=$(getid $uid)
|
|
if [[ -z $res ]]; then
|
|
res=$nextid
|
|
idmap[$uid]=$nextid
|
|
nextid=$((nextid + 1))
|
|
needsave=1
|
|
fi
|
|
return $res
|
|
}
|
|
|
|
function loadids() {
|
|
local LINE n uid id max
|
|
if [[ ! -e $idfile ]]; then
|
|
return 1
|
|
fi
|
|
max=0
|
|
while read LINE; do
|
|
uid=${LINE%:*}
|
|
id=${LINE#*:}
|
|
idmap[$uid]=$id
|
|
[[ $id -gt $max ]] && max=$id
|
|
done < "$idfile"
|
|
nextid=$((max + 1))
|
|
return 0
|
|
}
|
|
|
|
function saveids() {
|
|
local uid
|
|
cp /dev/null $idfile
|
|
for uid in ${!idmap[@]}; do
|
|
echo "$uid:${idmap[$uid]}" >> $idfile
|
|
done
|
|
}
|
|
|
|
function dumpids() {
|
|
local uid
|
|
for uid in ${!idmap[@]}; do
|
|
echo "$uid --> ${idmap[$uid]}"
|
|
done
|
|
}
|
|
|
|
function loadtasks() {
|
|
local f ess
|
|
maxid=-1
|
|
ntasks=0
|
|
dblog "Loading tasks..."
|
|
for f in $dir/*.vcf; do
|
|
loadtask $f
|
|
ntasks=$((ntasks + 1))
|
|
done
|
|
numwid=${#maxid}
|
|
|
|
[[ $ntasks -eq 1 ]] && ess="" || ess="s"
|
|
dblog "Finished loading $ntasks task$ess."
|
|
}
|
|
|
|
function dblog() {
|
|
[[ $DEBUG -eq 1 ]] && echo "$(date) $*"
|
|
}
|
|
|
|
function action() {
|
|
echo -e "$BOLD$YELLOW* $PLAIN$YELLOW$*$PLAIN"
|
|
}
|
|
|
|
function error() {
|
|
echo -e "$BOLD${RED}ERROR: $PLAIN$RED$*$PLAIN" >/dev/stderr
|
|
}
|
|
|
|
function info() {
|
|
echo -e "$BOLD${CYAN}>> $PLAIN$CYAN$*$PLAIN"
|
|
}
|
|
|
|
function confirm() {
|
|
local yn
|
|
echo -en "$BOLD${MAGENTA}CONFIRM: $PLAIN$MAGENTA$* (y/N)? $PLAIN"
|
|
read yn
|
|
if [[ $yn == "y" ]]; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
function loadtask() {
|
|
local uid sum checked desc file id parent res i
|
|
|
|
file="$1"
|
|
res=$(cat $file | awk -F: 'BEGIN { checked=0; } /^UID:/ { printf("uid©%s©",$2); } /^SUMMARY:/ { sub("SUMMARY:",""); printf("sum©%s©",$0); } /^DESCRIPTION:/ { sub("DESCRIPTION:",""); printf("desc©%s©",$0); } /^RELATED-TO/ { sub("^RELATED-TO.*:",""); printf("parent©%s©",$0); } /^STATUS:COMPLETED/ { checked=1; } END { printf("checked©%d\n",checked); }')
|
|
|
|
IFS='©'
|
|
read -ra tok <<< "$res"
|
|
parent=""
|
|
i=0
|
|
while [[ ! -z ${tok[$i]} ]]; do
|
|
if [[ ${tok[$i]} == "uid" ]]; then
|
|
uid=${tok[$((i + 1))]}
|
|
getorgenid $uid
|
|
id=$?
|
|
elif [[ ${tok[$i]} == "sum" ]]; then
|
|
sum="${tok[$((i + 1))]}"
|
|
elif [[ ${tok[$i]} == "desc" ]]; then
|
|
desc="${tok[$((i + 1))]}"
|
|
elif [[ ${tok[$i]} == "parent" ]]; then
|
|
parent="${tok[$((i + 1))]}"
|
|
elif [[ ${tok[$i]} == "checked" ]]; then
|
|
checked="${tok[$((i + 1))]}"
|
|
fi
|
|
i=$((i + 2))
|
|
done
|
|
IFS=' '
|
|
|
|
taskuid[$uid]=$uid
|
|
taskid[$uid]=$id
|
|
tasksum[$uid]=$sum
|
|
taskdesc[$uid]=$desc
|
|
taskchecked[$uid]=$checked
|
|
taskparent[$uid]=$parent
|
|
|
|
[[ $id -gt $maxid ]] && maxid=$id
|
|
[[ ${#sum} -gt $taskwid ]] && taskwid=${#sum}
|
|
[[ ${#desc} -gt $taskwid ]] && taskwid=${#desc}
|
|
}
|
|
|
|
function marknotdone() {
|
|
local uid rv file sedrv
|
|
local children childuid ischild noun
|
|
uid=$1
|
|
[[ $# -gt 1 ]] && ischild=1 || ischild=0
|
|
[[ $ischild -eq 1 ]] && noun=subtask || noun=task
|
|
# already not done?
|
|
if [[ ${taskchecked[$uid]} -eq 0 ]]; then
|
|
error "$noun #${taskid[$uid]} is already unfinished"
|
|
return 1
|
|
fi
|
|
file=$dir/$uid.vcf
|
|
sed -i '/^COMPLETED:/d;/^STATUS:COMPLETED/d;/PERCENT-COMPLETE:100/d' $file
|
|
sedrv=$((sedrv + $?))
|
|
set_lastmodified $uid
|
|
sedrv=$((sedrv + $?))
|
|
if [[ $sedrv -eq 0 ]]; then
|
|
action "Marked $noun #${taskid[$uid]} as completed."
|
|
processed="$processed ${uid}"
|
|
loadtask $file
|
|
rv=0
|
|
children=$(getchildren $uid)
|
|
for childuid in ${children}; do
|
|
marknotdone $childuid noprint
|
|
rv=$((rv + $?))
|
|
done
|
|
else
|
|
error "failed to mark $noun #${taskid[$uid]} as unfinished"
|
|
rv=1
|
|
fi
|
|
|
|
return $rv
|
|
}
|
|
|
|
function delq_clear() {
|
|
deluids=""
|
|
}
|
|
|
|
function delq_add() {
|
|
local x
|
|
if [[ ! $deluids == *\ $1\ * ]]; then
|
|
deluids="$deluids $1"
|
|
for x in $(getchildren $1); do
|
|
delq_add $x
|
|
done
|
|
fi
|
|
}
|
|
|
|
function delq_process() {
|
|
local uidlist uid rv yn file count ess wantshow
|
|
rv=0
|
|
|
|
# Remove duplicates
|
|
deluids=$(echo $deluids | tr ' ' '\n' | sort -u | tr '\n' ' ')
|
|
|
|
info "The following tasks will be removed:"
|
|
needtitle=0
|
|
for uid in $deluids; do
|
|
wantshow=0
|
|
|
|
# don't show if it's a subtask of one already in the list
|
|
if [[ -z ${taskparent[$uid]} ]]; then
|
|
wantshow=1
|
|
elif [[ $deluids == *${taskparent[$uid]}\ * ]]; then
|
|
wantshow=0
|
|
else
|
|
wantshow=1
|
|
fi
|
|
|
|
if [[ $wantshow -eq 1 ]]; then
|
|
showit $uid | sed -e 's/^/ /'
|
|
fi
|
|
done
|
|
confirm "Really remove these tasks"
|
|
if [[ $? -eq 0 ]]; then
|
|
count=0
|
|
for uid in $deluids; do
|
|
file=$dir/$uid.vcf
|
|
rm -f $file
|
|
unset idmap[$uid]
|
|
count=$((count + 1))
|
|
done
|
|
saveids
|
|
[[ $count -eq 1 ]] && ess="" || ess="s"
|
|
action "$count task$ess removed."
|
|
else
|
|
action "Aborted."
|
|
rv=1
|
|
fi
|
|
|
|
return $rv
|
|
}
|
|
|
|
function set_lastmodified() {
|
|
local uid file now
|
|
uid=$1
|
|
file=$dir/$uid.vcf
|
|
now=$(date -u +'%Y%m%dT%H%M%SZ')
|
|
sed -i "s/^LAST-MODIFIED:.*/LAST-MODIFIED:$now/" $file
|
|
return $?
|
|
}
|
|
|
|
function move_in() { # move_in uid
|
|
local uid rv parent parent2 sedrv
|
|
|
|
uid=$1
|
|
rv=0
|
|
parent=${taskparent[$uid]}
|
|
if [[ -z $parent ]]; then
|
|
error "Can't shift task #${taskid[$uid]} any further left."
|
|
fi
|
|
|
|
parent2=${taskparent[$parent]}
|
|
taskparent[$uid]="$parent2"
|
|
|
|
file=$dir/$uid.vcf
|
|
|
|
sed -i "s/^RELATED-TO.*/RELATED-TO;RELTYPE=PARENT:${taskparent[$uid]}/" $file
|
|
sedrv=$?
|
|
set_lastmodified $uid
|
|
sedrv=$((sedrv + $?))
|
|
if [[ $sedrv -eq 0 ]]; then
|
|
action "Shifted task #${taskid[$uid]} inwards/left."
|
|
loadtask $file
|
|
|
|
showit ${taskparent[$uid]} $uid
|
|
|
|
rv=0
|
|
else
|
|
error "Failed to shift task #${taskid[$uid]} left."
|
|
rv=1
|
|
fi
|
|
|
|
return $rv
|
|
}
|
|
|
|
function move_out() { # move_out uid new_parent
|
|
local uid rv newparent sedrv
|
|
|
|
uid=$1
|
|
newparent=$2
|
|
rv=0
|
|
|
|
taskparent[$uid]="$newparent"
|
|
|
|
file=$dir/$uid.vcf
|
|
|
|
sed -i "s/^RELATED-TO.*/RELATED-TO;RELTYPE=PARENT:${taskparent[$uid]}/" $file
|
|
sedrv=$?
|
|
set_lastmodified $uid
|
|
sedrv=$((sedrv + $?))
|
|
if [[ $sedrv -eq 0 ]]; then
|
|
action "Shifted task #${taskid[$uid]} underneath #${taskid[${taskparent[$uid]}]} ('${tasksum[${taskparent[$uid]}]}')."
|
|
loadtask $file
|
|
|
|
showit ${taskparent[$uid]} $uid
|
|
|
|
rv=0
|
|
else
|
|
error "Failed to shift task #${taskid[$uid]} under #${taskparent[$uid]}."
|
|
rv=1
|
|
fi
|
|
|
|
return $rv
|
|
}
|
|
|
|
function setnote() { # setnote uid new note goes here
|
|
local uid newnote sedrv rv file str
|
|
|
|
uid=$1
|
|
rv=0
|
|
shift
|
|
newnote="$*"
|
|
|
|
file=$dir/$uid.vcf
|
|
|
|
if grep -q ^DESCRIPTION: $file; then
|
|
sed -i "s/^DESCRIPTION:.*/DESCRIPTION:$newnote/" $file
|
|
sedrv=$?
|
|
else
|
|
str="END:VTODO"
|
|
toadd="DESCRIPTION:$newnote"
|
|
sed -i "/$str/i $toadd\n" $file
|
|
sedrv=$?
|
|
fi
|
|
set_lastmodified $uid
|
|
sedrv=$((sedrv + $?))
|
|
if [[ $sedrv -eq 0 ]]; then
|
|
action "Set note of task #${taskid[$uid]} to '$newnote'."
|
|
loadtask $file
|
|
rv=0
|
|
else
|
|
error "Failed to set note of task #${taskid[$uid]}."
|
|
rv=1
|
|
fi
|
|
|
|
return $rv
|
|
}
|
|
|
|
function rename() { # rename uid new name goes here
|
|
local uid newname sedrv rv file
|
|
|
|
uid=$1
|
|
rv=0
|
|
shift
|
|
newname="$*"
|
|
|
|
file=$dir/$uid.vcf
|
|
|
|
sed -i "s/^SUMMARY:.*/SUMMARY:$newname/" $file
|
|
sedrv=$?
|
|
set_lastmodified $uid
|
|
sedrv=$((sedrv + $?))
|
|
if [[ $sedrv -eq 0 ]]; then
|
|
action "Renamed task #${taskid[$uid]} to '$newname'."
|
|
loadtask $file
|
|
rv=0
|
|
else
|
|
error "failed to rename task #${taskid[$uid]}."
|
|
rv=1
|
|
fi
|
|
|
|
return $rv
|
|
}
|
|
|
|
function markdone() {
|
|
local uid sedrv rv file toadd1 toadd2 toadd3 str now
|
|
local children childuid ischild noun
|
|
uid=$1
|
|
[[ $# -gt 1 ]] && ischild=1 || ischild=0
|
|
[[ $ischild -eq 1 ]] && noun=subtask || noun=task
|
|
# already conplete?
|
|
if [[ ${taskchecked[$uid]} -eq 1 ]]; then
|
|
error "$noun #${taskid[$uid]} is already completed"
|
|
return 1
|
|
fi
|
|
str="END:VTODO"
|
|
now=$(date -u +'%Y%m%dT%H%M%SZ')
|
|
toadd1="STATUS:COMPLETED"
|
|
toadd2="PERCENT-COMPLETE:100"
|
|
toadd3="COMPLETED:$now"
|
|
|
|
file=$dir/$uid.vcf
|
|
sed -i "/$str/i $toadd1\n$toadd2\n$toadd3" $file
|
|
sedrv=$?
|
|
set_lastmodified $uid
|
|
sedrv=$((sedrv + $?))
|
|
if [[ $sedrv -eq 0 ]]; then
|
|
action "Marked $noun #${taskid[$uid]} as completed."
|
|
processed="$processed ${uid}"
|
|
loadtask $file
|
|
rv=0
|
|
children=$(getchildren $uid)
|
|
for childuid in ${children}; do
|
|
markdone $childuid noprint
|
|
rv=$((rv + $?))
|
|
done
|
|
else
|
|
error "failed to mark $noun #${taskid[$uid]} as completed"
|
|
rv=1
|
|
fi
|
|
|
|
return $rv
|
|
}
|
|
|
|
function randomuid() {
|
|
local dupe uid
|
|
dupe=1
|
|
while [[ $dupe -eq 1 ]]; do
|
|
uid=$(( $RANDOM % 4 + 1))
|
|
uid="$uid$(( $RANDOM % 5 + 1))"
|
|
while [[ ${#uid} -lt 19 ]]; do
|
|
uid="$uid$(( $RANDOM % 9 + 1))"
|
|
done
|
|
dupe=0
|
|
for x in ${!taskuid[@]}; do
|
|
if [[ $x == $uid ]]; then
|
|
dupe=1
|
|
break
|
|
fi
|
|
done
|
|
done
|
|
echo $uid
|
|
}
|
|
|
|
function addtask() {
|
|
local uid parent file
|
|
if [[ $1 == "-p" ]]; then
|
|
parentuid=$2
|
|
shift 2
|
|
else
|
|
parentuid=""
|
|
fi
|
|
uid=$(randomuid)
|
|
idmap[$uid]=$nextid
|
|
taskid[$uid]=$nextid
|
|
taskuid[$uid]=$nextid
|
|
tasksum[$uid]="$*"
|
|
taskdesc[$uid]=""
|
|
taskchecked[$uid]=0
|
|
taskparent[$uid]=$parentuid
|
|
file=$dir/$uid.vcf
|
|
now=$(date -u +'%Y%m%dT%H%M%SZ')
|
|
cat >$file <<EOF
|
|
BEGIN:VCALENDAR
|
|
VERSION:2.0
|
|
PRODID:+//IDN tasks.org//android-111003//EN
|
|
BEGIN:VTODO
|
|
DTSTAMP:$now
|
|
UID:$uid
|
|
CREATED:$now
|
|
LAST-MODIFIED:$now
|
|
SUMMARY:${tasksum[$uid]}
|
|
EOF
|
|
if [[ ! -z ${taskparent[$uid]} ]]; then
|
|
echo "RELATED-TO;RELTYPE=PARENT:${taskparent[$uid]}" >>$file
|
|
fi
|
|
cat >>$file <<EOF2
|
|
PRIORITY:9
|
|
X-APPLE-SORT-ORDER:611376630
|
|
END:VTODO
|
|
END:VCALENDAR
|
|
EOF2
|
|
|
|
nextid=$((nextid + 1))
|
|
saveids
|
|
needtitle=1
|
|
if [[ -z ${parentuid} ]]; then
|
|
action "Created new task #${taskid[$uid]}."
|
|
showit $uid
|
|
else
|
|
action "Created new subtask #${taskid[$uid]} under '${tasksum[${taskparent[$uid]}]}'."
|
|
showit ${taskparent[$uid]} $uid
|
|
fi
|
|
}
|
|
|
|
function nextline() {
|
|
local dummy morestring
|
|
morestring="<------ more ------>"
|
|
printed=$((printed + 1));
|
|
if [[ $printed -ge $((rows - 2)) ]]; then
|
|
echo -en "${CYAN}${morestring}${PLAIN}"
|
|
read -n1 -s dummy
|
|
printf "\r%*s\r" ${#morestring}
|
|
printed=0
|
|
needtitle=1
|
|
fi
|
|
}
|
|
|
|
function showit() {
|
|
local uid childuid children char hilite cols wid
|
|
uid=$1
|
|
if [[ $# -ge 2 ]]; then
|
|
hilite=$2
|
|
fi
|
|
|
|
if [[ $needtitle -eq 1 ]]; then
|
|
cols=$(tput cols)
|
|
wid=$((cols - $numwid - 2 - 1))
|
|
printf "$TOPTITLE%-${numwid}s %-${wid}s$PLAIN\n" "ID" "Task"
|
|
needtitle=0
|
|
fi
|
|
|
|
if [[ ${taskchecked[$uid]} -eq 1 ]]; then
|
|
char="✓"
|
|
col="$GREY$STRIKE"
|
|
else
|
|
char=" "
|
|
col="$PLAIN"
|
|
fi
|
|
|
|
if [[ $uid == $hilite ]]; then
|
|
col="$col$HILITE"
|
|
fi
|
|
|
|
printf "${LEFTTITLE}%-${numwid}d${PLAIN} %*s" ${taskid[$uid]} $indent
|
|
|
|
printf "$brack[$PLAIN$GREEN%s$PLAIN$brack]$PLAIN ${col}%s${PLAIN}\n" "${char}" "${tasksum[$uid]}"
|
|
nextline
|
|
|
|
if [[ ! -z ${taskdesc[$uid]} ]]; then
|
|
printf "${LEFTTITLE}%*s${PLAIN} " $numwid
|
|
printf "%*s" $(( $indent + 4))
|
|
printf "${col}${ITALIC}%s${PLAIN}\n" "${taskdesc[$uid]}"
|
|
nextline
|
|
fi
|
|
|
|
inc
|
|
children=$(getchildren $uid)
|
|
for childuid in ${children}; do
|
|
showit $childuid $hilite
|
|
done
|
|
dec
|
|
}
|
|
|
|
function addcmd() { # name usage description alt1|alt2|etc
|
|
local cmd usage desc alts
|
|
cmd="$1"
|
|
usage="$2"
|
|
desc="$3"
|
|
alts="$4"
|
|
|
|
[[ -z $valid_modes ]] && valid_modes=$cmd || valid_modes="$valid_modes $cmd"
|
|
eval "usage_${cmd}=\"${usage}\""
|
|
eval "desc_${cmd}=\"${desc}\""
|
|
eval "words_${cmd}=\"${alts}\""
|
|
}
|
|
|
|
function getchildren() {
|
|
local uid childuid children
|
|
uid=$1
|
|
children=""
|
|
for childuid in ${!taskuid[@]}; do
|
|
[[ ${taskparent[$childuid]} == $uid ]] && children="$children $childuid"
|
|
done
|
|
[[ -z $children ]] && return 1
|
|
echo "$children"
|
|
return 0
|
|
}
|
|
|
|
# Should be in config file:
|
|
#basedir=/Users/rpearce/scripts/t
|
|
#dir=$basedir/docs
|
|
#idfile=$basedir/idmappings.txt
|
|
#VDS_LOCAL=$cal_local
|
|
#VDS_REMOTE=$cal_remote
|
|
#VDIRSYNCER=/usr/local/bin/vdirsyncer
|
|
#VDS_BASEDIR="~/.config/vdirsyncer"
|
|
#VDS_CONFIG="${VDS_BASEDIR}/config"
|
|
#VDS_STATUSDIR="${VDS_BASEDIR}/status"
|
|
#VDS_CALDIR="${VDS_BASEDIR}/calendar"
|
|
|
|
# Base vdirsycner config in ${VDS_CONFIG}:
|
|
#[general]
|
|
#status_path = "${VDS_STATUSDIR}/"
|
|
#
|
|
#[pair cal]
|
|
#a = "${VDS_LOCAL}"
|
|
#b = "${VDS_REMOTE}"
|
|
#collections = ["from a", "from b"]
|
|
#
|
|
#[storage ${VDS_LOCAL}]
|
|
#type = "filesystem"
|
|
#path = "${VDS_CALDIR}/"
|
|
#fileext = ".vcf"
|
|
#
|
|
#[storage ${VDS_REMOTE}]
|
|
#type = "caldav"
|
|
#url = "https://tasks.haven.family/caldav.php/haven/"
|
|
#username = "xxx"
|
|
#password = "xxx"
|
|
|
|
|
|
VDIRSYNCER=/usr/local/bin/vdirsyncer
|
|
VDS_LOCAL=$cal_local
|
|
VDS_REMOTE=$cal_remote
|
|
basedir=/Users/rpearce/scripts/t
|
|
dir=$basedir/docs
|
|
idfile=$basedir/idmappings.txt
|
|
nextid=1
|
|
indent=0
|
|
indentamt=4
|
|
needsave=0
|
|
mode=list
|
|
|
|
# for pager
|
|
printed=0
|
|
rows=$(tput lines)
|
|
|
|
addcmd "list" "list [id1] .. [idX]" "List [just the specified] tasks" "list|ls|show"
|
|
addcmd "done" "done <taskid>" "Complete a task" "done|x|complete"
|
|
addcmd "notdone" "notdone <taskid>" "Uncomplete a task" "notdone|o|incomplete|uncomplete|clear"
|
|
addcmd "add" "add [parent] <name>" "Add a new task [as subtask of parent]" "a|add|new|create"
|
|
addcmd "del" "del [id1] .. [idX]" "Delete given task(s)" "del|rm|delete"
|
|
addcmd "cleanup" "cleanup" "Delete all completed tasks" "cleanup|clean|flush|dc"
|
|
addcmd "rename" "rename <id> <newname>" "Rename given task" "rename"
|
|
addcmd "in" "in <id>" "Decrease indent of given task" "in|left|h"
|
|
addcmd "out" "out <id> <parent>" "Move task below the given parent" "out|right|l|mv"
|
|
addcmd "note" "note <id> <notes>" "Change notes for given task" "note|desc|description|comment"
|
|
addcmd "sync" "sync" "Sync tasks using vdirsyncer" "sync"
|
|
|
|
DEBUG=0
|
|
TESTMODE=0
|
|
|
|
|
|
ARGS="hdt"
|
|
while getopts "$ARGS" i; do
|
|
case "$i" in
|
|
h)
|
|
usage;
|
|
exit 1;
|
|
;;
|
|
d)
|
|
DEBUG=1
|
|
;;
|
|
t)
|
|
DEBUG=1
|
|
TESTMODE=1
|
|
;;
|
|
*)
|
|
error "invalid argument: $i";
|
|
usage;
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
|
|
|
|
|
|
mode=""
|
|
for x in $valid_modes; do
|
|
thisone="words_$x"
|
|
tomatch=${!thisone}
|
|
if [[ $1 =~ ^(${tomatch})$ ]]; then
|
|
mode=$x
|
|
shift
|
|
fi
|
|
done
|
|
|
|
if [[ -z $mode ]]; then
|
|
mode=list
|
|
fi
|
|
|
|
# Commands that don't need tasks loaded
|
|
if [[ $mode == "sync" ]]; then
|
|
res=$(${VDIRSYNCER} sync 2>&1)
|
|
rv=$?
|
|
|
|
if [[ $rv -eq 0 ]]; then
|
|
upcount=$(echo "$res" | grep -v ^Sync | grep -c ${VDS_REMOTE})
|
|
downcount=$(echo "$res" | grep -v ^Sync | grep -c ${VDS_LOCAL})
|
|
|
|
[[ $upcount -eq 1 ]] && upess="" || upess="s"
|
|
[[ $downcount -eq 1 ]] && downess="" || downess="s"
|
|
|
|
if [[ $upcount -eq 0 && $downcount -eq 0 ]]; then
|
|
action "Sync complete - no changes."
|
|
elif [[ $upcount -eq 0 ]]; then
|
|
action "Sync complete - $downcount change$downess pulled."
|
|
elif [[ $downcount -eq 0 ]]; then
|
|
action "Sync complete - $upcount change$upess pushed."
|
|
else
|
|
action "Sync complete - $upcount change$upess pushed, $downcount change$downess pulled."
|
|
fi
|
|
else
|
|
error "sync failed. Output:"
|
|
echo "$res" | sed -e 's/^/ /'
|
|
fi
|
|
exit $rv
|
|
fi
|
|
|
|
loadids
|
|
loadtasks
|
|
|
|
|
|
[[ $TESTMODE -eq 1 ]] && exit 1
|
|
|
|
[[ $needsave -eq 1 ]] && saveids
|
|
|
|
# single-task commands
|
|
if [[ $mode == "add" ]]; then
|
|
if [[ $1 =~ ^[0-9]+$ ]]; then
|
|
parentid=$1
|
|
parentuid=$(getuid_witherror $parentid "parent task")
|
|
shift 1
|
|
else
|
|
parentid=""
|
|
parentuid=""
|
|
fi
|
|
newtasksum="$*"
|
|
|
|
if [[ -z $parentuid ]]; then
|
|
addtask "$newtasksum"
|
|
else
|
|
addtask -p $parentuid "$newtasksum"
|
|
fi
|
|
elif [[ $mode == "rename" ]]; then
|
|
uid=$(getuid_witherror $1)
|
|
shift
|
|
rename $uid "$*"
|
|
elif [[ $mode == "note" ]]; then
|
|
uid=$(getuid_witherror $1)
|
|
shift
|
|
setnote $uid "$*"
|
|
elif [[ $mode == "in" ]]; then
|
|
uid=$(getuid_witherror $1)
|
|
shift
|
|
move_in $uid
|
|
elif [[ $mode == "out" ]]; then
|
|
uid=$(getuid_witherror $1)
|
|
puid=$(getuid_witherror $2 "parent task")
|
|
shift 2
|
|
move_out $uid $puid
|
|
elif [[ $mode == "cleanup" ]]; then
|
|
action "Deleting all completed tasks."
|
|
for uid in ${!taskuid[@]}; do
|
|
[[ ${taskchecked[$uid]} -eq 1 ]] &&
|
|
delq_add $uid
|
|
done
|
|
|
|
delq_process $uid
|
|
# show results
|
|
if [[ ! -z $processed ]]; then
|
|
for uid in ${uids}; do
|
|
showit $uid
|
|
done
|
|
fi
|
|
else
|
|
# multi-task commands
|
|
|
|
filter=$*
|
|
|
|
uids=""
|
|
if [[ -z $filter ]]; then
|
|
for uid in ${!taskuid[@]}; do
|
|
[[ -z ${taskparent[$uid]} ]] && uids="$uids $uid"
|
|
done
|
|
elif [[ $filter =~ ^[0-9\ ]+$ ]]; then
|
|
# list of task IDs
|
|
for uid in ${!taskuid[@]}; do
|
|
for wantid in $filter; do
|
|
if [[ ${taskid[$uid]} == $wantid ]]; then
|
|
uids="$uids $uid"
|
|
fi
|
|
done
|
|
done
|
|
else
|
|
# text to match
|
|
a=$( echo ${filter} | tr 'A-Z' 'a-z')
|
|
for uid in ${!taskuid[@]}; do
|
|
b=$( echo ${tasksum[$uid]} | tr 'A-Z' 'a-z')
|
|
if [[ ${b} == *"${a}"* ]]; then
|
|
uids="$uids $uid"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
needtitle=1
|
|
|
|
if [[ -z $uids ]]; then
|
|
error "no matching tasks found."
|
|
exit 1
|
|
else
|
|
processed=""
|
|
for uid in ${uids}; do
|
|
if [[ $mode == "list" ]]; then
|
|
showit $uid
|
|
elif [[ $mode == "done" ]]; then
|
|
markdone $uid
|
|
elif [[ $mode == "notdone" ]]; then
|
|
marknotdone $uid
|
|
elif [[ $mode == "del" ]]; then
|
|
delq_add $uid
|
|
fi
|
|
done
|
|
|
|
# do queued actions
|
|
if [[ $mode == "del" ]]; then
|
|
delq_process $uid
|
|
fi
|
|
# show results
|
|
if [[ ! -z $processed ]]; then
|
|
for uid in ${uids}; do
|
|
showit $uid
|
|
done
|
|
fi
|
|
fi
|
|
|
|
|
|
|
|
fi
|