From 9739dc35f39381787d4988c6f8209246fbf0f40e Mon Sep 17 00:00:00 2001
From: a272-jones <Aaron8.jones@live.uwe.ac.uk>
Date: Sat, 3 May 2025 17:05:10 +0100
Subject: [PATCH] Glued ML and DESD side together.

---
 ActualProjectCode/DjangoProject/Dockerfile    |   5 +++-
 ActualProjectCode/DjangoProject/core/forms.py |   4 +--
 .../DjangoProject/core/models.py              |   7 +++--
 ActualProjectCode/DjangoProject/core/views.py |  24 ++++++++++++++-
 ActualProjectCode/DjangoProject/main.py       |  28 ++++++++++--------
 .../DjangoProject/requirements.txt            | Bin 310 -> 834 bytes
 .../DjangoProject/server/urls.py              |   1 -
 .../DjangoProject/templates/profile.html      |   2 +-
 8 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/ActualProjectCode/DjangoProject/Dockerfile b/ActualProjectCode/DjangoProject/Dockerfile
index 2e49ee69..932f82ff 100644
--- a/ActualProjectCode/DjangoProject/Dockerfile
+++ b/ActualProjectCode/DjangoProject/Dockerfile
@@ -9,7 +9,10 @@ COPY requirements.txt .
 
 RUN apk add --update --upgrade --no-cache postgresql-client && \
     apk add --update --upgrade --no-cache --virtual .tmp \
-        build-base postgresql-dev
+        build-base postgresql-dev && \
+    apk add --update --upgrade --no-cache libgomp && \
+    apk add --update --upgrade --no-cache libstdc++
+
 
 RUN pip install --no-cache-dir -r requirements.txt && apk del .tmp
 
diff --git a/ActualProjectCode/DjangoProject/core/forms.py b/ActualProjectCode/DjangoProject/core/forms.py
index 156c5b3a..4273e281 100644
--- a/ActualProjectCode/DjangoProject/core/forms.py
+++ b/ActualProjectCode/DjangoProject/core/forms.py
@@ -11,13 +11,13 @@ class UserUploadForm(forms.ModelForm):
     username = forms.CharField(max_length=100, widget=forms.HiddenInput)
     class Meta:
         model = models.Record
-        fields = ['username','uploadedFile','chosenML']
+        fields = ['username','uploadedFile', 'targetColumn', 'chosenML']
 
 class UploadModelForm(forms.ModelForm):
     username = forms.CharField(max_length=100, widget=forms.HiddenInput)
     class Meta:
         model = models.mlModel
-        fields = ['username','modelName']
+        fields = ['username', 'modelName']
 
 class GenerateBillingsForm(forms.ModelForm):
     username = forms.CharField(max_length=100, widget=forms.HiddenInput)
diff --git a/ActualProjectCode/DjangoProject/core/models.py b/ActualProjectCode/DjangoProject/core/models.py
index 1a2acf41..0927f75b 100644
--- a/ActualProjectCode/DjangoProject/core/models.py
+++ b/ActualProjectCode/DjangoProject/core/models.py
@@ -1,4 +1,5 @@
 from django.contrib.auth.models import User
+from django.contrib import admin
 from django.db import models
 
 class Profile(models.Model):
@@ -26,10 +27,12 @@ class Billing(models.Model):
         return f"{self.companyName} Billing - ID: {self.billingID}"
 
 class Record(models.Model):
+    recordID = models.AutoField(primary_key=True)
     username = models.CharField(max_length=100, default="default")
     uploadedFile = models.FileField(upload_to='./records/', null=True, blank=True)
     chosenML = models.CharField(max_length=100, default="baseML")
-    responseByML = models.CharField(max_length=100, default="PLACEHOLDER RESPONSE") # change to actual response by ML
+    targetColumn = models.CharField(max_length=100, default="DEFAULT") # temporary fix for choosing CSV column.
+    responseByML = models.CharField(max_length=10000, default="PLACEHOLDER RESPONSE") # change to actual response by ML#
 
     def __str__(self):
-        return f"{self.chosenML} Response to {self.username}"
\ No newline at end of file
+        return f"{self.chosenML} Response to {self.username}. ID = {self.recordID}"
diff --git a/ActualProjectCode/DjangoProject/core/views.py b/ActualProjectCode/DjangoProject/core/views.py
index 7ac33eb5..514d6197 100644
--- a/ActualProjectCode/DjangoProject/core/views.py
+++ b/ActualProjectCode/DjangoProject/core/views.py
@@ -4,7 +4,8 @@ from django.contrib.auth.models import User
 from django.shortcuts import render, redirect
 from django.contrib.auth.decorators import login_required
 from django.http import HttpResponse
-import os
+import subprocess
+import sys
 from .models import Profile, mlModel, Billing, Record
 from .forms import UserLoginForm, UserUploadForm, UploadModelForm, GenerateBillingsForm, UpdateUser
 
@@ -54,6 +55,27 @@ def userUpload(request):
         form = UserUploadForm(request.POST or None, request.FILES or None)
         if form.is_valid():
             form.save()
