implement timeplanning (commands h, p), do some cleanup
This commit is contained in:
parent
fdf854885a
commit
fdc00271af
208
clikan.sh
208
clikan.sh
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
# clikan.sh -- CLI Kanban
|
||||
ver='2021-05-07/HB9KNS'
|
||||
ver='2021-08-20/HB9KNS'
|
||||
|
||||
conf="${CLIKANCONF:-$HOME/.clikanconf}"
|
||||
defkanban="$HOME/clikanban.md"
|
||||
|
@ -8,7 +8,12 @@ editor="${CLIKANEDIT:-$VISUAL}"
|
|||
editor="${editor:-$EDITOR}"
|
||||
editor="${editor:-ed}"
|
||||
myshell='/bin/sh -c'
|
||||
|
||||
filtr='.'
|
||||
# pattern for target date and estimation: @YYYYMMDD:U.U
|
||||
# (contains two groups in parentheses)
|
||||
# if changed, also adjust line after TEPATT comment further down!
|
||||
tepatt=' @\([0-9][0-9]*\):\([0-9][.0-9]*\)'
|
||||
|
||||
buff=`mktemp -t clikanbXXXXXX` || buff=${TMPDIR:-/tmp}/clikanb$$`date +%S%M%d`
|
||||
self=`mktemp -t clikantXXXXXX` || self=${TMPDIR:-/tmp}/clikant$$`date +%S%M%d`
|
||||
|
@ -36,6 +41,15 @@ sortdir up
|
|||
# if newdate is 1, yes or true (actually, begins with'[1tTyY]'),
|
||||
# then the current date will be appended to new cards/entries
|
||||
newdate true
|
||||
# planunit defines the name used for units (purely informative)
|
||||
planunit h/day
|
||||
# total units per period of scheduled tasks, e.g hours per day
|
||||
tunits 24
|
||||
# planpart defines the percentage of time available for working on
|
||||
# scheduled/planned tasks (integer value), for example
|
||||
# '10' means 10% of total time is usable, like 2.4 h/day
|
||||
# (tunits*planpart/100)
|
||||
planpart 10
|
||||
# kanban defines a kanban file, may be given several times
|
||||
# kanban /some/path/to/jobkanban.txt
|
||||
# kanban /another/path/to/privatekanban.md
|
||||
|
@ -95,6 +109,7 @@ getselect(){
|
|||
fi
|
||||
}
|
||||
|
||||
# read config, set default values if missing
|
||||
kbs="`getlines kanban <"$conf"`"
|
||||
currkan="`echo "$kbs" | head -n 1`"
|
||||
prompt=`getlines prompt <"$conf" | head -n 1`
|
||||
|
@ -107,6 +122,12 @@ case $nd in
|
|||
1|[yY]*|[tT]*) newdate=true ;;
|
||||
*) newdate=false ;;
|
||||
esac
|
||||
planpart=`getlines planpart <"$conf" | head -n 1`
|
||||
planpart=${planpart:-10}
|
||||
planunit=`getlines planunit <"$conf" | head -n 1`
|
||||
planunit=${planunit:-h/day}
|
||||
tunits=`getlines tunits <"$conf" | head -n 1`
|
||||
tunits=${tunits:-24}
|
||||
|
||||
showprompt(){
|
||||
if test "$prompt" != ""
|
||||
|
@ -151,17 +172,17 @@ showall(){
|
|||
fi | showselect "$f " | head -n $ms
|
||||
}
|
||||
|
||||
# replace lines (in any kanban) containing some ed pattern
|
||||
# arg.1=pattern, remainder=new line contents
|
||||
# replace lines (in any kanban) containing some string
|
||||
# arg.1=string, remainder=new line contents
|
||||
repline(){
|
||||
local patt newl
|
||||
patt="$1"
|
||||
local strg newl
|
||||
strg="$1"
|
||||
shift
|
||||
newl="$*"
|
||||
for ff in $kbs
|
||||
do cat "$ff" > $buff
|
||||
cat $buff | { while read oldl
|
||||
do if test "`echo \"$oldl\"`" = "$patt"
|
||||
do if test "`echo \"$oldl\"`" = "$strg"
|
||||
then echo "$newl"
|
||||
else echo "$oldl"
|
||||
fi
|
||||
|
@ -200,6 +221,11 @@ command keys:
|
|||
do N: put card N into doing state
|
||||
note: done/wait/do accept several arguments separated by white space
|
||||
f F: filter cards for grep pattern F (empty='.')
|
||||
p: show planning (time scheduling) for active (doing) cards containing
|
||||
@YYMMDD/U.U target date (YYMMDD) and expected duration (U.U)
|
||||
h N U.U [[YY]MMDD]: update expected duration for card N and
|
||||
optionally set new target date [YY]MMDD
|
||||
(asks for date if card is missing @YYMMDD)
|
||||
ec: directly edit config file -- DANGER!
|
||||
ek: directly edit kanban file -- DANGER!
|
||||
!: execute arguments with "$myshell"
|
||||
|
@ -211,11 +237,41 @@ EOH
|
|||
esac
|
||||
}
|
||||
|
||||
# simple date number calculation:
|
||||
# assume each month has 30 days
|
||||
datnum() {
|
||||
local dn ds
|
||||
# normalize to YYYYMMDD
|
||||
if test "${1%????}" = ""
|
||||
then ds=`date +%Y`$1
|
||||
elif test "${1%??????}" = ""
|
||||
then ds=$century$1
|
||||
else ds=$1
|
||||
fi
|
||||
# 12*YYYY
|
||||
dn=$(( 12*${ds%????} ))
|
||||
# remove leading YYYY
|
||||
ds=${ds#????}
|
||||
# add 1MM, subtract 100, multiply by 30
|
||||
dn=$(( 30*($dn+1${ds%??}-100) ))
|
||||
# add 1DD, subtract 100
|
||||
dn=$(( $dn+1${ds#??}-100 ))
|
||||
echo $dn
|
||||
}
|
||||
|
||||
showall doing
|
||||
showprompt
|
||||
|
||||
while read com coa1 coa2 coa3 coar
|
||||
do case $com in
|
||||
do
|
||||
year=`date +%y`
|
||||
longyear=`date +%Y`
|
||||
century=${longyear%??}
|
||||
month=`date +%m`
|
||||
day=`date +%d`
|
||||
today=$year-$month-$day
|
||||
stoday=$century$year$month$day
|
||||
case $com in
|
||||
q) break ;;
|
||||
d) showall doing ;;
|
||||
w) showall waiting/todo/backlog ;;
|
||||
|
@ -234,12 +290,12 @@ do|wait|done) if test "$coa1" = ""
|
|||
stamp=''
|
||||
case $com in
|
||||
done) coa2='+'
|
||||
stamp=`date '+ // %y-%m-%d'`
|
||||
stamp=" // $today"
|
||||
;;
|
||||
wait) coa2='-' ;;
|
||||
*) coa2='*' ;;
|
||||
esac
|
||||
coa3=`echo "$coa1" | sed -e "s/^./$coa2/"`
|
||||
coa3="$coa2${coa1#?}"
|
||||
repline "$coa1" "$coa3$stamp"
|
||||
coar=${coar#* }
|
||||
done
|
||||
|
@ -252,12 +308,12 @@ k) echo "$kbs" | showselect
|
|||
n) newc=`echo "$coa1 $coa2 $coa3 $coar" | sed -e 's/ *$//'`
|
||||
if test "$newc" = ""
|
||||
then
|
||||
echo enter new card for target $currkan :
|
||||
echo enter new card for kanban file $currkan :
|
||||
read newc
|
||||
else echo adding card for target $currkan
|
||||
else echo adding card for kanban file $currkan
|
||||
fi
|
||||
if test $newdate = true
|
||||
then stamp=`date '+ // %y-%m-%d'`
|
||||
then stamp=" // $today"
|
||||
else stamp=''
|
||||
fi
|
||||
if test "$newc" != ""
|
||||
|
@ -273,6 +329,134 @@ ek) echo calling "$editor $currkan" ...
|
|||
"$editor" "$currkan" ;;
|
||||
f) filtr="${coa1:-.}"
|
||||
echo "filtering for grep pattern '$filtr'" ;;
|
||||
p) echo "## planning for $planpart% of $tunits $planunit"
|
||||
# generate list, but hidden
|
||||
showall doing >/dev/null
|
||||
# total current capacity in 0.1 units, to calculate limit
|
||||
# (planpart is in %=0.01 units, divide by 10 to get in 0.1)
|
||||
cap=$(( $tunits*$planpart/10 ))
|
||||
now=`datnum $stoday`
|
||||
echo "$planunit task"
|
||||
# get all tasks with planning information, sorted
|
||||
grep "$tepatt" $self | sort -k 2 | { while read nr flag task
|
||||
do
|
||||
# set weight for assigned time depending on priority value
|
||||
case $task in
|
||||
1*) w8=8 ;;
|
||||
2*) w8=6 ;;
|
||||
3*) w8=4 ;;
|
||||
4*) w8=2 ;;
|
||||
5*) w8=1 ;;
|
||||
*) w8=3 ;;
|
||||
esac
|
||||
# get target date number of task, and normalize
|
||||
tdate=`echo "$task" | sed -e "s/.*$tepatt.*/\1/"`
|
||||
tnum=`datnum $tdate`
|
||||
td=$(( $tnum-$now ))
|
||||
if test $td -le 0
|
||||
then td=1
|
||||
fi
|
||||
# get estimated units for task, append '.0' to force decimal notation,
|
||||
# remove dot, keep one decimal and truncate additional figures
|
||||
# (i.e multiply by 10)
|
||||
tunits=`echo "$task" | sed -e "s/.*$tepatt.*/\2/;s/$/.0/;s/[.]\([0-9]\).*/\1/"`
|
||||
# assign 2*weight/8*tunits/days per task, but not more than estimated units
|
||||
tcap=$(( $w8/4*$tunits/$td ))
|
||||
if test $tcap -gt $tunits
|
||||
then tcap=$tunits
|
||||
# or at least 0.1
|
||||
elif test $tcap -lt 1
|
||||
then tcap=1
|
||||
fi
|
||||
if test $tcap -gt 99
|
||||
then
|
||||
# remove trailing figure for values of 10 (100) or higher
|
||||
echo "$tcap $nr: $task" | sed -e 's/. / /'
|
||||
else
|
||||
# for smaller, insert decimal and prepend 0 if missing
|
||||
echo "$tcap $nr: $task" | sed -e 's/\(.\) /.\1 /;s/^[.]/0./'
|
||||
fi
|
||||
if test $cap -gt 0
|
||||
then cap=$(( $cap-$tcap ))
|
||||
if test $cap -le 0
|
||||
then echo ' # capacity limit reached! #'
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
;;
|
||||
h) if test "$coa1" = ""
|
||||
then echo "card number?"
|
||||
read coa1
|
||||
fi
|
||||
if test "$coa1" = ""
|
||||
then showprompt
|
||||
continue
|
||||
fi
|
||||
coa1=`echo "$coa1" | tr -cd '0-9'`
|
||||
oldl=`getlines $coa1 <$self`
|
||||
newl="$oldl"
|
||||
echo ": ${oldl#??}"
|
||||
if test "$coa2" = ""
|
||||
then echo "new estimated time requirement?"
|
||||
read coa2
|
||||
fi
|
||||
coa2=`echo "$coa2" | tr -cd '.0-9'`
|
||||
if test "$coa2" = ""
|
||||
then showprompt
|
||||
continue
|
||||
fi
|
||||
# arg.3 will override existing target date
|
||||
if test "$coa3" = ""
|
||||
then
|
||||
# search for ' @YYYYMMDD/U.U' and get YYYYMMDD
|
||||
odat=`echo "$oldl" | sed -e "s/.*$tepatt.*/\1/"`
|
||||
# if nothing found, ask for target date
|
||||
if test "$odat" = "$oldl"
|
||||
then
|
||||
echo "target date [YYYY]MMDD?"
|
||||
read coa3
|
||||
# add dummy for later pattern replacement
|
||||
newl="$newl @1:2"
|
||||
else
|
||||
coa3=$odat
|
||||
fi
|
||||
else
|
||||
# remove old pattern and add dummy for later
|
||||
newl=`echo "$oldl" | sed -e "s/\\(.*\\)$tepatt\\(.*\\)/\\1 @1:2\\4/"`
|
||||
# force if nothing yet found
|
||||
if test "$newl" = "$oldl"
|
||||
then newl="$newl @1:2"
|
||||
fi
|
||||
fi
|
||||
coa3=`echo $coa3 | tr -cd '0-9'`
|
||||
if test "$coa3" = ""
|
||||
then coa3=$stoday
|
||||
echo "(empty/malformed date, using today=$coa3 instead)"
|
||||
fi
|
||||
# handle [YY]MMDD dates
|
||||
# prepend 1 to prevent interpretation of leading 0 as octal
|
||||
# (use 9999 instead of 1231 to cope with bogus inputs)
|
||||
if test 1$coa3 -le 19999
|
||||
then
|
||||
# compare with today's MMDD
|
||||
if test 1$coa3 -lt 1$month$day
|
||||
# before, use next year, else this year
|
||||
then coa3="$(( 1+$century$year ))$coa3"
|
||||
else coa3="$century$year$coa3"
|
||||
fi
|
||||
elif test 1$coa3 -le 1999999
|
||||
# prepend century if missing
|
||||
then coa3=$century$coa3
|
||||
fi
|
||||
# TEPATT: adjust replacement string if $tepatt changed!
|
||||
# (last reference is group 4 because of two groups in tepatt)
|
||||
coar=`echo "$newl" | sed -e "s/\\(.*\\)$tepatt\\(.*\\)/\\1 @$coa3:$coa2\\4/"`
|
||||
echo was: "$oldl"
|
||||
echo now: "$coar"
|
||||
repline "$oldl" "$coar"
|
||||
showall doing
|
||||
;;
|
||||
!*) echo
|
||||
$myshell "${com#!} $coa1 $coa2 $coa3 $coar"
|
||||
echo ;;
|
||||
|
|
Loading…
Reference in New Issue