370 lines
18 KiB
Python
370 lines
18 KiB
Python
# -*- 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": "£", "EUR": "€", "USD": "$", "JPY": "¥", "KRW": "₩"}
|
|
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, theme):
|
|
super().__init__(config, theme, 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("{}{}".format(rate, SYMBOL[sym] if sym in SYMBOL else sym))
|
|
|
|
basefmt = "{}".format(self.parameter("sourceformat", "{}={}"))
|
|
ratefmt = "{}".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
|