123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #!/bin/bash
  2. #shellcheck disable=SC1090
  3. . "$(sfpath)" || exit 3
  4. shellfu import pretty
  5. #
  6. # Currency to use when not specified
  7. #
  8. CZKRATES_DEFAULT_CURRENCY=${CZKRATES_DEFAULT_CURRENCY:-USD}
  9. #
  10. # URL to daily table from
  11. #
  12. # The real URL is formed by appending current date.
  13. #
  14. CZKRATES_URL=${CZKRATES_URL:-http://www.cnb.cz/en/financial_markets/foreign_exchange_market/exchange_rate_fixing/daily.txt}
  15. usage() {
  16. mkusage "[options] [CURRENCY] [MULTIPLIER]" \
  17. "[options] [MULTIPLIER] [CURRENCY]" \
  18. "" \
  19. -o \
  20. "-D DATE, --date DATE Use currency rate from DATE instead" \
  21. " of today. DATEs like 'last sun' work, see section DATE"\
  22. " STRING of date(1) for more info." \
  23. "-d, --debug Turn on debbugging output" \
  24. "-v, --verbose Be more verbose"
  25. }
  26. type_of() {
  27. #
  28. # Print 'int' if $1 is an integer, 'nil' if empty; 'str' otherwise
  29. #
  30. local es_p es_n
  31. test -z "$1" && echo nil && return
  32. test "$1" -ge 0 2>/dev/null; es_p=$? # assuming positive
  33. test "$1" -lt 0 2>/dev/null; es_n=$? # assuming negative
  34. test $es_p -eq 2 && echo str && return
  35. test $es_n -eq 2 && echo str && return
  36. echo int
  37. }
  38. parse_rate1() {
  39. #
  40. # Parse field $2 from currency $1 data
  41. #
  42. local wntcur=$1
  43. local wntfld=${2:-Rate}
  44. case "$wntfld" in
  45. Country|Currency|Amount|Code|Rate) true;;
  46. *) mkusage "code Country|Currency|Amount|Code|Rate" ;;
  47. esac
  48. local date head
  49. read -r date
  50. debug "got: date=$date"
  51. read -r head
  52. debug "got: head=$head"
  53. while IFS='|' read -r Country Currency Amount Code Rate;
  54. do
  55. debug "got: Country=$Country Currency=$Currency Amount=$Amount Code=$Code Rate=$Rate"
  56. test "$wntcur" = "$Code" || continue
  57. case $Amount in
  58. 1) echo "${!wntfld}" ;;
  59. *) python -c "print(float($Rate)/$Amount)" ;;
  60. esac
  61. done
  62. }
  63. get_unit_price() {
  64. #
  65. # Get price of 1 unit of $currrency
  66. #
  67. local table # table with rate data
  68. think "getting currrency for: $Curr"
  69. table=$(curl -f --insecure --silent "$Uri") \
  70. || die "failed to download rates: $Uri"
  71. parse_rate1 "$Curr" Rate <<<"$table" | grep .
  72. }
  73. maybe_multiply() {
  74. #
  75. # Multiply if needed
  76. #
  77. local price
  78. read -r price
  79. if test "$Mult" = 1;
  80. then
  81. echo "$price"
  82. else
  83. think "multiplying by: $Mult"
  84. python -c "print(float($price) * $Mult)"
  85. fi
  86. }
  87. main() {
  88. local Uri
  89. local Curr
  90. local Mult
  91. local Date=now
  92. Uri=$CZKRATES_URL
  93. Uri+="?date=$(date +%d.%m.%Y)"
  94. #shellcheck disable=SC2034
  95. while true; do case "$1" in
  96. -D|--date) Date=$2; shift 2 || usage ;;
  97. -d|--debug) PRETTY_DEBUG=true; shift ;;
  98. -v|--verbose) PRETTY_VERBOSE=true; shift ;;
  99. -*) usage ;;
  100. *) break ;;
  101. esac done
  102. Uri+="?date=$(date -d "$Date" +%d.%m.%Y)"
  103. case "$(type_of "$1"):$(type_of "$2")" in
  104. int:int|str:str) usage ;;
  105. int:nil|nil:int) Mult="$1$2" ;;
  106. str:nil|nil:str) Curr="$1$2" ;;
  107. str:int) Curr="$1"; Mult="$2" ;;
  108. int:str) Curr="$2"; Mult="$1" ;;
  109. esac
  110. Curr="${Curr:-$CZKRATES_DEFAULT_CURRENCY}"
  111. Curr="${Curr^^}"
  112. Mult="${Mult:-1}"
  113. debug -v Uri Curr Mult
  114. get_unit_price | maybe_multiply
  115. }
  116. debug -v CZKRATES_DEFAULT_CURRENCY
  117. main "$@"