From 3954da5fb3c7338708dfaaf588e6dcf84d30d3c3 Mon Sep 17 00:00:00 2001
From: h4-rahman <hamidur2.rahman@live.uwe.ac.uk>
Date: Mon, 29 Apr 2024 03:42:28 +0100
Subject: [PATCH] Note: Have to delete existing database volume so migrations
 can work.

---
 myproject/myapp/migrations/0001_initial.py    |  31 +++-
 myproject/myapp/migrations/0002_log.py        |  25 ---
 myproject/myapp/migrations/0003_profile.py    |  24 ---
 .../myapp/migrations/0004_usertokencount.py   |  24 ---
 .../__pycache__/__init__.cpython-310.pyc      | Bin 199 -> 0 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 215 -> 0 bytes
 myproject/myapp/models.py                     |   4 +
 myproject/myapp/templates/_base.html          |   1 +
 myproject/myapp/templates/index1.html         |  69 +++++--
 myproject/myapp/templates/user_page.html      | 171 +++++++++---------
 myproject/myapp/urls.py                       |   5 +-
 myproject/myapp/views.py                      |  78 +++++---
 12 files changed, 232 insertions(+), 200 deletions(-)
 delete mode 100644 myproject/myapp/migrations/0002_log.py
 delete mode 100644 myproject/myapp/migrations/0003_profile.py
 delete mode 100644 myproject/myapp/migrations/0004_usertokencount.py
 delete mode 100644 myproject/myapp/migrations/__pycache__/__init__.cpython-310.pyc
 delete mode 100644 myproject/myapp/migrations/__pycache__/__init__.cpython-311.pyc

diff --git a/myproject/myapp/migrations/0001_initial.py b/myproject/myapp/migrations/0001_initial.py
index 8bf97a1..0136612 100644
--- a/myproject/myapp/migrations/0001_initial.py
+++ b/myproject/myapp/migrations/0001_initial.py
@@ -1,5 +1,7 @@
-# Generated by Django 5.0.1 on 2024-03-04 13:30
+# Generated by Django 5.0.1 on 2024-04-29 02:34
 
+import django.db.models.deletion
+from django.conf import settings
 from django.db import migrations, models
 
 
@@ -8,6 +10,7 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
     ]
 
     operations = [
@@ -18,4 +21,30 @@ class Migration(migrations.Migration):
                 ('file', models.FileField(upload_to='audio', verbose_name='audio')),
             ],
         ),
+        migrations.CreateModel(
+            name='Log',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date', models.DateTimeField(auto_now_add=True)),
+                ('log', models.JSONField()),
+                ('feedback', models.BooleanField(null=True)),
+                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Profile',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('user_type', models.IntegerField(choices=[(0, 'Basic User'), (1, 'Admin'), (2, 'ML Engineer'), (3, 'Accountant')], default=0)),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='UserTokenCount',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('token_count', models.IntegerField(default=0)),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
     ]
