1
0
mirror of https://gitlab.com/animath/si/plateforme-corres2math.git synced 2025-02-11 17:41:18 +00:00

Better photo authorization upload

This commit is contained in:
Yohann D'ANELLO 2020-09-27 12:36:37 +02:00
parent c84d4151bb
commit 9ef35217d3
7 changed files with 79 additions and 40 deletions

View File

@ -4,7 +4,7 @@ ENV PYTHONUNBUFFERED 1
ENV DJANGO_ALLOW_ASYNC_UNSAFE 1 ENV DJANGO_ALLOW_ASYNC_UNSAFE 1
# Install LaTeX requirements # Install LaTeX requirements
RUN apk add --no-cache gettext texlive nginx gcc libc-dev libffi-dev postgresql-dev RUN apk add --no-cache gettext texlive nginx gcc libc-dev libffi-dev postgresql-dev libmagic
RUN apk add --no-cache bash RUN apk add --no-cache bash

View File

@ -2,6 +2,7 @@ from django import forms
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms import FileInput
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import AdminRegistration, CoachRegistration, StudentRegistration from .models import AdminRegistration, CoachRegistration, StudentRegistration
@ -52,6 +53,10 @@ class PhotoAuthorizationForm(forms.ModelForm):
raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file.")) raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
return self.cleaned_data["photo_authorization"] return self.cleaned_data["photo_authorization"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["photo_authorization"].widget = FileInput()
class Meta: class Meta:
model = StudentRegistration model = StudentRegistration
fields = ('photo_authorization',) fields = ('photo_authorization',)

View File

@ -1,3 +1,5 @@
from django.core.exceptions import ValidationError
from corres2math.tokens import email_validation_token from corres2math.tokens import email_validation_token
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.db import models from django.db import models
@ -68,7 +70,7 @@ class Registration(PolymorphicModel):
def get_random_filename(instance, filename): def get_random_filename(instance, filename):
return get_random_string(64) return "authorization/photo/" + get_random_string(64)
class StudentRegistration(Registration): class StudentRegistration(Registration):

View File

@ -1,3 +1,10 @@
import mimetypes
import os
from django.http import Http404, HttpResponse, FileResponse
from django.views.generic.base import View
from magic import Magic
from corres2math.tokens import email_validation_token from corres2math.tokens import email_validation_token
from django.conf import settings from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
@ -164,5 +171,26 @@ class UserUploadPhotoAuthorizationView(LoginRequiredMixin, UpdateView):
form_class = PhotoAuthorizationForm form_class = PhotoAuthorizationForm
template_name = "registration/upload_photo_authorization.html" template_name = "registration/upload_photo_authorization.html"
@transaction.atomic
def form_valid(self, form):
old_instance = StudentRegistration.objects.get(pk=self.object.pk)
if old_instance.photo_authorization:
old_instance.photo_authorization.delete()
return super().form_valid(form)
def get_success_url(self): def get_success_url(self):
return reverse_lazy("registration:user_detail", args=(self.object.user.pk,)) return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))
class PhotoAuthorizationView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/photo/{filename}"
if not os.path.exists(path):
raise Http404
student = StudentRegistration.objects.get(photo_authorization__endswith=filename)
mime = Magic(mime=True)
mime_type = mime.from_file(path)
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
true_file_name = _("Photo authorization of {student}.{ext}").format(student=str(student), ext=ext)
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)

View File

