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