@ -2,7 +2,7 @@
PROFILE='default'
function debug() {
echo $DEBUG
# echo $DEBUG
if [ ${DEBUG:-0} -ne 0 ]; then
echo "$(date): $@"
fi
@ -35,11 +35,12 @@ $0 - Captain's log
Directories created under $BASEDIR are treated as profiles (if they exist). The default profile is assumed to be 'default'.
Specify -p <profile> as the first argument to $0 to operate on a different one
Run with a date-compatible string to generate/open only that file
i.e, $0 today; $0 tuesday; etc
Run with "asset" to spin up a new empty file with an asset tag. This is currently assumed to be plain text that complements the log, but makes little sense to included.
At some point this will be expanded to handle other files
Run with "asset <ID>" to open said asset.
Run with "review" ($0 review), and you will get a rundown of complete and incomplete tasks for the week.
Optionally, supply with date-compatible strings as "$0 review <start> [end] to use a range, end defaults to yesterday
A task is considered complete if it matches the regex /^ \*/ and incomplete matching /* \-/
@ -58,6 +59,13 @@ $0 - Captain's log
If $CLDIR is a git repo (git rev-parse returns 0), it will be updated and auto committed unless --no-git is passed
TAGS can be created by prefixing the name of the tag with '//'
This stores a list of generated links to the tag in an asset.
They can then be reviewed with "$0 tag review <tag>"
This allows for a quick view of the tag's history. Consider it like a project or ongoing task
Reminders for tasks not completed the day before are transferred to the following day
EOF
}
@ -124,18 +132,18 @@ function schedule() {
function prev_working_day() {
if [ "$(date +%a)" == 'Mon' ]; then modY=3;fi
date +%F -d "-${modY:-1} day"
if [ "$(date ${1+-d "$1"} +%a)" == 'Mon' ]; then modY=3;fi
date +%F -d "$1 -${modY:-1} day"
}
function today() {
date +%F
date ${1+-d "$1"} +%F
}
function next_working_day() {
if [ "$(date +%a)" == 'Fri' ]; then modT=3;fi
date +%F -d "+${modT:-1} day"
if [ "$(date ${1+-d "$1"} +%a)" == 'Fri' ]; then modT=3;fi
date +%F -d "${1} +${modT:-1} day"
}
function captains_log() {
@ -163,6 +171,7 @@ function captains_log() {
# Create files if they don't exist
if [ ${1-x} == 'x' ]; then
EDIT_FILES=$(echo $CLDIR/{$YESTERDAY,$TODAY,$TOMORROW})
for i in YESTERDAY TODAY TOMORROW; do
generate_file ${!i}
if [ $i == 'TODAY' ]; then
@ -175,13 +184,22 @@ function captains_log() {
vi -O $CLDIR/{$YESTERDAY,$TODAY,$TOMORROW}
fi
else
generate_file $1
transfer_items $CLDIR/$YESTERDAY $CLDIR/$TODAY
vi $CLDIR/$(date -d "$1" "+%F")
D=$(date -d "$1" "+%F")
EDIT_FILES=$CLDIR/$D
generate_file $D
transfer_items $CLDIR/$(prev_working_day) $CLDIR/$D
vi $CLDIR/$D
fi
asset generate_links
for i in $(grep -oP '\s//[^\s]+' $EDIT_FILES|sort -u); do
tag ${i#//} 2>/dev/null
done
tag generate_links
if [ $GIT -ne 0 ]; then
echo Updating git...
@ -261,12 +279,12 @@ function asset_generate_links() {
FILES=$(find ~/.captains_log/default/ -type f $MTIME \! \( -iname *.sw* -o -wholename "*/.git*" -wholename "*/assets/db" \))
# Look for references to assets
MATCHES="$(grep -oE '\[?ASSET:)?[a-zA-Z 0-9]+\]?' $FILES)"
MATCHES="$(grep -oE '\[?ASSET:)?[a-fA-F 0-9]+\]?' $FILES)"
while read line; do
# Nicely format things
FILE="$(echo $line | cut -d':' -f1)"
FILE="${FILE#$CLDIR/}"
REF="$(echo $line|cut -d ':' -f2-|grep -oE '[a-zA-Z 0-9]{8}')"
REF="$(echo $line|cut -d ':' -f2-|grep -oE '[a-fA-F 0-9]{8}')"
# Assets contain a self reference so that it can be easily copied while editing. Ignore these refs
if ! [[ "$REF" =~ $(basename $FILE 2>/dev/null) ]]; then
DB_STRING="$REF:link $FILE"
@ -291,15 +309,14 @@ function asset() {
while [ $1 ]; do
case $1 in
generate_links) shift; asset_generate_links $@; return;;
tag) TYPE=tag; shift;;
*) break;;
esac
done
if [ ${1:-0} != 0 ]; then
if [[ $1 =~ (\[?ASSET:)?[a-zA-Z0-9]+\]? ]]; then
ID="$(echo "$1"|grep -oE '[a-zA-Z0-9]{8}')"
if [ ${1:-0} != 0 ] && [[ $1 =~ (^\[?ASSET:)?[a-fA-F0-9]{8}\]? ]]; then
ID="$(echo "$1"|grep -oE '[a-fA-F0-9]{8}')"
vi "$ASSET_DIR/$ID"
fi
else
if ! [ -d "$ASSET_DIR" ]; then
@ -314,14 +331,76 @@ function asset() {
done
echo "$ID:type text" >> "$ADB"
echo "$ID:type ${TYPE-text}" >> "$ADB"
for i in $@; do
K="$(echo $@|cut -d= -f1)"
V="$(echo $@|cut -d= -f2-)"
echo "$ID:$K $V" >> "$ADB"
done
echo "[ASSET:$ID]" > "$ASSET_DIR/$ID"
vi "$ASSET_DIR/$ID"
if [ "$TYPE" != 'tag' ]; then
vi "$ASSET_DIR/$ID"
fi
fi
}
function tag() {
while [ $1 ]; do
case $1 in
generate_links) shift; tag_generate_links $@; return;;
review) shift; tag_review $@; return;;
*) break;;
esac
done
if [ "$(tag_get_id $1)" == "" ]; then
asset tag "name=$1"
echo "Created tag $1"
else echo "Tag $1 already exists: $(tag_get_id $1)" >&2; fi
}
function tag_generate_links() {
export ASSET_DIR="$CLDIR/assets/"
export ADB="$ASSET_DIR/db"
# Either do files modified in the last 7 days, or all files
if [ "$1" == "all" ]; then
MTIME=''
else
MTIME='-mtime -7'
fi
# Exclude things we don't care about (swap files, git, the db itself)
FILES=$(find ~/.captains_log/default/ -type f $MTIME \! \( -iname *.sw* -o -wholename "*/.git*" -wholename "*/assets/db" \))
# Get the asset ID for each tag, store it in an array
declare -A REFS
eval REFS=($(for i in $(grep -E '[a-fA-F0-9]{8}:type tag' $ADB|cut -d: -f1); do grep $i:name $ADB|sed 's/^\([a-fA-F0-9]\{8\}\):name \(.*\)/[\2]=\1/'; done))
# Look for references to assets
MATCHES="$(grep -oP '\s//[^\s]+' $FILES)"
while read line; do
# Nicely format things
FILE="$(echo $line | cut -d':' -f1)"
FILE="${FILE#$CLDIR/}"
TAG="$(echo $line|cut -d ':' -f2-|grep -oP '//[^\s]+'|tr -d '/')"
if [ "${REFS[$TAG]}" == '' ]; then
echo "$TAG from $FILE doesn't exist. Skipping"
continue
fi
# Assets contain a self reference so that it can be easily copied while editing. Ignore these refs
if ! [[ "$REF" =~ $(basename $FILE 2>/dev/null) ]]; then
DB_STRING="${REFS[${TAG}]}:link $FILE"
#Add it to the DB if it's not already there
if ! grep -q "$DB_STRING" $ASSET_DIR/${REFS[${TAG}]} 2>/dev/null; then
echo $DB_STRING >> $ASSET_DIR/${REFS[${TAG}]}
fi
fi
done < <(echo "$MATCHES")
}
function transfer_items() {
@ -346,16 +425,74 @@ function transfer_items() {
if [ "$TRANSFER" != '' ]; then
echo -e "\nThese income plete/ongoing items have been transferred from $(basename "$1"):\n $TRANSFER" >> $2
echo -e "\nThese incomplete/ongoing items have been transferred from $(basename "$1"):\n $TRANSFER" >> $2
fi
}
function tag_get_mentions() {
debug "getting tag mentions for $@"
F=$1;
shift
unset BLOCKS
declare -a TAGS
# Get a list of things that look like tasks
TASKS=($(grep -nE '^ ' $F |cut -d: -f1))
debug "TASKS ${TASKS[@]}"
# Set last element of the array to be EOF, so that if it matches the last block the below works
TASKS[${#TASKS[@]}]=$(wc -l $F|cut -d' ' -f1)
# Compare them to the line numbers given as arguments
for line in $@; do
debug LINE: $line
for i in $(seq 0 $((${#TASKS[@]} -1 )) ); do
if [ $(( ${TASKS[$i]} >= $line )) == 1 ]; then
if [ $(( ${TASKS[$i]} > $line )) == 1 ]; then
debug "LINE_MATCH_GT: $line > ${TASKS[$i]}"
BLOCKS="$BLOCKS ${TASKS[$(( $i - 1 ))]}";
else
debug "LINE_MATCH_EQ: $line = ${TASKS[$i]}"
BLOCKS="$BLOCKS ${TASKS[$i]}";
fi
break
fi
done
done
BLOCKS="$(echo "$BLOCKS"|tr ' ' "\n"|sort -n|uniq)"
debug "BLOCKS $BLOCKS"
for BLOCK_START in $BLOCKS; do
# Grab from the preceding start of yaml element, to the first line that doesn't start with two pieces of whitespace (i.e the yaml block)
BLOCK="$(sed -rn -e $BLOCK_START',/^ ?\S/p' $F|sed '$d')"
debug "BLOCK STARTING AT $BLOCK_START\n $BLOCK"
echo -e "$BLOCK"|fmt -w 100
done
}
function tag_get_id() {
export ASSET_DIR="$CLDIR/assets/"
export ADB="$ASSET_DIR/db"
echo $(for i in $(grep ":name $1" $ADB|cut -d: -f1); do grep $i $ADB|grep ':type tag'|cut -d: -f1;done)
}
function tag_review() {
export ASSET_DIR="$CLDIR/assets/"
export ADB="$ASSET_DIR/db"
cd $CLDIR
ID=$(tag_get_id $1)
for i in $(grep ':link' $ASSET_DIR/$ID|cut -d' ' -f2-); do
echo $i
tag_get_mentions $i $(grep -n //$1 $i|cut -d: -f1)
echo
done
}
BASEDIR="$HOME/.captains_log"
# Check if there are any profiles, otherwise just use the basedir
@ -374,9 +511,11 @@ while [ $1 ]; do
review) shift; review "$@"; exit;;
schedule) shift; schedule "$@";exit;;
asset) shift; asset "$@"; exit;;
tag) shift; tag "$@"; exit;;
*ASSET*) asset "$@"; exit;;
help|--help|-h) help; exit;;
transfer) transfer_items $CLDIR/$(today) $CLDIR/$(next_working_day); exit;;
dir) echo $CLDIR; exit;;
*) break;;
esac
done