Files
Learn-Python-Programming-Th…/ch14/apic/rails/views.py
T
adii1823 0a0ceaf7d7 ch14
2021-10-28 17:41:38 +05:30

170 lines
4.6 KiB
Python

# 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