diff --git a/myproject/myapp/migrations/0002_log.py b/myproject/myapp/migrations/0002_log.py
deleted file mode 100644
index 10c6dc9..0000000
--- a/myproject/myapp/migrations/0002_log.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 5.0.1 on 2024-03-11 06:11
-
-import django.db.models.deletion
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('myapp', '0001_initial'),
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Log',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('date', models.DateTimeField(auto_now_add=True)),
-                ('log', models.JSONField()),
-                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
-            ],
-        ),
-    ]
diff --git a/myproject/myapp/migrations/0003_profile.py b/myproject/myapp/migrations/0003_profile.py
deleted file mode 100644
index 23249ec..0000000
--- a/myproject/myapp/migrations/0003_profile.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 5.0.1 on 2024-03-25 00:43
-
-import django.db.models.deletion
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('myapp', '0002_log'),
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='Profile',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('user_type', models.IntegerField(choices=[(0, 'Basic User'), (1, 'Admin'), (2, 'ML Engineer'), (3, 'Accountant')], default=0)),
-                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
-            ],
-        ),
-    ]
diff --git a/myproject/myapp/migrations/0004_usertokencount.py b/myproject/myapp/migrations/0004_usertokencount.py
deleted file mode 100644
index 607bae5..0000000
--- a/myproject/myapp/migrations/0004_usertokencount.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 5.0.1 on 2024-03-25 17:46
-
-import django.db.models.deletion
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('myapp', '0003_profile'),
-        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-    ]
-
-    operations = [
-        migrations.CreateModel(
-            name='UserTokenCount',
-            fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('token_count', models.IntegerField(default=0)),
-                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
-            ],
-        ),
-    ]
diff --git a/myproject/myapp/migrations/__pycache__/__init__.cpython-310.pyc b/myproject/myapp/migrations/__pycache__/__init__.cpython-310.pyc
deleted file mode 100644
index 3584b84efdf6545757d52a23d02db0cf79131ec6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 199
zcmYk0Jqp4=5JoqWLWCT|LZ`5?5D`pTn-Iim8L~?<G5f>r2Fa1UkCm;S!pcph59WQ}
zOf@FU7A*4KKID|IN&h5qImGd4lwc)WCZ{`d)A^@Q2bGu3LyL;U;2gFJHRRG?gRxMZ
zi=$DttO+g>-3D?j${a+8x-qMO)Za)8P@{FGlXZv<tp!Dm!$3xR;G8rC&ewK)&Uea)
Np_lvV2S1BS*%x~dH7@`F

diff --git a/myproject/myapp/migrations/__pycache__/__init__.cpython-311.pyc b/myproject/myapp/migrations/__pycache__/__init__.cpython-311.pyc
deleted file mode 100644
index c6b2beed7acfc4d71d3d3ee2c366774701b430b0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 215
zcmXwzJqp4=5Jq<miU{I4EOZJR3$Zb_HX(>r7~Cb<=>9OfA~}gi5bxs+^Z<gLl^f8n
zc=Kkan7Iyz0~Yg~-(_1LE&ky@dH14Rm|z(j^UaM>C-(1l`KclIk~~zXl{gV$rO`kt
z{UKNf`F6ds+GTqMJBc)d6xUe_qDE8NNkDZxD<eQRj%+RWAsRXdT9t%BS>vH7lu@B5
frmp$)7ut%`Q7)+)Pq)wcQN%0ZoWIx~l*HK=Bdj_<

diff --git a/myproject/myapp/models.py b/myproject/myapp/models.py
index d29a03d..326123a 100644
--- a/myproject/myapp/models.py
+++ b/myproject/myapp/models.py
@@ -1,3 +1,4 @@
+# models.py
 from django.db import models
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import User, Group, Permission
@@ -40,6 +41,7 @@ class Action(Enum):
     GENERATE_FINANCIAL_STATEMENT = "{username} has generated a financial statement."
     CHANGE_MLA = "{username} has changed their maximum loss amount (MLA)."
     RUN_ALGORITHM = "{username} has run an algorithm."
+    FEEDBACK_SUBMITTED = "{username} has submitted feedback."
     INVALID_FILE = "{username} uploaded an invalid file that cannot be processed."
     INVALID_PASSWORD = "{username} has entered an invalid password."
     USER_DOES_NOT_EXIST = "The user {username} does not exist in the system."
@@ -53,3 +55,5 @@ class Log(models.Model):
     date = models.DateTimeField(auto_now_add=True)
     user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
     log = models.JSONField()
+    feedback = models.BooleanField(null=True)
+
diff --git a/myproject/myapp/templates/_base.html b/myproject/myapp/templates/_base.html
index 0a3beef..11c6ad5 100644
--- a/myproject/myapp/templates/_base.html
+++ b/myproject/myapp/templates/_base.html
@@ -94,6 +94,7 @@
     {% endblock navbar %}
     <div class="container mx-auto mt-6">
       {% block content %} {% endblock content %}
+      {% block scripts %} {% endblock scripts %}
       
     </div>
     <!-- <footer class="bg-white dark:bg-gray-900 fixed bottom-0 w-full"> -->
diff --git a/myproject/myapp/templates/index1.html b/myproject/myapp/templates/index1.html
index fda1160..fa2b7d2 100644
--- a/myproject/myapp/templates/index1.html
+++ b/myproject/myapp/templates/index1.html
@@ -51,19 +51,49 @@
     
     
     {% if predictions %}
-    <div id="predictions" class="py-8 px-4 mx-auto max-w-screen-xl">
-      <h3 class="text-2xl font-bold mb-4">{{ file_name }} Predictions:</h3>
-      <ul id="predictionList" class="space-y-2">
-        {% for prediction in predictions %}
-          <li class="bg-gray-100 dark:bg-gray-800 px-4 py-2 rounded-md" style="white-space: pre-line;">{{ prediction|safe }}</li>
-        {% endfor %}
-      </ul>
-    </div>
-    {% endif %}
+<div id="predictions" class="py-8 px-4 mx-auto max-w-screen-xl">
+  <h3 class="text-2xl font-bold mb-4">{{ file_name }} Predictions:</h3>
+  <form method="post" action="{% url 'submit_feedback' %}">
+    {% csrf_token %}
+    <input type="hidden" name="file_name" value="{{ file_name }}">
+    <ul id="predictionList" class="space-y-2">
+      {% for prediction in predictions %}
+      <li class="bg-gray-100 dark:bg-gray-800 px-4 py-2 rounded-md" style="white-space: pre-line;">
+        {{ prediction|safe }}
+        <input type="hidden" name="prediction" value="{{ prediction }}">
+        <div class="mt-2">
+          <label>
+            <input type="radio" name="feedback" value="true" required>
+            Like
+          </label>
+          <label class="ml-4">
+            <input type="radio" name="feedback" value="false">
+            Dislike
+          </label>
+        </div>
+      </li>
+      {% endfor %}
+    </ul>
+    <button type="submit" class="mt-4 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
+      Submit Feedback
+    </button>
+  </form>
+</div>
+{% endif %}
   </section>
+{% endblock content %}
 
+{% block scripts %}
 
   <script>
+function submitFeedback(prediction, liked) {
+      var xhr = new XMLHttpRequest();
+      xhr.open('POST', '/submit_feedback', true);
+      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+      xhr.send('prediction=' + encodeURIComponent(prediction) + '&liked=' + liked);
+    }
+
+
 
 function loadAudioFile(event) {
     var file = event.target.files[0];
@@ -177,10 +207,25 @@ function loadAudioFile(event) {
         document.getElementById('uploadForm').addEventListener('reset', function() {
             clearFormAndPredictions();
         });
-    }
 
+        var likeBtns = document.querySelectorAll('.like-btn');
+      var dislikeBtns = document.querySelectorAll('.dislike-btn');
 
-  </script>
+      likeBtns.forEach(function(btn) {
+        btn.addEventListener('click', function() {
+          var prediction = this.dataset.prediction;
+          submitFeedback(prediction, true);
+        });
+      });
+
+      dislikeBtns.forEach(function(btn) {
+        btn.addEventListener('click', function() {
+          var prediction = this.dataset.prediction;
+          submitFeedback(prediction, false);
+        });
+      });
+    };
 
+  </script>
 
-{% endblock content %}
+{% endblock scripts %}
diff --git a/myproject/myapp/templates/user_page.html b/myproject/myapp/templates/user_page.html
index 84c4288..1e221ed 100644
--- a/myproject/myapp/templates/user_page.html
+++ b/myproject/myapp/templates/user_page.html
@@ -179,6 +179,17 @@
         </div>
       </div>
     </div>
+
+  <!-- Modal -->
+  <div id="myModal" class="hidden fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
+    <!-- Modal content with scrolling enabled -->
+    <div class="modal-body bg-white dark:bg-gray-800 rounded-lg p-4 md:p-6 w-full max-w-2xl">
+      <h3 class="text-2xl font-bold mb-4">Predictions:</h3>
+      <ul id="predictionList" class="space-y-2"></ul>
+      <button onclick="closeModal()" class="mt-4 px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600">Close</button>
+    </div>
+  </div>
+
     <div
       class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"
     >
@@ -225,97 +236,57 @@
       </table>
     </div>
 
-<!-- Modal -->
-<div id="myModal" class="hidden fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
-  <!-- Modal content with scrolling enabled -->
-  <div class="modal-body bg-white dark:bg-gray-800 rounded-lg p-4 md:p-6 w-full max-w-2xl">
-    <h3 class="text-2xl font-bold mb-4">Predictions:</h3>
-    <ul id="predictionList" class="space-y-2"></ul>
-    <button onclick="closeModal()" class="mt-4 px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600">Close</button>
-  </div>
-</div>
 
-<!-- Modal -->
-<div id="myModal" class="hidden fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
-  <!-- Modal content with scrolling enabled -->
-  <div class="modal-body bg-white dark:bg-gray-800 rounded-lg p-4 md:p-6 w-full max-w-2xl">
-    <h3 class="text-2xl font-bold mb-4">Predictions:</h3>
-    <ul id="predictionList" class="space-y-2"></ul>
-    <button onclick="closeModal()" class="mt-4 px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600">Close</button>
-  </div>
-</div>
 
-<script>
-function showModal(predictions) {
-  var predictionList = document.getElementById('predictionList');
-  predictionList.innerHTML = '';
-  predictions.split('\n').forEach(function(prediction) {
-    var li = document.createElement('li');
-    li.innerHTML = prediction;
-    li.className = 'bg-gray-100 dark:bg-gray-700 px-4 py-2 rounded-md';
-    predictionList.appendChild(li);
-  });
-  document.getElementById('myModal').classList.remove('hidden');
-}
+{% if 1 %} {% comment %} REPLACE WITH LOGIC TO CHECK PROPER USER {% endcomment %}
+{% if user_profile.user_type == 2 or user.is_superuser %}
+<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
+  <h3 class="mb-4 text-xl font-semibold dark:text-white">Application Logs</h3>
+  <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
+    <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
+      <tr>
+        <th scope="col" class="px-6 py-3">Date</th>
+        <th scope="col" class="px-6 py-3">Action</th>
+        <th scope="col" class="px-6 py-3">User ID</th>
+        <th scope="col" class="px-6 py-3">Status</th>
+        <th scope="col" class="px-6 py-3">Feedback</th>
+      </tr>
+    </thead>
+    <tbody>
+      {% for entry in admin_data %}
+      <tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700">
+        <td scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
+          {{entry.date}}
+        </td>
+        <td class="px-6 py-4">
+          <a href="#" class="font-medium text-blue-600 dark:text-blue-500 hover:underline">{{entry.action}}</a>
+          {% if entry.description %}
+            <button type="button" class="ml-4 px-2 py-1 bg-blue-500 text-white rounded-md hover:bg-blue-600" onclick="showModal('{{entry.description|join:'\n'}}')">
+            Show Results
+            </button>
+          {% endif %}
+        </td>
+        <td class="px-6 py-4">{{entry.user}}</td>
+        <td class="px-6 py-4">{{entry.status}}</td>
+        <td class="px-6 py-4">
+          {% if entry.feedback is not None %}
+            {% if entry.feedback %}
+              <span class="text-green-500">Liked</span>
+            {% else %}
+              <span class="text-red-500">Disliked</span>
+            {% endif %}
+          {% else %}
+            N/A
+          {% endif %}
+        </td>
+      </tr>
+      {% endfor %}
+    </tbody>
+  </table>
+</div>
+{% endif %}
 
-function closeModal() {
-  document.getElementById('myModal').classList.add('hidden');
-}
-</script>
 
-    {% if 1 %} {% comment %} REPLACE WITH LOGIC TO CHECK PROPER USER
-    {%endcomment %}
-    {% if user_profile.user_type == 2 or user.is_superuser%}
-    <div
-      class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"
-    >
-      <h3 class="mb-4 text-xl font-semibold dark:text-white">
-        Application Logs
-      </h3>
-      <table
-        class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400"
-      >
-        <thead
-          class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"
-        >
-          <tr>
-            <th scope="col" class="px-6 py-3">Date</th>
-            <th scope="col" class="px-6 py-3">Action</th>
-            <th scope="col" class="px-6 py-3">User ID</th>
-            <th scope="col" class="px-6 py-3">status</th>
-          </tr>
-        </thead>
-        <tbody>
-          {% for entry in admin_data %}
-          <tr
-            class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700"
-          >
-            <td
-              scope="row"
-              class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
-            >
-{{entry.date}}          </td>
-            <td class="px-6 py-4">
-              <a
-                href="#"
-                class="font-medium text-blue-600 dark:text-blue-500 hover:underline"
-                >{{entry.action}}</a
-              >
-              {% if entry.description %}
-              <button type="button" class="ml-4 px-2 py-1 bg-blue-500 text-white rounded-md hover:bg-blue-600" onclick="showModal('{{entry.description|join:'\n'}}')">
-                Show Results
-              </button>
-              {% endif %}
-            </td>
-            <td class="px-6 py-4">{{entry.user}}</td>
-            <td class="px-6 py-4">
-            {{entry.status}}</td>
-          </tr>
-          {% endfor %}
-        </tbody>
-      </table>
-    </div>
-    {% endif %}
     {% if user.is_superuser  or user_profile.user_type == 1 %}
   <div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
     <h3 class="mb-4 text-xl font-semibold dark:text-white">
@@ -371,3 +342,29 @@ function closeModal() {
   </div>
 </div>
 {% endblock content %}
+
+{% block scripts %}
+<script>
+  function showModal(predictions, action) {
+    var predictionList = document.getElementById('predictionList');
+    predictionList.innerHTML = '';
+  
+    // Split the predictions string into an array
+    var predictionsArray = predictions.split(', ');
+  
+    // Iterate over the predictionsArray and create list items
+    predictionsArray.forEach(function(prediction) {
+      var li = document.createElement('li');
+      li.innerHTML = prediction;
+      li.className = 'bg-gray-100 dark:bg-gray-700 px-4 py-2 rounded-md';
+      predictionList.appendChild(li);
+    });
+  
+    document.getElementById('myModal').classList.remove('hidden');
+  }
+  
+  function closeModal() {
+    document.getElementById('myModal').classList.add('hidden');
+  }
+</script>
+{% endblock scripts %}
diff --git a/myproject/myapp/urls.py b/myproject/myapp/urls.py
index e4a7f40..2126860 100644
--- a/myproject/myapp/urls.py
+++ b/myproject/myapp/urls.py
@@ -1,5 +1,7 @@
 from django.urls import path
-from .views import InstrumentDetectionView, ModelPerformanceView, index, log_fileupload, users, maintenance, handler404, handler500, terms_conditions, privacy_policy, handling_music_file, pricing, generate_pdf, admin_table, change_user_type
+from .views import InstrumentDetectionView, ModelPerformanceView, index, log_fileupload, users, maintenance, \
+handler404, handler500, terms_conditions, privacy_policy, handling_music_file, pricing, generate_pdf, admin_table,\
+      change_user_type, submit_feedback
 from .payments import create_payment, execute_payment, payment_cancelled, payment_success
 from django.contrib.auth import views as auth_views
 
@@ -19,6 +21,7 @@ urlpatterns = [
     path('pricay_policy/', privacy_policy, name='privacy_policy'),
     path('pricing/', pricing, name='pricing'),
     path('uploading_file/', handling_music_file, name='uploading_file'),
+    path('submit_feedback/', submit_feedback, name='submit_feedback'),
     path('generate_pdf/', generate_pdf, name='generate_pdf'),
     path('pricing/', pricing, name='pricing'),
     path('generate_pdf/', generate_pdf, name='generate_pdf'),
diff --git a/myproject/myapp/views.py b/myproject/myapp/views.py
index 51017a7..d7354e9 100644
--- a/myproject/myapp/views.py
+++ b/myproject/myapp/views.py
@@ -38,18 +38,19 @@ import re
 
 logger = logging.getLogger(__name__)
 
-def get_log_data(user, action, status='success', file=None, description=None):
+def get_log_data(user, action, status='success', file=None, description=None, feedback=None):
     log_data = {
         'username': user.username,
         'action': action.value.format(username=user.username),
         'status': status,
         'file': file,
         'description': description,
+        'feedback': feedback,  # Add the feedback field
     }
     return log_data
 
 def create_log(user, log_data):
-    Log.objects.create(user=user, log=log_data)
+    Log.objects.create(user=user, log=log_data, feedback=log_data.get('feedback'))
 
 def handling_music_file(request):
     if request.method == 'POST':
@@ -80,35 +81,58 @@ def log_fileupload(request):
 
     return JsonResponse({'error': 'Invalid request'}, status=400)
 
+def submit_feedback(request):
+    if request.method == 'POST' and request.user.is_authenticated:
+        prediction = request.POST.get('prediction')
+        liked = request.POST.get('feedback') == 'true'
+        file_name = request.POST.get('file_name')  # Get the filename from the form data
+        
+        # Create log data using the get_log_data function
+        log_data = get_log_data(
+            user=request.user,
+            action=Action.FEEDBACK_SUBMITTED,
+            status='success',
+            file=file_name,  # Use the filename obtained from the form
+            description=prediction,
+            feedback=liked
+        )
+        
+        # Create the Log entry using the create_log function
+        create_log(request.user, log_data)
+        
+        return redirect('index')
+    
+    return redirect('index')
+
 def admin_table(request):
     # Execute the query and fetch all rows
-    query = """SELECT date, log, user_id FROM myapp_log ORDER BY date DESC"""
+    query = """SELECT date, log, user_id, feedback FROM myapp_log ORDER BY date DESC"""
     with connection.cursor() as cursor:
         cursor.execute(query)
         rows = cursor.fetchall()
+
     # Create a list of dictionaries from the query results
     data = []
     for row in rows:
         # Parse the JSON string into a dictionary
         log = json.loads(row[1])
-
         # Get the user object based on the user_id
         user_id = row[2]
-
-        # Create a dictionary with the date, user, and JSON fields
+        # Get the feedback value
+        feedback = row[3]
+        # Create a dictionary with the date, user, JSON fields, and feedback
         date = row[0].strftime('%Y-%m-%d %H:%M:%S')
         entry = {'date': date, 'user': user_id, 'file': log['file'], 'action': log['action'], 'status': log['status'],
-                 'description': log['description']}
+                 'description': log['description'], 'feedback': feedback}
         data.append(entry)
 
     # Return the data as a JSON response
     return JsonResponse({'data': data}, safe=False)
 
-
 def user_table(request):
-    user_id= request.user.id
+    user_id = request.user.id
     # Only display user logs code below
-    query = """SELECT date, log, user_id FROM myapp_log WHERE user_id = {} ORDER BY date DESC""".format(user_id)
+    query = """SELECT date, log, user_id, feedback FROM myapp_log WHERE user_id = {} ORDER BY date DESC""".format(user_id)
     with connection.cursor() as cursor:
         cursor.execute(query)
         rows = cursor.fetchall()
@@ -118,14 +142,14 @@ def user_table(request):
     for row in rows:
         # Parse the JSON string into a dictionary
         log = json.loads(row[1])
-
         # Get the user object based on the user_id
         user_id = row[2]
-
-        # Create a dictionary with the date, user, and JSON fields
+        # Get the feedback value
+        feedback = row[3]
+        # Create a dictionary with the date, user, JSON fields, and feedback
         date = row[0].strftime('%Y-%m-%d %H:%M:%S')
         entry = {'date': date, 'user': user_id, 'file': log['file'], 'action': log['action'], 'status': log['status'],
-                 'description': log['description']}
+                 'description': log['description'], 'feedback': feedback}
         data.append(entry)
 
     # Return the data as a JSON response
@@ -133,36 +157,35 @@ def user_table(request):
 
 def index(request):
     # Initialize default context
-    context = {'form': InstrumentDetectionForm(),
-               'predictions': [],
-               'file_name': None
-               }
+    context = {'form': InstrumentDetectionForm(), 'predictions': [], 'file_name': None}
 
     # Handle authenticated users
     if request.user.is_authenticated:
         token_count = UserTokenCount.objects.get(user=request.user).token_count
         context['token_count'] = token_count
+
         if request.method == 'POST':
             form = InstrumentDetectionForm(request.POST, request.FILES)
             if form.is_valid() and 'audio_file' in request.FILES:
                 uploaded_file = request.FILES['audio_file']
                 context['file_name'] = uploaded_file.name
+
                 # Make a request to the InstrumentDetectionView to get the predictions
                 view = InstrumentDetectionView().as_view()
                 response = view(request)
+
                 # Ensure there's a response and it contains predictions before updating context
                 if response and hasattr(response, 'data') and 'predictions' in response.data:
                     context['predictions'] = response.data['predictions']
+
                     if request.user.is_authenticated:
-                        log_data = get_log_data(request.user, Action.RUN_ALGORITHM, 'success', file=uploaded_file.name,\
-                                                description=response.data["predictions"])
+                        feedback = request.POST.get('feedback')  # Get the user's feedback from the form
+                        predictions_string = ', '.join(response.data['predictions'])
+                        log_data = get_log_data(request.user, Action.RUN_ALGORITHM, 'success', file=uploaded_file.name, 
+                                                description=predictions_string, feedback=feedback)
                         create_log(request.user, log_data)
             else:
                 context['form'] = form
-        # For GET requests or if form is not valid, render the page with the default or updated context
-        return render(request, 'index1.html', context)
-
-    # Handle unauthenticated users
     else:
         if request.method == 'POST':
             # Assuming you want to do something specific with the file if it's uploaded
@@ -170,8 +193,11 @@ def index(request):
             if uploaded_file:
                 # Process the uploaded file as needed
                 pass
-            # For now, just render the main page again, potentially after handling the uploaded file
-        # For GET requests or if POST doesn't involve a file, just show the main page
+
+    # For GET requests or if form is not valid, render the page with the default or updated context
+    if request.user.is_authenticated:
+        return render(request, 'index1.html', context)
+    else:
         return render(request, 'index2.html')
 
 
-- 
GitLab