2017-06-20 23:45:13 +02:00
|
|
|
#!/bin/sh
|
|
|
|
# clikan.sh -- CLI Kanban
|
2022-07-18 15:24:02 +02:00
|
|
|
ver='2022-07-18/HB9KNS'
|
2017-06-20 23:45:13 +02:00
|
|
|
|
|
|
|
conf="${CLIKANCONF:-$HOME/.clikanconf}"
|
2017-06-21 08:15:29 +02:00
|
|
|
defkanban="$HOME/clikanban.md"
|
2017-06-20 23:45:13 +02:00
|
|
|
editor="${CLIKANEDIT:-$VISUAL}"
|
|
|
|
editor="${editor:-$EDITOR}"
|
2017-06-21 01:25:27 +02:00
|
|
|
editor="${editor:-ed}"
|
2019-12-12 13:21:26 +01:00
|
|
|
myshell='/bin/sh -c'
|
2021-08-26 00:23:20 +02:00
|
|
|
|
2020-05-11 22:31:08 +02:00
|
|
|
filtr='.'
|
2021-08-26 00:23:20 +02:00
|
|
|
# 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]*\)'
|
2017-06-21 13:46:50 +02:00
|
|
|
|
2020-09-21 14:26:26 +02:00
|
|
|
buff=`mktemp -t clikanbXXXXXX` || buff=${TMPDIR:-/tmp}/clikanb$$`date +%S%M%d`
|
|
|
|
self=`mktemp -t clikantXXXXXX` || self=${TMPDIR:-/tmp}/clikant$$`date +%S%M%d`
|
|
|
|
chmod 600 $self $buff
|
|
|
|
: >$self
|
2017-06-20 23:45:13 +02:00
|
|
|
|
|
|
|
if test ! -f "$conf"
|
2017-06-21 08:15:29 +02:00
|
|
|
then cat <<EOT
|
|
|
|
no config found, generating default config file $conf
|
|
|
|
and default kanban file $defkanban
|
|
|
|
(this should happen only once at first use)
|
|
|
|
EOT
|
2017-06-20 23:45:13 +02:00
|
|
|
cat <<EOT >"$conf"
|
2017-06-21 08:15:29 +02:00
|
|
|
# configuration file for $0
|
|
|
|
# (autogenerated at `date`)
|
|
|
|
# file name can be defined by env.var CLIKANCONF
|
|
|
|
#
|
|
|
|
# prompt is displayed when waiting for command
|
2017-06-21 01:25:27 +02:00
|
|
|
prompt |<
|
2017-06-21 17:30:09 +02:00
|
|
|
# maxshow defines the maximum number of cards/lines to be displayed
|
2021-02-25 23:49:49 +01:00
|
|
|
maxshow 23
|
2019-12-17 09:24:03 +01:00
|
|
|
# sortdir defines order of non-calendar kanban cards
|
|
|
|
# and can be one of up, down or none (default)
|
2021-02-25 23:49:49 +01:00
|
|
|
sortdir up
|
2021-05-07 14:47:59 +02:00
|
|
|
# if newdate is 1, yes or true (actually, begins with'[1tTyY]'),
|
|
|
|
# then the current date will be appended to new cards/entries
|
|
|
|
newdate true
|
2021-08-26 00:23:20 +02:00
|
|
|
# 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
|
2017-06-21 08:15:29 +02:00
|
|
|
# kanban defines a kanban file, may be given several times
|
|
|
|
# kanban /some/path/to/jobkanban.txt
|
|
|
|
# kanban /another/path/to/privatekanban.md
|
2017-06-20 23:45:13 +02:00
|
|
|
kanban $defkanban
|
|
|
|
EOT
|
2017-06-22 13:22:35 +02:00
|
|
|
if test -f "$defkanban"
|
|
|
|
then cp "$defkanban" "$defkanban.bak"
|
|
|
|
echo found existing $defkanban,
|
|
|
|
echo saved as backup $defkanban.bak
|
|
|
|
fi
|
2017-06-20 23:45:13 +02:00
|
|
|
cat <<EOT >"$defkanban"
|
|
|
|
# my kanban file
|
2017-06-21 08:36:38 +02:00
|
|
|
|
2017-06-21 01:25:27 +02:00
|
|
|
* learn to use clikan
|
|
|
|
- improve clikan
|
2017-06-21 08:15:29 +02:00
|
|
|
+ install clikan
|
2017-06-21 08:36:38 +02:00
|
|
|
|
|
|
|
### titles work as comments
|
|
|
|
# might be a future card you don't yet want in waiting
|
2017-06-20 23:45:13 +02:00
|
|
|
EOT
|
|
|
|
fi
|
|
|
|
|
|
|
|
# get lines beginning with a value, and remove that column
|
|
|
|
# note SPC&TAB in patterns: make sure there is a SPC,
|
|
|
|
# and that the value is complete
|
|
|
|
getlines(){
|
|
|
|
sed -e 's/$/ /' | grep "^$1[ ]" | { while read _ values
|
|
|
|
# remove trailing added TAB
|
|
|
|
do echo "${values% }"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-21 14:26:26 +02:00
|
|
|
# display selection, and put selection list in selection file,
|
2017-06-21 01:25:27 +02:00
|
|
|
# input through stdin, with lines prepended with index number, TAB and arg1
|
2017-06-20 23:45:13 +02:00
|
|
|
showselect(){
|
|
|
|
local i
|
|
|
|
i=1
|
2020-09-21 14:26:26 +02:00
|
|
|
: >$self
|
2017-06-21 01:25:27 +02:00
|
|
|
while read l
|
|
|
|
do echo $i: $l
|
2020-09-21 14:26:26 +02:00
|
|
|
echo "$i $1$l" >>$self
|
2017-06-20 23:45:13 +02:00
|
|
|
i=$(( $i+1 ))
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
# get input from selection (showselect must be called before)
|
|
|
|
getselect(){
|
|
|
|
if test "$1" != ""
|
|
|
|
then echo "choice? (default: $1)" >&2
|
|
|
|
else echo "choice?" >&2
|
|
|
|
fi
|
|
|
|
read i
|
|
|
|
if test "$i" = ""
|
|
|
|
then echo "$1"
|
2020-09-21 14:26:26 +02:00
|
|
|
else getlines $i <$self
|
2017-06-20 23:45:13 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-08-26 00:23:20 +02:00
|
|
|
# read config, set default values if missing
|
2017-06-20 23:45:13 +02:00
|
|
|
kbs="`getlines kanban <"$conf"`"
|
|
|
|
currkan="`echo "$kbs" | head -n 1`"
|
|
|
|
prompt=`getlines prompt <"$conf" | head -n 1`
|
2017-06-21 17:30:09 +02:00
|
|
|
maxshow=`getlines maxshow <"$conf" | head -n 1`
|
|
|
|
maxshow=${maxshow:-22}
|
2019-12-17 09:24:03 +01:00
|
|
|
sortdir=`getlines sortdir <"$conf" | head -n 1`
|
|
|
|
sortdir=${sortdir:-none}
|
2021-05-07 14:47:59 +02:00
|
|
|
nd=`getlines newdate <"$conf" | head -n 1`
|
|
|
|
case $nd in
|
|
|
|
1|[yY]*|[tT]*) newdate=true ;;
|
|
|
|
*) newdate=false ;;
|
|
|
|
esac
|
2021-08-26 00:23:20 +02:00
|
|
|
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}
|
2017-06-20 23:45:13 +02:00
|
|
|
|
|
|
|
showprompt(){
|
|
|
|
if test "$prompt" != ""
|
2017-06-23 19:21:05 +02:00
|
|
|
then printf '%s ' "$prompt"
|
2017-06-20 23:45:13 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:03 +01:00
|
|
|
# conditional sort
|
|
|
|
condsort(){
|
|
|
|
case $sortdir in
|
|
|
|
up) sort ;;
|
|
|
|
down) sort -r ;;
|
|
|
|
*) cat ;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2017-06-20 23:45:13 +02:00
|
|
|
# display all 'something' cards
|
|
|
|
showall(){
|
2020-02-10 10:54:59 +01:00
|
|
|
local f t ms
|
|
|
|
ms=$maxshow
|
2017-06-20 23:45:13 +02:00
|
|
|
case $1 in
|
|
|
|
d*) f='*' ;;
|
|
|
|
w*) f='-' ;;
|
2020-02-10 10:54:59 +01:00
|
|
|
# for archive/done, show a LOT of archived stuff
|
|
|
|
a*) f='+' ; ms=99999 ;;
|
2017-06-20 23:45:13 +02:00
|
|
|
*) f='' ;;
|
|
|
|
esac
|
|
|
|
echo
|
2020-01-09 14:08:18 +01:00
|
|
|
echo " $1 // `date`"
|
2020-05-11 22:31:08 +02:00
|
|
|
if test "$filtr" != "."
|
2020-05-11 22:52:51 +02:00
|
|
|
then echo " ($filtr)"
|
2020-05-11 22:31:08 +02:00
|
|
|
fi
|
2019-12-17 09:24:03 +01:00
|
|
|
if test "$f" = "*"
|
|
|
|
then t=`date +%m-%d`
|
2020-05-11 22:31:08 +02:00
|
|
|
# for "doing", sort filtered cards
|
2022-07-18 15:24:02 +02:00
|
|
|
cat $kbs | grep -i -e "$filtr" | getlines "$f" | condsort
|
2019-12-17 09:24:03 +01:00
|
|
|
# and also display '- ...(MM-DD)...' calendar entries
|
|
|
|
cat $kbs | grep "^[*+-] .*($t)" | sed -e 's/^. //'
|
2020-05-11 22:31:08 +02:00
|
|
|
# for waiting and archive, filter but keep saved card order
|
2022-07-18 15:24:02 +02:00
|
|
|
else cat $kbs | grep -i -e "$filtr" | getlines "$f"
|
2019-12-17 09:24:03 +01:00
|
|
|
# for all cases, select the cards and show the beginning of the list
|
2020-02-10 10:54:59 +01:00
|
|
|
fi | showselect "$f " | head -n $ms
|
2017-06-20 23:45:13 +02:00
|
|
|
}
|
|
|
|
|
2021-08-26 00:23:20 +02:00
|
|
|
# replace lines (in any kanban) containing some string
|
|
|
|
# arg.1=string, remainder=new line contents
|
2017-06-20 23:45:13 +02:00
|
|
|
repline(){
|
2021-08-26 00:23:20 +02:00
|
|
|
local strg newl
|
|
|
|
strg="$1"
|
2017-06-20 23:45:13 +02:00
|
|
|
shift
|
|
|
|
newl="$*"
|
|
|
|
for ff in $kbs
|
2020-09-21 14:26:26 +02:00
|
|
|
do cat "$ff" > $buff
|
|
|
|
cat $buff | { while read oldl
|
2021-08-26 00:23:20 +02:00
|
|
|
do if test "`echo \"$oldl\"`" = "$strg"
|
2020-09-21 14:26:26 +02:00
|
|
|
then echo "$newl"
|
|
|
|
else echo "$oldl"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
} > "$ff"
|
2017-06-20 23:45:13 +02:00
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2022-09-07 09:17:21 +02:00
|
|
|
# put waiting cards of today or older into doing state
|
|
|
|
dotodays(){
|
|
|
|
echo :: yet unimplemented
|
|
|
|
}
|
|
|
|
|
2017-06-20 23:45:13 +02:00
|
|
|
showhelp(){ cat <<EOH
|
|
|
|
$0 : command line kanban
|
2017-06-21 08:15:29 +02:00
|
|
|
($ver)
|
2017-06-20 23:45:13 +02:00
|
|
|
configuration file: $conf
|
|
|
|
for help about commands, just hit RETURN
|
|
|
|
to show configuration, enter 'c'
|
|
|
|
EOH
|
|
|
|
read k
|
|
|
|
case $k in
|
2017-06-21 01:25:27 +02:00
|
|
|
c*) cat <<EOT
|
|
|
|
CLIKANCONF=$CLIKANCONF
|
|
|
|
configfile=$conf
|
|
|
|
editor=$editor
|
2017-06-21 17:30:09 +02:00
|
|
|
maxshow=$maxshow
|
2017-06-21 01:25:27 +02:00
|
|
|
configfile contents:
|
|
|
|
EOT
|
2017-06-20 23:45:13 +02:00
|
|
|
sed -e 's/^/ /' $conf
|
|
|
|
;;
|
|
|
|
*) cat <<EOH
|
|
|
|
command keys:
|
|
|
|
q: quit
|
|
|
|
d/w/a: show 'doing/waiting(todo)/archive(done)' cards
|
|
|
|
k: select target kanban for entry of new cards
|
2019-12-11 12:39:32 +01:00
|
|
|
n: add new card to target kanban, separated by whitespace
|
|
|
|
(e.g "n buy present!")
|
2017-06-20 23:45:13 +02:00
|
|
|
done N: archive card N as done
|
|
|
|
wait N: put card N back to waiting/todo state
|
|
|
|
do N: put card N into doing state
|
2020-01-03 15:08:06 +01:00
|
|
|
note: done/wait/do accept several arguments separated by white space
|
2022-07-18 15:24:02 +02:00
|
|
|
f F: filter for grep pattern F (case insensitive, empty='.', use _ for space)
|
2021-08-26 00:23:20 +02:00
|
|
|
p: show planning (time scheduling) for active (doing) cards containing
|
|
|
|
@YYMMDD/U.U target date (YYMMDD) and expected duration (U.U)
|
2022-09-07 09:17:21 +02:00
|
|
|
t: search waiting cards with target date of today or older and put them into doing state
|
2021-08-26 00:23:20 +02:00
|
|
|
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)
|
2017-06-20 23:45:13 +02:00
|
|
|
ec: directly edit config file -- DANGER!
|
|
|
|
ek: directly edit kanban file -- DANGER!
|
2019-12-12 13:21:26 +01:00
|
|
|
!: execute arguments with "$myshell"
|
2021-02-25 23:49:49 +01:00
|
|
|
note: if the command does not match any of the
|
|
|
|
internal commands, and starts with a letter,
|
2019-12-17 15:25:44 +01:00
|
|
|
you can even omit the leading exclamation mark!
|
2017-06-20 23:45:13 +02:00
|
|
|
EOH
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
2021-08-26 00:23:20 +02:00
|
|
|
# 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
|
|
|
|
}
|
|
|
|
|
2022-09-07 09:17:21 +02:00
|
|
|
# extract tepatt from argument
|
|
|
|
getsdate() {
|
|
|
|
echo "$*" | sed -e "s/.*$tepatt.*/\1/"
|
|
|
|
}
|
|
|
|
|
2017-06-20 23:45:13 +02:00
|
|
|
showall doing
|
|
|
|
showprompt
|
|
|
|
|
|
|
|
while read com coa1 coa2 coa3 coar
|
2021-08-26 00:23:20 +02:00
|
|
|
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
|
2020-04-23 09:11:26 +02:00
|
|
|
q) break ;;
|
2017-06-20 23:45:13 +02:00
|
|
|
d) showall doing ;;
|
2017-06-21 01:25:27 +02:00
|
|
|
w) showall waiting/todo/backlog ;;
|
2017-06-20 23:45:13 +02:00
|
|
|
a) showall archived/done ;;
|
2022-09-07 09:17:21 +02:00
|
|
|
t) dotodays ;;
|
2017-06-20 23:45:13 +02:00
|
|
|
do|wait|done) if test "$coa1" = ""
|
|
|
|
then echo "card number?"
|
|
|
|
read coa1
|
|
|
|
fi
|
2021-05-07 14:47:59 +02:00
|
|
|
coar=`echo "$coa1 $coa2 $coa3 $coar" | tr -cd ' 0-9' | sed -e 's/ *$/ /'`
|
|
|
|
if test "$coar" = " "
|
|
|
|
then coar=''
|
|
|
|
fi
|
2020-01-03 14:59:40 +01:00
|
|
|
while test "$coar" != ""
|
|
|
|
do
|
2020-09-21 14:26:26 +02:00
|
|
|
coa1=`getlines ${coar%% *} <$self`
|
2019-12-18 14:32:10 +01:00
|
|
|
stamp=''
|
2017-06-20 23:45:13 +02:00
|
|
|
case $com in
|
2019-12-18 14:32:10 +01:00
|
|
|
done) coa2='+'
|
2021-08-26 00:23:20 +02:00
|
|
|
stamp=" // $today"
|
2019-12-18 14:32:10 +01:00
|
|
|
;;
|
2017-06-20 23:45:13 +02:00
|
|
|
wait) coa2='-' ;;
|
|
|
|
*) coa2='*' ;;
|
|
|
|
esac
|
2021-08-26 00:23:20 +02:00
|
|
|
coa3="$coa2${coa1#?}"
|
2019-12-18 14:32:10 +01:00
|
|
|
repline "$coa1" "$coa3$stamp"
|
2020-01-03 14:59:40 +01:00
|
|
|
coar=${coar#* }
|
|
|
|
done
|
2017-06-20 23:45:13 +02:00
|
|
|
showall doing
|
|
|
|
;;
|
|
|
|
k) echo "$kbs" | showselect
|
|
|
|
currkan=`getselect $currkan`
|
|
|
|
showall doing
|
|
|
|
;;
|
2019-12-11 12:39:32 +01:00
|
|
|
n) newc=`echo "$coa1 $coa2 $coa3 $coar" | sed -e 's/ *$//'`
|
|
|
|
if test "$newc" = ""
|
|
|
|
then
|
2021-08-26 00:23:20 +02:00
|
|
|
echo enter new card for kanban file $currkan :
|
2019-12-11 12:39:32 +01:00
|
|
|
read newc
|
2021-08-26 00:23:20 +02:00
|
|
|
else echo adding card for kanban file $currkan
|
2019-12-11 12:39:32 +01:00
|
|
|
fi
|
2021-05-07 14:47:59 +02:00
|
|
|
if test $newdate = true
|
2021-08-26 00:23:20 +02:00
|
|
|
then stamp=" // $today"
|
2021-05-07 14:47:59 +02:00
|
|
|
else stamp=''
|
|
|
|
fi
|
2017-06-20 23:45:13 +02:00
|
|
|
if test "$newc" != ""
|
2021-05-07 14:47:59 +02:00
|
|
|
then echo '*' "$newc$stamp" >>$currkan
|
2019-12-11 12:39:32 +01:00
|
|
|
else echo no content found, nothing added
|
2017-06-20 23:45:13 +02:00
|
|
|
fi
|
|
|
|
showall doing
|
|
|
|
;;
|
|
|
|
ec) echo calling "$editor $conf" ...
|
|
|
|
"$editor" "$conf"
|
|
|
|
echo please quit and restart to reload config ;;
|
2017-06-21 01:25:27 +02:00
|
|
|
ek) echo calling "$editor $currkan" ...
|
2019-12-12 13:32:08 +01:00
|
|
|
"$editor" "$currkan" ;;
|
2020-05-11 22:31:08 +02:00
|
|
|
f) filtr="${coa1:-.}"
|
2022-07-18 15:24:02 +02:00
|
|
|
echo "filtering for grep pattern '$filtr' (_ means SPC)"
|
|
|
|
filtr=`echo "$filtr" | sed -e 's/_/ /g'` ;;
|
2021-08-26 00:23:20 +02:00
|
|
|
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`
|
2021-08-26 14:05:35 +02:00
|
|
|
# difference in days
|
2021-08-26 00:23:20 +02:00
|
|
|
td=$(( $tnum-$now ))
|
2021-08-26 14:05:35 +02:00
|
|
|
# set minimum delta and mark
|
|
|
|
if test $td -gt 0
|
|
|
|
then tmark=' '
|
|
|
|
else
|
|
|
|
td=1
|
|
|
|
tmark='*'
|
2021-08-26 00:23:20 +02:00
|
|
|
fi
|
|
|
|
# get estimated units for task, append '.0' to force decimal notation,
|
|
|
|
# remove dot, keep one decimal and truncate additional figures
|
2021-09-09 17:38:35 +02:00
|
|
|
# (i.e multiply by 10), remove leading 0s
|
|
|
|
# TODO: following 2 lines are really ugly, should be simplified...
|
|
|
|
tunits=`echo "$task" | sed -e "s/.*$tepatt.*/\2/;s/$/.0/;s/[.]\([0-9]\).*/\1/;s/^0*//"`
|
|
|
|
# if empty, set to 0
|
|
|
|
tunits=${tunits:-0}
|
2021-08-26 00:23:20 +02:00
|
|
|
# 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
|
2021-08-26 14:05:35 +02:00
|
|
|
# result: today's amount / (mark) / task nr / task
|
|
|
|
tres="$tcap $tmark$nr: $task"
|
2021-08-26 00:23:20 +02:00
|
|
|
if test $tcap -gt 99
|
|
|
|
then
|
|
|
|
# remove trailing figure for values of 10 (100) or higher
|
2021-08-26 14:05:35 +02:00
|
|
|
echo "$tres" | sed -e 's/. / /'
|
2021-08-26 00:23:20 +02:00
|
|
|
else
|
|
|
|
# for smaller, insert decimal and prepend 0 if missing
|
2021-08-26 14:05:35 +02:00
|
|
|
echo "$tres" | sed -e 's/\(.\) /.\1 /;s/^[.]/0./'
|
2021-08-26 00:23:20 +02:00
|
|
|
fi
|
|
|
|
if test $cap -gt 0
|
|
|
|
then cap=$(( $cap-$tcap ))
|
|
|
|
if test $cap -le 0
|
2021-08-26 14:05:35 +02:00
|
|
|
then echo ' (capacity limit reached)'
|
2021-08-26 00:23:20 +02:00
|
|
|
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
|
|
|
|
;;
|
2019-12-17 15:25:44 +01:00
|
|
|
!*) echo
|
|
|
|
$myshell "${com#!} $coa1 $coa2 $coa3 $coar"
|
|
|
|
echo ;;
|
|
|
|
[A-Za-z]*) echo
|
|
|
|
$myshell "$com $coa1 $coa2 $coa3 $coar"
|
|
|
|
echo ;;
|
2017-06-20 23:45:13 +02:00
|
|
|
*) showhelp
|
2022-07-18 15:24:02 +02:00
|
|
|
echo '(hit return to continue)'
|
|
|
|
read _
|
2017-06-20 23:45:13 +02:00
|
|
|
showall doing ;;
|
|
|
|
esac
|
|
|
|
showprompt
|
|
|
|
done
|
|
|
|
|
2017-06-21 01:25:27 +02:00
|
|
|
echo
|
2020-09-21 14:26:26 +02:00
|
|
|
rm -f $self $buff
|