From 775f1bddaa7e3b5e3c5cefa764d2f844eafabf85 Mon Sep 17 00:00:00 2001 From: Silvio Heinze Date: Mon, 13 Jan 2025 18:34:38 +0100 Subject: [PATCH 1/3] add error handling to stations and cities list view --- app/cities/views.py | 16 +++- app/stations/views.py | 89 +++++++++++++----- app/templates/cities/list.html | 29 ++++-- app/templates/stations/list.html | 152 +++++++++++++++++++++++++------ 4 files changed, 223 insertions(+), 63 deletions(-) diff --git a/app/cities/views.py b/app/cities/views.py index 2dc7a67..2ca110b 100644 --- a/app/cities/views.py +++ b/app/cities/views.py @@ -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}) \ No newline at end of file + return render(request, "cities/list.html", {"cities": cities, "error": error_message}) \ No newline at end of file diff --git a/app/stations/views.py b/app/stations/views.py index 7bd2509..f9ed700 100644 --- a/app/stations/views.py +++ b/app/stations/views.py @@ -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 @@ -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) \ No newline at end of file diff --git a/app/templates/cities/list.html b/app/templates/cities/list.html index be366e7..323f00b 100644 --- a/app/templates/cities/list.html +++ b/app/templates/cities/list.html @@ -8,10 +8,27 @@ {% endblock styles %} {% block content %} +

{% trans "Cities and municipalities" %}

-

- {% for city in cities %} - {{ city.name }} ({{ city.country.name }}){% if not forloop.last %}, {% endif %} - {% endfor %} -

-{% endblock content %} + +{% if error %} + +{% endif %} + +{% if cities %} +

+ {% for city in cities %} + {{ city.name }} ({{ city.country.name }}){% if not forloop.last %}, {% endif %} + {% endfor %} +

+{% else %} + {% if not error %} + + {% endif %} +{% endif %} +
+{% endblock content %} \ No newline at end of file diff --git a/app/templates/stations/list.html b/app/templates/stations/list.html index 05352b2..33d3604 100644 --- a/app/templates/stations/list.html +++ b/app/templates/stations/list.html @@ -33,32 +33,130 @@ {% endblock styles %} {% block content %} -

{% trans "Stations overview" %}

-
- -
-

{% trans "Top 10 with the highest values for PM2.5" %}

- -
- -
-

{% trans "Top 10 with the lowest values for PM2.5" %}

- +
+

{% trans "Stations overview" %}

+ + + {% if error %} + + {% endif %} + +
+ +
+

{% trans "Top 10 with the highest values for PM2.5" %}

+ + + {% if top_stations.has_other_pages %} + + {% endif %} +
+ + +
+

{% trans "Top 10 with the lowest values for PM2.5" %}

+ + + {% if lowest_stations.has_other_pages %} + + {% endif %} +
- -{% endblock content %} +{% endblock content %} \ No newline at end of file From 4c82586b173e61b238b88a8e4b6215e0ed8109e9 Mon Sep 17 00:00:00 2001 From: Silvio Heinze Date: Mon, 13 Jan 2025 18:35:43 +0100 Subject: [PATCH 2/3] workshop list template: add top margin to h2 --- app/templates/workshops/list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/workshops/list.html b/app/templates/workshops/list.html index 933682c..013bf2e 100644 --- a/app/templates/workshops/list.html +++ b/app/templates/workshops/list.html @@ -5,7 +5,7 @@ {% block title %}{% trans "Workshops" %}{% endblock title %} {% block content %} -

{% trans "Workshops" %}

+

{% trans "Workshops" %}

{% trans "We continuously host workshops where air quality is measured together. On this page, the results of all public workshops are listed." %}

From ba5304e4957b024f58c62b693cc6b8398f6df7f9 Mon Sep 17 00:00:00 2001 From: Silvio Heinze Date: Mon, 13 Jan 2025 18:41:35 +0100 Subject: [PATCH 3/3] templates cities and stations list: change margins h2 --- app/templates/cities/list.html | 4 +- app/templates/stations/list.html | 222 +++++++++++++++---------------- 2 files changed, 111 insertions(+), 115 deletions(-) diff --git a/app/templates/cities/list.html b/app/templates/cities/list.html index 323f00b..b5ea0a1 100644 --- a/app/templates/cities/list.html +++ b/app/templates/cities/list.html @@ -8,8 +8,7 @@ {% endblock styles %} {% block content %} -
-

{% trans "Cities and municipalities" %}

+

{% trans "Cities and municipalities" %}

{% if error %} {% endif %} {% endif %} -
{% endblock content %} \ No newline at end of file diff --git a/app/templates/stations/list.html b/app/templates/stations/list.html index 33d3604..7275e08 100644 --- a/app/templates/stations/list.html +++ b/app/templates/stations/list.html @@ -33,130 +33,128 @@ {% endblock styles %} {% block content %} -
-

{% trans "Stations overview" %}

+

{% trans "Stations overview" %}

- - {% if error %} - - {% endif %} - -
- -
-

{% trans "Top 10 with the highest values for PM2.5" %}

- + +{% if error %} + +{% else %} +
+ +
+

{% trans "Top 10 with the highest values for PM2.5" %}

+ - {% if top_stations.has_other_pages %} -
+ {% endfor %} + + {% if top_stations.has_next %} +
  • + + + +
  • + {% else %} +
  • + +
  • + {% endif %} + + + {% endif %} +
    - -
    -

    {% trans "Top 10 with the lowest values for PM2.5" %}

    - + +
    +

    {% trans "Top 10 with the lowest values for PM2.5" %}

    + - {% if lowest_stations.has_other_pages %} -
    + {% endfor %} + + {% if lowest_stations.has_next %} +
  • + + + +
  • + {% else %} +
  • + +
  • + {% endif %} + + + {% endif %}
    +{% endif %} {% endblock content %} \ No newline at end of file