123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 'num' if $1 is a number (float or integer), 'nil' if empty; 'str' otherwise
  29. #
  30. test -z "$1" && echo nil && return
  31. grep -qxEe '-?[0-9]*[.][0-9]+' <<<"$1" && echo num && return
  32. grep -qxEe '-?[0-9]+' <<<"$1" && echo num && return
  33. echo str
  34. }
  35. parse_rate1() {
  36. #
  37. # Parse field $2 from currency $1 data
  38. #
  39. local wntcur=$1
  40. local wntfld=${2:-Rate}
  41. case "$wntfld" in
  42. Country|Currency|Amount|Code|Rate) true;;
  43. *) mkusage "code Country|Currency|Amount|Code|Rate" ;;
  44. esac
  45. local date head
  46. read -r date
  47. debug "got: date=$date"
  48. read -r head
  49. debug "got: head=$head"
  50. while IFS='|' read -r Country Currency Amount Code Rate;
  51. do
  52. debug "got: Country=$Country Currency=$Currency Amount=$Amount Code=$Code Rate=$Rate"
  53. test "$wntcur" = "$Code" || continue
  54. case $Amount in
  55. 1) echo "${!wntfld}" ;;
  56. *) python -c "print(float($Rate)/$Amount)" ;;
  57. esac
  58. done
  59. }
  60. get_unit_price() {
  61. #
  62. # Get price of 1 unit of $currrency
  63. #
  64. local table # table with rate data
  65. think "getting currrency for: $Curr"
  66. table=$(curl -f --insecure --silent "$Uri") \
  67. || die "failed to download rates: $Uri"
  68. parse_rate1 "$Curr" Rate <<<"$table" | grep .
  69. }
  70. maybe_multiply() {
  71. #
  72. # Multiply if needed
  73. #
  74. local price
  75. read -r price
  76. if test "$Mult" = 1;
  77. then
  78. echo "$price"
  79. else
  80. think "multiplying by: $Mult"
  81. python -c "print(float($price) * $Mult)"
  82. fi
  83. }
  84. main() {
  85. local Uri
  86. local Curr
  87. local Mult
  88. local Date=now
  89. Uri=$CZKRATES_URL
  90. Uri+="?date=$(date +%d.%m.%Y)"
  91. #shellcheck disable=SC2034
  92. while true; do case "$1" in
  93. -D|--date) Date=$2; shift 2 || usage ;;
  94. -d|--debug) PRETTY_DEBUG=true; shift ;;
  95. -v|--verbose) PRETTY_VERBOSE=true; shift ;;
  96. -*) usage ;;
  97. *) break ;;
  98. esac done
  99. Uri+="?date=$(date -d "$Date" +%d.%m.%Y)"
  100. case "$(type_of "$1"):$(type_of "$2")" in
  101. num:num|str:str) usage ;;
  102. num:nil|nil:num) Mult="$1$2" ;;
  103. str:nil|nil:str) Curr="$1$2" ;;
  104. str:num) Curr="$1"; Mult="$2" ;;
  105. num:str) Curr="$2"; Mult="$1" ;;
  106. esac
  107. Curr="${Curr:-$CZKRATES_DEFAULT_CURRENCY}"
  108. Curr="${Curr^^}"
  109. Mult="${Mult:-1}"
  110. debug -v Uri Curr Mult
  111. get_unit_price | maybe_multiply
  112. }
  113. debug -v CZKRATES_DEFAULT_CURRENCY
  114. main "$@"