# -*- coding: utf-8 -*- # passerelle - uniform access to multiple data sources and services # Copyright (C) 2017-2020 Entr'ouvert # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import datetime from django.db import models from django.http import Http404 from django.utils.translation import ugettext_lazy as _ from passerelle.base.models import BaseResource from passerelle.utils.api import endpoint from passerelle.utils.jsonresponse import APIError class AirQuality(BaseResource): category = _('Misc') api_description = _( u''' This API provides a unique format for the air quality data of various places. (But only supports the Rhône-Alpes region for now). ''' ) atmo_aura_api_token = models.CharField( max_length=100, verbose_name=_('ATMO AURA API token'), blank=True, null=True ) class Meta: verbose_name = _('Air Quality') @endpoint( pattern='^(?P\w+)/(?P\w+)/$', example_pattern='{country}/{city}/', parameters={ 'country': {'description': _('Country Code'), 'example_value': 'fr'}, 'city': {'description': _('City Name'), 'example_value': 'lyon'}, }, ) def details(self, request, country, city, **kwargs): methods = { ('fr', 'albertville'): 'air_rhonealpes', ('fr', 'annecy'): 'air_rhonealpes', ('fr', 'bourg-en-bresse'): 'air_rhonealpes', ('fr', 'chambery'): 'air_rhonealpes', ('fr', 'chamonix'): 'air_rhonealpes', ('fr', 'grenoble'): 'air_rhonealpes', ('fr', 'lyon'): 'air_rhonealpes', ('fr', 'roanne'): 'air_rhonealpes', ('fr', 'saint-etienne'): 'air_rhonealpes', ('fr', 'valence'): 'air_rhonealpes', ('fr', 'vienne'): 'air_rhonealpes', } local_method = methods.get((country, city)) if not local_method: raise Http404() return getattr(self, local_method)(request, country, city, **kwargs) def air_rhonealpes(self, request, country, city, **kwargs): if not self.atmo_aura_api_token: raise APIError('missing access token for ATMO AURA API') insee_codes = { 'albertville': '73011', 'annecy': '74010', 'bourg-en-bresse': '01053', 'chambery': '73065', 'chamonix': '74056', 'grenoble': '38185', 'lyon': '69381', 'roanne': '42187', 'saint-etienne': '42218', 'valence': '26362', 'vienne': '38544', } insee_code = insee_codes.get(city.lower()) response = self.requests.get( 'https://api.atmo-aura.fr/communes/%s/indices' % insee_code, params={'api_token': self.atmo_aura_api_token}, ) json_response = response.json() today = datetime.datetime.today().strftime('%Y-%m-%d') tomorrow = (datetime.datetime.today() + datetime.timedelta(days=1)).strftime('%Y-%m-%d') response_data = {} for indice in json_response['indices']['data']: if indice['date'] == today: response_data['latest'] = { 'date': today, 'value': indice['valeur'], } elif indice['date'] == tomorrow: response_data['forecast'] = { 'j1': { 'date': today, 'value': indice['valeur'], } } if 'latest' in response_data and 'forecast' in response_data: break if 'latest' in response_data: comment_response = self.requests.get( 'https://api.atmo-aura.fr/commentaire', params={ 'date': response_data['latest']['date'], 'api_token': self.atmo_aura_api_token, }, ) if comment_response.ok: response_data['comment'] = comment_response.json().get('commentaire') return {'data': response_data, 'err': 0}