bumblebee-status/bumblebee_status/modules/contrib/currency.py

373 lines
18 KiB
Python
Raw Permalink Normal View History

2020-04-13 19:35:06 +02:00
# -*- 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.
2020-04-13 19:35:27 +02:00
* 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,
2020-05-06 12:57:38 +02:00
the base symbol and the rate list
2020-04-13 19:35:27 +02:00
* currency.destinationdelimiter: Delimiter used for separating individual rates (defaults to '|')
2020-04-13 19:35:06 +02:00
Note: source and destination names right now must correspond to the names used by the API of https://markets.ft.com
contributed by `AntouanK <https://github.com/AntouanK>`_ - many thanks!
2020-04-13 19:35:06 +02:00
"""
2020-04-13 19:40:50 +02:00
import requests
2020-04-13 19:35:06 +02:00
try:
from babel.numbers import format_currency
except ImportError:
format_currency = None
import json
import os
2020-04-13 19:40:50 +02:00
import core.module
import core.widget
import core.decorators
import util.format
import util.location
2020-04-13 19:40:50 +02:00
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={}"
2020-04-13 19:35:06 +02:00
def load_country_to_currency():
2020-04-13 19:40:50 +02:00
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"},
2020-04-13 19:40:50 +02:00
{
"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"},
2020-04-13 19:40:50 +02:00
]
2020-04-13 19:40:50 +02:00
class Module(core.module.Module):
@core.decorators.every(minutes=5)
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.price))
2020-04-13 19:40:50 +02:00
self.__data = []
2020-04-13 19:35:06 +02:00
src = self.parameter("source", DEFAULT_SRC)
if src == "auto":
2020-04-13 19:40:50 +02:00
self.__base = self.find_local_currency()
2020-04-13 19:35:06 +02:00
else:
2020-04-13 19:40:50 +02:00
self.__base = src
2020-04-13 19:35:06 +02:00
2020-04-13 19:40:50 +02:00
self.__symbols = []
for d in util.format.aslist(self.parameter("destination", DEFAULT_DEST)):
if d == "auto":
2020-04-13 19:35:06 +02:00
new = self.find_local_currency()
else:
new = d
2020-04-13 19:40:50 +02:00
if new != self.__base:
self.__symbols.append(new)
2020-04-13 19:35:06 +02:00
def price(self, widget):
2020-04-13 19:40:50 +02:00
if len(self.__data) == 0:
return "?"
2020-04-13 19:35:06 +02:00
rates = []
2020-04-13 19:40:50 +02:00
for sym, rate in self.__data:
rate_float = float(rate.replace(",", ""))
2020-04-13 19:35:06 +02:00
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))
2020-04-13 19:35:06 +02:00
basefmt = "{}".format(self.parameter("sourceformat", "{}={}"))
ratefmt = "{}".format(self.parameter("destinationdelimiter", "="))
2020-04-13 19:35:06 +02:00
if format_currency:
2020-04-13 19:40:50 +02:00
base_val = format_currency(1, self.__base)
2020-04-13 19:35:06 +02:00
else:
base_val = "1{}".format(
SYMBOL[self.__base] if self.__base in SYMBOL else self.__base
)
2020-04-13 19:35:06 +02:00
return basefmt.format(base_val, ratefmt.join(rates))
2020-04-13 19:40:50 +02:00
def update(self):
self.__data = []
for symbol in self.__symbols:
url = API_URL.format(self.__base, symbol)
2020-04-13 19:35:06 +02:00
try:
response = requests.get(url).json()
self.__data.append((symbol, response["data"]["exchangeRate"]))
2020-04-13 19:35:06 +02:00
except Exception:
pass
def find_local_currency(self):
2020-04-13 19:35:27 +02:00
"""Use geolocation lookup to find local currency"""
2020-04-13 19:35:06 +02:00
try:
country = util.location.country()
2020-04-13 19:35:06 +02:00
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(",", ""))
2020-04-13 19:35:06 +02:00
if not 0.01 < float_rate < 100:
ret = rate
else:
ret = "%.3g" % float_rate
2020-04-13 19:35:06 +02:00
return ret
2020-04-13 19:35:06 +02:00
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4