Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

113 catch api error in stations and cities #114

Merged
merged 3 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions app/cities/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,24 @@ def CitiesDetailView(request, pk):

def CitiesListView(request):
api_url = f"{settings.API_URL}/city/all"

error_message = None
cities = []

try:
# Perform the GET request
response = requests.get(api_url)
response.raise_for_status() # Raise an error for unsuccessful requests
data = response.json() # Parse JSON response

# Extract and sort the list of cities alphabetically by name
cities = data.get("cities", [])
cities = sorted(cities, key=lambda city: city.get("name", "").lower()) # Sort case-insensitively

except requests.exceptions.HTTPError as err:
raise Http404(f"Cities not found.")
# Instead of raising a 404, store an error message to be shown in the template.
error_message = "There was an error fetching the city data: 404."
except requests.exceptions.RequestException as err:
# Catch any other request exceptions that might occur.
error_message = "There was an error fetching the city data."

return render(request, "cities/list.html", {"cities": cities})
return render(request, "cities/list.html", {"cities": cities, "error": error_message})
89 changes: 64 additions & 25 deletions app/stations/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import requests
from datetime import datetime, timezone, timedelta
from datetime import datetime, timedelta
from collections import defaultdict
from django.shortcuts import render, get_object_or_404
from django.shortcuts import render
from django.http import Http404
from django.conf import settings
from main.enums import Dimension, SensorModel, OutputFormat, Precision, Order
from main.enums import OutputFormat, Precision, Order
from requests.exceptions import HTTPError, RequestException
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def StationDetailView(request, pk):
# Beispiel API-URL, die von der Station-ID abhängt
Expand Down Expand Up @@ -61,33 +63,70 @@ def StationDetailView(request, pk):

def StationListView(request):
"""
max_station: List[Tuple[device,time_measured,dimension,value]]
min_stations: List[Tuple[device,time_measured,dimension,value]]
Fetches two lists: stations with the highest PM2.5 values and
stations with the lowest PM2.5 values.
"""

url_min = f"{settings.API_URL}/station/topn?n=10&dimension=3&order={Order.MIN.value}&output_format={OutputFormat.CSV.value}"
url_max = f"{settings.API_URL}/station/topn?n=10&dimension=3&order={Order.MAX.value}&output_format={OutputFormat.CSV.value}"

resp_min = requests.get(url_min)
resp_max = requests.get(url_max)

# TODO: try catch
resp_min.raise_for_status()
resp_max.raise_for_status()
error_message = None
try:
resp_min = requests.get(url_min)
resp_max = requests.get(url_max)

min_stations = [
line.split(",")
for i, line in enumerate(resp_min.text.splitlines())
if i
]
# Raise HTTPError for bad responses
resp_min.raise_for_status()
resp_max.raise_for_status()

max_stations = [
line.split(",")
for i, line in enumerate(resp_max.text.splitlines())
# Skip header line (i == 0)
min_stations = [
line.split(",")
for i, line in enumerate(resp_min.text.splitlines())
if i
]
]
max_stations = [
line.split(",")
for i, line in enumerate(resp_max.text.splitlines())
if i
]

except (HTTPError, RequestException) as e:
# Instead of raising a 404, store an error message in the context.
error_message = "There was an error fetching station data: 404."
# Optionally, you can log the error:
print(f"Error fetching station data: {e}")
min_stations = []
max_stations = []

# Paginate each list separately (example: 5 stations per page)
paginator_top = Paginator(max_stations, 5)
paginator_low = Paginator(min_stations, 5)

page_top = request.GET.get('page_top')
page_low = request.GET.get('page_low')

try:
top_stations_page = paginator_top.page(page_top)
except PageNotAnInteger:
top_stations_page = paginator_top.page(1)
except EmptyPage:
top_stations_page = paginator_top.page(paginator_top.num_pages)

try:
lowest_stations_page = paginator_low.page(page_low)
except PageNotAnInteger:
lowest_stations_page = paginator_low.page(1)
except EmptyPage:
lowest_stations_page = paginator_low.page(paginator_low.num_pages)

context = {
'top_stations': top_stations_page,
'lowest_stations': lowest_stations_page,
'paginator_top': paginator_top,
'paginator_low': paginator_low,
'page_top': top_stations_page,
'page_low': lowest_stations_page,
'error': error_message,
}

return render(request, 'stations/list.html', {
'top_stations': max_stations,
'lowest_stations': min_stations,
})
return render(request, 'stations/list.html', context)
29 changes: 22 additions & 7 deletions app/templates/cities/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,25 @@
{% endblock styles %}

