connect / api /views.py
thejagstudio's picture
Upload 363 files
2a065c3 verified
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, user_passes_test
from django.http import JsonResponse, HttpResponse
from django.views.decorators.http import require_POST
from django.utils import timezone
import json
from .models import (
Bhagat,
Event,
Attendance,
PushSubscription,
Notification,
Region,
BhajanCategory,
Bhajan,
OptionPoll,
Poll,
Books,
Sections,
Chapters,
Gallery,
Wallpaper
)
from django.conf import settings
from django.core import serializers
from django.db.models import Q
import requests
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from .utils import jwt_required
from rest_framework_simplejwt.tokens import RefreshToken
from pywebpush import webpush, WebPushException
def gCaptchaVerifer(token):
secret_key = settings.RECAPTCHA_SECRET_KEY
data = {"response": token, "secret": secret_key}
resp = requests.post("https://www.google.com/recaptcha/api/siteverify", data=data)
return resp.json()
def is_superadmin(user):
return user.user_type == "superadmin"
def is_regionadmin(user):
return user.user_type == "regionadmin"
def is_monitor(user):
return user.user_type == "monitor"
def dataEntry(request):
# with open("./api/bhajanData.json", "r",encoding="utf-8") as f:
# data = json.load(f)["Prasang"]
# for bhajan in data:
# category = BhajanCategory.objects.filter(link=bhajan['CatId']).first()
# Bhajan.objects.create(
# title=bhajan['title'],
# title_guj=bhajan['title_guj'],
# category=category,
# lyrics=bhajan['lyrics'],
# isEng = bhajan['isEng'],
# isHnd = bhajan['isHnd'],
# isGer = bhajan['isGer'],
# isAudio = bhajan['isAudio'],
# audio_url=bhajan['audio_url'] if bhajan['isAudio'] else ""
# )
# print(bhajan['title'])
return HttpResponse("Data Entry Page")
def bhajanCategoryList(request):
categories = BhajanCategory.objects.all()
categoryArr = []
for category in categories:
categoryArr.append(
{"name": category.name, "link": category.link, "icon": category.icon if category.icon else None}
)
lyricsBase = (
"https://huggingface.co/spaces/thejagstudio/MusicStore/raw/main/HTML Files/"
)
audioBase = "https://huggingface.co/spaces/thejagstudio/MusicStore/resolve/main/Bhajan Audio/"
return JsonResponse(
{"categories": categoryArr, "lyricsBase": lyricsBase, "audioBase": audioBase}
)
def bhajanList(request, catLink):
if catLink == "all-kirtan":
bhajans = Bhajan.objects.all()
category = "All Kirtan"
else:
bhajans = Bhajan.objects.filter(category__link=catLink)
category = BhajanCategory.objects.get(link=catLink).name
bhajanArr = []
for bhajan in bhajans:
bhajanArr.append(
{
"id": bhajan.bhajanId,
"title": bhajan.title,
"title_guj": bhajan.title_guj,
"lyrics": bhajan.lyrics,
"audio_url": bhajan.audio_url,
"isEng": bhajan.isEng,
"isHnd": bhajan.isHnd,
"isGer": bhajan.isGer,
"isAudio": bhajan.isAudio,
}
)
lyricsBase = (
"https://huggingface.co/spaces/thejagstudio/MusicStore/raw/main/HTML Files/"
)
audioBase = "https://huggingface.co/spaces/thejagstudio/MusicStore/resolve/main/Bhajan Audio/"
return JsonResponse(
{
"bhajans": bhajanArr,
"lyricsBase": lyricsBase,
"audioBase": audioBase,
"category": category,
}
)
def bhajanDetail(request, bhajanId):
bhajan = Bhajan.objects.filter(bhajanId=bhajanId).first()
if not bhajan:
return JsonResponse({"error": "Bhajan not found"})
else:
return JsonResponse(
{
"id": bhajan.bhajanId,
"title": bhajan.title,
"title_guj": bhajan.title_guj,
"category": bhajan.category.name,
"lyrics": bhajan.lyrics,
"audio_url": bhajan.audio_url,
"isEng": bhajan.isEng,
"isHnd": bhajan.isHnd,
"isGer": bhajan.isGer,
"isAudio": bhajan.isAudio,
"lyricsBase": "https://huggingface.co/spaces/thejagstudio/MusicStore/raw/main/HTML Files/",
"audioBase": "https://huggingface.co/spaces/thejagstudio/MusicStore/resolve/main/Bhajan Audio/",
}
)
def eventList(request):
events = Event.objects.all()
eventArr = []
for event in events:
# convert date to Sept 26,2024 | 8:30 - 9:30
dateFormatted = (
event.date.strftime("%b %d, %Y")
+ " | "
+ event.date.strftime("%I:%M %p")
+ " - "
+ event.time.strftime("%I:%M %p")
)
eventArr.append(
{
"title": event.title,
"description": event.description,
"date": dateFormatted,
"day": int(event.date.strftime("%d")),
"month": int(event.date.strftime("%m")),
"year": int(event.date.strftime("%Y")),
"created_by": event.created_by.__str__(),
"region": event.region.name,
"is_approved": event.is_approved,
"color": event.color,
}
)
return JsonResponse({"events": eventArr})
@jwt_required()
def notification(request):
notifications = Notification.objects.all()
notificationArr = []
for notification in notifications:
notificationArr.append(
{
"sender": notification.sender.__str__(),
"category": notification.sender.user_type,
"title": notification.title,
"content": notification.content,
"timestamp": notification.timestamp.strftime("%b %d, %Y | %I:%M %p"),
"notification_type": notification.notification_type,
}
)
return JsonResponse({"notifications": notificationArr})
@user_passes_test(is_superadmin)
@csrf_exempt
@jwt_required()
def send_notification(request):
if request.method == "POST":
content = request.POST.get("content")
recipient_type = request.POST.get("recipient_type")
notification = Notification.objects.create(
sender=request.user, content=content, notification_type="custom"
)
# Send web push notifications
subscriptions = PushSubscription.objects.all()
for subscription in subscriptions:
send_push_notification(
subscription,
{
"title": "New Notification",
"content": content,
"url": "/notifications",
},
)
return JsonResponse({"status": "success"})
return JsonResponse({"status": "error"})
def birthday_notifications():
today = timezone.now().date()
birthday_users = Bhagat.objects.filter(
birthday__month=today.month, birthday__day=today.day
)
for user in birthday_users:
notification = Notification.objects.create(
sender=Bhagat.objects.get(user_type="superadmin"),
content=f"Happy Birthday to {user.get_full_name()}!",
notification_type="birthday",
)
notification.recipients.set(Bhagat.objects.all())
@csrf_exempt
def login(request):
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
captcha_response = request.POST.get("captcha_response")
# Verify captcha
result = gCaptchaVerifer(captcha_response)
if not result.get("success"):
return JsonResponse({"error": "Invalid Captcha", "status": "error"})
# Authenticate user
user = Bhagat.objects.filter(username=username).first()
if user is not None and user.check_password(password):
# Generate tokens
refresh = RefreshToken.for_user(user)
return JsonResponse(
{
"status": "success",
"tokens": {
"access_token": str(refresh.access_token),
"refresh_token": str(refresh),
},
"user": {
"id": user.id,
"username": user.username,
"first_name": user.first_name,
"last_name": user.last_name,
"email": user.email,
"phone": user.phone,
"region": user.region.name,
"user_type": user.user_type,
"profile_image": user.profile_image.url if user.profile_image else None,
},
}
)
return JsonResponse({"error": "Invalid credentials", "status": "error"})
return JsonResponse({"error": "Invalid Method", "status": "error"})
@csrf_exempt
@jwt_required()
def logout(request):
if request.method == "POST":
refresh_token = request.POST.get("refresh_token")
if not refresh_token:
return JsonResponse(
{"error": "Refresh token is required", "status": "error"}
)
else:
try:
refresh = RefreshToken(refresh_token)
refresh.blacklist()
return JsonResponse(
{"status": "success", "message": "Successfully logged out"}
)
except Exception as e:
return JsonResponse(
{"error": "Invalid token | " + str(e), "status": "error"}
)
return JsonResponse({"status": "error", "error": "Invalid Method"})
@jwt_required()
def get_user_profile(request):
try:
user = request.user
return JsonResponse(
{
"status": "success",
"user": {
"id": user.id,
"username": user.username,
"first_name": user.first_name,
"last_name": user.last_name,
"email": user.email,
"phone": user.phone,
"region": user.region.name,
"user_type": user.user_type,
"profile_image": user.profile_image.url if user.profile_image else None,
},
}
)
except Exception as e:
return JsonResponse({"status": "error", "error": str(e)})
@csrf_exempt
@jwt_required()
def profile_updater(request):
if request.method == "POST":
try:
user = request.user
first_name = request.POST.get("first_name")
if first_name:
user.first_name = first_name
last_name = request.POST.get("last_name")
if last_name:
user.last_name = last_name
email = request.POST.get("email")
if email:
user.email = email
phone = request.POST.get("phone")
if phone:
user.phone = phone
region_name = request.POST.get("region")
if region_name:
user.region = Region.objects.get(name=region_name)
birth_date = request.POST.get("birth_date")
if birth_date:
user.birthday = birth_date
street_name = request.POST.get("street_name")
if street_name:
user.streetName = street_name
pincode = request.POST.get("pincode")
if pincode:
user.pincode = pincode
city = request.POST.get("city")
if city:
user.city = city
state = request.POST.get("state")
if state:
user.state = state
country = request.POST.get("country")
if country:
user.country = country
profile_image = request.FILES.get("profile_image")
if profile_image:
user.profile_image = profile_image
user.save()
return JsonResponse(
{"status": "success", "message": "Profile updated successfully"}
)
except Exception as e:
return JsonResponse({"status": "error", "error": str(e)})
else:
user = request.user
regions = Region.objects.all()
data = {
"first_name": user.first_name,
"last_name": user.last_name,
"email": user.email,
"phone": user.phone,
"region": user.region.name,
"birth_date": user.birthday,
"street_name": user.streetName,
"pincode": user.pincode,
"city": user.city,
"state": user.state,
"country": user.country,
"profile_image": user.profile_image,
}
return JsonResponse(
{
"status": "success",
"regions": [region.name for region in regions],
"user": data,
}
)
@jwt_required()
def bhaktoList(request):
current_user = request.user
bhaktos = Bhagat.objects.filter(assigned_to=current_user).all()
bhaktoArr = []
for bhakto in bhaktos:
bhaktoArr.append(
{
"id": bhakto.id,
"first_name": bhakto.first_name,
"last_name": bhakto.last_name,
"region": bhakto.region.name,
"user_type": bhakto.user_type,
"profile_image": bhakto.profile_image.url if bhakto.profile_image else None,
}
)
return JsonResponse({"bhaktos": bhaktoArr})
@api_view(["POST"])
@permission_classes([AllowAny])
def send_otp(request):
try:
data = json.loads(request.body)
phone = data.get("phone")
if not phone:
return JsonResponse(
{"status": "error", "error": "Phone number is required"}
)
# Check if user exists
user = Bhagat.objects.filter(phone=phone).first()
if not user:
return JsonResponse(
{"status": "error", "error": "No account found with this phone number"}
)
# Generate dummy OTP (in production, use proper OTP generation and SMS service)
otp = "123456" # Dummy OTP for testing
print(f"Generated OTP for {phone}: {otp}") # This simulates sending OTP
# In production, store OTP with timestamp in database or cache
# For now, we'll just return success
return JsonResponse({"status": "success", "message": "OTP sent successfully"})
except Exception as e:
return JsonResponse({"status": "error", "error": str(e)})
@api_view(["POST"])
@permission_classes([AllowAny])
def verify_otp(request):
try:
data = json.loads(request.body)
phone = data.get("phone")
otp = data.get("otp")
if not phone or not otp:
return JsonResponse(
{"status": "error", "error": "Phone number and OTP are required"}
)
# For demo purposes, accept any 6-digit OTP
if otp == "123456": # Dummy verification
return JsonResponse(
{"status": "success", "message": "OTP verified successfully"}
)
return JsonResponse({"status": "error", "error": "Invalid OTP"})
except Exception as e:
return JsonResponse({"status": "error", "error": str(e)})
@api_view(["POST"])
@jwt_required()
@csrf_exempt
@permission_classes([AllowAny])
def change_password(request):
try:
data = json.loads(request.body)
new_password = data.get("new_password")
if not new_password:
return JsonResponse(
{
"status": "error",
"error": "Phone number and new password are required",
}
)
# Update user's password
user = request.user
if not user:
return JsonResponse({"status": "error", "error": "User not found"})
user.password = new_password
user.save()
return JsonResponse(
{"status": "success", "message": "Password changed successfully"}
)
except Exception as e:
return JsonResponse({"status": "error", "error": str(e)})
@jwt_required()
@api_view(["POST"])
@csrf_exempt
@permission_classes([AllowAny])
def save_push_subscription(request):
try:
subscription_data = json.loads(request.body)
user = request.user
pushUser = PushSubscription.objects.filter(user=user).first()
if pushUser:
pushUser.endpoint = subscription_data["endpoint"]
pushUser.p256dh = subscription_data["keys"]["p256dh"]
pushUser.auth = subscription_data["keys"]["auth"]
pushUser.save()
else:
PushSubscription.objects.create(
user=user,
endpoint=subscription_data["endpoint"],
p256dh=subscription_data["keys"]["p256dh"],
auth=subscription_data["keys"]["auth"],
)
return JsonResponse({"status": "success"})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
def send_push_notification(subscription, message):
try:
webpush(
subscription_info={
"endpoint": subscription.endpoint,
"keys": {"p256dh": subscription.p256dh, "auth": subscription.auth},
},
data=json.dumps(message),
vapid_private_key=settings.WEBPUSH_SETTINGS["VAPID_PRIVATE_KEY"],
vapid_claims={
"sub": f"mailto:{settings.WEBPUSH_SETTINGS['VAPID_ADMIN_EMAIL']}"
},
)
except WebPushException as e:
print(f"Web push failed: {e}")
@api_view(["GET", "POST"])
@jwt_required()
@csrf_exempt
@permission_classes([AllowAny])
def polls(request):
if request.method == "GET":
user = request.user
polls = Poll.objects.filter(participants=user)
pollArr = []
for poll in polls:
# Poll verification: Remove votes from users who are not in poll participants
# This ensures data integrity when displaying poll results
for option in poll.options.all():
# Get all voters for this option
voters_to_remove = []
for voter in option.voters.all():
if voter not in poll.participants.all():
voters_to_remove.append(voter)
# Remove invalid votes
if voters_to_remove:
option.voters.remove(*voters_to_remove)
# Use the same data structure as the POST endpoint for consistency
poll_data = {
"id": poll.id,
"question": poll.question,
"image": poll.image.url if poll.image else None,
"options": [],
"created_by": {
"id": poll.created_by.id,
"first_name": poll.created_by.first_name,
"last_name": poll.created_by.last_name,
"profile_image": poll.created_by.profile_image.url if poll.created_by.profile_image else None,
},
"created_at": poll.created_at,
}
total_voters = poll.participants.count()
for option in poll.options.all():
vote_count = option.voters.count()
percentage = (vote_count / total_voters * 100) if total_voters > 0 else 0
poll_data["options"].append({
"id": option.id,
"optionText": option.optionText,
"count": vote_count,
"precentage": percentage, # Note: keeping the typo for consistency
"voters": [
{
"id": voter.id,
"first_name": voter.first_name,
"last_name": voter.last_name,
"profile_image": voter.profile_image.url if voter.profile_image else None,
}
for voter in option.voters.all()
]
})
pollArr.append(poll_data)
return JsonResponse({"data": pollArr})
if request.method == "POST":
data = json.loads(request.body)
user = request.user
poll_id = data.get("poll_id")
option_id = data.get("option_id")
if not poll_id or not option_id:
return JsonResponse(
{"status": "error", "message": "Poll ID and option ID are required"}
)
try:
poll = Poll.objects.get(id=poll_id)
option = OptionPoll.objects.get(id=option_id)
# Check if user is a participant in this poll
if user not in poll.participants.all():
return JsonResponse(
{"status": "error", "message": "You are not a participant in this poll"}
)
# Poll verification: Remove votes from users who are not in poll participants
# This prevents API spamming and ensures only valid participants can vote
for existing_option in poll.options.all():
# Get all voters for this option
voters_to_remove = []
for voter in existing_option.voters.all():
if voter not in poll.participants.all():
voters_to_remove.append(voter)
# Remove invalid votes
if voters_to_remove:
existing_option.voters.remove(*voters_to_remove)
# Check if user has already voted for this exact option (prevent duplicate/unnecessary update)
if user in option.voters.all():
# User already voted for this option, just return current poll data without error
pass
else:
# Remove user's previous votes for this poll (if any) - allows vote changing
for existing_option in poll.options.all():
if user in existing_option.voters.all():
existing_option.voters.remove(user)
# Add user to the new option
option.voters.add(user)
# Recalculate percentages and return updated poll data
poll_data = {
"id": poll.id,
"question": poll.question,
"image": poll.image.url if poll.image else None,
"options": [],
"created_by": {
"id": poll.created_by.id,
"first_name": poll.created_by.first_name,
"last_name": poll.created_by.last_name,
"profile_image": poll.created_by.profile_image.url if poll.created_by.profile_image else None,
},
"created_at": poll.created_at,
}
total_voters = poll.participants.count()
for opt in poll.options.all():
vote_count = opt.voters.count()
percentage = (vote_count / total_voters * 100) if total_voters > 0 else 0
poll_data["options"].append({
"id": opt.id,
"optionText": opt.optionText,
"count": vote_count,
"precentage": percentage, # Note: keeping the typo for consistency
"voters": [
{
"id": voter.id,
"first_name": voter.first_name,
"last_name": voter.last_name,
"profile_image": voter.profile_image.url if voter.profile_image else None,
}
for voter in opt.voters.all()
]
})
return JsonResponse(
{
"status": "success",
"message": "Vote updated successfully",
"poll": poll_data
}
)
except Poll.DoesNotExist:
return JsonResponse({"status": "error", "message": "Poll not found"})
except OptionPoll.DoesNotExist:
return JsonResponse({"status": "error", "message": "Option not found"})
@api_view(["GET"])
@jwt_required()
@permission_classes([AllowAny])
def voterList(request, id):
user = request.user
try:
poll = Poll.objects.filter(participants=user).get(id=id)
# Poll verification: Remove votes from users who are not in poll participants
# This ensures data integrity when displaying voter lists
for option in poll.options.all():
# Get all voters for this option
voters_to_remove = []
for voter in option.voters.all():
if voter not in poll.participants.all():
voters_to_remove.append(voter)
# Remove invalid votes
if voters_to_remove:
option.voters.remove(*voters_to_remove)
options = poll.options.all()
optionsList = []
for option in options:
tempOption = {}
tempOption["id"] = option.id
tempOption["optionText"] = option.optionText
tempOption["count"] = option.voters.count()
tempOption["voters"] = []
for voter in option.voters.all():
tempOption["voters"].append(
{
"id": voter.id,
"first_name": voter.first_name,
"last_name": voter.last_name,
"profile_image": voter.profile_image.url if voter.profile_image else None,
}
)
optionsList.append(tempOption)
return JsonResponse({"data": optionsList})
except Poll.DoesNotExist:
return JsonResponse(
{"error": "Poll may not exist or you may not have access to it"}
)
@api_view(["POST"])
@jwt_required()
@csrf_exempt
@permission_classes([AllowAny])
def create_poll(request):
try:
user = request.user
# Check if user is authorized to create polls (superadmin, regionadmin or karyakarta)
if user.user_type not in ["superadmin", "regionadmin", "karyakarta"]:
return JsonResponse(
{"status": "error", "message": "You are not authorized to create polls"}
)
question = request.POST.get("question")
image = request.FILES.get("image")
options = json.loads(request.POST.get("options", "[]"))
participants = json.loads(request.POST.get("participants", "[]"))
delivery_type = request.POST.get("delivery_type", "all")
if not question:
return JsonResponse(
{"status": "error", "message": "Question is required"}
)
if not options or len(options) < 2:
return JsonResponse(
{"status": "error", "message": "At least 2 options are required"}
)
# Create the poll
poll = Poll.objects.create(
question=question,
created_by=user,
image=image if image else None
)
# Add options
for option_text in options:
if option_text.strip(): # Only add non-empty options
option = OptionPoll.objects.create(optionText=option_text.strip())
poll.options.add(option)
# Determine participants based on delivery_type
participant_users = []
if delivery_type == "all":
participant_users = Bhagat.objects.all()
elif delivery_type == "region":
region_id = participants[0] if isinstance(participants, list) and len(participants) > 0 else participants
participant_users = Bhagat.objects.filter(region_id=region_id)
elif delivery_type == "usertype":
user_type = participants[0] if isinstance(participants, list) and len(participants) > 0 else participants
participant_users = Bhagat.objects.filter(user_type=user_type)
elif delivery_type == "individualuser":
participant_ids = [p if isinstance(p, int) else p.get('id') for p in participants]
participant_users = Bhagat.objects.filter(id__in=participant_ids)
# Add participants to poll
if participant_users:
poll.participants.set(participant_users)
# Ensure creator is a participant
if user not in poll.participants.all():
poll.participants.add(user)
poll.save()
return JsonResponse(
{
"status": "success",
"message": "Poll created successfully",
"poll_id": poll.id,
"participants_count": poll.participants.count()
}
)
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
@api_view(["PUT"])
@jwt_required()
@csrf_exempt
@permission_classes([AllowAny])
def edit_poll(request, poll_id):
"""
Edit a poll (only the creator can edit their own poll)
"""
try:
user = request.user
# Get the poll
poll = Poll.objects.get(id=poll_id)
# Check if user is the creator of the poll
if poll.created_by.id != user.id:
return JsonResponse(
{"status": "error", "message": "You are not authorized to edit this poll"}
)
# Get updated data
question = request.POST.get("question")
image = request.FILES.get("image")
options = json.loads(request.POST.get("options", "[]"))
participants = json.loads(request.POST.get("participants", "[]"))
delivery_type = request.POST.get("delivery_type", "all")
remove_image = request.POST.get("remove_image", "false") == "true"
# Update question
if question:
poll.question = question
# Handle image update/removal
if remove_image and poll.image:
poll.image.delete()
poll.image = None
elif image:
# Delete old image if exists
if poll.image:
poll.image.delete()
poll.image = image
# Update options if provided
if options and len(options) >= 2:
# Get existing options
existing_options = list(poll.options.all())
# Clear all current options
poll.options.clear()
# Delete old option objects
for old_option in existing_options:
old_option.delete()
# Create new options
for option_text in options:
if option_text.strip():
option = OptionPoll.objects.create(optionText=option_text.strip())
poll.options.add(option)
# Update participants if provided
if delivery_type:
participant_users = []
if delivery_type == "all":
participant_users = Bhagat.objects.all()
elif delivery_type == "region":
region_id = participants[0] if isinstance(participants, list) and len(participants) > 0 else participants
participant_users = Bhagat.objects.filter(region_id=region_id)
elif delivery_type == "usertype":
user_type = participants[0] if isinstance(participants, list) and len(participants) > 0 else participants
participant_users = Bhagat.objects.filter(user_type=user_type)
elif delivery_type == "individualuser":
participant_ids = [p if isinstance(p, int) else p.get('id') for p in participants]
participant_users = Bhagat.objects.filter(id__in=participant_ids)
# Update participants
if participant_users:
poll.participants.set(participant_users)
# Ensure creator is a participant
if user not in poll.participants.all():
poll.participants.add(user)
poll.save()
# Return updated poll data
poll_data = {
"id": poll.id,
"question": poll.question,
"image": poll.image.url if poll.image else None,
"options": [],
"created_by": {
"id": poll.created_by.id,
"first_name": poll.created_by.first_name,
"last_name": poll.created_by.last_name,
"profile_image": poll.created_by.profile_image.url if poll.created_by.profile_image else None,
},
"created_at": poll.created_at,
}
total_voters = poll.participants.count()
for opt in poll.options.all():
vote_count = opt.voters.count()
percentage = (vote_count / total_voters * 100) if total_voters > 0 else 0
poll_data["options"].append({
"id": opt.id,
"optionText": opt.optionText,
"count": vote_count,
"precentage": percentage,
"voters": [
{
"id": voter.id,
"first_name": voter.first_name,
"last_name": voter.last_name,
"profile_image": voter.profile_image.url if voter.profile_image else None,
}
for voter in opt.voters.all()
]
})
return JsonResponse(
{
"status": "success",
"message": "Poll updated successfully",
"poll": poll_data
}
)
except Poll.DoesNotExist:
return JsonResponse({"status": "error", "message": "Poll not found"})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
@api_view(["DELETE"])
@jwt_required()
@csrf_exempt
@permission_classes([AllowAny])
def delete_poll(request, poll_id):
"""
Delete a poll (only the creator can delete their own poll)
"""
try:
user = request.user
# Get the poll
poll = Poll.objects.get(id=poll_id)
# Check if user is the creator of the poll
if poll.created_by.id != user.id:
return JsonResponse(
{"status": "error", "message": "You are not authorized to delete this poll"}
)
# Delete the poll image if it exists
if poll.image:
poll.image.delete()
# Delete all options associated with the poll
for option in poll.options.all():
option.delete()
# Delete the poll itself
poll.delete()
return JsonResponse(
{
"status": "success",
"message": "Poll deleted successfully"
}
)
except Poll.DoesNotExist:
return JsonResponse({"status": "error", "message": "Poll not found"})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
@api_view(["GET"])
@permission_classes([AllowAny])
def bookList(request):
books = Books.objects.all().order_by("index")
bookArr = []
for book in books:
bookArr.append(
{
"id": book.id,
"urlId": book.urlId,
"title": book.title,
"author": book.author,
"description": book.description,
"poster": book.poster.url if book.poster else None,
"pdf": book.pdf.url if book.pdf else None,
"isPdf": book.isPdf,
"hasSections": book.hasSections,
}
)
return JsonResponse({"books": bookArr})
@api_view(["GET"])
@permission_classes([AllowAny])
def bookDetail(request, urlId):
book = Books.objects.filter(urlId=urlId).first()
if not book:
return JsonResponse({"error": "Book not found"}, status=404)
sections = []
if book.hasSections:
bookSections = Sections.objects.filter(book=book)
for section in bookSections:
chapters = []
bookChapters = Chapters.objects.filter(section=section)
for chapter in bookChapters:
chapters.append(
{
"id": chapter.id,
"urlId": chapter.urlId,
"data": chapter.data,
"title": chapter.title,
}
)
sections.append(
{"id": section.id, "title": section.title, "chapters": chapters}
)
return JsonResponse(
{
"book": {
"id": book.id,
"urlId": book.urlId,
"title": book.title,
"author": book.author,
"description": book.description,
"poster": book.poster.url if book.poster else None,
"pdf": book.pdf.url if book.pdf else None,
"isPdf": book.isPdf,
"hasSections": book.hasSections,
"sections": sections if book.hasSections else None,
}
}
)
@api_view(["GET"])
@permission_classes([AllowAny])
def bookChapterDetail(request, urlId, chapterId):
book = Books.objects.filter(urlId=urlId).first()
chapter = Chapters.objects.filter(urlId=chapterId, book=book).first()
if not chapter:
return JsonResponse({"error": "Chapter not found"}, status=404)
return JsonResponse(
{
"chapter": {
"id": chapter.id,
"urlId": chapter.urlId,
"title": chapter.title,
"data": chapter.data,
"book": {
"id": chapter.book.id,
"title": chapter.book.title,
"author": chapter.book.author,
"poster": chapter.book.poster.url if chapter.book.poster else None,
"pdf": chapter.book.pdf.url if chapter.book.pdf else None,
},
}
}
)
@api_view(["GET"])
def data(request):
with open("swamini_vato_data.json", "r", encoding="utf-8") as file:
data = json.load(file)
book = Books.objects.get(id=1)
i = 1
for section in data:
section_obj = Sections.objects.create(title=section["section_title_gu"], urlId=section["section_title_gu"].lower().replace(" ", "-").replace("(", "").replace(")", "").replace("/", "-"), isPdf=False, book=book, hasChapters=True)
for vato in section["chapter"]:
Chapters.objects.create(
section=section_obj,
book=book,
title=vato["gujarati_title"],
urlId=str(i),
data=vato,
isPdf=False,
)
i = i + 1
print(f"Added vato: {vato['gujarati_title']}")
print(f"Added section: {section['section_title_gu']}")
return JsonResponse({"data": ""})
@api_view(["GET"])
@jwt_required()
def gallery_list(request):
"""
Get gallery images for the current user based on their region and user type.
Returns today's images, or if not available, the most recent previous day's images.
"""
user = request.user
today = timezone.now().date()
# Build base query based on user type and region
if user.user_type == "superadmin":
base_query = Gallery.objects.all()
elif user.user_type == "regionadmin":
base_query = Gallery.objects.filter(region=user.region)
else:
# Regular users see images from their region
base_query = Gallery.objects.filter(
Q(region=user.region) | Q(region__name="All")
)
# First, try to get today's images
gallery_images = base_query.filter(date=today).order_by('-uploaded_at')
# If no images for today, get the most recent previous day's images
if not gallery_images.exists():
# Get the most recent date with images
latest_date = base_query.values_list('date', flat=True).order_by('-date').first()
if latest_date:
gallery_images = base_query.filter(date=latest_date).order_by('-uploaded_at')
gallery_arr = []
for image in gallery_images:
gallery_arr.append({
"id": image.id,
"image": image.image.url if image.image else None,
"date": image.date.strftime("%B %d, %Y"),
"region": image.region.name if image.region else None,
"uploaded_at": image.uploaded_at.strftime("%b %d, %Y | %I:%M %p")
})
return JsonResponse({"gallery": gallery_arr})
@api_view(["GET"])
@jwt_required()
def gallery_all_list(request):
"""
Get all gallery images for the current user based on their region and user type.
Returns all images in chronological order (newest first).
"""
user = request.user
# Build base query based on user type and region
if user.user_type == "superadmin":
base_query = Gallery.objects.all()
elif user.user_type == "regionadmin":
base_query = Gallery.objects.filter(region=user.region)
else:
# Regular users see images from their region
base_query = Gallery.objects.filter(
Q(region=user.region) | Q(region__name="All")
)
# Get all images ordered by upload date (newest first)
gallery_images = base_query.order_by('-uploaded_at')
gallery_arr = []
for image in gallery_images:
gallery_arr.append({
"id": image.id,
"image": image.image.url if image.image else None,
"date": image.date.strftime("%B %d, %Y"),
"region": image.region.name if image.region else None,
"uploaded_at": image.uploaded_at.strftime("%b %d, %Y | %I:%M %p")
})
return JsonResponse({"gallery": gallery_arr})
@api_view(["POST"])
@jwt_required()
@csrf_exempt
def upload_gallery_image(request):
"""
Upload new gallery image (only for regionadmin and superadmin)
"""
user = request.user
# Check if user is authorized to upload images
if user.user_type not in ["superadmin", "regionadmin"]:
return JsonResponse({
"status": "error",
"message": "You are not authorized to upload gallery images"
})
try:
# Handle bulk image upload
images = request.FILES.getlist('images')
if not images:
return JsonResponse({
"status": "error",
"message": "At least one image is required"
})
uploaded_images = []
today = timezone.now().date()
# Create gallery entries for each image with today's date
for image in images:
gallery_image = Gallery.objects.create(
image=image,
region=user.region,
date=today
)
uploaded_images.append({
"id": gallery_image.id,
"image": gallery_image.image.url if gallery_image.image else None,
"date": gallery_image.date.strftime("%B %d, %Y"),
"region": gallery_image.region.name if gallery_image.region else None,
"uploaded_at": gallery_image.uploaded_at.strftime("%b %d, %Y | %I:%M %p")
})
return JsonResponse({
"status": "success",
"message": f"Successfully uploaded {len(uploaded_images)} images",
"images": uploaded_images
})
except Exception as e:
return JsonResponse({
"status": "error",
"message": str(e)
})
@api_view(["DELETE"])
@jwt_required()
def delete_gallery_image(request, image_id):
"""
Delete gallery image (only for superadmin or the uploader)
"""
user = request.user
try:
gallery_image = Gallery.objects.get(id=image_id)
# Check permissions: superadmin can delete any, regionadmin can delete their own
if user.user_type != "superadmin" and gallery_image.uploaded_by != user:
return JsonResponse({
"status": "error",
"message": "You are not authorized to delete this image"
})
# Delete the image file
if gallery_image.image:
gallery_image.image.delete()
# Delete the gallery entry
gallery_image.delete()
return JsonResponse({
"status": "success",
"message": "Gallery image deleted successfully"
})
except Gallery.DoesNotExist:
return JsonResponse({
"status": "error",
"message": "Gallery image not found"
})
except Exception as e:
return JsonResponse({
"status": "error",
"message": str(e)
})
@api_view(["GET"])
@jwt_required()
def wallpaper_list(request):
"""
Get all wallpaper images for the current user based on their region and user type.
Returns all images in chronological order (newest first).
"""
base_query = Wallpaper.objects.all()
# Get all images ordered by upload date (newest first)
wallpaper_images = base_query.order_by('-uploaded_at')
wallpaper_arr = []
for image in wallpaper_images:
wallpaper_arr.append({
"id": image.id,
"image": image.image.url if image.image else None,
"uploaded_at": image.uploaded_at.strftime("%b %d, %Y | %I:%M %p")
})
return JsonResponse({"wallpaper": wallpaper_arr})