Ejemplo n.º 1
0
            log.debug('Request url: {}'.format(url))

            r = requests.get(url)
            self.dump_http_response(r)

            rate = r.text

            try:
                rate = float(rate)
            except ValueError as e:
                raise APIError(e, self.id_)

            if rate == -1:
                raise APIError('Invalid amount used')
            if rate == -2:
                raise APIError('Invalid currency code: {} -> {}'
                               .format(transaction, payment))
            if rate == -3:
                raise APIError('Invalid API key: {}'.format(self.api_key))
            if rate == -4:
                raise APIError('API query limit reached')
            if rate == -5:
                raise APIError('Unresolved IP address used')

            self.save_cache(transaction, payment, rate)

        return rate


register_api_provider(ExchangeRateAPI.id_, ExchangeRateAPI, ['api_key'])
Ejemplo n.º 2
0
        # If rate is None here the exchange rate was either not cached
        # or its timestamp was too old, therefor we need to do a
        # request for an up-to-date exchange rate.
        if not rate:
            url = self.url.format(transaction, payment)
            log.debug('Request url: {}'.format(url))

            r = requests.get(url)
            self.dump_http_response(r)

            # TODO:2014-10-23:einar: provide better user feedback.
            # Should probably provide some sort of 'contact developer'
            # functionality is implemented.
            if r.status_code != 200:
                raise APIError('Unknown API error happend.', self.id_)

            rate = r.text

            try:
                rate = float(rate)
            except ValueError:
                raise APIError(rate, self.id_)

            self.save_cache(transaction, payment, rate)

        return rate


register_api_provider(Yahoo.id_, Yahoo)
Ejemplo n.º 3
0
            log.debug('Request url: {}'.format(url))

            r = requests.get(url)
            self.dump_http_response(r)

            rate = r.text

            try:
                rate = float(rate)
            except ValueError as e:
                raise APIError(e, self.id_)

            if rate == -1:
                raise APIError('Invalid amount used')
            if rate == -2:
                raise APIError('Invalid currency code: {} -> {}'.format(
                    transaction, payment))
            if rate == -3:
                raise APIError('Invalid API key: {}'.format(self.api_key))
            if rate == -4:
                raise APIError('API query limit reached')
            if rate == -5:
                raise APIError('Unresolved IP address used')

            self.save_cache(transaction, payment, rate)

        return rate


register_api_provider(ExchangeRateAPI.id_, ExchangeRateAPI, ['api_key'])
Ejemplo n.º 4
0
        if status_code == 401:
            message = r.json().get('message')
            if message in ['missing_appid_', 'invalid_appid_']:
                raise APIError('Invalid API key: {}'.format(self.api_key),
                               self.id_)
            # TODO:2014-10-22:einar: provide an else cause here?
            if message == 'not_allowed':
                raise APIError('Not allowed to access requested feature')
        if status_code == 429:
            raise APIError('Access restricted for over-use', self.id_)
        # TODO:2014-10-22:einar: use 'description' for better feedback
        if status_code == 403:
            raise APIError('Access restricted', self.id_)
        if status_code == 400:
            raise APIError('Invalid base currency', self.id_)

        if status_code == 200 or status_code == 304:
            return status_code, (r.json().get('base'),
                                 r.json().get('rates'),
                                 r.headers.get('etag'),
                                 r.headers.get('last_modified'))
        else:
            # TODO:2014-10-22:einar: provide better user feedback.
            # Should probably provide some sort of 'contact developer'
            # functionality is implemented.
            raise APIError('Received unexpected status code: {}'
                           .format(status_code), self.id_)


register_api_provider(OpenExchangeRates.id_, OpenExchangeRates, ['api_key'])
Ejemplo n.º 5
0
        rate = self.get_exchange_rate_from_cache(transaction, payment)

        if not rate:
            url = self.url.format(transaction, payment)
            log.debug('Request url: {}'.format(url))

            r = requests.get(url)
            self.dump_http_response(r)

            if r.status_code == 503:
                # FIXME:2014-10-23:einar: Copy-paste of msg from HTML response
                raise APIError(
                    'Application is temporarily over its serving '
                    'quota. Please try again later.', self.id_)

            try:
                rate = r.json().get('rate')
            except KeyError as ke:
                log.error(ke)
                raise APIError('Unable to extract rate key from json response')
            except ValueError as ve:
                log.error(ve)
                raise APIError('Unable to convert exchange rate to float')

            self.save_cache(transaction, payment, rate)

        return rate


register_api_provider(RateExchange.id_, RateExchange)
Ejemplo n.º 6
0
                raise APIError('Unable to fetch data.', self.id_)

    def _parse_html(self, html):
        """Parse the return HTML document for exchange rate data.

        :param html: the HTML content to parse.

        :returns: two dictionaries (rates and inverse_rates), which
            contains exchange rates on success, or is empty otherwise.
        """
        soup = BeautifulSoup(html, self._parser)
        content = soup.find(id='content_section').find('table').find('font')

        f = io.StringIO(content.text)
        reader = csv.reader(f)
        data = [row for row in reader if len(row) > 0][1:]

        assert len(data) > 0
        assert len(data[0]) == 4

        rates, inverse_rates = {}, {}
        for row in data:
            name, code, inverse, rate = row
            rates[code] = float(rate)
            inverse_rates[code] = float(inverse)

        return rates, inverse_rates


register_api_provider(Oanda.id_, Oanda)
Ejemplo n.º 7
0
        """
        rate = self.get_exchange_rate_from_cache(transaction, payment)

        if not rate:
            url = self.url.format(transaction, payment)
            log.debug('Request url: {}'.format(url))

            r = requests.get(url)
            self.dump_http_response(r)

            if r.status_code == 503:
                # FIXME:2014-10-23:einar: Copy-paste of msg from HTML response
                raise APIError('Application is temporarily over its serving '
                               'quota. Please try again later.', self.id_)

            try:
                rate = r.json().get('rate')
            except KeyError as ke:
                log.error(ke)
                raise APIError('Unable to extract rate key from json response')
            except ValueError as ve:
                log.error(ve)
                raise APIError('Unable to convert exchange rate to float')

            self.save_cache(transaction, payment, rate)

        return rate


register_api_provider(RateExchange.id_, RateExchange)
Ejemplo n.º 8
0
        if status_code == 401:
            message = r.json().get('message')
            if message in ['missing_appid_', 'invalid_appid_']:
                raise APIError('Invalid API key: {}'.format(self.api_key),
                               self.id_)
            # TODO:2014-10-22:einar: provide an else cause here?
            if message == 'not_allowed':
                raise APIError('Not allowed to access requested feature')
        if status_code == 429:
            raise APIError('Access restricted for over-use', self.id_)
        # TODO:2014-10-22:einar: use 'description' for better feedback
        if status_code == 403:
            raise APIError('Access restricted', self.id_)
        if status_code == 400:
            raise APIError('Invalid base currency', self.id_)

        if status_code == 200 or status_code == 304:
            return status_code, (r.json().get('base'), r.json().get('rates'),
                                 r.headers.get('etag'),
                                 r.headers.get('last_modified'))
        else:
            # TODO:2014-10-22:einar: provide better user feedback.
            # Should probably provide some sort of 'contact developer'
            # functionality is implemented.
            raise APIError(
                'Received unexpected status code: {}'.format(status_code),
                self.id_)


register_api_provider(OpenExchangeRates.id_, OpenExchangeRates, ['api_key'])