@ -18,8 +18,7 @@ from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.views.defaults import bad_request, permission_denied, page_not_found, server_error from django.views.defaults import bad_request, permission_denied, page_not_found, server_error
from django.views.generic import TemplateView from django.views.generic import TemplateView
from registration.views import PhotoAuthorizationView
from corres2math import settings
urlpatterns = [ urlpatterns = [
path('', TemplateView.as_view(template_name="index.html"), name='index'), path('', TemplateView.as_view(template_name="index.html"), name='index'),
@ -32,12 +31,11 @@ urlpatterns = [
path('participation/', include('participation.urls')), path('participation/', include('participation.urls')),
path('registration/', include('registration.urls')), path('registration/', include('registration.urls')),
path('media/authorization/photo/<str:filename>/', PhotoAuthorizationView.as_view(), name='photo_authorization'),
path('', include('eastereggs.urls')), path('', include('eastereggs.urls')),
] ]
# FIXME Protect files
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
handler400 = bad_request handler400 = bad_request
handler403 = permission_denied handler403 = permission_denied
handler404 = page_not_found handler404 = page_not_found

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Corres2math\n" "Project-Id-Version: Corres2math\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-27 11:18+0200\n" "POT-Creation-Date: 2020-09-27 12:35+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n" "Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -38,7 +38,7 @@ msgstr "Fermer"
msgid "Logs" msgid "Logs"
msgstr "Logs" msgstr "Logs"
#: apps/logs/models.py:22 apps/registration/models.py:16 #: apps/logs/models.py:22 apps/registration/models.py:18
msgid "user" msgid "user"
msgstr "utilisateur" msgstr "utilisateur"
@ -141,7 +141,7 @@ msgid "Team {name} ({trigram})"
msgstr "Équipe {name} ({trigram})" msgstr "Équipe {name} ({trigram})"
#: apps/participation/models.py:45 apps/participation/models.py:56 #: apps/participation/models.py:45 apps/participation/models.py:56
#: apps/registration/models.py:81 apps/registration/models.py:127 #: apps/registration/models.py:83 apps/registration/models.py:129
msgid "team" msgid "team"
msgstr "équipe" msgstr "équipe"
@ -302,104 +302,104 @@ msgstr "Vous n'êtes pas dans une équipe."
msgid "You don't participate, so you don't have any team." msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe." msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
#: apps/registration/forms.py:12 #: apps/registration/forms.py:13
msgid "role" msgid "role"
msgstr "rôle" msgstr "rôle"
#: apps/registration/forms.py:14 #: apps/registration/forms.py:15
msgid "participant" msgid "participant"
msgstr "participant" msgstr "participant"
#: apps/registration/forms.py:15 apps/registration/models.py:136 #: apps/registration/forms.py:16 apps/registration/models.py:138
msgid "coach" msgid "coach"
msgstr "encadrant" msgstr "encadrant"
#: apps/registration/forms.py:52 #: apps/registration/forms.py:53
msgid "The uploaded file must be a PDF, PNG of JPEG file." msgid "The uploaded file must be a PDF, PNG of JPEG file."
msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG." msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG."
#: apps/registration/models.py:21 #: apps/registration/models.py:23
msgid "Grant Animath to contact me in the future about other actions" msgid "Grant Animath to contact me in the future about other actions"
msgstr "" msgstr ""
"Autoriser Animath à me recontacter à l'avenir à propos d'autres actions" "Autoriser Animath à me recontacter à l'avenir à propos d'autres actions"
#: apps/registration/models.py:26 #: apps/registration/models.py:28
msgid "email confirmed" msgid "email confirmed"
msgstr "email confirmé" msgstr "email confirmé"
#: apps/registration/models.py:30 #: apps/registration/models.py:32
msgid "Activate your Correspondances account" msgid "Activate your Correspondances account"
msgstr "Activez votre compte des Correspondances" msgstr "Activez votre compte des Correspondances"
#: apps/registration/models.py:66 #: apps/registration/models.py:68
msgid "registration" msgid "registration"
msgstr "inscription" msgstr "inscription"
#: apps/registration/models.py:67 #: apps/registration/models.py:69
msgid "registrations" msgid "registrations"
msgstr "inscriptions" msgstr "inscriptions"
#: apps/registration/models.py:86 #: apps/registration/models.py:88
msgid "12th grade" msgid "12th grade"
msgstr "Terminale" msgstr "Terminale"
#: apps/registration/models.py:87 #: apps/registration/models.py:89
msgid "11th grade" msgid "11th grade"
msgstr "Première" msgstr "Première"
#: apps/registration/models.py:88 #: apps/registration/models.py:90
msgid "10th grade or lower" msgid "10th grade or lower"
msgstr "Seconde ou inférieur" msgstr "Seconde ou inférieur"
#: apps/registration/models.py:90 #: apps/registration/models.py:92
msgid "student class" msgid "student class"
msgstr "classe" msgstr "classe"
#: apps/registration/models.py:95 #: apps/registration/models.py:97
msgid "school" msgid "school"
msgstr "école" msgstr "école"
#: apps/registration/models.py:100 #: apps/registration/models.py:102
msgid "photo authorization" msgid "photo authorization"
msgstr "autorisation de droit à l'image" msgstr "autorisation de droit à l'image"
#: apps/registration/models.py:108 #: apps/registration/models.py:110
msgid "student" msgid "student"
msgstr "étudiant" msgstr "étudiant"
#: apps/registration/models.py:116 #: apps/registration/models.py:118
msgid "student registration" msgid "student registration"
msgstr "inscription d'élève" msgstr "inscription d'élève"
#: apps/registration/models.py:117 #: apps/registration/models.py:119
msgid "student registrations" msgid "student registrations"
msgstr "inscriptions d'élève" msgstr "inscriptions d'élève"
#: apps/registration/models.py:131 #: apps/registration/models.py:133
msgid "professional activity" msgid "professional activity"
msgstr "activité professionnelle" msgstr "activité professionnelle"
#: apps/registration/models.py:144 #: apps/registration/models.py:146
msgid "coach registration" msgid "coach registration"
msgstr "inscription d'encadrant" msgstr "inscription d'encadrant"
#: apps/registration/models.py:145 #: apps/registration/models.py:147
msgid "coach registrations" msgid "coach registrations"
msgstr "inscriptions d'encadrants" msgstr "inscriptions d'encadrants"
#: apps/registration/models.py:150 #: apps/registration/models.py:152
msgid "role of the administrator" msgid "role of the administrator"
msgstr "rôle de l'administrateur" msgstr "rôle de l'administrateur"
#: apps/registration/models.py:155 #: apps/registration/models.py:157
msgid "admin" msgid "admin"
msgstr "admin" msgstr "admin"
#: apps/registration/models.py:163 #: apps/registration/models.py:165
msgid "admin registration" msgid "admin registration"
msgstr "inscription d'administrateur" msgstr "inscription d'administrateur"
#: apps/registration/models.py:164 #: apps/registration/models.py:166
msgid "admin registrations" msgid "admin registrations"
msgstr "inscriptions d'administrateur" msgstr "inscriptions d'administrateur"
@ -635,26 +635,31 @@ msgstr "Modifier l'utilisateur"
msgid "Upload photo authorization" msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image" msgstr "Téléverser l'autorisation de droit à l'image"
#: apps/registration/views.py:56 #: apps/registration/views.py:63
msgid "Email validation" msgid "Email validation"
msgstr "Validation de l'adresse mail" msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:58 #: apps/registration/views.py:65
msgid "Validate email" msgid "Validate email"
msgstr "Valider l'adresse mail" msgstr "Valider l'adresse mail"
#: apps/registration/views.py:97 #: apps/registration/views.py:104
msgid "Email validation unsuccessful" msgid "Email validation unsuccessful"
msgstr "Échec de la validation de l'adresse mail" msgstr "Échec de la validation de l'adresse mail"
#: apps/registration/views.py:108 #: apps/registration/views.py:115
msgid "Email validation email sent" msgid "Email validation email sent"
msgstr "Mail de confirmation de l'adresse mail envoyé" msgstr "Mail de confirmation de l'adresse mail envoyé"
#: apps/registration/views.py:116 #: apps/registration/views.py:123
msgid "Resend email validation link" msgid "Resend email validation link"
msgstr "Renvoyé le lien de validation de l'adresse mail" msgstr "Renvoyé le lien de validation de l'adresse mail"
#: apps/registration/views.py:195
#, python-brace-format
msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}"
#: corres2math/settings.py:150 #: corres2math/settings.py:150
msgid "English" msgid "English"
msgstr "Anglais" msgstr "Anglais"

View File

@ -9,4 +9,5 @@ django-tables2
djangorestframework djangorestframework
django-rest-polymorphic django-rest-polymorphic
ptpython ptpython
python-magic
gunicorn gunicorn