diff --git a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc index eb099c0f33c5d18bf9acdf8a6efd7cf622a93044..8217cae40ee3843e77dc74817b9b954ad653e373 100644 Binary files a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc and b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc differ diff --git a/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-310.pyc index 1397f24a529d580e045772ec86045765240c6432..8483a1b21baf23ab9ef05a13e9bf9e1254ecb39f 100644 Binary files a/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-310.pyc and b/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-310.pyc differ diff --git a/MisplaceAI/MisplaceAI/settings.py b/MisplaceAI/MisplaceAI/settings.py index 57e48e4964fa45b25c8686a8a6dd99e989720717..001bfb42ba867edea794ac8a092fc53cb895a225 100644 --- a/MisplaceAI/MisplaceAI/settings.py +++ b/MisplaceAI/MisplaceAI/settings.py @@ -51,7 +51,7 @@ INSTALLED_APPS = [ 'process_misplaced_manager.apps.ProcessMisplacedManagerConfig', 'rest_framework', 'corsheaders', - 'live_testing_object', + 'rest_framework_simplejwt', ] diff --git a/MisplaceAI/MisplaceAI/urls.py b/MisplaceAI/MisplaceAI/urls.py index bb80cfbf2f23317b7f82ce5e87c492fa3adb7c29..c1e4986b9219382381f473935b895129cccda8a0 100644 --- a/MisplaceAI/MisplaceAI/urls.py +++ b/MisplaceAI/MisplaceAI/urls.py @@ -1,5 +1,4 @@ # MisplaceAI/urls.py - from django.conf import settings from django.conf.urls.static import static from django.contrib import admin @@ -7,15 +6,15 @@ from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), + path('api/', include('core.urls')), path('', include('core.urls')), - path('rules/', include('rules.urls')), - path('auth/', include('authentication.urls')), - path('admin-app/', include('admin_app.urls')), - path('process_misplaced_manager/', include('process_misplaced_manager.urls', namespace='process_misplaced_manager')), - path('results_viewer/', include('results_viewer.urls', namespace='results_viewer')), - path('placement_rules/', include('placement_rules.urls')), # Ensure placement_rules URLs are included - + path('api/rules/', include('rules.urls')), + path('api/auth/', include('authentication.urls')), + path('api/admin-app/', include('admin_app.urls')), + path('api/process_misplaced_manager/', include('process_misplaced_manager.urls', namespace='process_misplaced_manager')), + path('api/results_viewer/', include('results_viewer.urls', namespace='results_viewer')), + path('api/placement_rules/', include('placement_rules.urls')), ] if settings.DEBUG: - urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/MisplaceAI/authentication/__pycache__/urls.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/urls.cpython-310.pyc index 28687c0997b0bf63ef2b497719cf6d140f18c603..8bb1713bf934e8764d4b1e4c353a79cd98bf0961 100644 Binary files a/MisplaceAI/authentication/__pycache__/urls.cpython-310.pyc and b/MisplaceAI/authentication/__pycache__/urls.cpython-310.pyc differ diff --git a/MisplaceAI/authentication/__pycache__/views.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/views.cpython-310.pyc index c943d54e210c85516d9a08c994095d5bf3796c37..5fe73a8a01b42fc98c48199de2c648f55a70125c 100644 Binary files a/MisplaceAI/authentication/__pycache__/views.cpython-310.pyc and b/MisplaceAI/authentication/__pycache__/views.cpython-310.pyc differ diff --git a/MisplaceAI/authentication/urls.py b/MisplaceAI/authentication/urls.py index 0742d9cd9ad6e90f7b8ddf52c2f53cd385f593e4..aeb63868587b9405b02b869c8511cd8106fa1035 100644 --- a/MisplaceAI/authentication/urls.py +++ b/MisplaceAI/authentication/urls.py @@ -5,4 +5,5 @@ from .views import RegisterView, LoginView urlpatterns = [ path('register/', RegisterView.as_view(), name='register'), path('login/', LoginView.as_view(), name='login'), + ] diff --git a/MisplaceAI/authentication/views.py b/MisplaceAI/authentication/views.py index e905d261a31f3a634e006e06eeca25a524e7a88b..f0eb4cd8c9d971363aa875bbd9d97a07d5e87139 100644 --- a/MisplaceAI/authentication/views.py +++ b/MisplaceAI/authentication/views.py @@ -28,3 +28,6 @@ class LoginView(APIView): 'access': str(refresh.access_token), }, status=status.HTTP_200_OK) return Response({'error': 'Invalid credentials'}, status=status.HTTP_400_BAD_REQUEST) + + + \ No newline at end of file diff --git a/MisplaceAI/core/__pycache__/urls.cpython-310.pyc b/MisplaceAI/core/__pycache__/urls.cpython-310.pyc index 8f202e656e5806acf4e4d41b19da4ed61228bf9a..dfb154929e33a89ea6e36cf073540e653f8f29b8 100644 Binary files a/MisplaceAI/core/__pycache__/urls.cpython-310.pyc and b/MisplaceAI/core/__pycache__/urls.cpython-310.pyc differ diff --git a/MisplaceAI/core/__pycache__/views.cpython-310.pyc b/MisplaceAI/core/__pycache__/views.cpython-310.pyc index ec8cf50e1cbf55cb9add4527a42245ccf79c71aa..49eb0b21d57c3cd3b7eff1903583bb6f28e86375 100644 Binary files a/MisplaceAI/core/__pycache__/views.cpython-310.pyc and b/MisplaceAI/core/__pycache__/views.cpython-310.pyc differ diff --git a/MisplaceAI/core/templates/core/home.html b/MisplaceAI/core/templates/core/home.html deleted file mode 100644 index 7045201b4e526036830694f130ecc710420964d1..0000000000000000000000000000000000000000 --- a/MisplaceAI/core/templates/core/home.html +++ /dev/null @@ -1 +0,0 @@ -<p>This is the home page of the MisplaceAI application.</p> \ No newline at end of file diff --git a/MisplaceAI/core/urls.py b/MisplaceAI/core/urls.py index 049a4a57471032d0c3309b5e36c61f24256a2263..3fab617afb0a5b703018b7211e0fd82aa9c447a3 100644 --- a/MisplaceAI/core/urls.py +++ b/MisplaceAI/core/urls.py @@ -1,6 +1,8 @@ +# core/urls.py from django.urls import path -from .views import home_view +from .views import root_view urlpatterns = [ - path('', home_view, name='home'), + path('', root_view, name='root_view'), + # ... other paths ] diff --git a/MisplaceAI/core/views.py b/MisplaceAI/core/views.py index 0cecdb1b905af367d7eea4d1131e1f8d5856848d..456720d337734ad142b232913ae79939af14734a 100644 --- a/MisplaceAI/core/views.py +++ b/MisplaceAI/core/views.py @@ -1,4 +1,5 @@ -from django.shortcuts import render +# core/views.py +from django.http import JsonResponse -def home_view(request): - return render(request, 'core/home.html') +def root_view(request): + return JsonResponse({"message": "Welcome to the MisplaceAI API"}) diff --git a/MisplaceAI/live_testing_object/__init__.py b/MisplaceAI/live_testing_object/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/MisplaceAI/live_testing_object/admin.py b/MisplaceAI/live_testing_object/admin.py deleted file mode 100644 index 8c38f3f3dad51e4585f3984282c2a4bec5349c1e..0000000000000000000000000000000000000000 --- a/MisplaceAI/live_testing_object/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/MisplaceAI/live_testing_object/apps.py b/MisplaceAI/live_testing_object/apps.py deleted file mode 100644 index 200c1e69af6b03844e1c7518d1638a86c17c4473..0000000000000000000000000000000000000000 --- a/MisplaceAI/live_testing_object/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class LiveTestingObjectConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'live_testing_object' diff --git a/MisplaceAI/live_testing_object/models.py b/MisplaceAI/live_testing_object/models.py deleted file mode 100644 index 71a836239075aa6e6e4ecb700e9c42c95c022d91..0000000000000000000000000000000000000000 --- a/MisplaceAI/live_testing_object/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/MisplaceAI/live_testing_object/templates/live_testing_object/object_detection.html b/MisplaceAI/live_testing_object/templates/live_testing_object/object_detection.html deleted file mode 100644 index e7e7d71dae17951090eb2e60f92e4c2fa265ddb8..0000000000000000000000000000000000000000 --- a/MisplaceAI/live_testing_object/templates/live_testing_object/object_detection.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends "base.html" %} - -{% block title %} -Object Detection -{% endblock %} - -{% block content %} -<div id="root"></div> -<script src="http://localhost:3000/static/js/bundle.js"></script> <!-- Adjust the path as needed --> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/live_testing_object/tests.py b/MisplaceAI/live_testing_object/tests.py deleted file mode 100644 index 7ce503c2dd97ba78597f6ff6e4393132753573f6..0000000000000000000000000000000000000000 --- a/MisplaceAI/live_testing_object/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/MisplaceAI/live_testing_object/urls.py b/MisplaceAI/live_testing_object/urls.py deleted file mode 100644 index b15ee7588e9e2477355d15fb9580f0d0a11aa29c..0000000000000000000000000000000000000000 --- a/MisplaceAI/live_testing_object/urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.urls import path -from .views import ObjectDetectionView, index - -urlpatterns = [ - path('detect/', ObjectDetectionView.as_view(), name='object_detection'), - path('', index, name='index'), -] diff --git a/MisplaceAI/live_testing_object/views.py b/MisplaceAI/live_testing_object/views.py deleted file mode 100644 index 07e8aa466de26aa17d99616feabcd5e53ff6acea..0000000000000000000000000000000000000000 --- a/MisplaceAI/live_testing_object/views.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.shortcuts import render -from rest_framework.views import APIView -from rest_framework.response import Response - -class ObjectDetectionView(APIView): - def post(self, request): - # Placeholder for TensorFlow.js object detection logic - data = request.data - # Process the data with TensorFlow.js here - result = {"detected_objects": [ - {"name": "object1", "box": [50, 50, 100, 100]}, - {"name": "object2", "box": [150, 150, 100, 100]} - ]} - return Response(result) - -def index(request): - return render(request, 'live_testing_object/object_detection.html') diff --git a/MisplaceAI/placement_rules/urls.py b/MisplaceAI/placement_rules/urls.py index febb9102e27573a337e6d273b7a8a526bb6aedc3..2f4a42a232a9766507e7df5e271779ad52ad1790 100644 --- a/MisplaceAI/placement_rules/urls.py +++ b/MisplaceAI/placement_rules/urls.py @@ -1,10 +1,8 @@ -# placement_rules/urls.py from django.urls import path from . import views app_name = 'placement_rules' # Ensure app_name is set for namespacing urlpatterns = [ - path('live-detection/', views.live_detection, name='live_detection'), path('check_placement/', views.check_placement, name='check_placement'), ] diff --git a/MisplaceAI/placement_rules/views.py b/MisplaceAI/placement_rules/views.py index 1817defdebc3266caa940c6138935c59317ad7ad..abdd4aebdd19f977011806aeec1724e883b02500 100644 --- a/MisplaceAI/placement_rules/views.py +++ b/MisplaceAI/placement_rules/views.py @@ -1,10 +1,13 @@ from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt +from rest_framework.decorators import api_view, permission_classes +from rest_framework.permissions import IsAuthenticated from placement_rules.utils import PlacementRules import json -from django.shortcuts import render @csrf_exempt +@api_view(['POST']) +@permission_classes([IsAuthenticated]) def check_placement(request): if request.method == 'POST': data = json.loads(request.body) @@ -12,11 +15,3 @@ def check_placement(request): misplaced_items = placement_rules.check_placement(data) return JsonResponse({'misplaced_items': misplaced_items}) return JsonResponse({'error': 'Invalid request method'}, status=400) - -def live_detection(request): - return render(request, 'process_misplaced_manager/live_detection.html') - - - - -#################################################################### \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/serializers.py b/MisplaceAI/process_misplaced_manager/serializers.py new file mode 100644 index 0000000000000000000000000000000000000000..1fd67f26ac2cd61f24be964f2ad650785b4eb1cc --- /dev/null +++ b/MisplaceAI/process_misplaced_manager/serializers.py @@ -0,0 +1,13 @@ +# process_misplaced_manager/serializers.py +from rest_framework import serializers +from .models import UploadedImage, UploadedVideo + +class UploadedImageSerializer(serializers.ModelSerializer): + class Meta: + model = UploadedImage + fields = ['id', 'image', 'uploaded_at'] + +class UploadedVideoSerializer(serializers.ModelSerializer): + class Meta: + model = UploadedVideo + fields = ['id', 'video', 'uploaded_at'] diff --git a/MisplaceAI/process_misplaced_manager/static/css/styles.css b/MisplaceAI/process_misplaced_manager/static/css/styles.css deleted file mode 100644 index 6951a9fc77a6170501f9d387f1db867b284ae3a6..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/static/css/styles.css +++ /dev/null @@ -1,49 +0,0 @@ -/* styles.css */ - -#live-detection { - text-align: center; -} - -#videoContainer { - display: block; - margin: 0 auto; - position: relative; - width: 100%; - height: 0; - padding-bottom: 56.25%; - /* 16:9 aspect ratio */ -} - -video, -canvas { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} - -#fullscreenButton { - display: inline-block; - margin: 10px; -} - -select { - margin: 10px; - padding: 5px; -} - -@media (max-width: 768px) { - - #fullscreenButton, - #startDetection, - #stopDetection, - select { - width: 100%; - margin: 5px 0; - } - - #videoContainer { - padding-bottom: 56.25%; - } -} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/static/js/camera.js b/MisplaceAI/process_misplaced_manager/static/js/camera.js deleted file mode 100644 index a253f94173ef2e70a39a9ce0bd23f3816890dc5a..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/static/js/camera.js +++ /dev/null @@ -1,168 +0,0 @@ -// camera.js -let stream; -const video = document.getElementById('video'); -const canvas = document.getElementById('canvas'); -const cameraSelect = document.getElementById('cameraSelect'); -const videoContainer = document.getElementById('videoContainer'); -const context = canvas.getContext('2d'); -let model; - -// Utility function to handle errors -function handleError(message, error) { - console.error(message, error); - alert(`${message}: ${error.message}. Please check your camera and try again.`); -} - -// Populate camera options for selection -function populateCameraOptions() { - navigator.mediaDevices.enumerateDevices() - .then(devices => { - const videoDevices = devices.filter(device => device.kind === 'videoinput'); - cameraSelect.innerHTML = ''; - videoDevices.forEach((device, index) => { - const option = document.createElement('option'); - option.value = device.deviceId; - option.text = device.label || `Camera ${index + 1}`; - cameraSelect.appendChild(option); - }); - }) - .catch(error => handleError('Error listing cameras', error)); -} - -// Start the video stream from the selected camera -async function startVideo() { - try { - const videoSource = cameraSelect.value; - stream = await navigator.mediaDevices.getUserMedia({ - video: { - deviceId: videoSource, - width: { ideal: 1280 }, - height: { ideal: 720 }, - facingMode: "environment" // Prefer rear camera on mobile - } - }); - video.srcObject = stream; - video.onloadedmetadata = () => { - video.play(); - adjustVideoCanvas(); - }; - } catch (error) { - handleError('Error accessing the camera', error); - } -} - -// Stop the video stream -function stopVideo() { - if (stream) { - stream.getTracks().forEach(track => track.stop()); - } -} - -// Adjust video and canvas elements for responsive design -function adjustVideoCanvas() { - const aspectRatio = 16 / 9; - const containerWidth = videoContainer.clientWidth; - - videoContainer.style.height = `${containerWidth / aspectRatio}px`; - - video.width = videoContainer.clientWidth; - video.height = videoContainer.clientHeight; - canvas.width = videoContainer.clientWidth; - canvas.height = videoContainer.clientHeight; -} - -// Draw predictions on the canvas -function drawPredictions(predictions) { - context.clearRect(0, 0, canvas.width, canvas.height); - context.drawImage(video, 0, 0, canvas.width, canvas.height); - - predictions.forEach(prediction => { - const [x, y, width, height] = prediction.bbox; - const text = `${prediction.class} (${Math.round(prediction.score * 100)}%)`; - - // Draw bounding box - context.strokeStyle = '#00FF00'; - context.lineWidth = 2; - context.strokeRect(x, y, width, height); - - // Draw label - context.fillStyle = '#00FF00'; - context.font = '18px Arial'; - context.fillText(text, x, y > 10 ? y - 5 : y + 15); - }); -} - -// Detect frame and make predictions -async function detectFrame() { - if (video.readyState === 4) { - const predictions = await model.detect(video); - console.log(predictions); - - drawPredictions(predictions); - - // Send the predictions to the server for rule checking - checkPlacement(predictions); - } - - if (document.getElementById('stopDetection').style.display === 'block') { - requestAnimationFrame(detectFrame); - } -} - -// Start detection -function startDetection() { - if (!model) { - console.log('Model is not loaded yet.'); - return; - } - - document.getElementById('stopDetection').style.display = 'block'; - document.getElementById('startDetection').style.display = 'none'; - detectFrame(); -} - -// Stop detection -function stopDetection() { - document.getElementById('stopDetection').style.display = 'none'; - document.getElementById('startDetection').style.display = 'block'; - stopVideo(); -} - -// Toggle full screen -function toggleFullScreen() { - if (!document.fullscreenElement) { - canvas.requestFullscreen().catch(err => { - alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`); - }); - } else { - document.exitFullscreen(); - } -} - -// Initialize Plyr for enhanced video controls -const player = new Plyr(video, { - controls: ['play', 'progress', 'mute', 'volume', 'fullscreen'], -}); - -// Initialize and handle events -document.addEventListener('DOMContentLoaded', () => { - populateCameraOptions(); - adjustVideoCanvas(); - startVideo(); - loadModel(); - - // Use ResizeObserver to handle dynamic resizing - const resizeObserver = new ResizeObserver(() => adjustVideoCanvas()); - resizeObserver.observe(videoContainer); - - window.addEventListener('resize', adjustVideoCanvas); - - document.getElementById('startDetection').addEventListener('click', startDetection); - document.getElementById('stopDetection').addEventListener('click', stopDetection); - document.getElementById('fullscreenButton').addEventListener('click', toggleFullScreen); - - cameraSelect.addEventListener('change', () => { - stopVideo(); - startVideo(); - }); -}); diff --git a/MisplaceAI/process_misplaced_manager/static/js/csrf.js b/MisplaceAI/process_misplaced_manager/static/js/csrf.js deleted file mode 100644 index cbc6bada02ed2b436f5dfdb7c8540225eca63a50..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/static/js/csrf.js +++ /dev/null @@ -1,15 +0,0 @@ -// csrf.js -function getCookie(name) { - let cookieValue = null; - if (document.cookie && document.cookie !== '') { - const cookies = document.cookie.split(';'); - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i].trim(); - if (cookie.substring(0, name.length + 1) === (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; -} diff --git a/MisplaceAI/process_misplaced_manager/static/js/main.js b/MisplaceAI/process_misplaced_manager/static/js/main.js deleted file mode 100644 index 7ebe40f07ecd7f37baab5955c8074bf85bb09aa4..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/static/js/main.js +++ /dev/null @@ -1,28 +0,0 @@ -// main.js -const startButton = document.getElementById('startDetection'); -const stopButton = document.getElementById('stopDetection'); -const fullscreenButton = document.getElementById('fullscreenButton'); - -async function startDetection() { - if (!model) { - console.log('Model is not loaded yet.'); - return; - } - - stopButton.style.display = 'block'; - startButton.style.display = 'none'; - detectFrame(); -} - -function stopDetection() { - stopButton.style.display = 'none'; - startButton.style.display = 'block'; - stopVideo(); -} - -// Initialize and handle events -document.addEventListener('DOMContentLoaded', () => { - document.getElementById('startDetection').addEventListener('click', startDetection); - document.getElementById('stopDetection').addEventListener('click', stopDetection); - document.getElementById('fullscreenButton').addEventListener('click', toggleFullScreen); -}); diff --git a/MisplaceAI/process_misplaced_manager/static/js/model.js b/MisplaceAI/process_misplaced_manager/static/js/model.js deleted file mode 100644 index 3519e05179f3e2fe41d87cf2f109e034f16db1c8..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/static/js/model.js +++ /dev/null @@ -1,17 +0,0 @@ -// model.js -let model; - -async function loadModel() { - console.log('Loading model...'); - try { - model = await cocoSsd.load(); - console.log('Model loaded.'); - } catch (error) { - console.error('Error loading model:', error); - alert('Error loading model. Please try again.'); - } -} - -document.addEventListener('DOMContentLoaded', () => { - loadModel(); -}); diff --git a/MisplaceAI/process_misplaced_manager/static/js/placement.js b/MisplaceAI/process_misplaced_manager/static/js/placement.js deleted file mode 100644 index 2b81b59e224da55bd33699bf0d25a5c588d90afc..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/static/js/placement.js +++ /dev/null @@ -1,104 +0,0 @@ -// placement.js -// Utility function to handle errors -function handleError(message, error) { - console.error(message, error); - alert(`${message}: ${error.message}. Please try again.`); -} - -// Function to get CSRF token from cookies -function getCookie(name) { - let cookieValue = null; - if (document.cookie && document.cookie !== '') { - const cookies = document.cookie.split(';'); - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i].trim(); - if (cookie.substring(0, name.length + 1) === (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; -} - -// Function to check placement of detected objects -function checkPlacement(predictions) { - const data = predictions.map(prediction => ({ - class_name: prediction.class, - xmin: prediction.bbox[0], - ymin: prediction.bbox[1], - xmax: prediction.bbox[0] + prediction.bbox[2], - ymax: prediction.bbox[1] + prediction.bbox[3], - })); - - fetch('/placement_rules/check_placement/', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': getCookie('csrftoken'), - }, - body: JSON.stringify(data), - }) - .then(response => { - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - return response.json(); - }) - .then(data => { - console.log('Placement check result:', data); - handlePlacementCheckResult(data.misplaced_items); - }) - .catch((error) => { - handleError('Error checking placement', error); - }); -} - -// Function to handle the placement check results -function handlePlacementCheckResult(misplacedItems) { - const context = canvas.getContext('2d'); - - misplacedItems.forEach(item => { - const [x, y, width, height] = [item.xmin, item.ymin, item.xmax - item.xmin, item.ymax - item.ymin]; - const text = `${item.class_name} is misplaced. Allowed locations: ${item.allowed_locations.join(', ')}`; - - context.strokeStyle = '#FF0000'; // Red color for misplaced items - context.lineWidth = 2; - context.strokeRect(x, y, width, height); - - context.fillStyle = '#FF0000'; - context.font = '18px Arial'; - context.fillText(text, x, y > 10 ? y - 5 : y + 15); - }); -} - -// Function to initialize and handle events -function initializePlacement() { - document.addEventListener('DOMContentLoaded', () => { - console.log('Placement module initialized'); - }); - - // Example event listener for a button to trigger placement check manually - const checkPlacementButton = document.getElementById('checkPlacement'); - if (checkPlacementButton) { - checkPlacementButton.addEventListener('click', () => { - console.log('Manual placement check triggered'); - // Here you would typically call a function to capture the current video frame and run detection - captureFrameAndCheckPlacement(); - }); - } -} - -// Function to capture frame and check placement -// This is a placeholder function. Replace it with your actual frame capture and detection logic. -function captureFrameAndCheckPlacement() { - if (video.readyState === 4) { - model.detect(video).then(predictions => { - console.log('Predictions for manual check:', predictions); - checkPlacement(predictions); - }).catch(error => handleError('Error detecting objects', error)); - } -} - -// Initialize the placement module -initializePlacement(); diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html deleted file mode 100644 index 1e9dd4c4f01a12c8385f1fbe9f6c4f9b6aaac9c3..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends 'core/base.html' %} - -{% block content %} -<h1>Select Detection Method</h1> -<div> - <a href="{% url 'process_misplaced_manager:normal_detection' %}"> - <button>Misplaced Items using Normal Object Detection</button> - </a> -</div> -<div> - <a href="{% url 'process_misplaced_manager:segmentation_detection' %}"> - <button>Misplaced Items using Segmentation</button> - </a> -</div> -<div> - <a href="{% url 'process_misplaced_manager:upload_video' %}"> - <button>Misplaced Items using Video Detection</button> - </a> -</div> - -<div> - <a href="{% url 'process_misplaced_manager:live_detection' %}"> - <button>Misplaced Items using Live Detection</button> - </a> -</div> - -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html deleted file mode 100644 index e9082d12bf65810bd67db3158ff2002601df73cd..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends 'core/base.html' %} - -{% block content %} -<div class="container mt-5"> - <div class="row justify-content-center"> - <div class="col-md-8"> - <h1 class="text-center">Detection Results</h1> - <img src="{{ output_image_url }}" alt="Detected Objects" class="img-fluid"> - <h2 class="mt-4">Misplaced Objects</h2> - <ul class="list-group"> - {% for obj in misplaced_objects %} - <li class="list-group-item"> - {{ obj.class_name }} is misplaced. Allowed locations: {{ obj.allowed_locations|join:", " }} - </li> - {% endfor %} - </ul> - <div class="text-center mt-4"> - <a href="{% url 'process_misplaced_manager:detection_options' %}" class="btn btn-link"> - Try another detection - </a> - </div> - </div> - </div> -</div> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_video_results.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_video_results.html deleted file mode 100644 index 3fef4082fa0feb682a7f5a7252b641236d4fc764..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_video_results.html +++ /dev/null @@ -1,36 +0,0 @@ -{% extends 'core/base.html' %} - -{% block content %} -<div class="container mt-5"> - <div class="row justify-content-center"> - <div class="col-md-8"> - <h1 class="text-center">Detection Results</h1> - <video width="100%" controls> - <source src="{{ video.video.url }}" type="video/mp4"> - Your browser does not support the video tag. - </video> - <h2 class="mt-4">Detected Objects</h2> - <ul class="list-group"> - {% for obj in detected_objects %} - <li class="list-group-item"> - {{ obj.class_name }} detected - </li> - {% endfor %} - </ul> - <h2 class="mt-4">Misplaced Objects</h2> - <ul class="list-group"> - {% for obj in misplaced_objects %} - <li class="list-group-item"> - {{ obj.class_name }} is misplaced. Allowed locations: {{ obj.allowed_locations|join:", " }} - </li> - {% endfor %} - </ul> - <div class="text-center mt-4"> - <a href="{% url 'process_misplaced_manager:detection_options' %}" class="btn btn-link"> - Try another detection - </a> - </div> - </div> - </div> -</div> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/live_detection.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/live_detection.html deleted file mode 100644 index 1a0fffae61cfdb96a848b8fb3cd7c7d9b9030960..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/live_detection.html +++ /dev/null @@ -1,42 +0,0 @@ -{% extends 'core/base.html' %} -{% load static %} - -{% block title %}Live Detection{% endblock %} - -{% block extra_head %} -<link rel="stylesheet" href="{% static 'css/styles.css' %}"> -<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> -<link rel="stylesheet" href="https://cdn.plyr.io/3.6.8/plyr.css"> -{% endblock %} - -{% block content %} -<div id="live-detection" class="container mt-4"> - <div id="videoContainer" class="mb-3"> - <video id="video" autoplay class="plyr__video-embed" playsinline></video> - <canvas id="canvas"></canvas> - </div> - <div class="d-flex justify-content-around mb-3 flex-wrap"> - <button id="startDetection" class="btn btn-primary">Start Detection</button> - <button id="stopDetection" class="btn btn-danger" style="display: none;">Stop Detection</button> - <button id="fullscreenButton" class="btn btn-secondary">Fullscreen</button> - </div> - <div class="form-group"> - <label for="cameraSelect">Choose Camera:</label> - <select id="cameraSelect" class="form-control"></select> - </div> -</div> -{% endblock %} - -{% block extra_js %} -<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script> -<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd"></script> -<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> -<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script> -<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> -<script src="https://cdn.plyr.io/3.6.8/plyr.polyfilled.js"></script> -<script src="{% static 'js/csrf.js' %}"></script> -<script src="{% static 'js/model.js' %}"></script> -<script src="{% static 'js/camera.js' %}"></script> -<script src="{% static 'js/placement.js' %}"></script> -<script src="{% static 'js/main.js' %}"></script> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html deleted file mode 100644 index 614a8a45299c8fb819c65d6110f5d2a774bb511f..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html +++ /dev/null @@ -1,72 +0,0 @@ -{% extends 'core/base.html' %} - -{% block content %} -<div class="container mt-5"> - <div class="row justify-content-center"> - <div class="col-md-8"> - <div class="card shadow-lg border-0"> - <div class="card-header text-center bg-primary text-white py-4"> - <h1 class="mb-0">Upload Image for Normal Detection</h1> - </div> - <div class="card-body p-5"> - <form method="post" enctype="multipart/form-data" id="uploadForm" class="text-center"> - {% csrf_token %} - - <!-- Camera Button --> - <div class="form-group"> - <label class="h5 d-block"> - <button type="button" id="openCameraBtn" class="btn btn-primary btn-lg"> - <i class="fas fa-camera-retro fa-3x mb-3"></i> Take Photo - </button> - </label> - <input type="file" id="cameraInput" name="image" accept="image/*" capture="environment" - class="form-control-file d-none"> - </div> - - <!-- Gallery Button --> - <div class="form-group"> - <label class="h5 d-block"> - <button type="button" id="openGalleryBtn" class="btn btn-secondary btn-lg"> - <i class="fas fa-folder-open fa-3x mb-3"></i> Choose from Gallery - </button> - </label> - <input type="file" id="galleryInput" name="image" accept="image/*" - class="form-control-file d-none"> - </div> - - <button type="submit" class="btn btn-success btn-lg mt-4"> - <i class="fas fa-upload"></i> Upload - </button> - </form> - <div class="text-center mt-4"> - <a href="{% url 'process_misplaced_manager:detection_options' %}" class="btn btn-link"> - <i class="fas fa-arrow-left"></i> Back to Detection Options - </a> - </div> - </div> - </div> - </div> - </div> -</div> - -<script> - document.getElementById('openCameraBtn').addEventListener('click', function () { - document.getElementById('cameraInput').click(); - }); - - document.getElementById('openGalleryBtn').addEventListener('click', function () { - document.getElementById('galleryInput').click(); - }); -</script> - -<style> - .container { - max-width: 600px; - margin: auto; - } - - .btn-lg i { - margin-right: 8px; - } -</style> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html deleted file mode 100644 index 892e93b633cfab9cd627cb583eb5fd2b94dc9a68..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends 'core/base.html' %} - -{% block content %} -<h1>Upload Image for Segmentation Detection</h1> -<form method="post" enctype="multipart/form-data"> - {% csrf_token %} - <label for="id_image">Image:</label> - <input type="file" name="image" accept="image/*" capture="camera" required> - <button type="submit">Upload</button> -</form> -<a href="{% url 'process_misplaced_manager:detection_options' %}">Back to Detection Options</a> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html deleted file mode 100644 index 0451cc3677170ef4a2485f59661d25c1e58ffa42..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends 'core/base.html' %} - -{% block content %} -<h1>Upload Image</h1> -<form method="post" enctype="multipart/form-data"> - {% csrf_token %} - {{ form.as_p }} - <button type="submit">Upload</button> -</form> -<a href="{% url 'process_misplaced_manager:detection_options' %}">Back to Detection Options</a> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html deleted file mode 100644 index c17a76f94290ea515846e074816a6d9dc56cffd7..0000000000000000000000000000000000000000 --- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html +++ /dev/null @@ -1,34 +0,0 @@ -{% extends 'core/base.html' %} - -{% block content %} -<div class="container mt-5"> - <div class="row justify-content-center"> - <div class="col-md-8"> - <div class="card shadow-lg border-0"> - <div class="card-header text-center bg-primary text-white py-4"> - <h1 class="mb-0">Upload Video for Detection</h1> - </div> - <div class="card-body p-5"> - <form method="post" enctype="multipart/form-data" id="uploadForm" class="text-center"> - {% csrf_token %} - <div class="form-group"> - <label for="id_video" class="h5 d-block"> - <i class="fas fa-video fa-3x mb-3 text-primary"></i> - </label> - <input type="file" id="id_video" name="video" accept="video/*" class="form-control-file"> - </div> - <button type="submit" class="btn btn-primary btn-lg mt-4"> - <i class="fas fa-upload"></i> Upload - </button> - </form> - <div class="text-center mt-4"> - <a href="{% url 'process_misplaced_manager:detection_options' %}" class="btn btn-link"> - <i class="fas fa-arrow-left"></i> Back to Detection Options - </a> - </div> - </div> - </div> - </div> - </div> -</div> -{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/process_misplaced_manager/urls.py b/MisplaceAI/process_misplaced_manager/urls.py index 8d59a21f796eac12d70355a192355b19c7efc296..529d411f38f6519cc3b5edeef4e1db8f0da791c6 100644 --- a/MisplaceAI/process_misplaced_manager/urls.py +++ b/MisplaceAI/process_misplaced_manager/urls.py @@ -1,17 +1,23 @@ -from django.urls import path -from . import views +# process_misplaced_manager/urls.py +from django.urls import path, include +from rest_framework.routers import DefaultRouter +from .views import ( + UploadedImageViewSet, UploadedVideoViewSet, + normal_detection, + display_results, display_video_results +) + +router = DefaultRouter() +router.register(r'images', UploadedImageViewSet) +router.register(r'videos', UploadedVideoViewSet) app_name = 'process_misplaced_manager' urlpatterns = [ - path('detection-options/', views.detection_options, name='detection_options'), - path('normal-detection/', views.normal_detection, name='normal_detection'), - path('segmentation-detection/', views.segmentation_detection, name='segmentation_detection'), - path('upload-video/', views.upload_video, name='upload_video'), - path('video-results/<int:video_id>/', views.display_video_results, name='display_video_results'), - path('live-detection/', views.live_detection, name='live_detection'), - path('display-results/<int:image_id>/', views.display_results, name='display_results'), - path('react/', views.ReactAppView.as_view(), name='react_app'), - - + path('', include(router.urls)), + path('normal-detection/', normal_detection, name='normal_detection'), + # path('segmentation-detection/', segmentation_detection, name='segmentation_detection'), + # path('upload-video/', upload_video, name='upload_video'), + path('video-results/<int:video_id>/', display_video_results, name='display_video_results'), + path('display-results/<int:image_id>/', display_results, name='display_results'), ] diff --git a/MisplaceAI/process_misplaced_manager/views.py b/MisplaceAI/process_misplaced_manager/views.py index 58ef935f4cb2e2347d04addd4235917b6bdd9b13..ac9dada05686d8f31954687ea5f5ae15abe0d08d 100644 --- a/MisplaceAI/process_misplaced_manager/views.py +++ b/MisplaceAI/process_misplaced_manager/views.py @@ -1,72 +1,64 @@ -from django.shortcuts import render, redirect, get_object_or_404 -from .forms import ImageUploadForm, VideoUploadForm +from rest_framework import viewsets, status +from rest_framework.decorators import api_view, permission_classes +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from django.shortcuts import get_object_or_404 from .models import UploadedImage, UploadedVideo +from .serializers import UploadedImageSerializer, UploadedVideoSerializer from item_detector.utils import run_inference, load_model, create_category_index_from_labelmap from placement_rules.utils import PlacementRules from results_viewer.utils import visualize_misplaced_objects, visualize_video_misplaced_objects +from django.core.files.base import ContentFile import base64 -from PIL import Image, ExifTags - import os -from django.core.files.base import ContentFile -from django.http import JsonResponse +from PIL import Image, ExifTags -# Load the model and category index for object detection MODEL_PATH = "models/research/object_detection/faster_rcnn_resnet50_v1_1024x1024_coco17_tpu-8/saved_model" LABEL_MAP_PATH = "models/research/object_detection/data/mscoco_label_map.pbtxt" detection_model = load_model(MODEL_PATH) category_index = create_category_index_from_labelmap(LABEL_MAP_PATH) -def detection_options(request): - return render(request, 'process_misplaced_manager/detection_options.html') - - - +class UploadedImageViewSet(viewsets.ModelViewSet): + queryset = UploadedImage.objects.all() + serializer_class = UploadedImageSerializer + permission_classes = [IsAuthenticated] +class UploadedVideoViewSet(viewsets.ModelViewSet): + queryset = UploadedVideo.objects.all() + serializer_class = UploadedVideoSerializer + permission_classes = [IsAuthenticated] +@api_view(['POST']) +@permission_classes([IsAuthenticated]) def normal_detection(request): - if request.method == 'POST': - if 'capturedImageData' in request.POST: - captured_image_data = request.POST['capturedImageData'] - format, imgstr = captured_image_data.split(';base64,') - ext = format.split('/')[-1] - image_data = ContentFile(base64.b64decode(imgstr), name='temp.' + ext) - - new_image = UploadedImage.objects.create(image=image_data) - return redirect('process_misplaced_manager:display_results', image_id=new_image.id) - else: - form = ImageUploadForm(request.POST, request.FILES) - if form.is_valid(): - new_image = form.save() - return redirect('process_misplaced_manager:display_results', image_id=new_image.id) - else: - form = ImageUploadForm() - return render(request, 'process_misplaced_manager/normal_detection.html', {'form': form}) - -def segmentation_detection(request): - if request.method == 'POST': - form = ImageUploadForm(request.POST, request.FILES) - if form.is_valid(): - new_image = form.save() - return redirect('process_misplaced_manager:display_results', image_id=new_image.id) - else: - form = ImageUploadForm() - return render(request, 'process_misplaced_manager/segmentation_detection.html', {'form': form}) + if 'capturedImageData' in request.data: + captured_image_data = request.data['capturedImageData'] + format, imgstr = captured_image_data.split(';base64,') + ext = format.split('/')[-1] + image_data = ContentFile(base64.b64decode(imgstr), name='temp.' + ext) -def upload_video(request): - if request.method == 'POST': - form = VideoUploadForm(request.POST, request.FILES) - if form.is_valid(): - new_video = form.save() - return redirect('process_misplaced_manager:display_video_results', video_id=new_video.id) + new_image = UploadedImage.objects.create(image=image_data) else: - form = VideoUploadForm() - return render(request, 'process_misplaced_manager/upload_video.html', {'form': form}) - - - + serializer = UploadedImageSerializer(data=request.data) + if serializer.is_valid(): + new_image = serializer.save() + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + image_path = new_image.image.path + correct_image_orientation(image_path) + detected_objects = run_inference(detection_model, category_index, image_path) + placement_rules = PlacementRules() + misplaced_objects = placement_rules.check_placement(detected_objects) + output_image_path = visualize_misplaced_objects(image_path, detected_objects, misplaced_objects) + response_data = { + 'image_url': new_image.image.url, + 'output_image_url': request.build_absolute_uri("/media/" + os.path.basename(output_image_path)), + 'misplaced_objects': misplaced_objects + } + return Response(response_data, status=status.HTTP_200_OK) def correct_image_orientation(image_path): try: @@ -85,71 +77,39 @@ def correct_image_orientation(image_path): image = image.rotate(90, expand=True) image.save(image_path) except (AttributeError, KeyError, IndexError): - # Cases where the image does not have EXIF data pass +@api_view(['GET']) +@permission_classes([IsAuthenticated]) def display_results(request, image_id): image = get_object_or_404(UploadedImage, id=image_id) image_path = image.image.path - # Correct image orientation correct_image_orientation(image_path) - # Run object detection detected_objects = run_inference(detection_model, category_index, image_path) - print(f"Detected objects: {detected_objects}") # Debugging - - # Check placement rules placement_rules = PlacementRules() misplaced_objects = placement_rules.check_placement(detected_objects) - print(f"Misplaced objects: {misplaced_objects}") # Debugging - - # Visualize results output_image_path = visualize_misplaced_objects(image_path, detected_objects, misplaced_objects) - return render(request, 'process_misplaced_manager/display_results.html', { - 'image': image, + response_data = { + 'image_url': image.image.url, 'output_image_url': "/media/" + os.path.basename(output_image_path), 'misplaced_objects': misplaced_objects - }) - - -##################################################################### - - - - -def upload_video(request): - if request.method == 'POST': - form = VideoUploadForm(request.POST, request.FILES) - if form.is_valid(): - new_video = form.save() - return redirect('process_misplaced_manager:display_video_results', video_id=new_video.id) - else: - form = VideoUploadForm() - return render(request, 'process_misplaced_manager/upload_video.html', {'form': form}) + } + return Response(response_data, status=status.HTTP_200_OK) +@api_view(['GET']) +@permission_classes([IsAuthenticated]) def display_video_results(request, video_id): video = get_object_or_404(UploadedVideo, id=video_id) video_path = video.video.path - # Process video for misplaced object detection detected_objects, misplaced_objects = visualize_video_misplaced_objects(video_path, detection_model, category_index) - return render(request, 'process_misplaced_manager/display_video_results.html', { - 'video': video, + response_data = { + 'video_url': video.video.url, 'detected_objects': detected_objects, 'misplaced_objects': misplaced_objects - }) - -def live_detection(request): - return render(request, 'process_misplaced_manager/live_detection.html') - - -########################################################################### - - -from django.views.generic import TemplateView - -class ReactAppView(TemplateView): - template_name = "index.html" \ No newline at end of file + } + return Response(response_data, status=status.HTTP_200_OK) diff --git a/MisplaceAI/results_viewer/templates/results_viewer/visualize_results.html b/MisplaceAI/results_viewer/templates/results_viewer/visualize_results.html deleted file mode 100644 index 861052d881a83d1fa306a75b068f1a00afcb784f..0000000000000000000000000000000000000000 --- a/MisplaceAI/results_viewer/templates/results_viewer/visualize_results.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends 'core/base.html' %} -{% load static %} - -{% block title %}Visualize Results{% endblock %} - -{% block content %} -<div class="container mt-5"> - <h1>Visualization Results</h1> - <img src="{{ output_image_url }}" alt="Visualization Results" class="img-fluid"> - <h2>Detected Objects</h2> - <ul> - {% for obj in detected_objects %} - <li>{{ obj.class_name }}: [{{ obj.ymin }}, {{ obj.xmin }}, {{ obj.ymax }}, {{ obj.xmax }}]</li> - {% endfor %} - </ul> - <h2>Misplaced Objects</h2> - {% if misplaced_objects %} - <ul> - {% for obj in misplaced_objects %} - <li>{{ obj.class_name }} is misplaced. It should be on {{ obj.allowed_locations|join:", " }}.</li> - {% endfor %} - </ul> - {% else %} - <p>No misplaced objects detected.</p> - {% endif %} -</div> -{% endblock %} \ No newline at end of file diff --git a/frontend/src/App.js b/frontend/src/App.js index bad3669ee49096c50a293ee658a0b334d86742d3..1f8039ea0470fc706816fdbb24fa0081dd9105dc 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -10,10 +10,12 @@ import LoginPage from './pages/Auth/LoginPage'; import RegisterPage from './pages/Auth/RegisterPage'; import ManageLocationsPage from './pages/Locations/ManageLocationsPage'; import ManageItems from './pages/Items/ManageItemsPage'; +import ManageRulesPage from './pages/Rules/ManageRulesPage'; +import DetectionOptionsPage from './pages/DetectionOptions/DetectionOptionsPage'; +import NormalDetectionPage from './pages/NormalDetection/NormalDetectionPage'; import ProtectedRoute from './firewall/ProtectedRoute'; import RouteProtection from './firewall/RouteProtection'; -import ManageRulesPage from './pages/Rules/ManageRulesPage'; import './App.css'; @@ -49,7 +51,7 @@ function App() { <ManageItems /> </ProtectedRoute> } /> - <Route path="/admin/Manage-Locations" element={ + <Route path="/admin/manage-locations" element={ <ProtectedRoute isAdminRoute={true}> <ManageLocationsPage /> </ProtectedRoute> @@ -59,6 +61,17 @@ function App() { <ManageRulesPage /> </ProtectedRoute> } /> + <Route path="/detection-options" element={ + <ProtectedRoute> + <DetectionOptionsPage /> + </ProtectedRoute> + } /> + <Route path="/normal-detection" element={ + <ProtectedRoute> + <NormalDetectionPage /> + </ProtectedRoute> + } /> + <Route path="*" element={<HomePage />} /> {/* Catch-all route */} </Routes> </div> </div> diff --git a/frontend/src/forms/Auth/AdminLoginForm.js b/frontend/src/forms/Auth/AdminLoginForm.js index 5ad3451b75a6eb3d695b2e80f19d4b7c3fce4002..4f6846210349460dc8310a6e7f0ca141aedb045a 100644 --- a/frontend/src/forms/Auth/AdminLoginForm.js +++ b/frontend/src/forms/Auth/AdminLoginForm.js @@ -15,7 +15,7 @@ const AdminLoginForm = () => { const handleSubmit = async (e) => { e.preventDefault(); try { - const response = await api.post('/admin-app/login/', { username, password }); + const response = await api.post('/api/admin-app/login/', { username, password }); localStorage.setItem('adminToken', response.data.access); localStorage.setItem('isAdmin', true); localStorage.setItem('isAuthenticated', true); diff --git a/frontend/src/forms/Auth/LoginForm.js b/frontend/src/forms/Auth/LoginForm.js index da725a86ac951d40ae7a09028baa0022470071e2..bb1be29b1e0f487ef37e1f75abcc46ee571ebcfa 100644 --- a/frontend/src/forms/Auth/LoginForm.js +++ b/frontend/src/forms/Auth/LoginForm.js @@ -16,7 +16,7 @@ const LoginForm = () => { const handleSubmit = async (e) => { e.preventDefault(); try { - const response = await api.post('/auth/login/', { username, password }); + const response = await api.post('/api/auth/login/', { username, password }); localStorage.setItem('token', response.data.access); localStorage.setItem('isAuthenticated', true); // Set the authentication flag navigate('/'); diff --git a/frontend/src/forms/Auth/RegisterForm.js b/frontend/src/forms/Auth/RegisterForm.js index 6f839f65c65b75aeeb2a2e6cbf4f217d41289ce1..f6dbb7027d2c62ff55f71c938ab0048875973229 100644 --- a/frontend/src/forms/Auth/RegisterForm.js +++ b/frontend/src/forms/Auth/RegisterForm.js @@ -77,7 +77,7 @@ const RegisterForm = () => { return; } try { - const response = await api.post('/auth/register/', { username, email, password, password2 }); + const response = await api.post('/api/auth/register/', { username, email, password, password2 }); localStorage.setItem('token', response.data.access); localStorage.setItem('isAuthenticated', true); navigate('/'); diff --git a/frontend/src/layouts/Navbar/Navbar.js b/frontend/src/layouts/Navbar/Navbar.js index 26d027b7bc1d203f5b605fad233f529052ca85db..12293a397a7949ecb354a13c515b9b8875e6f9bc 100644 --- a/frontend/src/layouts/Navbar/Navbar.js +++ b/frontend/src/layouts/Navbar/Navbar.js @@ -30,9 +30,11 @@ const Navbar = () => { <li className="nav-item"> <Link className="nav-link" to="/">Home</Link> </li> - <li className="nav-item"> - <Link className="nav-link" to="/detection-options">Detect Misplaced Items</Link> - </li> + {isAuthenticated && ( + <li className="nav-item"> + <Link className="nav-link" to="/detection-options">Detect Misplaced Items</Link> + </li> + )} {!isAuthenticated && ( <> <li className="nav-item"> diff --git a/frontend/src/pages/Admin/AdminUsers.js b/frontend/src/pages/Admin/AdminUsers.js index a4997c8192c1d20e9bc7144d8507cf5bf7fcba64..6de0c656acd16e69e2f501e83927ac1bcf27bd67 100644 --- a/frontend/src/pages/Admin/AdminUsers.js +++ b/frontend/src/pages/Admin/AdminUsers.js @@ -14,17 +14,17 @@ const AdminUsers = () => { }, []); const handleDeactivate = async (userId) => { - await api.post(`/admin-app/users/deactivate/${userId}/`); + await api.post(`/api/admin-app/users/deactivate/${userId}/`); setUsers(users.map(user => user.id === userId ? { ...user, is_active: false } : user)); }; const handleActivate = async (userId) => { - await api.post(`/admin-app/users/activate/${userId}/`); + await api.post(`/api/admin-app/users/activate/${userId}/`); setUsers(users.map(user => user.id === userId ? { ...user, is_active: true } : user)); }; const handleDelete = async (userId) => { - await api.post(`/admin-app/users/delete/${userId}/`); + await api.post(`/api/admin-app/users/delete/${userId}/`); setUsers(users.filter(user => user.id !== userId)); }; diff --git a/frontend/src/pages/DetectionOptions/DetectionOptionsPage.js b/frontend/src/pages/DetectionOptions/DetectionOptionsPage.js new file mode 100644 index 0000000000000000000000000000000000000000..3dd29ae4f4607f53ce2402ce0f0c269011160a93 --- /dev/null +++ b/frontend/src/pages/DetectionOptions/DetectionOptionsPage.js @@ -0,0 +1,29 @@ +// src/pages/DetectionOptions/DetectionOptionsPage.js +import React from 'react'; +import { Link } from 'react-router-dom'; + +const DetectionOptionsPage = () => { + return ( + <div className="container mt-5"> + <h1 className="text-center">Select Detection Method</h1> + <div className="row justify-content-center mt-4"> + <div className="col-md-6 text-center"> + <Link to="/normal-detection"> + <button className="btn btn-primary btn-lg mb-3 w-100">Misplaced Items using Normal Object Detection</button> + </Link> + <Link to="/segmentation-detection"> + <button className="btn btn-secondary btn-lg mb-3 w-100">Misplaced Items using Segmentation</button> + </Link> + <Link to="/upload-video"> + <button className="btn btn-success btn-lg mb-3 w-100">Misplaced Items using Video Detection</button> + </Link> + <Link to="/live-detection"> + <button className="btn btn-info btn-lg mb-3 w-100">Misplaced Items using Live Detection</button> + </Link> + </div> + </div> + </div> + ); +}; + +export default DetectionOptionsPage; diff --git a/frontend/src/pages/NormalDetection/NormalDetectionPage.css b/frontend/src/pages/NormalDetection/NormalDetectionPage.css new file mode 100644 index 0000000000000000000000000000000000000000..27102eb4a115d9abe392fdf3388fc51f64c1e4c8 --- /dev/null +++ b/frontend/src/pages/NormalDetection/NormalDetectionPage.css @@ -0,0 +1,9 @@ +/* src/pages/NormalDetection/NormalDetectionPage.css */ +.container { + max-width: 600px; + margin: auto; +} + +.btn-lg i { + margin-right: 8px; +} \ No newline at end of file diff --git a/frontend/src/pages/NormalDetection/NormalDetectionPage.js b/frontend/src/pages/NormalDetection/NormalDetectionPage.js new file mode 100644 index 0000000000000000000000000000000000000000..6c01bd3ab5be9008a1baa7e5340f6fb1e488db27 --- /dev/null +++ b/frontend/src/pages/NormalDetection/NormalDetectionPage.js @@ -0,0 +1,102 @@ +// src/pages/NormalDetection/NormalDetectionPage.js +import React, { useState } from 'react'; +import { normalDetection } from '../../services/processMisplacedManagerApi'; +import './NormalDetectionPage.css'; + +const NormalDetectionPage = () => { + const [imageFile, setImageFile] = useState(null); + const [resultImageUrl, setResultImageUrl] = useState(null); + const [misplacedObjects, setMisplacedObjects] = useState([]); + + const handleCameraClick = () => { + document.getElementById('cameraInput').click(); + }; + + const handleGalleryClick = () => { + document.getElementById('galleryInput').click(); + }; + + const handleFileChange = (event) => { + setImageFile(event.target.files[0]); + }; + + const handleSubmit = async (event) => { + event.preventDefault(); + if (imageFile) { + const formData = new FormData(); + formData.append('image', imageFile); + + try { + const response = await normalDetection(formData); + setResultImageUrl(response.output_image_url); + setMisplacedObjects(response.misplaced_objects); + } catch (error) { + console.error('Upload failed', error); + } + } else { + alert('Please select an image to upload.'); + } + }; + + return ( + <div className="container mt-5"> + <div className="row justify-content-center"> + <div className="col-md-8"> + <div className="card shadow-lg border-0"> + <div className="card-header text-center bg-primary text-white py-4"> + <h1 className="mb-0">Upload Image for Normal Detection</h1> + </div> + <div className="card-body p-5"> + <form id="uploadForm" className="text-center" onSubmit={handleSubmit}> + <div className="form-group"> + <label className="h5 d-block"> + <button type="button" id="openCameraBtn" className="btn btn-primary btn-lg" onClick={handleCameraClick}> + <i className="fas fa-camera-retro fa-3x mb-3"></i> Take Photo + </button> + </label> + <input type="file" id="cameraInput" name="image" accept="image/*" capture="environment" + className="form-control-file d-none" onChange={handleFileChange} /> + </div> + + <div className="form-group"> + <label className="h5 d-block"> + <button type="button" id="openGalleryBtn" className="btn btn-secondary btn-lg" onClick={handleGalleryClick}> + <i className="fas fa-folder-open fa-3x mb-3"></i> Choose from Gallery + </button> + </label> + <input type="file" id="galleryInput" name="image" accept="image/*" + className="form-control-file d-none" onChange={handleFileChange} /> + </div> + + <button type="submit" className="btn btn-success btn-lg mt-4"> + <i className="fas fa-upload"></i> Upload + </button> + </form> + {resultImageUrl && ( + <div className="mt-5"> + <h2>Detection Results</h2> + <img src={resultImageUrl} alt="Detected Objects" className="img-fluid" /> + <h3 className="mt-4">Misplaced Objects</h3> + <ul className="list-group"> + {misplacedObjects.map((obj, index) => ( + <li key={index} className="list-group-item"> + {obj.class_name} is misplaced. Allowed locations: {obj.allowed_locations.join(", ")} + </li> + ))} + </ul> + </div> + )} + <div className="text-center mt-4"> + <a href="/detection-options" className="btn btn-link"> + <i className="fas fa-arrow-left"></i> Back to Detection Options + </a> + </div> + </div> + </div> + </div> + </div> + </div> + ); +}; + +export default NormalDetectionPage; diff --git a/frontend/src/pages/ProcessMisplacedManager/ManageImages.js b/frontend/src/pages/ProcessMisplacedManager/ManageImages.js new file mode 100644 index 0000000000000000000000000000000000000000..294def29aeedcaaa825a54ef2208c8890b8e89d8 --- /dev/null +++ b/frontend/src/pages/ProcessMisplacedManager/ManageImages.js @@ -0,0 +1,48 @@ +// src/pages/ProcessMisplacedManager/ManageImages.js +import React, { useState, useEffect } from 'react'; +import { getImages, createImage } from '../../services/processMisplacedManagerApi'; + +const ManageImages = () => { + const [images, setImages] = useState([]); + const [image, setImage] = useState(null); + + useEffect(() => { + const fetchData = async () => { + const result = await getImages(); + setImages(result); + }; + fetchData(); + }, []); + + const handleImageChange = (e) => { + setImage(e.target.files[0]); + }; + + const handleImageUpload = async (e) => { + e.preventDefault(); + const formData = new FormData(); + formData.append('image', image); + await createImage(formData); + const result = await getImages(); + setImages(result); + }; + + return ( + <div> + <h1>Manage Images</h1> + <form onSubmit={handleImageUpload}> + <input type="file" onChange={handleImageChange} /> + <button type="submit">Upload</button> + </form> + <ul> + {images.map((img) => ( + <li key={img.id}> + <img src={img.image} alt="uploaded" /> + </li> + ))} + </ul> + </div> + ); +}; + +export default ManageImages; diff --git a/frontend/src/pages/ProcessMisplacedManager/ManageVideos.js b/frontend/src/pages/ProcessMisplacedManager/ManageVideos.js new file mode 100644 index 0000000000000000000000000000000000000000..4641d482eec4e7dd0a59f17ea5985e42e12a201e --- /dev/null +++ b/frontend/src/pages/ProcessMisplacedManager/ManageVideos.js @@ -0,0 +1,51 @@ +// src/pages/ProcessMisplacedManager/ManageVideos.js +import React, { useState, useEffect } from 'react'; +import { getVideos, createVideo } from '../../services/processMisplacedManagerApi'; + +const ManageVideos = () => { + const [videos, setVideos] = useState([]); + const [video, setVideo] = useState(null); + + useEffect(() => { + const fetchData = async () => { + const result = await getVideos(); + setVideos(result); + }; + fetchData(); + }, []); + + const handleVideoChange = (e) => { + setVideo(e.target.files[0]); + }; + + const handleVideoUpload = async (e) => { + e.preventDefault(); + const formData = new FormData(); + formData.append('video', video); + await createVideo(formData); + const result = await getVideos(); + setVideos(result); + }; + + return ( + <div> + <h1>Manage Videos</h1> + <form onSubmit={handleVideoUpload}> + <input type="file" onChange={handleVideoChange} /> + <button type="submit">Upload</button> + </form> + <ul> + {videos.map((vid) => ( + <li key={vid.id}> + <video width="320" height="240" controls> + <source src={vid.video} type="video/mp4" /> + Your browser does not support the video tag. + </video> + </li> + ))} + </ul> + </div> + ); +}; + +export default ManageVideos; diff --git a/frontend/src/pages/Results/DisplayResultsPage.js b/frontend/src/pages/Results/DisplayResultsPage.js new file mode 100644 index 0000000000000000000000000000000000000000..a4a9ef74b55e6181cadc22521e9822f0686f45ba --- /dev/null +++ b/frontend/src/pages/Results/DisplayResultsPage.js @@ -0,0 +1,47 @@ +// src/pages/Results/DisplayResultsPage.js +import React, { useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { getImageResults } from '../../services/processMisplacedManagerApi'; + +const DisplayResultsPage = () => { + const { imageId } = useParams(); + const [results, setResults] = useState(null); + + useEffect(() => { + const fetchResults = async () => { + const data = await getImageResults(imageId); + setResults(data); + }; + fetchResults(); + }, [imageId]); + + if (!results) { + return <div>Loading...</div>; + } + + return ( + <div className="container mt-5"> + <div className="row justify-content-center"> + <div className="col-md-8"> + <h1 className="text-center">Detection Results</h1> + <img src={results.output_image_url} alt="Detected Objects" className="img-fluid" /> + <h2 className="mt-4">Misplaced Objects</h2> + <ul className="list-group"> + {results.misplaced_objects.map(obj => ( + <li key={obj.class_name} className="list-group-item"> + {obj.class_name} is misplaced. Allowed locations: {obj.allowed_locations.join(", ")} + </li> + ))} + </ul> + <div className="text-center mt-4"> + <a href="/detection-options" className="btn btn-link"> + Try another detection + </a> + </div> + </div> + </div> + </div> + ); +}; + +export default DisplayResultsPage; diff --git a/frontend/src/services/auth.js b/frontend/src/services/auth.js index 91bac962cf7fec20dfcf34ac61699b24f62e2212..8f3f0ead6a9d6b876b319cbb66383cef717bd230 100644 --- a/frontend/src/services/auth.js +++ b/frontend/src/services/auth.js @@ -2,7 +2,7 @@ import api from './api'; export const login = async (credentials) => { - const response = await api.post('/auth/login/', credentials); + const response = await api.post('/api/auth/login/', credentials); if (response.data.access) { localStorage.setItem('token', response.data.access); } @@ -10,7 +10,7 @@ export const login = async (credentials) => { }; export const register = async (userData) => { - const response = await api.post('/auth/register/', userData); + const response = await api.post('/api/auth/register/', userData); return response.data; }; @@ -19,6 +19,6 @@ export const logout = () => { }; export const getCurrentUser = async () => { - const response = await api.get('/auth/user/'); + const response = await api.get('/api/auth/user/'); return response.data; }; diff --git a/frontend/src/services/itemApi.js b/frontend/src/services/itemApi.js index a093cc9e61bc33843b184ccd86763587838857d0..93d55760239dfa01a36f37da7d8e5e9433fc9546 100644 --- a/frontend/src/services/itemApi.js +++ b/frontend/src/services/itemApi.js @@ -3,7 +3,7 @@ import api, { getCsrfToken } from './api'; export const addItem = async (itemData) => { const csrfToken = getCsrfToken(); - const response = await api.post('/rules/admin_manage_item/', itemData, { + const response = await api.post('/api/rules/admin_manage_item/', itemData, { headers: { 'X-CSRFToken': csrfToken, } @@ -13,7 +13,7 @@ export const addItem = async (itemData) => { export const getItems = async () => { const csrfToken = getCsrfToken(); - const response = await api.get('/rules/admin_manage_item/', { + const response = await api.get('/api/rules/admin_manage_item/', { headers: { 'X-CSRFToken': csrfToken, } @@ -23,7 +23,7 @@ export const getItems = async () => { export const updateItem = async (itemId, itemData) => { const csrfToken = getCsrfToken(); - const response = await api.put(`/rules/admin_manage_item/${itemId}/`, itemData, { + const response = await api.put(`/api/rules/admin_manage_item/${itemId}/`, itemData, { headers: { 'X-CSRFToken': csrfToken, } @@ -33,7 +33,7 @@ export const updateItem = async (itemId, itemData) => { export const deleteItem = async (itemId) => { const csrfToken = getCsrfToken(); - const response = await api.delete(`/rules/admin_manage_item/${itemId}/`, { + const response = await api.delete(`/api/rules/admin_manage_item/${itemId}/`, { headers: { 'X-CSRFToken': csrfToken, } diff --git a/frontend/src/services/locationApi.js b/frontend/src/services/locationApi.js index bdf45b962f4e3b2ac08fe75b48e3ee31cfb8aa59..58e95a761df8cd2354d1680b9dbe9173c57062c9 100644 --- a/frontend/src/services/locationApi.js +++ b/frontend/src/services/locationApi.js @@ -2,7 +2,7 @@ import api, { getCsrfToken } from './api'; export const addLocation = async (locationData) => { const csrfToken = getCsrfToken(); - const response = await api.post('/rules/admin_manage_location/', locationData, { + const response = await api.post('/api/rules/admin_manage_location/', locationData, { headers: { 'X-CSRFToken': csrfToken, } @@ -12,7 +12,7 @@ export const addLocation = async (locationData) => { export const getLocations = async () => { const csrfToken = getCsrfToken(); - const response = await api.get('/rules/admin_manage_location/', { + const response = await api.get('/api/rules/admin_manage_location/', { headers: { 'X-CSRFToken': csrfToken, } @@ -22,7 +22,7 @@ export const getLocations = async () => { export const updateLocation = async (locationId, locationData) => { const csrfToken = getCsrfToken(); - const response = await api.put(`/rules/admin_manage_location/${locationId}/`, locationData, { + const response = await api.put(`/api/rules/admin_manage_location/${locationId}/`, locationData, { headers: { 'X-CSRFToken': csrfToken, } @@ -32,7 +32,7 @@ export const updateLocation = async (locationId, locationData) => { export const deleteLocation = async (locationId) => { const csrfToken = getCsrfToken(); - const response = await api.delete(`/rules/admin_manage_location/${locationId}/`, { + const response = await api.delete(`/api/rules/admin_manage_location/${locationId}/`, { headers: { 'X-CSRFToken': csrfToken, } diff --git a/frontend/src/services/processMisplacedManagerApi.js b/frontend/src/services/processMisplacedManagerApi.js new file mode 100644 index 0000000000000000000000000000000000000000..526b31cd41e5f296830a241217580b392cb293a2 --- /dev/null +++ b/frontend/src/services/processMisplacedManagerApi.js @@ -0,0 +1,116 @@ +// src/services/processMisplacedManagerApi.js +import api from './api'; + +// Function to get all images +export const getImages = async () => { + try { + const response = await api.get('/api/process_misplaced_manager/images/'); + return response.data; + } catch (error) { + console.error("Error fetching images:", error); + throw error; + } +}; + +// Function to get a single image by ID +export const getImage = async (id) => { + try { + const response = await api.get(`/api/process_misplaced_manager/images/${id}/`); + return response.data; + } catch (error) { + console.error(`Error fetching image with ID ${id}:`, error); + throw error; + } +}; + +// Function to create a new image +export const createImage = async (data) => { + try { + const response = await api.post('/api/process_misplaced_manager/images/', data); + return response.data; + } catch (error) { + console.error("Error creating image:", error); + throw error; + } +}; + +// Function to get all videos +export const getVideos = async () => { + try { + const response = await api.get('/api/process_misplaced_manager/videos/'); + return response.data; + } catch (error) { + console.error("Error fetching videos:", error); + throw error; + } +}; + +// Function to get a single video by ID +export const getVideo = async (id) => { + try { + const response = await api.get(`/api/process_misplaced_manager/videos/${id}/`); + return response.data; + } catch (error) { + console.error(`Error fetching video with ID ${id}:`, error); + throw error; + } +}; + +// Function to create a new video +export const createVideo = async (data) => { + try { + const response = await api.post('/api/process_misplaced_manager/videos/', data); + return response.data; + } catch (error) { + console.error("Error creating video:", error); + throw error; + } +}; + +// Function for normal detection +export const normalDetection = async (data) => { + try { + const response = await api.post('/api/process_misplaced_manager/normal-detection/', data, { + headers: { + 'Content-Type': 'multipart/form-data', + } + }); + return response.data; + } catch (error) { + console.error("Error in normal detection:", error); + throw error; + } +}; + +// Function for segmentation detection +export const segmentationDetection = async (data) => { + try { + const response = await api.post('/api/process_misplaced_manager/segmentation-detection/', data); + return response.data; + } catch (error) { + console.error("Error in segmentation detection:", error); + throw error; + } +}; + +// Function to upload a video +export const uploadVideo = async (data) => { + try { + const response = await api.post('/api/process_misplaced_manager/upload-video/', data); + return response.data; + } catch (error) { + console.error("Error uploading video:", error); + throw error; + } +}; + +// Function to check placement rules +export const checkPlacement = async (data) => { + try { + const response = await api.post('/api/placement_rules/check_placement/', data); + return response.data; + } catch (error) { + console.error("Error in checking placement:", error); + throw error; + } +}; diff --git a/frontend/src/services/ruleApi.js b/frontend/src/services/ruleApi.js index 3ce415c04c1539ad72382849da4d89798f3639ca..c3b2a5abba8b19134d8e29f1099bca340166dee9 100644 --- a/frontend/src/services/ruleApi.js +++ b/frontend/src/services/ruleApi.js @@ -2,7 +2,7 @@ import api, { getCsrfToken } from './api'; export const addRule = async (ruleData) => { const csrfToken = getCsrfToken(); - const response = await api.post('/rules/admin_manage_rule/', ruleData, { + const response = await api.post('/api/rules/admin_manage_rule/', ruleData, { headers: { 'X-CSRFToken': csrfToken, } @@ -12,7 +12,7 @@ export const addRule = async (ruleData) => { export const getRules = async () => { const csrfToken = getCsrfToken(); - const response = await api.get('/rules/admin_manage_rule/', { + const response = await api.get('/api/rules/admin_manage_rule/', { headers: { 'X-CSRFToken': csrfToken, } @@ -22,7 +22,7 @@ export const getRules = async () => { export const updateRule = async (ruleId, ruleData) => { const csrfToken = getCsrfToken(); - const response = await api.put(`/rules/admin_manage_rule/${ruleId}/`, ruleData, { + const response = await api.put(`/api/rules/admin_manage_rule/${ruleId}/`, ruleData, { headers: { 'X-CSRFToken': csrfToken, } @@ -32,7 +32,7 @@ export const updateRule = async (ruleId, ruleData) => { export const deleteRule = async (ruleId) => { const csrfToken = getCsrfToken(); - const response = await api.delete(`/rules/admin_manage_rule/${ruleId}/`, { + const response = await api.delete(`/api/rules/admin_manage_rule/${ruleId}/`, { headers: { 'X-CSRFToken': csrfToken, } diff --git a/frontend/src/services/userApi.js b/frontend/src/services/userApi.js index e0e91b2ec34cd9188f3c1509c0c9e702ec25dcd7..30fbb91f97c5849e8084a7d5ee7207aed078da6f 100644 --- a/frontend/src/services/userApi.js +++ b/frontend/src/services/userApi.js @@ -2,6 +2,6 @@ import api from './api'; export const getUsers = async () => { - const response = await api.get('/rules/users/'); + const response = await api.get('/api/rules/users/'); return response.data; };