+
+        # CONNECTING WITH ML MODELS.
+        uName = form.cleaned_data['username']
+        chosenML = form.cleaned_data['chosenML']
+        tColumn = form.cleaned_data['targetColumn']
+        tempID = Record.objects.latest('recordID')
+        filePath = tempID.uploadedFile # janky way of doing it, but it works??? fix in the future.
+
+        result = subprocess.run(
+            [sys.executable, 'main.py', f'{chosenML}', f'{tColumn}', f'{filePath}'],
+            capture_output=True,
+            text=True
+        )
+        output = result.stdout
+
+        # Appending DB
+
+        response = Record.objects.get(recordID=tempID.recordID)
+        response.responseByML = output
+        response.save()
+
         return redirect('profile')
     context = {'form': form}
     return render(request, 'modelForms/userUpload.html', context)
diff --git a/ActualProjectCode/DjangoProject/main.py b/ActualProjectCode/DjangoProject/main.py
index e1d3ad6e..9ad53436 100644
--- a/ActualProjectCode/DjangoProject/main.py
+++ b/ActualProjectCode/DjangoProject/main.py
@@ -1,13 +1,15 @@
-# point of this file is do be the driver of a selected ML model / IPYNB file in modelName directory
-
-# This file is planned to be called when a end-user uploads a file.
-
-#
-
-print("Hello!")
-
-# receive form from main website
-
-# contact model in directory and get response from it - store in variable
-
-# return response by ml back into db.
\ No newline at end of file
+import sys
+import subprocess
+
+result = subprocess.run(
+    [sys.executable, f'./mlModels/modelName/{sys.argv[1]}.py', sys.argv[2], sys.argv[3]],
+    capture_output=True,
+    text=True
+)
+
+# Error Handling
+if result.returncode != 0:
+    print("Script Failed")
+    print(result.stderr)
+else:
+    print(result.stdout)
\ No newline at end of file
diff --git a/ActualProjectCode/DjangoProject/requirements.txt b/ActualProjectCode/DjangoProject/requirements.txt
index 734c063ee9348a185bb8e0a7cdd7cba2ab6546c7..49c06b391ca58d0d3525cc8bb877f1ce64d6d681 100644
GIT binary patch
literal 834
zcmezWFOi{`A)O(Up@<=sA&tS7!Ir_8L65<LL65<ZftP`c!G$4<A(0`EA)O%~ENcpu
z(PJ<N%N8>fGUPB6FeEY*F%&bTf>jtW=rMp)8G}`nFjO(5FeEaRFeHLyjTj6VjKJ~`
z^9vY?87di)8S)tl7}6P{8Il=d!RkP+Fk;YSfS6Lukj#+Dkj;?EP{N?gki(D)wlNQ^
z(vU%q!3^vwkb6OH$phP143-6%0m3kIKsu8c@)?R4Ai6=WH3a+F2<+Zmuv-flav1U%
zN*Hn&G8vM<=78K|$N*6dvL~GZqy}UfvPmWkdJGVA@)$}Pav2I3D#5xzE&yRuupJQJ
zz~n&gHw1?WL}wO5K0^|c%^-P%xg`u4;J8X;NMR^o$Y;oB$YDqZyA&38ps+9i+mj3q
zSx{&dfn5P{J;)u9um^>D9zzL3K0_%(5!|gH`#`>hxF(Gup8=!>qzYsgBve7}F=a4k
z&|`qu1d5q*hD?THuzSiFQW+pNg3JP`wE(*Z6gSBX*$j!`6bDLEAU8u&1H>Fqn1ED)
zQd1^4)qzw%TmwrBAT^*+0J%#S9MdHXsSKqIB@CGiIbeT+d}s-Fn;tlfiWy3v?u6*A
of~tb0M2Jrd!1_V)UJjNwWB|DyWELc}iWxE)Dxfl;+yU`D06j)|3IG5A

delta 7
OcmX@awvB0n86yA-i~?u?

diff --git a/ActualProjectCode/DjangoProject/server/urls.py b/ActualProjectCode/DjangoProject/server/urls.py
index f79a9058..71cffa88 100644
--- a/ActualProjectCode/DjangoProject/server/urls.py
+++ b/ActualProjectCode/DjangoProject/server/urls.py
@@ -45,5 +45,4 @@ urlpatterns = [
     path('modelForms/interactionView/', views.interactionView, name="interactionView"),
     path('modelForms/billingsView/', views.billingsView, name="billingsView"),
     path('modelForms/deleteBillings/<str:billingID>', views.deleteBillings, name="deleteBillings"),
-
 ]
\ No newline at end of file
diff --git a/ActualProjectCode/DjangoProject/templates/profile.html b/ActualProjectCode/DjangoProject/templates/profile.html
index f30bd27e..4c2a182f 100644
--- a/ActualProjectCode/DjangoProject/templates/profile.html
+++ b/ActualProjectCode/DjangoProject/templates/profile.html
@@ -194,7 +194,7 @@
                 <p>Manage your tasks and profile.</p>
                 <hr>
                 <h2>Upload Files to ML</h2>
-                <h1><a href="{% url 'userUpload' %}">Upload Thing</a></h1>
+                <h1><a href="{% url 'userUpload' %}">Upload CSV</a></h1>
 
             {% endif %}
 
-- 
GitLab