from django.http import JsonResponse from django.views.decorators.http import require_http_methods from django.contrib.auth.decorators import login_required from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied from django.shortcuts import get_object_or_404 import json import logging from .models import Photo logger = logging.getLogger(__name__) @login_required @require_http_methods(["POST"]) def upload_photo(request): """Handle photo upload for any model""" try: # Get app label, model, and object ID app_label = request.POST.get("app_label") model = request.POST.get("model") object_id = request.POST.get("object_id") # Log received data logger.debug( f"Received upload request - app_label: {app_label}, model: {model}, object_id: {object_id}" ) logger.debug(f"Files in request: {request.FILES}") # Validate required fields missing_fields = [] if not app_label: missing_fields.append("app_label") if not model: missing_fields.append("model") if not object_id: missing_fields.append("object_id") if "image" not in request.FILES: missing_fields.append("image") if missing_fields: return JsonResponse( {"error": f'Missing required fields: {", ".join(missing_fields)}'}, status=400, ) # Get content type try: content_type = ContentType.objects.get( app_label=app_label.lower(), model=model.lower() ) except ContentType.DoesNotExist: return JsonResponse( {"error": f"Invalid content type: {app_label}.{model}"}, status=400 ) # Get the object instance try: obj = content_type.get_object_for_this_type(pk=object_id) except Exception as e: return JsonResponse( { "error": f"Object not found: {app_label}.{model} with id {object_id}. Error: {str(e)}" }, status=404, ) # Check if user has permission to add photos if not request.user.has_perm("media.add_photo"): logger.warning( f"User {request.user} attempted to upload photo without permission" ) return JsonResponse( {"error": "You do not have permission to upload photos"}, status=403 ) # Determine if the photo should be auto-approved is_approved = request.user.is_superuser or request.user.is_staff or request.user.groups.filter(name='Moderators').exists() # Create the photo photo = Photo.objects.create( image=request.FILES["image"], content_type=content_type, object_id=obj.pk, uploaded_by=request.user, # Add the user who uploaded the photo is_primary=not Photo.objects.filter( content_type=content_type, object_id=obj.pk ).exists(), is_approved=is_approved # Auto-approve if the user is a moderator, admin, or superuser ) return JsonResponse( { "id": photo.pk, "url": photo.image.url, "caption": photo.caption, "is_primary": photo.is_primary, "is_approved": photo.is_approved, } ) except Exception as e: logger.error(f"Error in upload_photo: {str(e)}", exc_info=True) return JsonResponse( {"error": f"An error occurred while uploading the photo: {str(e)}"}, status=400, ) @login_required @require_http_methods(["POST"]) def set_primary_photo(request, photo_id): """Set a photo as primary""" try: photo = get_object_or_404(Photo, pk=photo_id) # Check if user has permission to edit photos if not request.user.has_perm("media.change_photo"): return JsonResponse( {"error": "You do not have permission to edit photos"}, status=403 ) # Set this photo as primary photo.is_primary = True photo.save() # This will automatically unset other primary photos return JsonResponse({"status": "success"}) except Exception as e: logger.error(f"Error in set_primary_photo: {str(e)}", exc_info=True) return JsonResponse({"error": str(e)}, status=400) @login_required @require_http_methods(["POST"]) def update_caption(request, photo_id): """Update a photo's caption""" try: photo = get_object_or_404(Photo, pk=photo_id) # Check if user has permission to edit photos if not request.user.has_perm("media.change_photo"): return JsonResponse( {"error": "You do not have permission to edit photos"}, status=403 ) # Update caption data = json.loads(request.body) photo.caption = data.get("caption", "") photo.save() return JsonResponse({"id": photo.pk, "caption": photo.caption}) except Exception as e: logger.error(f"Error in update_caption: {str(e)}", exc_info=True) return JsonResponse({"error": str(e)}, status=400) @login_required @require_http_methods(["DELETE"]) def delete_photo(request, photo_id): """Delete a photo""" try: photo = get_object_or_404(Photo, pk=photo_id) # Check if user has permission to delete photos if not request.user.has_perm("media.delete_photo"): return JsonResponse( {"error": "You do not have permission to delete photos"}, status=403 ) photo.delete() return JsonResponse({"status": "success"}) except Exception as e: logger.error(f"Error in delete_photo: {str(e)}", exc_info=True) return JsonResponse({"error": str(e)}, status=400)