-#!/usr/bin/env bash
-#
-# This script builds a file, usually /var/currencies where each line as the syntax
-# <3 letter international currency code> <decimal value>
-# All the lines do have the same value
-#
-# Exemple:
-# GBP 1.4758
-# USD 0.7469
-# means than £ 1.4758 = $ 0.7469. From there all kind of conversion are possibles.
-#
-# You are free to copy / modify / redistribute / resell that file, just keep the author name.
-# Author: Jean-Michel Vourgère <jmv_deb@nirgal.com>
+#!/usr/bin/env python3
-set -e
+import logging
-target_file=/var/currencies
-REFERENCE="EUR"
-unset verbose
-unset aggressive
+REFERENCE='EUR'
-curlcmd="curl --user-agent curcy -s -S"
+def get_yahoo_file():
+ from urllib import request
+ req = request.Request(
+ 'http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote;currency=true?view=basic&format=json',
+ headers={'User-Agent': 'curcy'})
+ uo = request.urlopen(req)
+ httpdata = uo.read()
+ uo.close()
+ return httpdata.decode('UTF-8')
-function usage() {
- #echo $'\n' $@ $'\n'
- echo "Usage: curcy-update [options]"
- echo " -v|--verbose Display informational messages"
- echo " -l|--listonly Just list the supported currencies"
- echo " --aggressive Don't sleep between server requests"
- echo " --target=<filename> Set target filename. Defaults to $target_file"
- echo "See man curcy-update(1) for documentation."
-}
+def get_yahoo_raw():
+ import json
+ yahoo_file = get_yahoo_file()
+ #file('curency.json', 'w').write(yahoo_file)
+ #yahoo_file = open('curency.json').read()
+ #print yahoo_file
+ yahoo_file = yahoo_file.replace(',\n]', ']')
+ return json.loads(yahoo_file)
-function parsearg() {
- _OPT="${1%=?*}"
- _VAL="${1#?*=}"
-}
+def parse_yahoo(json_obj):
+ list = json_obj['list']
+ for res in list['resources']:
+ quote = res['resource']['fields']
+ if not quote['name'].startswith('USD/') or len(quote['name']) != 7:
+ logging.debug('Invalid name quote name %s', quote['name'])
+ continue
+ #yield quote['name']
+ yield quote['name'][4:], float(quote['price'])
-for arg in "$@"; do
- parsearg $arg
+def get_yahoo_quotes():
+ quotes = {}
+ for name, value in parse_yahoo(get_yahoo_raw()):
+ quotes[name] = value
- case $_OPT in
- -v|--verbose)
- verbose=1
- continue
- ;;
- -l|--listonly)
- listonly=1
- continue
- ;;
- --aggressive)
- echo "Setting aggressive"
- aggressive=1
- continue
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- --target)
- target_file=$_VAL
- continue
- ;;
- *)
- echo "Unknown option $_OPT"
- usage
- exit 22
- ;;
- esac
-done
+ ref_usd = quotes[REFERENCE]
+ for cur in quotes.keys():
+ quotes[cur] /= ref_usd
+ assert len(quotes) > 0
+ quotes['USD'] = 1/ref_usd
+ # add historical european values
+ if REFERENCE == 'EUR':
+ quotes['ATS'] = 0.07267283416785971236
+ quotes['BEF'] = 0.02478935247732393982
+ quotes['DEM'] = 0.51129188119621848524
+ quotes['ESP'] = 0.00601012104383782289
+ quotes['FIM'] = 0.16818792646151103396
+ quotes['FRF'] = 0.15244901723741037903
+ quotes['GRD'] = 0.00293470286133528980
+ quotes['IEP'] = 1.26973807842918162841
+ quotes['ITL'] = 0.00051645689908948648
+ quotes['LUF'] = 0.02478935247732393982
+ quotes['NLG'] = 0.45378021609013890212
+ quotes['PTE'] = 0.00498797897068065961
+ quotes['SIT'] = 0.00417292605575029210
+ quotes['VAL'] = 0.00051645689908948648
+ else:
+ logging.warning('reference must be EUR to get legacy currencies exchange rates.')
+ logging.warning('WARNING: ATS BEF DEM ESP FIM FRF GRD IEP ITL LUF NLG PTE SIT VAL will be unavailable!')
-# get list of curencies
-currencies=`$curlcmd "http://finance.yahoo.com/currency/convert?amt=1&from=${REFERENCE}&to=${REFERENCE}" \
- | grep yfnc_tabledata1 \
- | sed -e "s/<select name=\"from\">\(.*\)<\/select>.*<select.*/\1/g" \
- | sed -e "s/selected //g" \
- | sed -e "s/<option value=\"/\n/g" \
- | grep -v script \
- | cut -d \" -f 1`
+ return quotes
-if [ -n "$listonly" -o "$verbose" ]; then
- echo "Supported currencies:"
- for c in $currencies; do
- echo -n $c$' '
- done
- echo
- if [ -n "$listonly" ]; then
- exit 0
- fi
-fi
-
-[ -f $target_file.new ] && rm -r $target_file.new
-for c in $currencies; do
- # google doesn't do many currencies; yahoo is better in that regard
- #equiv=`curl -s -S "http://finance.google.com/finance?q=${c}${REFERENCE}&hl=en" \
- # | grep -E " 1 ${c} =<b> [0-9]+\.[0-9]+ ${REFERENCE} </b>" \
- # | sed -e "s/^ 1 ${c} =<b> \(.*\) ${REFERENCE} <\/b>/\1/g"`
-
- # http://finance.google.com/robots.txt allows /currency
-
- equiv=`$curlcmd "http://finance.yahoo.com/currency/convert?amt=1&from=${c}&to=${REFERENCE}" \
- | grep yfnc_tabledata1 \
- | sed -e "s/.*<\/b>.*<b>\(.*\)<\/b>.*/\1/g"`
+def main():
+ from optparse import OptionParser
+ parser = OptionParser('%prog [options]')
+ parser.add_option('-v', '--verbose',
+ help='Display informational messages',
+ action='store_true', dest='verbose', default=False)
+ parser.add_option('-l', '--listonly',
+ help='Just list the supported currencies',
+ action='store_true', dest='listonly', default=False)
+ parser.add_option('-a', '--aggressive',
+ help='Deprecaded.',
+ action='store_true', dest='aggressive', default=False)
+ parser.add_option('--target',
+ help='Set target filename. Defaults to %default',
+ dest='target_file', default='/var/currencies')
+ options, args = parser.parse_args()
- if [ -n "$verbose" ]; then
- echo 1 $c = $equiv $REFERENCE
- fi
- echo $c $equiv>> $target_file.new
+ if options.verbose:
+ loglevel = logging.DEBUG
+ else:
+ loglevel = logging.INFO
+ logging.basicConfig(level=loglevel, format='%(asctime)s %(levelname)s %(message)s')
- if [ -z "$aggressive" ]; then
- # be nice with server: wait 1 to 2 minutes
- sleep $(( 60 + $RANDOM % 60 ))
- fi
-done
+ target_file = open(options.target_file, 'w')
+ for cur, value in get_yahoo_quotes().items():
+ print(cur, value, file=target_file)
+
+if __name__ == '__main__':
+ main()
-if [ "REFERENCE" == "EUR" ]; then
- #echo ATS 1/13.7603>> $target_file.new
- #echo BEF 1/40.3399>> $target_file.new
- #echo DEM 1/1.95583>> $target_file.new
- #echo ESP 1/166.386>> $target_file.new
- #echo FIM 1/5.94573>> $target_file.new
- #echo FRF 1/6.55957>> $target_file.new
- #echo GRD 1/340.750>> $target_file.new
- #echo IEP 1/0.787564>> $target_file.new
- #echo ITL 1/1936.27>> $target_file.new
- #echo LUF 1/40.3399>> $target_file.new
- #echo NLG 1/2.20371>> $target_file.new
- #echo PTE 1/200.482>> $target_file.new
- #echo SIT 1/239.640>> $target_file.new
- #echo VAL 1/1936.27>> $target_file.new
-
- echo ATS .07267283416785971236>> $target_file.new
- echo BEF .02478935247732393982>> $target_file.new
- echo DEM .51129188119621848524>> $target_file.new
- echo ESP .00601012104383782289>> $target_file.new
- echo FIM .16818792646151103396>> $target_file.new
- echo FRF .15244901723741037903>> $target_file.new
- echo GRD .00293470286133528980>> $target_file.new
- echo IEP 1.26973807842918162841>> $target_file.new
- echo ITL .00051645689908948648>> $target_file.new
- echo LUF .02478935247732393982>> $target_file.new
- echo NLG .45378021609013890212>> $target_file.new
- echo PTE .00498797897068065961>> $target_file.new
- echo SIT .00417292605575029210>> $target_file.new
- echo VAL .00051645689908948648>> $target_file.new
-else
- echo "WARNING: reference must be EUR to get legacy currencies exchange rates."
- echo "WARNING: ATS BEF DEM ESP FIM FRF GRD IEP ITL LUF NLG PTE SIT VAL will be unavailable!"
-fi
-mv $target_file.new $target_file