# -*- coding: UTF-8 -*- # pylint: disable=C0111,R0903 """Displays currency exchange rates. Currently, displays currency between GBP and USD/EUR only. Requires the following python packages: * requests Parameters: * currency.interval: Interval in minutes between updates, default is 1. * currency.source: Source currency (ex. 'GBP', 'EUR'). Defaults to 'auto', which infers the local one from IP address. * currency.destination: Comma-separated list of destination currencies (defaults to 'USD,EUR') * currency.sourceformat: String format for source formatting; Defaults to '{}: {}' and has two variables, the base symbol and the rate list * currency.destinationdelimiter: Delimiter used for separating individual rates (defaults to '|') Note: source and destination names right now must correspond to the names used by the API of https://markets.ft.com """ import requests try: from babel.numbers import format_currency except ImportError: format_currency = None import json import os import core.module import core.widget import core.decorators import util.format import util.location SYMBOL = { 'GBP': u'£', 'EUR': u'€', 'USD': u'$', 'JPY': u'¥', 'KRW': u'₩' } DEFAULT_DEST = 'USD,EUR,auto' DEFAULT_SRC = 'GBP' API_URL = 'https://markets.ft.com/data/currencies/ajax/conversion?baseCurrency={}&comparison={}' def load_country_to_currency(): return [ { "country": "Afghanistan", "currency_code": "AFN" }, { "country": "Albania", "currency_code": "ALL" }, { "country": "Algeria", "currency_code": "DZD" }, { "country": "American Samoa", "currency_code": "USD" }, { "country": "Andorra", "currency_code": "EUR" }, { "country": "Angola", "currency_code": "AOA" }, { "country": "Anguilla", "currency_code": "XCD" }, { "country": "Antarctica", "currency_code": "XCD" }, { "country": "Antigua and Barbuda", "currency_code": "XCD" }, { "country": "Argentina", "currency_code": "ARS" }, { "country": "Armenia", "currency_code": "AMD" }, { "country": "Aruba", "currency_code": "AWG" }, { "country": "Australia", "currency_code": "AUD" }, { "country": "Austria", "currency_code": "EUR" }, { "country": "Azerbaijan", "currency_code": "AZN" }, { "country": "Bahamas", "currency_code": "BSD" }, { "country": "Bahrain", "currency_code": "BHD" }, { "country": "Bangladesh", "currency_code": "BDT" }, { "country": "Barbados", "currency_code": "BBD" }, { "country": "Belarus", "currency_code": "BYR" }, { "country": "Belgium", "currency_code": "EUR" }, { "country": "Belize", "currency_code": "BZD" }, { "country": "Benin", "currency_code": "XOF" }, { "country": "Bermuda", "currency_code": "BMD" }, { "country": "Bhutan", "currency_code": "BTN" }, { "country": "Bolivia", "currency_code": "BOB" }, { "country": "Bosnia and Herzegovina", "currency_code": "BAM" }, { "country": "Botswana", "currency_code": "BWP" }, { "country": "Bouvet Island", "currency_code": "NOK" }, { "country": "Brazil", "currency_code": "BRL" }, { "country": "British Indian Ocean Territory", "currency_code": "USD" }, { "country": "Brunei", "currency_code": "BND" }, { "country": "Bulgaria", "currency_code": "BGN" }, { "country": "Burkina Faso", "currency_code": "XOF" }, { "country": "Burundi", "currency_code": "BIF" }, { "country": "Cambodia", "currency_code": "KHR" }, { "country": "Cameroon", "currency_code": "XAF" }, { "country": "Canada", "currency_code": "CAD" }, { "country": "Cape Verde", "currency_code": "CVE" }, { "country": "Cayman Islands", "currency_code": "KYD" }, { "country": "Central African Republic", "currency_code": "XAF" }, { "country": "Chad", "currency_code": "XAF" }, { "country": "Chile", "currency_code": "CLP" }, { "country": "China", "currency_code": "CNY" }, { "country": "Christmas Island", "currency_code": "AUD" }, { "country": "Cocos (Keeling) Islands", "currency_code": "AUD" }, { "country": "Colombia", "currency_code": "COP" }, { "country": "Comoros", "currency_code": "KMF" }, { "country": "Congo", "currency_code": "XAF" }, { "country": "Cook Islands", "currency_code": "NZD" }, { "country": "Costa Rica", "currency_code": "CRC" }, { "country": "Croatia", "currency_code": "HRK" }, { "country": "Cuba", "currency_code": "CUP" }, { "country": "Cyprus", "currency_code": "EUR" }, { "country": "Czech Republic", "currency_code": "CZK" }, { "country": "Denmark", "currency_code": "DKK" }, { "country": "Djibouti", "currency_code": "DJF" }, { "country": "Dominica", "currency_code": "XCD" }, { "country": "Dominican Republic", "currency_code": "DOP" }, { "country": "East Timor", "currency_code": "USD" }, { "country": "Ecuador", "currency_code": "ECS" }, { "country": "Egypt", "currency_code": "EGP" }, { "country": "El Salvador", "currency_code": "SVC" }, { "country": "England", "currency_code": "GBP" }, { "country": "Equatorial Guinea", "currency_code": "XAF" }, { "country": "Eritrea", "currency_code": "ERN" }, { "country": "Estonia", "currency_code": "EUR" }, { "country": "Ethiopia", "currency_code": "ETB" }, { "country": "Falkland Islands", "currency_code": "FKP" }, { "country": "Faroe Islands", "currency_code": "DKK" }, { "country": "Fiji Islands", "currency_code": "FJD" }, { "country": "Finland", "currency_code": "EUR" }, { "country": "France", "currency_code": "EUR" }, { "country": "French Guiana", "currency_code": "EUR" }, { "country": "French Polynesia", "currency_code": "XPF" }, { "country": "French Southern territories", "currency_code": "EUR" }, { "country": "Gabon", "currency_code": "XAF" }, { "country": "Gambia", "currency_code": "GMD" }, { "country": "Georgia", "currency_code": "GEL" }, { "country": "Germany", "currency_code": "EUR" }, { "country": "Ghana", "currency_code": "GHS" }, { "country": "Gibraltar", "currency_code": "GIP" }, { "country": "Greece", "currency_code": "EUR" }, { "country": "Greenland", "currency_code": "DKK" }, { "country": "Grenada", "currency_code": "XCD" }, { "country": "Guadeloupe", "currency_code": "EUR" }, { "country": "Guam", "currency_code": "USD" }, { "country": "Guatemala", "currency_code": "QTQ" }, { "country": "Guinea", "currency_code": "GNF" }, { "country": "Guinea-Bissau", "currency_code": "CFA" }, { "country": "Guyana", "currency_code": "GYD" }, { "country": "Haiti", "currency_code": "HTG" }, { "country": "Heard Island and McDonald Islands", "currency_code": "AUD" }, { "country": "Holy See (Vatican City State)", "currency_code": "EUR" }, { "country": "Honduras", "currency_code": "HNL" }, { "country": "Hong Kong", "currency_code": "HKD" }, { "country": "Hungary", "currency_code": "HUF" }, { "country": "Iceland", "currency_code": "ISK" }, { "country": "India", "currency_code": "INR" }, { "country": "Indonesia", "currency_code": "IDR" }, { "country": "Iran", "currency_code": "IRR" }, { "country": "Iraq", "currency_code": "IQD" }, { "country": "Ireland", "currency_code": "EUR" }, { "country": "Israel", "currency_code": "ILS" }, { "country": "Italy", "currency_code": "EUR" }, { "country": "Ivory Coast", "currency_code": "XOF" }, { "country": "Jamaica", "currency_code": "JMD" }, { "country": "Japan", "currency_code": "JPY" }, { "country": "Jordan", "currency_code": "JOD" }, { "country": "Kazakhstan", "currency_code": "KZT" }, { "country": "Kenya", "currency_code": "KES" }, { "country": "Kiribati", "currency_code": "AUD" }, { "country": "Kuwait", "currency_code": "KWD" }, { "country": "Kyrgyzstan", "currency_code": "KGS" }, { "country": "Laos", "currency_code": "LAK" }, { "country": "Latvia", "currency_code": "LVL" }, { "country": "Lebanon", "currency_code": "LBP" }, { "country": "Lesotho", "currency_code": "LSL" }, { "country": "Liberia", "currency_code": "LRD" }, { "country": "Libyan Arab Jamahiriya", "currency_code": "LYD" }, { "country": "Liechtenstein", "currency_code": "CHF" }, { "country": "Lithuania", "currency_code": "LTL" }, { "country": "Luxembourg", "currency_code": "EUR" }, { "country": "Macao", "currency_code": "MOP" }, { "country": "North Macedonia", "currency_code": "MKD" }, { "country": "Madagascar", "currency_code": "MGF" }, { "country": "Malawi", "currency_code": "MWK" }, { "country": "Malaysia", "currency_code": "MYR" }, { "country": "Maldives", "currency_code": "MVR" }, { "country": "Mali", "currency_code": "XOF" }, { "country": "Malta", "currency_code": "EUR" }, { "country": "Marshall Islands", "currency_code": "USD" }, { "country": "Martinique", "currency_code": "EUR" }, { "country": "Mauritania", "currency_code": "MRO" }, { "country": "Mauritius", "currency_code": "MUR" }, { "country": "Mayotte", "currency_code": "EUR" }, { "country": "Mexico", "currency_code": "MXN" }, { "country": "Micronesia, Federated States of", "currency_code": "USD" }, { "country": "Moldova", "currency_code": "MDL" }, { "country": "Monaco", "currency_code": "EUR" }, { "country": "Mongolia", "currency_code": "MNT" }, { "country": "Montserrat", "currency_code": "XCD" }, { "country": "Morocco", "currency_code": "MAD" }, { "country": "Mozambique", "currency_code": "MZN" }, { "country": "Myanmar", "currency_code": "MMR" }, { "country": "Namibia", "currency_code": "NAD" }, { "country": "Nauru", "currency_code": "AUD" }, { "country": "Nepal", "currency_code": "NPR" }, { "country": "Netherlands", "currency_code": "EUR" }, { "country": "Netherlands Antilles", "currency_code": "ANG" }, { "country": "New Caledonia", "currency_code": "XPF" }, { "country": "New Zealand", "currency_code": "NZD" }, { "country": "Nicaragua", "currency_code": "NIO" }, { "country": "Niger", "currency_code": "XOF" }, { "country": "Nigeria", "currency_code": "NGN" }, { "country": "Niue", "currency_code": "NZD" }, { "country": "Norfolk Island", "currency_code": "AUD" }, { "country": "North Korea", "currency_code": "KPW" }, { "country": "Northern Ireland", "currency_code": "GBP" }, { "country": "Northern Mariana Islands", "currency_code": "USD" }, { "country": "Norway", "currency_code": "NOK" }, { "country": "Oman", "currency_code": "OMR" }, { "country": "Pakistan", "currency_code": "PKR" }, { "country": "Palau", "currency_code": "USD" }, { "country": "Palestine", "currency_code": null }, { "country": "Panama", "currency_code": "PAB" }, { "country": "Papua New Guinea", "currency_code": "PGK" }, { "country": "Paraguay", "currency_code": "PYG" }, { "country": "Peru", "currency_code": "PEN" }, { "country": "Philippines", "currency_code": "PHP" }, { "country": "Pitcairn", "currency_code": "NZD" }, { "country": "Poland", "currency_code": "PLN" }, { "country": "Portugal", "currency_code": "EUR" }, { "country": "Puerto Rico", "currency_code": "USD" }, { "country": "Qatar", "currency_code": "QAR" }, { "country": "Reunion", "currency_code": "EUR" }, { "country": "Romania", "currency_code": "RON" }, { "country": "Russian Federation", "currency_code": "RUB" }, { "country": "Rwanda", "currency_code": "RWF" }, { "country": "Saint Helena", "currency_code": "SHP" }, { "country": "Saint Kitts and Nevis", "currency_code": "XCD" }, { "country": "Saint Lucia", "currency_code": "XCD" }, { "country": "Saint Pierre and Miquelon", "currency_code": "EUR" }, { "country": "Saint Vincent and the Grenadines", "currency_code": "XCD" }, { "country": "Samoa", "currency_code": "WST" }, { "country": "San Marino", "currency_code": "EUR" }, { "country": "Sao Tome and Principe", "currency_code": "STD" }, { "country": "Saudi Arabia", "currency_code": "SAR" }, { "country": "Scotland", "currency_code": "GBP" }, { "country": "Senegal", "currency_code": "XOF" }, { "country": "Seychelles", "currency_code": "SCR" }, { "country": "Sierra Leone", "currency_code": "SLL" }, { "country": "Singapore", "currency_code": "SGD" }, { "country": "Slovakia", "currency_code": "EUR" }, { "country": "Slovenia", "currency_code": "EUR" }, { "country": "Solomon Islands", "currency_code": "SBD" }, { "country": "Somalia", "currency_code": "SOS" }, { "country": "South Africa", "currency_code": "ZAR" }, { "country": "South Georgia and the South Sandwich Islands", "currency_code": "GBP" }, { "country": "South Korea", "currency_code": "KRW" }, { "country": "South Sudan", "currency_code": "SSP" }, { "country": "Spain", "currency_code": "EUR" }, { "country": "SriLanka", "currency_code": "LKR" }, { "country": "Sudan", "currency_code": "SDG" }, { "country": "Suriname", "currency_code": "SRD" }, { "country": "Svalbard and Jan Mayen", "currency_code": "NOK" }, { "country": "Swaziland", "currency_code": "SZL" }, { "country": "Sweden", "currency_code": "SEK" }, { "country": "Switzerland", "currency_code": "CHF" }, { "country": "Syria", "currency_code": "SYP" }, { "country": "Tajikistan", "currency_code": "TJS" }, { "country": "Tanzania", "currency_code": "TZS" }, { "country": "Thailand", "currency_code": "THB" }, { "country": "The Democratic Republic of Congo", "currency_code": "CDF" }, { "country": "Togo", "currency_code": "XOF" }, { "country": "Tokelau", "currency_code": "NZD" }, { "country": "Tonga", "currency_code": "TOP" }, { "country": "Trinidad and Tobago", "currency_code": "TTD" }, { "country": "Tunisia", "currency_code": "TND" }, { "country": "Turkey", "currency_code": "TRY" }, { "country": "Turkmenistan", "currency_code": "TMT" }, { "country": "Turks and Caicos Islands", "currency_code": "USD" }, { "country": "Tuvalu", "currency_code": "AUD" }, { "country": "Uganda", "currency_code": "UGX" }, { "country": "Ukraine", "currency_code": "UAH" }, { "country": "United Arab Emirates", "currency_code": "AED" }, { "country": "United Kingdom", "currency_code": "GBP" }, { "country": "United States", "currency_code": "USD" }, { "country": "United States Minor Outlying Islands", "currency_code": "USD" }, { "country": "Uruguay", "currency_code": "UYU" }, { "country": "Uzbekistan", "currency_code": "UZS" }, { "country": "Vanuatu", "currency_code": "VUV" }, { "country": "Venezuela", "currency_code": "VEF" }, { "country": "Vietnam", "currency_code": "VND" }, { "country": "Virgin Islands, British", "currency_code": "USD" }, { "country": "Virgin Islands, U.S.", "currency_code": "USD" }, { "country": "Wales", "currency_code": "GBP" }, { "country": "Wallis and Futuna", "currency_code": "XPF" }, { "country": "Western Sahara", "currency_code": "MAD" }, { "country": "Yemen", "currency_code": "YER" }, { "country": "Yugoslavia", "currency_code": null }, { "country": "Zambia", "currency_code": "ZMW" }, { "country": "Zimbabwe", "currency_code": "ZWD" } ] class Module(core.module.Module): @core.decorators.every(minutes=5) def __init__(self, config): super().__init__(config, core.widget.Widget(self.price)) self.__data = [] src = self.parameter('source', DEFAULT_SRC) if src == 'auto': self.__base = self.find_local_currency() else: self.__base = src self.__symbols = [] for d in util.format.aslist(self.parameter('destination', DEFAULT_DEST)): if d == 'auto': new = self.find_local_currency() else: new = d if new != self.__base: self.__symbols.append(new) def price(self, widget): if len(self.__data) == 0: return '?' rates = [] for sym, rate in self.__data: rate_float = float(rate.replace(',','')) if format_currency: rates.append(format_currency(rate_float, sym)) else: rate = self.fmt_rate(rate) rates.append(u'{}{}'.format(rate, SYMBOL[sym] if sym in SYMBOL else sym)) basefmt = u'{}'.format(self.parameter('sourceformat', '{}={}')) ratefmt = u'{}'.format(self.parameter('destinationdelimiter', '=')) if format_currency: base_val = format_currency(1, self.__base) else: base_val = '1{}'.format(SYMBOL[self.__base] if self.__base in SYMBOL else self.__base) return basefmt.format(base_val, ratefmt.join(rates)) def update(self): self.__data = [] for symbol in self.__symbols: url = API_URL.format(self.__base, symbol) try: response = requests.get(url).json() self.__data.append((symbol, response['data']['exchangeRate'])) except Exception: pass def find_local_currency(self): """Use geolocation lookup to find local currency""" try: country = util.location.country() currency_map = load_country_to_currency() return currency_map.get(country, DEFAULT_SRC) except: return DEFAULT_SRC def fmt_rate(self, rate): float_rate = float(rate.replace(',', '')) if not 0.01 < float_rate < 100: ret = rate else: ret = '%.3g' % float_rate return ret # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4