Files @ 5a73d3d8f8d4
Branch filter:

Location: NPO-Accounting/oxrlib/oxrlib/rate.py

Brett Smith
historical: Move normalize_rate and _pretty_rate to base Formatter.

This reduces the number of method overrides to help readability,
and gets rid of the annoying format_rate/pretty_rate distinction.
import datetime
import decimal
import functools
import json

class Rate:
    FIELDS = [
        'base',
        'disclaimer',
        'license',
        'rates',
        'timestamp',
    ]

    @classmethod
    def walk_fields(cls, get_field, transform_prefix):
        for fieldname in cls.FIELDS:
            value = get_field(fieldname)
            if value is not None:
                try:
                    transformer = getattr(cls, '{}_{}'.format(transform_prefix, fieldname))
                except AttributeError:
                    pass
                else:
                    value = transformer(value)
            yield (fieldname, value)

    def __init__(self, base, rates, **kwargs):
        for key, value in self.walk_fields(kwargs.get, 'deserialize'):
            setattr(self, key, value)
        self.base = base
        self.rates = rates

    @classmethod
    def deserialize_timestamp(cls, value):
        return datetime.datetime.fromtimestamp(value)

    @classmethod
    def serialize_rates(cls, rates):
        return {code: float(rates[code]) for code in rates}

    @classmethod
    def serialize_timestamp(cls, value):
        return int(value.timestamp())

    @classmethod
    def from_json_file(cls, json_file):
        response = json.load(json_file, parse_int=decimal.Decimal, parse_float=decimal.Decimal)
        return cls(**response)

    def convert(self, amount, from_currency, to_currency):
        return amount * self.rates[to_currency] / self.rates[from_currency]

    def serialize(self):
        return dict(self.walk_fields(functools.partial(getattr, self), 'serialize'))