{% block content %}
<h2>{% trans "Cities and municipalities" %}</h2>
<p>
{% for city in cities %}
<a href="/cities/{{ city.slug }}">{{ city.name }}</a> ({{ city.country.name }}){% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
{% endblock content %}
<h2 class="mb-4 mt-5">{% trans "Cities and municipalities" %}</h2>

{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}

{% if cities %}
<p>
{% for city in cities %}
<a href="/cities/{{ city.slug }}">{{ city.name }}</a> ({{ city.country.name }}){% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
{% else %}
{% if not error %}
<div class="alert alert-info" role="alert">
{% trans "No cities available." %}
</div>
{% endif %}
{% endif %}
{% endblock content %}
114 changes: 105 additions & 9 deletions app/templates/stations/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,128 @@
{% endblock styles %}

{% block content %}
<h2>{% trans "Stations overview" %}</h2>
<h2 class="mb-4 mt-5">{% trans "Stations overview" %}</h2>

<!-- Display error message if present -->
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% else %}
<div class="row">
<!-- Spalte 1: Stationen mit den höchsten Werten -->
<!-- Column 1: Top 10 with the highest values -->
<div class="col-md-6">
<h3 class="text-center">{% trans "Top 10 with the highest values for PM2.5" %}</h3>
<ul class="list-group">
{% for station in top_stations %}
<li class="list-group-item d-flex justify-content-between align-items-center">
<a href="/stations/{{ station.0 }}" class="station-link">Station {{ station.0 }}</a>
<span class="badge bg-danger rounded-pill">{{ station.3 }} µg/m³</span> <!-- Value -->
<a href="{% url 'station-detail' station.0 %}" class="station-link">
Station {{ station.0 }}
</a>
<span class="badge bg-danger rounded-pill">{{ station.3 }} µg/m³</span>
</li>
{% endfor %}
</ul>

{% if top_stations.has_other_pages %}
<nav aria-label="{% trans 'Top station pagination' %}">
<ul class="pagination justify-content-center mt-2">
{% if top_stations.has_previous %}
<li class="page-item">
<a class="page-link" href="?page_top={{ top_stations.previous_page_number }}" aria-label="{% trans 'Previous' %}">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&laquo;</span>
</li>
{% endif %}

{% for num in paginator_top.page_range %}
{% if top_stations.number == num %}
<li class="page-item active" aria-current="page">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > top_stations.number|add:'-3' and num < top_stations.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page_top={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}

{% if top_stations.has_next %}
<li class="page-item">
<a class="page-link" href="?page_top={{ top_stations.next_page_number }}" aria-label="{% trans 'Next' %}">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&raquo;</span>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
<!-- Spalte 2: Stationen mit den niedrigsten Werten -->

<!-- Column 2: Top 10 with the lowest values -->
<div class="col-md-6">
<h3 class="text-center">{% trans "Top 10 with the lowest values for PM2.5" %}</h3>
<ul class="list-group">
{% for station in lowest_stations %}
<li class="list-group-item d-flex justify-content-between align-items-center">
<a href="/stations/{{ station.0 }}" class="station-link">Station {{ station.0 }}</a>
<span class="badge bg-success rounded-pill">{{ station.3 }} µg/m³</span> <!-- Value -->
<a href="{% url 'station-detail' station.0 %}" class="station-link">
Station {{ station.0 }}
</a>
<span class="badge bg-success rounded-pill">{{ station.3 }} µg/m³</span>
</li>
{% endfor %}
</ul>

{% if lowest_stations.has_other_pages %}
<nav aria-label="{% trans 'Lowest station pagination' %}">
<ul class="pagination justify-content-center mt-2">
{% if lowest_stations.has_previous %}
<li class="page-item">
<a class="page-link" href="?page_low={{ lowest_stations.previous_page_number }}" aria-label="{% trans 'Previous' %}">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&laquo;</span>
</li>
{% endif %}

{% for num in paginator_low.page_range %}
{% if lowest_stations.number == num %}
<li class="page-item active" aria-current="page">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > lowest_stations.number|add:'-3' and num < lowest_stations.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page_low={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}

{% if lowest_stations.has_next %}
<li class="page-item">
<a class="page-link" href="?page_low={{ lowest_stations.next_page_number }}" aria-label="{% trans 'Next' %}">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link" aria-hidden="true">&raquo;</span>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</div>

{% endblock content %}
{% endif %}
{% endblock content %}
2 changes: 1 addition & 1 deletion app/templates/workshops/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{% block title %}{% trans "Workshops" %}{% endblock title %}

{% block content %}
<h2 class="mb-4">{% trans "Workshops" %}</h2>
<h2 class="mb-4 mt-5">{% trans "Workshops" %}</h2>
<p>{% trans "We continuously host workshops where air quality is measured together. On this page, the results of all public workshops are listed." %}</p>

<!-- Laufende Workshops -->
Expand Down
Loading