passerelle/passerelle/apps/airquality/models.py

125 lines
4.7 KiB
Python
Raw Normal View History

# -*- 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 <http://www.gnu.org/licenses/>.
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')
2021-02-20 16:26:01 +01:00
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).
2021-02-20 16:26:01 +01:00
'''
)
2021-02-20 16:26:01 +01:00
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')
2021-02-20 16:26:01 +01:00
@endpoint(
pattern='^(?P<country>\w+)/(?P<city>\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())
2021-02-20 16:26:01 +01:00
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:
2021-02-20 16:26:01 +01:00
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}