timesheet.sh 4.3 KB
#!/bin/zsh

function tasktimes() {
    [[ $# -eq 0 ]] && return 1

    local KEY=${2:-\\1}
    local T
    local D='([0-9]{4}-[0-9]{2}-[0-9]{2})'
    local N='([0-9]+)'
    local EXPR='s/'$D'.*PT('$N'H)?('$N'M)?('$N').*/'${KEY}':\3:\5:\7/;te;d;:e'

    task $1 info | sed -r ${EXPR} | awk -F: '
    {
        s = (d[$1][2] + $4) % 60
        _m = int((d[$1][2] + $4) / 60)
        m = (d[$1][1] + $3 + _m) % 60
        _h = int((d[$1][1] + $3 + _m) / 60)
        d[$1][0] += $2 + _h
        d[$1][1] = m
        d[$1][2] = s
    }
    END {
        for(i in d)
            printf("%s:%d:%d:%d\n", i, d[i][0], d[i][1], d[i][2])
    }'
}

function tasktimestotal() {
    tasktimes $1 TOTAL
}

function taskdescription() {
    [[ $# -eq 0 ]] && return 1
    task $1 _unique description
}

function taskproject() {
    [[ $# -eq 0 ]] && return 1
    task $1 _unique project
}

function taskurgency() {
    [[ $# -eq 0 ]] && return 1
    task $1 _urgency | cut -d\  -f 4
}

function taskentry() {
    [[ $# -eq 0 ]] && return 1
    task $1 _unique entry
}

function taskend() {
    [[ $# -eq 0 ]] && return 1
    task $1 _unique end
}

function taskuuids() {
    local UUID

    [[ $# -eq 0 ]] && set \( +PENDING or +DONE \)
    for UUID in $(task $@ _uuid)
    do
        printf "%05.2f\037%s\037%s\n" \
            "$(taskurgency $UUID)" \
            "$(taskdescription $UUID)" \
            $UUID
    done | sort -t$'\037' -k1nr,2 | cut -d$'\037' -f3
}

function pendinguuids() {
    taskuuids +PENDING $@
}

function doneuuids() {
    taskuuids +DONE $@
}

function blockeduuids() {
    taskuuids +BLOCKED $@
}

function blockinguuids() {
    taskuuids +BLOCKING $@
}

function deleteduuids() {
    taskuuids +DELETED $@
}

function underline() {
    [[ $# -lt 2 ]] && return 1
    printf "\033[4m%${1}s\033[24m" "$2"
}

function bold() {
    [[ $# -lt 2 ]] && return 1
    printf "\033[1m%${1}s\033[22m" "$2"
}

function tstodate() {
    [[ $# -eq 0 ]] && return 1
    date -d @${1} +%Y-%m-%d
}

function extracttime() {
    [[ $# -eq 0 ]] && return 1

    local OIFS=${IFS}

    if [[ -z $1 ]]
    then
        TIMEKEY=""
        TIME="00:00:00"
    else
        IFS=:
        set $(echo $1)
        IFS=${OIFS}
        TIMEKEY="$1"
        TIME=$(printf "%02d:%02d:%02d" ${2:-0} ${3:-0} $4)
    fi
}

function printtimes() {
    local T
    for T in "$@"
    do
        extracttime "$T"
        printf "%51s: %s\n" "spent - $TIMEKEY" $TIME
    done
}

function truncate() {
    [[ $# -lt 2 ]] && return 1

    local STRING=$1

    [[ ${#STRING} -gt ${2} ]] && STRING="${STRING:0:$(($2-3))}..."
    echo -n "${STRING}"
}

function showall() {
    [[ $# -eq 0 ]] && return 1

    local T UUID OIFS

    printf "%s %s %s %s %s\n" \
        "$(underline -16 project)" \
        "$(underline -35 description)" \
        "$(underline -8 spent)" \
        "$(underline -10 completed)" \
        "$(underline -10 entered)"

    for UUID in "$@"
    do
        extracttime "$(tasktimes $UUID TOTAL)"
        printf "%-16s %-35s %-10s %-10s %-8s\n" \
            "$(truncate "$(taskproject $UUID)" 16)" \
            "$(truncate "$(taskdescription $UUID)" 35)" \
            "$(bold "" "$TIME")" \
            "$(tstodate $(taskend $UUID))" \
            "$(tstodate $(taskentry $UUID))" \

        printtimes $(tasktimes $UUID)
    done
}

function timesheet() {
    local phrase="1-week-ago"
    local start="$(date +%Y-%m-%d -d ${phrase})"
    local end="$(date +%Y-%m-%d)"

    printf " (generated at %s)\n\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" \
        "$(date)" \
        "$(bold "" "Tasks completed from $start to $end (back $phrase)")" \
        "$(showall $(doneuuids end.after:${start} $@))" \
        "$(bold "" "Upcoming tasks")" \
        "$(showall $(pendinguuids $@))" \
        "$(bold "" "Blocked tasks")" \
        "$(showall $(blockeduuids $@))" \
        "$(bold "" "Blocking tasks")" \
        "$(showall $(blockinguuids $@))"

    printf "%s%s\n\n%s%s\n%s\n\n%s\n\n%s\n" \
        "$(bold "" "Summary")" \
        "$(task rc._forcecolor=on $@ summary 2>/dev/null)" \
        "$(bold "" "History")" \
        "$(task rc._forcecolor=on $@ history 2>/dev/null)" \
        "$(task rc._forcecolor=on $@ ghistory 2>/dev/null)" \
        "$(task rc._forcecolor=on $@ burndown.daily 2>/dev/null)" \
        "$(task rc._forcecolor=on $@ burndown 2>/dev/null)"
}

timesheet $@

# vim: set et ts=4 sw=4: