diff --git a/PlanktonDetector/Community/views.py b/PlanktonDetector/Community/views.py index 50fb78a..99ce625 100644 --- a/PlanktonDetector/Community/views.py +++ b/PlanktonDetector/Community/views.py @@ -12,3 +12,4 @@ class ListPosts(ListView): class PostDetails(DetailView): model = Post + template_name = "post_details.html" diff --git a/PlanktonDetector/DetectionApp/forms.py b/PlanktonDetector/DetectionApp/forms.py index c2c108b..d53a209 100644 --- a/PlanktonDetector/DetectionApp/forms.py +++ b/PlanktonDetector/DetectionApp/forms.py @@ -1,11 +1,33 @@ from django import forms +from pyparsing import removeQuotes from .models import UploadImage +from django.forms import ClearableFileInput, HiddenInput +from django.contrib.auth.models import User -class DetectForm(forms.ModelForm): - class Meta: - model = UploadImage - fields = [ - "image", - ] - labels = {"image": ""} +class MultipleFileInput(forms.ClearableFileInput): + allow_multiple_selected = True + + +class MultipleFileField(forms.FileField): + def __init__(self, *args, **kwargs): + kwargs.setdefault("widget", MultipleFileInput()) + super().__init__(*args, **kwargs) + + def clean(self, data, initial=None): + single_file_clean = super().clean + if isinstance(data, (list, tuple)): + result = [single_file_clean(d, initial) for d in data] + else: + result = single_file_clean(data, initial) + return result + + +class DetectForm(forms.Form): + image = MultipleFileField() + predicted_image_url = forms.CharField( + max_length=500, widget=HiddenInput(), required=False + ) + owner = forms.ModelChoiceField( + queryset=User.objects.all(), widget=HiddenInput(), required=False + ) diff --git a/PlanktonDetector/DetectionApp/views.py b/PlanktonDetector/DetectionApp/views.py index c8cd5ce..ef076f7 100644 --- a/PlanktonDetector/DetectionApp/views.py +++ b/PlanktonDetector/DetectionApp/views.py @@ -22,27 +22,43 @@ class DetectView(View): @method_decorator(login_required) def post(self, request, *args, **kwargs): form = self.form_class(request.POST, request.FILES) + files = request.FILES.getlist("image") + predictions = [] if form.is_valid(): - image = form.save(commit=False) - image.owner = request.user - image.save() - prediciton_results = predict_image(image) - image.predicted_image_url = ( - f"{image.image.name}_predicted/{image.image.name.split('/')[-1]}" - ) - image.save() - PredictedImage.objects.create( - original_image=image, - image=image.predicted_image_url, - confidence=prediciton_results[0]["confidence"], - class_name=prediciton_results[0]["name"], - ) + for f in files: + image = UploadImage( + image=f, + ) + image.owner = request.user + image.save() + prediciton_results = predict_image(image) + image.predicted_image_url = ( + f"{image.image.name}_predicted/{image.image.name.split('/')[-1]}" + ) + image.save() + try: + results_metrics = prediciton_results[0] + except IndexError as e: + PredictedImage.objects.create( + original_image=image, + image=image.predicted_image_url, + confidence=0.0, + class_name="no predictions", + ) + else: + PredictedImage.objects.create( + original_image=image, + image=image.predicted_image_url, + confidence=results_metrics["confidence"], + class_name=results_metrics["name"], + ) + predictions.append(image) return render( request, - "upload.html", + "results.html", { "img_saved": True, - "img_url": image.predicted_image_url, + "img_url": predictions, }, ) else: @@ -53,7 +69,7 @@ class ListHistory(LoginRequiredMixin, ListView): model = PredictedImage queryset = PredictedImage.objects.all() template_name = "history.html" - paginate_by = 4 + paginate_by = 3 def get_queryset(self) -> QuerySet[Any]: queryset = PredictedImage.objects.filter( diff --git a/PlanktonDetector/db.sqlite3 b/PlanktonDetector/db.sqlite3 index 8352d6e..47ebd67 100644 Binary files a/PlanktonDetector/db.sqlite3 and b/PlanktonDetector/db.sqlite3 differ diff --git a/PlanktonDetector/static/Community/css/post_details.css b/PlanktonDetector/static/Community/css/post_details.css new file mode 100644 index 0000000..a7ed936 --- /dev/null +++ b/PlanktonDetector/static/Community/css/post_details.css @@ -0,0 +1,3 @@ +.class{ + display:flex; +} \ No newline at end of file diff --git a/PlanktonDetector/static/DetectionApp/css/base.css b/PlanktonDetector/static/DetectionApp/css/base.css index bf17a48..b750861 100644 --- a/PlanktonDetector/static/DetectionApp/css/base.css +++ b/PlanktonDetector/static/DetectionApp/css/base.css @@ -16,13 +16,14 @@ body, html{ .top-menu{ display: flex; flex-direction: row; - height: 5%; justify-content:flex-end; align-items: center; background-color:lightgray; margin-bottom:5px; + height: 45px; border: grey solid; border-width: 0px 2px 2px 2px; + transition: top 0.3s; } diff --git a/PlanktonDetector/static/DetectionApp/css/results.css b/PlanktonDetector/static/DetectionApp/css/results.css new file mode 100644 index 0000000..fe8f81a --- /dev/null +++ b/PlanktonDetector/static/DetectionApp/css/results.css @@ -0,0 +1,64 @@ + +form{ + height:100%; + width:100%; + display:flex; + flex-direction:row; + margin:auto; +} + + +.side_menu{ + display: flex; + justify-content: center; + align-items:center; + flex-direction: column; + width: 25%; + background-color: lightgray; + border: grey solid; + border-width: 2px; + margin-bottom: 59px; +} + + +#description{ + font-size: 40px; + text-align: center; +} + +#submit{ + margin-bottom: 40px; + background-color: chartreuse; + margin-top: auto; + height: 50px; + width: 80%; + border-radius: 25px; + border: 2px white; + box-shadow: 0 0 0 4px white; + font-size: 25px; +} + +.upload_field { + margin: auto; + display: flex; + flex-direction: row; + justify-content: right; + width:645px; + height: 465px; +} + + +.upload_field label{ + display:flex; + flex-direction: row; + overflow-x: scroll; + overflow-y: hidden; +} + + +.upload_field label img{ + margin-right:5px; + display: block; +} + + diff --git a/PlanktonDetector/static/DetectionApp/css/upload.css b/PlanktonDetector/static/DetectionApp/css/upload.css index 7b492bf..a7c5132 100644 --- a/PlanktonDetector/static/DetectionApp/css/upload.css +++ b/PlanktonDetector/static/DetectionApp/css/upload.css @@ -41,6 +41,7 @@ form{ .upload_field { margin: auto; display: flex; + flex-direction: column; justify-content: right; flex-basis: auto; } @@ -48,6 +49,7 @@ form{ .upload_button{ display:flex; + flex-direction: row; justify-content: flex-start; align-items: flex-start; } @@ -57,6 +59,8 @@ form{ } - +.upload_field label img{ + margin-bottom: 5px; +} diff --git a/PlanktonDetector/templates/base.html b/PlanktonDetector/templates/base.html index 34a976b..0884c38 100644 --- a/PlanktonDetector/templates/base.html +++ b/PlanktonDetector/templates/base.html @@ -27,5 +27,17 @@ + \ No newline at end of file diff --git a/PlanktonDetector/templates/post_details.html b/PlanktonDetector/templates/post_details.html new file mode 100644 index 0000000..c0fb22b --- /dev/null +++ b/PlanktonDetector/templates/post_details.html @@ -0,0 +1,19 @@ +{%extends 'base.html'%} +{%load static%} +{%block extracss%} + +{%endblock extracss%} +{%block content%} +
+

{{object.title}}

+

{{object.content}}

+

{{object.author}}

+
+
+ {%for comments in object.comment_set.all%} +

{{comments.author}}

+

{{comments.content}}

+

{{comments.post}}

+ {%endfor%} +
+{%endblock content%} \ No newline at end of file diff --git a/PlanktonDetector/templates/results.html b/PlanktonDetector/templates/results.html new file mode 100644 index 0000000..6b39262 --- /dev/null +++ b/PlanktonDetector/templates/results.html @@ -0,0 +1,26 @@ +{% extends 'base.html' %} +{%load static%} +{%block extracss%} + +{%endblock extracss%} +{%block content%} +
+ {% csrf_token %} +
+ {% if not user.is_authenticated %} +

Please login to see results

+ + {% else %} +

Results:

+ + {%endif%} +
+
+ +
+
+ {%endblock content%} \ No newline at end of file diff --git a/PlanktonDetector/templates/upload.html b/PlanktonDetector/templates/upload.html index 2a564a1..74f0d3b 100644 --- a/PlanktonDetector/templates/upload.html +++ b/PlanktonDetector/templates/upload.html @@ -10,40 +10,62 @@ {% if not user.is_authenticated %}

Please login to submit image

- {% elif img_saved is None %} + {% else %}

Choose image for analysis

- {% else %} -

Photo saved

- {%endif%} -
-
{%endblock content%} \ No newline at end of file