| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 | #!/bin/bash
#shellcheck disable=SC1090
. "$(sfpath)" || exit 3
shellfu import pretty
#
# Currency to use when not specified
#
CZKRATES_DEFAULT_CURRENCY=${CZKRATES_DEFAULT_CURRENCY:-USD}
#
# URL to daily table from
#
# The real URL is formed by appending current date.
#
CZKRATES_URL=${CZKRATES_URL:-http://www.cnb.cz/en/financial_markets/foreign_exchange_market/exchange_rate_fixing/daily.txt}
usage() {
    mkusage "[options] [CURRENCY] [MULTIPLIER]" \
            "[options] [MULTIPLIER] [CURRENCY]" \
            "" \
        -o \
            "-D DATE, --date DATE   Use currency rate from DATE instead"    \
            "       of today.  DATEs like 'last sun' work, see section DATE"\
            "       STRING of date(1) for more info."                       \
            "-d, --debug    Turn on debbugging output"                      \
            "-v, --verbose  Be more verbose"
}
type_of() {
    #
    # Print 'int' if $1 is an integer, 'nil' if empty; 'str' otherwise
    #
    local es_p es_n
    test -z "$1" && echo nil && return
    test "$1" -ge 0 2>/dev/null; es_p=$?    # assuming positive
    test "$1" -lt 0 2>/dev/null; es_n=$?    # assuming negative
    test $es_p -eq 2 && echo str && return
    test $es_n -eq 2 && echo str && return
    echo int
}
parse_rate1() {
    #
    # Parse field $2 from currency $1 data
    #
    local wntcur=$1
    local wntfld=${2:-Rate}
    case "$wntfld" in
        Country|Currency|Amount|Code|Rate) true;;
        *) mkusage "code Country|Currency|Amount|Code|Rate" ;;
    esac
    local date head
    read -r date
    debug "got: date=$date"
    read -r head
    debug "got: head=$head"
    while IFS='|' read -r Country Currency Amount Code Rate;
    do
        debug "got: Country=$Country Currency=$Currency Amount=$Amount Code=$Code Rate=$Rate"
        test "$wntcur" = "$Code" || continue
        case $Amount in
            1) echo "${!wntfld}" ;;
            *) python -c "print(float($Rate)/$Amount)" ;;
        esac
    done
}
get_unit_price() {
    #
    # Get price of 1 unit of $currrency
    #
    local table     # table with rate data
    think "getting currrency for: $Curr"
    table=$(curl -f --insecure --silent "$Uri") \
     || die "failed to download rates: $Uri"
    parse_rate1 "$Curr" Rate <<<"$table" | grep .
}
maybe_multiply() {
    #
    # Multiply if needed
    #
    local price
    read -r price
    if test "$Mult" = 1;
    then
        echo "$price"
    else
        think "multiplying by: $Mult"
        python -c "print(float($price) * $Mult)"
    fi
}
main() {
    local Uri
    local Curr
    local Mult
    local Date=now
    Uri=$CZKRATES_URL
    Uri+="?date=$(date +%d.%m.%Y)"
    #shellcheck disable=SC2034
    while true; do case "$1" in
        -D|--date)    Date=$2;  shift 2 || usage ;;
        -d|--debug)   PRETTY_DEBUG=true;   shift ;;
        -v|--verbose) PRETTY_VERBOSE=true; shift ;;
        -*)           usage ;;
        *)            break ;;
    esac done
    Uri+="?date=$(date -d "$Date" +%d.%m.%Y)"
    case "$(type_of "$1"):$(type_of "$2")" in
        int:int|str:str)    usage ;;
        int:nil|nil:int)    Mult="$1$2"          ;;
        str:nil|nil:str)    Curr="$1$2"          ;;
        str:int)            Curr="$1"; Mult="$2" ;;
        int:str)            Curr="$2"; Mult="$1" ;;
    esac
    Curr="${Curr:-$CZKRATES_DEFAULT_CURRENCY}"
    Curr="${Curr^^}"
    Mult="${Mult:-1}"
    debug -v Uri Curr Mult
    get_unit_price | maybe_multiply
}
debug -v CZKRATES_DEFAULT_CURRENCY
main "$@"
 |