38515-vm/core/views.py
2026-02-17 14:18:59 +00:00

173 lines
5.9 KiB
Python

import os
import platform
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib import messages
from django.utils import timezone
from .models import Donor, BloodRequest, BloodBank
import math
def haversine(lat1, lon1, lat2, lon2):
# Radius of the Earth in km
R = 6371.0
dlat = math.radians(lat2 - lat1)
dlon = math.radians(lon2 - lon1)
a = math.sin(dlat / 2)**2 + math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dlon / 2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
return R * c
def login_view(request):
if request.method == "POST":
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect("home")
else:
form = AuthenticationForm()
return render(request, "core/login.html", {"form": form})
def logout_view(request):
logout(request)
return redirect("home")
def register_view(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect("home")
else:
form = UserCreationForm()
return render(request, "core/register.html", {"form": form})
def home(request):
"""Render the RaktaPulse Dashboard experience."""
query_blood = request.GET.get('blood_group', '')
query_location = request.GET.get('location', '')
user_lat = request.GET.get('lat')
user_lng = request.GET.get('lng')
donors = Donor.objects.all()
if query_blood:
donors = donors.filter(blood_group=query_blood)
if query_location:
donors = donors.filter(location__icontains=query_location)
donor_list_data = list(donors)
if user_lat and user_lng:
try:
u_lat = float(user_lat)
u_lng = float(user_lng)
for d in donor_list_data:
if d.latitude and d.longitude:
d.distance = haversine(u_lat, u_lng, float(d.latitude), float(d.longitude))
else:
d.distance = 999999 # Very far
donor_list_data.sort(key=lambda x: x.distance)
except ValueError:
donor_list_data.sort(key=lambda x: (-x.is_available, x.name))
else:
donor_list_data.sort(key=lambda x: (-x.is_available, x.name))
blood_requests = BloodRequest.objects.filter(status='Active').order_by('-urgency', '-created_at')
blood_banks = BloodBank.objects.all()
# Stats for Dashboard
stats = {
"total_donors": Donor.objects.count(),
"active_requests": BloodRequest.objects.filter(status='Active').count(),
"total_stock": sum([
bb.stock_a_plus + bb.stock_a_minus + bb.stock_b_plus + bb.stock_b_minus +
bb.stock_o_plus + bb.stock_o_minus + bb.stock_ab_plus + bb.stock_ab_minus
for bb in blood_banks
]),
"vaccinated_percentage": 0
}
total_d = stats["total_donors"]
if total_d > 0:
vaccinated_count = Donor.objects.filter(vaccination_status__icontains='Fully').count()
stats["vaccinated_percentage"] = int((vaccinated_count / total_d) * 100)
context = {
"donors": donor_list_data[:8],
"blood_requests": blood_requests[:6],
"blood_banks": blood_banks,
"blood_groups": [g[0] for g in Donor.BLOOD_GROUPS],
"stats": stats,
"project_name": "RaktaPulse",
"current_time": timezone.now(),
}
return render(request, "core/index.html", context)
def donor_list(request):
blood_group = request.GET.get('blood_group', '')
district = request.GET.get('district', '')
user_lat = request.GET.get('lat')
user_lng = request.GET.get('lng')
donors = Donor.objects.all()
if blood_group:
donors = donors.filter(blood_group=blood_group)
if district:
donors = donors.filter(district__icontains=district)
donor_list_data = list(donors)
if user_lat and user_lng:
try:
u_lat = float(user_lat)
u_lng = float(user_lng)
for d in donor_list_data:
if d.latitude and d.longitude:
d.distance = haversine(u_lat, u_lng, float(d.latitude), float(d.longitude))
else:
d.distance = 999999
donor_list_data.sort(key=lambda x: x.distance)
except ValueError:
donor_list_data.sort(key=lambda x: (-x.is_verified, x.name))
else:
donor_list_data.sort(key=lambda x: (-x.is_verified, x.name))
context = {
'donors': donor_list_data,
'blood_groups': [g[0] for g in Donor.BLOOD_GROUPS],
}
return render(request, 'core/donor_list.html', context)
def blood_request_list(request):
requests = BloodRequest.objects.all().order_by('-created_at')
context = {
'requests': requests,
}
return render(request, 'core/blood_request_list.html', context)
def blood_bank_list(request):
banks = BloodBank.objects.all()
context = {
'banks': banks,
}
return render(request, 'core/blood_bank_list.html', context)
def vaccination_info(request):
stats = {
"total_donors": Donor.objects.count(),
"vaccinated_count": Donor.objects.filter(vaccination_status__icontains='Fully').count(),
}
if stats["total_donors"] > 0:
stats["percentage"] = int((stats["vaccinated_count"] / stats["total_donors"]) * 100)
else:
stats["percentage"] = 0
return render(request, 'core/vaccination_info.html', {'stats': stats})