ch14
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
# apic/rails/views.py
|
||||
from datetime import datetime
|
||||
from operator import itemgetter
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from requests.exceptions import RequestException
|
||||
|
||||
from .forms import AuthenticateForm
|
||||
|
||||
|
||||
class IndexView(generic.TemplateView):
|
||||
template_name = "rails/index.html"
|
||||
|
||||
|
||||
class StationsView(generic.TemplateView):
|
||||
template_name = "rails/stations.html"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
context = self.get_context_data(**kwargs)
|
||||
|
||||
api_url = urljoin(settings.BASE_API_URL, "stations")
|
||||
|
||||
try:
|
||||
response = requests.get(api_url)
|
||||
response.raise_for_status()
|
||||
except RequestException as err:
|
||||
context["error"] = err
|
||||
else:
|
||||
context["stations"] = response.json()
|
||||
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
class DeparturesView(generic.TemplateView):
|
||||
template_name = "rails/departures.html"
|
||||
|
||||
def get(self, request, station_id, *args, **kwargs):
|
||||
context = self.get_context_data(**kwargs)
|
||||
|
||||
api_url = urljoin(
|
||||
settings.BASE_API_URL,
|
||||
f"stations/{station_id}/departures",
|
||||
)
|
||||
|
||||
try:
|
||||
response = requests.get(api_url)
|
||||
response.raise_for_status()
|
||||
except RequestException as err:
|
||||
context["error"] = err
|
||||
else:
|
||||
trains = prepare_trains(response.json(), "departs_at")
|
||||
context["departures"] = trains
|
||||
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
class ArrivalsView(generic.TemplateView):
|
||||
template_name = "rails/arrivals.html"
|
||||
|
||||
def get(self, request, station_id, *args, **kwargs):
|
||||
context = self.get_context_data(**kwargs)
|
||||
|
||||
api_url = urljoin(
|
||||
settings.BASE_API_URL,
|
||||
f"stations/{station_id}/arrivals",
|
||||
)
|
||||
|
||||
try:
|
||||
response = requests.get(api_url)
|
||||
response.raise_for_status()
|
||||
except RequestException as err:
|
||||
context["error"] = err
|
||||
else:
|
||||
trains = prepare_trains(response.json(), "arrives_at")
|
||||
context["arrivals"] = trains
|
||||
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
class UsersView(generic.TemplateView):
|
||||
template_name = "rails/users.html"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
context = self.get_context_data(**kwargs)
|
||||
|
||||
api_url = urljoin(
|
||||
settings.BASE_API_URL,
|
||||
"users",
|
||||
)
|
||||
|
||||
try:
|
||||
response = requests.get(api_url)
|
||||
response.raise_for_status()
|
||||
except RequestException as err:
|
||||
context["error"] = err
|
||||
else:
|
||||
context["users"] = response.json()
|
||||
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
class AuthenticateView(generic.FormView):
|
||||
template_name = "rails/authenticate.html"
|
||||
success_url = reverse_lazy("auth_result")
|
||||
form_class = AuthenticateForm
|
||||
|
||||
def form_valid(self, form):
|
||||
data = form.cleaned_data
|
||||
self.api_authenticate(data["email"], data["password"])
|
||||
# leave this as final instruction as it will just perform the redir.
|
||||
return super().form_valid(form)
|
||||
|
||||
def api_authenticate(self, email, password):
|
||||
api_url = urljoin(
|
||||
settings.BASE_API_URL,
|
||||
f"users/authenticate",
|
||||
)
|
||||
|
||||
payload = {
|
||||
"email": email,
|
||||
"password": password,
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(api_url, json=payload)
|
||||
response.raise_for_status()
|
||||
except RequestException as err:
|
||||
self.set_session_data("auth_error", str(err))
|
||||
else:
|
||||
key = "token" if response.ok else "auth_error"
|
||||
self.set_session_data(key, response.json())
|
||||
|
||||
def set_session_data(self, key, data):
|
||||
self.request.session[key] = data
|
||||
|
||||
|
||||
class AuthenticateResultView(generic.TemplateView):
|
||||
template_name = "rails/authenticate.result.html"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
context = self.get_context_data(**kwargs)
|
||||
context["token"] = request.session.pop("token", None)
|
||||
context["auth_error"] = request.session.pop(
|
||||
"auth_error", None
|
||||
)
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
def prepare_trains(trains: list[dict], key: str):
|
||||
return list(
|
||||
map(
|
||||
parse_datetimes,
|
||||
sorted(trains, key=itemgetter(key)),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def parse_datetimes(train: dict):
|
||||
train["arrives_at"] = datetime.fromisoformat(
|
||||
train["arrives_at"]
|
||||
)
|
||||
train["departs_at"] = datetime.fromisoformat(
|
||||
train["departs_at"]
|
||||
)
|
||||
return train
|
||||
Reference in New Issue
Block a user