Merge pull request #122 into master
a0c257dcontainer: plugins: implement 'timew_to_timeclock' plugin (Aaron Fiore)6aadc6fcontainer: plugins: refactor example plugin (Aaron Fiore)
This commit was merged in pull request #122.
This commit is contained in:
@@ -38,9 +38,12 @@
|
||||
[ -z "$DOCKER_FINANCE_CONTAINER_REPO" ] && exit 1
|
||||
source "${DOCKER_FINANCE_CONTAINER_REPO}/src/finance/lib/lib_finance.bash"
|
||||
|
||||
[[ -z "$global_parent_profile" || -z "$global_arg_delim_1" || -z "$global_child_profile" ]] && lib_utils::die_fatal
|
||||
instance="${global_parent_profile}${global_arg_delim_1}${global_child_profile}"
|
||||
|
||||
# Initialize "constructor"
|
||||
[[ -z "$global_parent_profile" || -z "$global_arg_delim_1" || -z "$global_child_profile" ]] && exit 1
|
||||
lib_finance::finance "${global_parent_profile}${global_arg_delim_1}${global_child_profile}"
|
||||
# NOTE: "constructor" only needed if calling library directly
|
||||
lib_finance::finance "$instance" || lib_utils::die_fatal
|
||||
|
||||
#
|
||||
# Implementation
|
||||
@@ -48,14 +51,14 @@ lib_finance::finance "${global_parent_profile}${global_arg_delim_1}${global_chil
|
||||
|
||||
function main()
|
||||
{
|
||||
echo -e "
|
||||
local -r _example="
|
||||
This container's environment:
|
||||
|
||||
$(printenv | grep ^DOCKER_FINANCE | sort)
|
||||
|
||||
This plugin's caller profile:
|
||||
|
||||
${global_parent_profile}${global_arg_delim_1}${global_child_profile}
|
||||
$instance
|
||||
|
||||
This plugin's path is:
|
||||
|
||||
@@ -66,10 +69,11 @@ This plugin's arguments:
|
||||
'${*}'
|
||||
|
||||
Showing total current BTC balance:
|
||||
|
||||
$(lib_finance::ledger bal assets liabilities cur:BTC | tail -n1)
|
||||
|
||||
"
|
||||
echo -n " "
|
||||
lib_finance::ledger bal assets liabilities cur:BTC | tail -n1
|
||||
echo
|
||||
lib_utils::print_custom "$_example"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
116
container/plugins/finance/timew_to_timeclock.bash
Executable file
116
container/plugins/finance/timew_to_timeclock.bash
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# docker-finance | modern accounting for the power-user
|
||||
#
|
||||
# Copyright (C) 2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation either version 3 of the License or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# "Libraries"
|
||||
#
|
||||
|
||||
[ -z "$DOCKER_FINANCE_CONTAINER_REPO" ] && exit 1
|
||||
source "${DOCKER_FINANCE_CONTAINER_REPO}/src/finance/lib/lib_finance.bash"
|
||||
|
||||
[[ -z "$global_parent_profile" || -z "$global_arg_delim_1" || -z "$global_child_profile" ]] && lib_utils::die_fatal
|
||||
instance="${global_parent_profile}${global_arg_delim_1}${global_child_profile}"
|
||||
|
||||
# Initialize "constructor"
|
||||
lib_finance::finance "$instance" || lib_utils::die_fatal
|
||||
|
||||
#
|
||||
# Implementation
|
||||
#
|
||||
|
||||
lib_utils::deps_check "jq" # *should* be provided by dependency `yq`
|
||||
|
||||
function __format_time()
|
||||
{
|
||||
[[ -z "$1" || -z "$2" ]] && lib_utils::die_fatal
|
||||
|
||||
local -r _direction="$1"
|
||||
local -r _timestamp="$2"
|
||||
|
||||
# Expects timewarrior *exported* time format
|
||||
echo -n "$_direction $(echo ${_timestamp:0:4}-${_timestamp:4:2}-${_timestamp:6:2} ${_timestamp:9:2}:${_timestamp:11:2}:${_timestamp:13:2})"
|
||||
}
|
||||
|
||||
# - Converts exported timewarrior JSON schema into hledger timeclock format
|
||||
# - Expects the following timewarrior style tags in the format of `key=value`
|
||||
#
|
||||
# desc="My Description"
|
||||
# comment="My Comment"
|
||||
# tag:type=value
|
||||
# tag:...
|
||||
#
|
||||
# TODO: optimize: export only needed once if the majority of parsing is done within gawk
|
||||
function main()
|
||||
{
|
||||
# Stop tracking or else format breaks
|
||||
lib_finance::times stop &>/dev/null
|
||||
|
||||
# Commands and timeclock entries
|
||||
local -r _cmd=("lib_finance::times" "export")
|
||||
local -r _count=$("${_cmd[@]}" | jq '. | length')
|
||||
local _id _start _end _tags
|
||||
|
||||
# Cycle through total count of timewarrior entries
|
||||
for ((_i = 1; _i <= _count; _i++)); do
|
||||
|
||||
# Parse timewarrior format
|
||||
local _array=()
|
||||
while read _line; do
|
||||
_array+=("$_line")
|
||||
done < <("${_cmd[@]}" | jq -Mer ".[${_i}-1] | .id,.start,.end")
|
||||
|
||||
local _id="${_array[0]}"
|
||||
local _start="${_array[1]}"
|
||||
local _end="${_array[2]}"
|
||||
|
||||
local _tags
|
||||
_tags="$("${_cmd[@]}" | jq -Mer ".[${_i}-1] | .tags.[]")"
|
||||
|
||||
# Print parsed as timeclock format
|
||||
__format_time "i" "$_start"
|
||||
echo "$_tags" \
|
||||
| grep -E "(^profile=|^desc=|^comment=|^tag:)" \
|
||||
| gawk -F'=' -v _id="$_id" '{
|
||||
switch ($1)
|
||||
{
|
||||
case "profile":
|
||||
account=$2
|
||||
break
|
||||
case "desc":
|
||||
description=$2
|
||||
break
|
||||
case "comment":
|
||||
comment=$2
|
||||
break
|
||||
default:
|
||||
# All others are considered "real" tags
|
||||
tags=substr($0, 5)
|
||||
sub(/=/, ":", tags) # Reconstruct to hledger tag format
|
||||
# TODO: push to an array for more tags
|
||||
break
|
||||
}
|
||||
} END { printf " " account " " description " ; " comment ", id:" _id ", " tags "\n"}'
|
||||
__format_time "o" "$_end"
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
# vim: sw=2 sts=2 si ai et
|
||||
Reference in New Issue
Block a user