From 65e6b44b786149434c2b5ff6a42a44270eb446ee Mon Sep 17 00:00:00 2001
From: a2-imeri <Alfret2.imeri@live.uwe.ac.uk>
Date: Mon, 20 May 2024 15:49:54 +0100
Subject: [PATCH] Web Config

---
 .gitignore                                    |   7 +-
 MisplaceAI/Dockerfile                         |   6 +-
 .../__pycache__/settings.cpython-310.pyc      | Bin 2821 -> 3114 bytes
 MisplaceAI/MisplaceAI/settings.py             |  13 ++-
 MisplaceAI/core/templates/core/navbar.html    |   3 +-
 MisplaceAI/docker-compose.yml                 |  22 ++++-
 MisplaceAI/docs/webAPI.md                     |  31 ++++++
 MisplaceAI/ngrok.yml                          |   6 ++
 MisplaceAI/process_misplaced_manager/forms.py |   7 +-
 .../process_misplaced_manager/models.py       |   7 +-
 .../detection_options.html                    |  20 ++++
 .../display_results.html                      |   4 +-
 .../normal_detection.html                     |  88 ++++++++++++++++++
 .../segmentation_detection.html               |  12 +++
 .../upload_image.html                         |   1 +
 .../upload_video.html                         |  12 +++
 MisplaceAI/process_misplaced_manager/urls.py  |  10 +-
 MisplaceAI/process_misplaced_manager/views.py |  66 ++++++++++++-
 README.md                                     |  12 ++-
 19 files changed, 302 insertions(+), 25 deletions(-)
 create mode 100644 MisplaceAI/docs/webAPI.md
 create mode 100644 MisplaceAI/ngrok.yml
 create mode 100644 MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html
 create mode 100644 MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html
 create mode 100644 MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html
 create mode 100644 MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html

diff --git a/.gitignore b/.gitignore
index 12a9eb2..5d4be96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,9 @@ __pycache__/
 migrations/
 
 /media/
-media/
\ No newline at end of file
+media/
+
+
+uploads/
+
+/uploads/
\ No newline at end of file
diff --git a/MisplaceAI/Dockerfile b/MisplaceAI/Dockerfile
index 75bc760..665e631 100644
--- a/MisplaceAI/Dockerfile
+++ b/MisplaceAI/Dockerfile
@@ -34,8 +34,8 @@ ENV PYTHONPATH=$PYTHONPATH:/app/models:/app/models/research:/app/models/research
 # Create the media directory
 RUN mkdir -p /app/media
 
-# Expose port 8000 for the Django app
-EXPOSE 8000
+# Expose port 8080 for the Django app
+EXPOSE 8080
 
 # Run the Django server
-CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
+CMD ["python", "manage.py", "runserver", "0.0.0.0:8080"]
diff --git a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc
index 35c5da5b4fd5d421b404460cb3cdf37b3220e3ae..9bb104919fd41b0c254cad8c4525ffa468b51048 100644
GIT binary patch
delta 569
zcmZn_TP4Al&&$ijz`(%J?&h7gOK>8e43i7vL>-s<6pnPpD86)t6wXDAQT*u)DO`&f
zqXbg8qXbiU(iu|NQ+U%EQur1zW-_Mm&tXYtj1o!_h!Rc_Oc6>EP7z5FO%Y2GPm!3z
zmdO|;k|LQRmC2YQog$MWo5`3WH-{-jGDSX<F-0;(A(JtkB}z0!F-j~&DM~zrJxU^l
zJxVgAUO7rCl|4m8njw`vMOB(1oheE>MJ-AumA7a?3S$a$j%<`{m13&w0=X3Rg^Ua2
z7c!)1NHU}_N;0HqN-{(#q$(^>Own4%n4&Gous|_IXCWg<E=nntZ-H{E(n3Z?hH!=y
z=3oXEhE&-sl`PfD`HT!87zq|FXJ7+KYU*z0Vw}#%e2Y<Q^FpT2ENnas3=CBslN~uU
zCLdxi0dtGkCfjh_a;s9zC@Cqh($~+)PfpCq$S*FjGBGeQ&`&JL)GsN`%S+8Ej$(%~
zxC%;>ax#<SON(-<nDq5u{{R2~|1U->O|{Juoc@fNQ5;37g{7&*CB?Ux(^E@sv1AqJ
z=SA`4r5ELA$3x7x#adjDlUWkQ2N49>mzS8EdW$Wwpdd9b<rY_JMRICENoIatag;z1
z#57l!&`O3PGX@5RBD2W_T>27a3=9k`j66IXi~`Io>@3WDj4Ui{Y#gkUw{!W3v2d|4
XaWFD5N-;_>3NQ*VvN1CKXZZyHsXdvc

delta 269
zcmZ1_(JIE5&&$ijz`(%p-P$cpM_?kK4AU)!i8?Oz=?qbP=?p0xix{K$(-~4Y7coW&
zq;N$Erf{b-q_C&(q%)-OE@I4NOyQfulFk?<l)@h+oFb4Sm?D%SoFbAUnj)4WK8G!n
zF-jywB1JNjF-0mxIz=XvF-3L`Q;I~2Tqa|RM2dVSV>(NeXo^CVSc+nlcnW)zL<)P9
zWQtOhv{Wj4in26ADtn5GG($R5lyr(}luQb9FoUMr<`Tx~jGOtGKeMoLGcYhzc}x!E
z(3q^xQNj)47O{fF?7?E!IMy<0%5FZ%>CecylA%bCfq|h&Z*n8IK4a44joiX4EG!&s
MlTUE_FmZ4J01g2@6#xJL

diff --git a/MisplaceAI/MisplaceAI/settings.py b/MisplaceAI/MisplaceAI/settings.py
index b6afaac..7696ee1 100644
--- a/MisplaceAI/MisplaceAI/settings.py
+++ b/MisplaceAI/MisplaceAI/settings.py
@@ -34,8 +34,9 @@ DEBUG = True
 
 
 
-ALLOWED_HOSTS = []
-
+# ALLOWED_HOSTS = []
+ 
+ALLOWED_HOSTS = ['*']  # This allows all hosts. Use with caution.
 
 
 # Application definition
@@ -153,3 +154,11 @@ STATICFILES_DIRS = [
 
 DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
 
+if DEBUG:
+    import requests
+    try:
+        ngrok_tunnel = requests.get('http://localhost:4040/api/tunnels').json()['tunnels'][0]['public_url']
+        ngrok_hostname = ngrok_tunnel.split("//")[-1].split(":")[0]
+        ALLOWED_HOSTS.append(ngrok_hostname)
+    except requests.exceptions.RequestException:
+        pass
\ No newline at end of file
diff --git a/MisplaceAI/core/templates/core/navbar.html b/MisplaceAI/core/templates/core/navbar.html
index 12bd440..ab74ace 100644
--- a/MisplaceAI/core/templates/core/navbar.html
+++ b/MisplaceAI/core/templates/core/navbar.html
@@ -11,7 +11,8 @@
             </li>
             <!-- Add link to the image upload page -->
             <li class="nav-item">
-                <a class="nav-link" href="{% url 'process_misplaced_manager:upload_image' %}">Upload Image</a>
+                <a class="nav-link" href="{% url 'process_misplaced_manager:detection_options' %}">Detect Misplaced
+                    Items</a>
             </li>
             {% if user.is_authenticated %}
             {% if user.is_staff %}
diff --git a/MisplaceAI/docker-compose.yml b/MisplaceAI/docker-compose.yml
index 14ed08a..ef1b375 100644
--- a/MisplaceAI/docker-compose.yml
+++ b/MisplaceAI/docker-compose.yml
@@ -1,17 +1,21 @@
-#docker-compose.yml
 version: '3.7'
 
 services:
   web:
     build: .
-    command: python manage.py runserver 0.0.0.0:8000
+    command: python manage.py runserver 0.0.0.0:8080
     volumes:
       - .:/app
       - ./media:/app/media
     ports:
-      - "8000:8000"
+      - "8080:8080"
     depends_on:
       - db
+    healthcheck:
+      test: [ "CMD-SHELL", "curl -f http://localhost:8080/ || exit 1" ]
+      interval: 30s
+      timeout: 10s
+      retries: 5
 
   db:
     image: mysql:5.7
@@ -23,5 +27,17 @@ services:
     volumes:
       - mysql_data:/var/lib/mysql
 
+  ngrok:
+    image: wernight/ngrok
+    volumes:
+      - ./ngrok.yml:/home/ngrok/.ngrok2/ngrok.yml
+    command: ngrok start --all
+    depends_on:
+      web:
+        condition: service_healthy
+    ports:
+      - "4040:4040" # Expose Ngrok's web interface
+      - "8080" # Forward the port Django is running on through Ngrok
+
 volumes:
   mysql_data:
diff --git a/MisplaceAI/docs/webAPI.md b/MisplaceAI/docs/webAPI.md
new file mode 100644
index 0000000..204e425
--- /dev/null
+++ b/MisplaceAI/docs/webAPI.md
@@ -0,0 +1,31 @@
+## Adding ngrok URL to Django ALLOWED_HOSTS
+
+### Overview
+When using ngrok to tunnel your local Django server, you may encounter an Invalid HTTP_HOST header error. This happens because Django’s `ALLOWED_HOSTS` setting does not include the ngrok URL. To resolve this issue, you need to add the ngrok URL to the `ALLOWED_HOSTS` setting in your Django project’s `settings.py` file.
+
+### Steps to Fix the Issue
+1. **Locate Your Django Settings File**
+   First, locate your Django settings file. This file is typically named `settings.py` and can be found in your project directory. For example, it might be located at:
+
+<your_project>/<your_project>/settings.py
+
+### 2. Edit the ALLOWED_HOSTS Setting
+   Open the `settings.py` file in your preferred text editor or IDE. Find the `ALLOWED_HOSTS` setting and add your ngrok URL to the list. If the `ALLOWED_HOSTS` list is currently empty or not defined, it will look something like this:
+
+
+```bash
+ALLOWED_HOSTS = [
+    'localhost',
+    '127.0.0.1',
+    'f382-164-11-203-57.ngrok-free.app',  # Add your ngrok URL here
+]
+```
+
+### 3. Alternative Development Setting (Use with Caution)
+For development purposes, you can allow all hosts by using a wildcard `*`. However, this is not recommended for production environments due to security risks:
+
+```bash
+
+ALLOWED_HOSTS = ['*']  # This allows all hosts. Use with caution.
+
+```
diff --git a/MisplaceAI/ngrok.yml b/MisplaceAI/ngrok.yml
new file mode 100644
index 0000000..6ae991e
--- /dev/null
+++ b/MisplaceAI/ngrok.yml
@@ -0,0 +1,6 @@
+version: "2"
+authtoken: 2gjASz2oymOKoIZiuEWvPHog4MB_4q4if5LATt17Vc1hbsvnC
+tunnels:
+  django:
+    proto: http
+    addr: web:8080 # Use the service name defined in docker-compose.yml
diff --git a/MisplaceAI/process_misplaced_manager/forms.py b/MisplaceAI/process_misplaced_manager/forms.py
index fa7edd5..47b2ce4 100644
--- a/MisplaceAI/process_misplaced_manager/forms.py
+++ b/MisplaceAI/process_misplaced_manager/forms.py
@@ -1,7 +1,12 @@
 from django import forms
-from .models import UploadedImage
+from .models import UploadedImage, UploadedVideo
 
 class ImageUploadForm(forms.ModelForm):
     class Meta:
         model = UploadedImage
         fields = ['image']
+
+class VideoUploadForm(forms.ModelForm):
+    class Meta:
+        model = UploadedVideo
+        fields = ['video']
diff --git a/MisplaceAI/process_misplaced_manager/models.py b/MisplaceAI/process_misplaced_manager/models.py
index 1d73a62..1a45378 100644
--- a/MisplaceAI/process_misplaced_manager/models.py
+++ b/MisplaceAI/process_misplaced_manager/models.py
@@ -1,8 +1,9 @@
 from django.db import models
 
 class UploadedImage(models.Model):
-    image = models.ImageField(upload_to='uploads/')
+    image = models.ImageField(upload_to='images/')
     uploaded_at = models.DateTimeField(auto_now_add=True)
 
-    def __str__(self):
-        return f"Image {self.id} uploaded at {self.uploaded_at}"
+class UploadedVideo(models.Model):
+    video = models.FileField(upload_to='videos/')
+    uploaded_at = models.DateTimeField(auto_now_add=True)
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
new file mode 100644
index 0000000..ff86bea
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/detection_options.html
@@ -0,0 +1,20 @@
+{% 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>
+{% 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
index 0ddd160..8a842a7 100644
--- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/display_results.html
@@ -6,8 +6,8 @@
 <h2>Misplaced Objects</h2>
 <ul>
     {% for obj in misplaced_objects %}
-    <li>{{ obj.class_name }} is misplaced. Allowed locations: {{ obj.allowed_locations }}</li>
+    <li>{{ obj.class_name }} is misplaced. Allowed locations: {{ obj.allowed_locations|join:", " }}</li>
     {% endfor %}
 </ul>
-<a href="{% url 'process_misplaced_manager:upload_image' %}">Upload another image</a>
+<a href="{% url 'process_misplaced_manager:detection_options' %}">Try another detection</a>
 {% 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
new file mode 100644
index 0000000..b388c1c
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/normal_detection.html
@@ -0,0 +1,88 @@
+{% extends 'core/base.html' %}
+
+{% block content %}
+<h1>Upload Image for Normal Detection</h1>
+<!-- Include WebcamJS library -->
+<script src="https://cdnjs.cloudflare.com/ajax/libs/webcamjs/1.0.26/webcam.min.js"></script>
+
+<form method="post" enctype="multipart/form-data" id="uploadForm">
+    {% csrf_token %}
+    <label for="id_image">Image:</label>
+    <input type="file" id="id_image" name="image" accept="image/*">
+    <button type="submit">Upload</button>
+</form>
+
+<!-- Button to open the camera interface -->
+<button id="openCameraBtn">Capture Image from Camera</button>
+
+<!-- Container for the camera feed -->
+<div id="camera" style="display: none;"></div>
+<!-- Container for the captured image -->
+<div id="capturedImage" style="display: none;">
+    <img id="imagePreview" src="" alt="Captured Image">
+    <input type="hidden" id="capturedImageData" name="capturedImageData">
+</div>
+
+<a href="{% url 'process_misplaced_manager:detection_options' %}">Back to Detection Options</a>
+
+<script>
+    document.getElementById('openCameraBtn').addEventListener('click', function () {
+        // Show the camera interface
+        document.getElementById('camera').style.display = 'block';
+
+        // Configure and attach the camera
+        Webcam.set({
+            width: 320,
+            height: 240,
+            image_format: 'jpeg',
+            jpeg_quality: 90
+        });
+        Webcam.attach('#camera');
+
+        // Capture the image
+        Webcam.snap(function (data_uri) {
+            // Show the captured image
+            document.getElementById('capturedImage').style.display = 'block';
+            document.getElementById('imagePreview').src = data_uri;
+
+            // Save the captured image data to the hidden input field
+            document.getElementById('capturedImageData').value = data_uri;
+
+            // Hide the camera interface
+            Webcam.reset();
+            document.getElementById('camera').style.display = 'none';
+        });
+    });
+
+    document.getElementById('uploadForm').addEventListener('submit', function (event) {
+        // If an image is captured from the camera, prevent the default form submission
+        const capturedImageData = document.getElementById('capturedImageData').value;
+        if (capturedImageData) {
+            event.preventDefault();
+
+            // Create a FormData object
+            const formData = new FormData();
+
+            // Append the CSRF token
+            formData.append('csrfmiddlewaretoken', '{{ csrf_token }}');
+
+            // Append the captured image data
+            formData.append('capturedImageData', capturedImageData);
+
+            // Send the form data via AJAX
+            fetch('{% url "process_misplaced_manager:normal_detection" %}', {
+                method: 'POST',
+                body: formData,
+            })
+                .then(response => response.json())
+                .then(data => {
+                    // Handle the response (e.g., redirect to the results page)
+                    window.location.href = data.redirect_url;
+                })
+                .catch(error => {
+                    console.error('Error:', error);
+                });
+        }
+    });
+</script>
+{% 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
new file mode 100644
index 0000000..892e93b
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/segmentation_detection.html
@@ -0,0 +1,12 @@
+{% 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
index 7de40c0..0451cc3 100644
--- a/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_image.html
@@ -7,4 +7,5 @@
     {{ 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
new file mode 100644
index 0000000..f5fe13c
--- /dev/null
+++ b/MisplaceAI/process_misplaced_manager/templates/process_misplaced_manager/upload_video.html
@@ -0,0 +1,12 @@
+{% extends 'core/base.html' %}
+
+{% block content %}
+<h1>Upload Video for Detection</h1>
+<form method="post" enctype="multipart/form-data">
+    {% csrf_token %}
+    <label for="id_video">Video:</label>
+    <input type="file" name="video" accept="video/*" capture="camcorder" 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/urls.py b/MisplaceAI/process_misplaced_manager/urls.py
index d8e6e97..1b521fd 100644
--- a/MisplaceAI/process_misplaced_manager/urls.py
+++ b/MisplaceAI/process_misplaced_manager/urls.py
@@ -1,9 +1,13 @@
 from django.urls import path
-from .views import upload_image, display_results
+from . import views
 
 app_name = 'process_misplaced_manager'
 
 urlpatterns = [
-    path('upload/', upload_image, name='upload_image'),
-    path('results/<int:image_id>/', display_results, name='display_results'),
+    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('results/<int:image_id>/', views.display_results, name='display_results'),
+    path('video-results/<int:video_id>/', views.display_video_results, name='display_video_results'),
 ]
diff --git a/MisplaceAI/process_misplaced_manager/views.py b/MisplaceAI/process_misplaced_manager/views.py
index 3563197..9634b56 100644
--- a/MisplaceAI/process_misplaced_manager/views.py
+++ b/MisplaceAI/process_misplaced_manager/views.py
@@ -1,11 +1,13 @@
 from django.shortcuts import render, redirect, get_object_or_404
-from .forms import ImageUploadForm
-from .models import UploadedImage
+from .forms import ImageUploadForm, VideoUploadForm
+from .models import UploadedImage, UploadedVideo
 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
+import base64
 
 import os
+from django.core.files.base import ContentFile
 
 # 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"
@@ -14,7 +16,38 @@ 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 upload_image(request):
+def detection_options(request):
+    return render(request, 'process_misplaced_manager/detection_options.html')
+
+
+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)
+
+            # Save the image to the UploadedImage model
+            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():
@@ -22,7 +55,17 @@ def upload_image(request):
             return redirect('process_misplaced_manager:display_results', image_id=new_image.id)
     else:
         form = ImageUploadForm()
-    return render(request, 'process_misplaced_manager/upload_image.html', {'form': form})
+    return render(request, 'process_misplaced_manager/segmentation_detection.html', {'form': form})
+
+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})
 
 def display_results(request, image_id):
     image = get_object_or_404(UploadedImage, id=image_id)
@@ -45,3 +88,18 @@ def display_results(request, image_id):
         'output_image_url': "/media/" + os.path.basename(output_image_path),
         'misplaced_objects': misplaced_objects
     })
+
+def display_video_results(request, video_id):
+    # Placeholder for video processing results view
+    video = get_object_or_404(UploadedVideo, id=video_id)
+    video_path = video.video.path
+
+    # Here you would run video analysis, currently, it's a placeholder
+    detected_objects = []  # Replace with actual video detection logic
+    misplaced_objects = []  # Replace with actual video detection logic
+
+    return render(request, 'process_misplaced_manager/display_video_results.html', {
+        'video': video,
+        'detected_objects': detected_objects,
+        'misplaced_objects': misplaced_objects
+    })
diff --git a/README.md b/README.md
index 0045961..3e01936 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,14 @@
 # Identification of Misplaced Items
 
+ngrok http 8080  
 
+
+
+
+docker-compose down
+docker-compose up -d 
+
+docker-compose up --build
 ## DATABASE
 
 ### Connect though terminal
@@ -74,9 +82,9 @@ docker-compose exec web python manage.py migrate
 
 create superuser:
 
-``` bash
+``` bashhttps://wrb.uwe.ac.uk/Scientia/Portal/Login.aspx?ReturnUrl=%2fScientia%2fPortal%2fMain.aspx
 
- docker-compose exec web python manage.py createsuperuser
+docker-compose exec web python manage.py createsuperuser
 ```
 
 
-- 
GitLab