aboutsummaryrefslogtreecommitdiff
path: root/ihatemoney/currency_convertor.py
blob: 10026eea6997468d662c03b71ada883cd9c3e000 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from cachetools import TTLCache, cached
import requests


class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class CurrencyConverter(object, metaclass=Singleton):
    # Get exchange rates
    no_currency = "XXX"
    api_url = "https://api.exchangeratesapi.io/latest?base=USD"

    def __init__(self):
        pass

    @cached(cache=TTLCache(maxsize=1, ttl=86400))
    def get_rates(self):
        rates = requests.get(self.api_url).json()["rates"]
        rates[self.no_currency] = 1.0
        return rates

    def get_currencies(self, with_no_currency=True):
        rates = [
            rate
            for rate in self.get_rates()
            if with_no_currency or rate != self.no_currency
        ]
        rates.sort(key=lambda rate: "" if rate == self.no_currency else rate)
        return rates

    def exchange_currency(self, amount, source_currency, dest_currency):
        if (
            source_currency == dest_currency
            or source_currency == self.no_currency
            or dest_currency == self.no_currency
        ):
            return amount

        rates = self.get_rates()
        source_rate = rates[source_currency]
        dest_rate = rates[dest_currency]
        new_amount = (float(amount) / source_rate) * dest_rate
        # round to two digits because we are dealing with money
        return round(new_amount, 2)