1
0
mirror of https://gitlab.com/animath/si/plateforme-corres2math.git synced 2025-06-23 03:58:22 +02:00

💚 Install libmagic in CI

This commit is contained in:
Yohann D'ANELLO
2020-09-27 14:32:05 +02:00
parent 972902eb23
commit 2d62bec690
11 changed files with 271 additions and 97 deletions

View File

@ -4,7 +4,7 @@ from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from .models import Participation, Team
from .models import Participation, Team, Video
class TeamForm(forms.ModelForm):
@ -42,3 +42,9 @@ class ParticipationForm(forms.ModelForm):
class Meta:
model = Participation
fields = ('problem',)
class UploadVideoForm(forms.ModelForm):
class Meta:
model = Video
fields = ('link',)

View File

@ -1,3 +1,6 @@
import re
from django.core.exceptions import ObjectDoesNotExist
from django.core.validators import RegexValidator
from django.db import models
from django.db.models import Index
@ -63,10 +66,10 @@ class Participation(models.Model):
verbose_name=_("problem number"),
)
solution = models.ForeignKey(
solution = models.OneToOneField(
"participation.Video",
on_delete=models.SET_NULL,
related_name="+",
related_name="participation_solution",
null=True,
default=None,
verbose_name=_("solution video"),
@ -81,10 +84,10 @@ class Participation(models.Model):
verbose_name=_("received participation"),
)
synthesis = models.ForeignKey(
synthesis = models.OneToOneField(
"participation.Video",
on_delete=models.SET_NULL,
related_name="+",
related_name="participation_synthesis",
null=True,
default=None,
verbose_name=_("synthesis video"),
@ -99,12 +102,6 @@ class Participation(models.Model):
class Video(models.Model):
participation = models.ForeignKey(
"participation.Participation",
on_delete=models.CASCADE,
verbose_name=_("participation"),
)
link = models.URLField(
verbose_name=_("link"),
help_text=_("The full video link."),
@ -117,6 +114,24 @@ class Video(models.Model):
help_text=_("The video got the validation of the administrators."),
)
@property
def participation(self):
try:
return self.participation_solution
except ObjectDoesNotExist:
return self.participation_synthesis
@property
def platform(self):
if "youtube.com" in self.link or "youtu.be" in self.link:
return "youtube"
return "unknown"
@property
def youtube_code(self):
return re.compile("(https?://|)(www\\.|)(youtube\\.com/watch\\?v=|youtu\\.be/)([a-zA-Z0-9-_]*)?.*?")\
.match("https://www.youtube.com/watch?v=73nsrixx7eI").group(4)
def __str__(self):
return _("Video of team {name} ({trigram})")\
.format(name=self.participation.team.name, trigram=self.participation.team.trigram)

View File

@ -1,5 +1,10 @@
from participation.models import Participation
from participation.models import Participation, Video
def create_team_participation(instance, **_):
Participation.objects.get_or_create(team=instance)
participation = Participation.objects.get_or_create(team=instance)[0]
if not participation.solution:
participation.solution = Video.objects.create()
if not participation.synthesis:
participation.synthesis = Video.objects.create()
participation.save()

View File

@ -0,0 +1,61 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
{% trans "any" as any %}
<div class="row mt-4">
<div class="col-xl-4">
<div class="card bg-light shadow">
<div class="card-header text-center">
<h4>{% trans "Participation of team" %} {{ participation.team.name }} ({{ participation.team.trigram }})</h4>
</div>
<div class="card-body">
<dl class="row">
<dt class="col-sm-6 text-right">{% trans "Chosen problem:" %}</dt>
<dd class="col-sm-6">{{ participation.get_problem_display }}</dd>
</dl>
</div>
<div class="card-footer text-center">
</div>
</div>
</div>
<div class="col-xl-8">
<div class="card bg-light shadow">
<div class="card-header text-center">
<h4>{% trans "Participation of team" %} {{ participation.team.name }} ({{ participation.team.trigram }})</h4>
</div>
<div class="card-body">
{% trans "No video sent" as novideo %}
{% trans "Video link:" %} <a href="{{ participation.solution.link|default:"#" }}" target="_blank">{{ participation.solution.link|default:novideo }}</a>
<button class="btn btn-primary" data-toggle="modal" data-target="#uploadVideoModal">{% trans "Upload" %}</button>
{% if participation.solution.platform == "youtube" %}
{% include "participation/youtube_iframe.html" with youtube_code=participation.solution.youtube_code %}
{% else %}
<div class="alert alert-danger">
{% trans "This video platform is not supported yet." %}
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% trans "Upload video" as modal_title %}
{% trans "Upload" as modal_button %}
{% url "participation:upload_video" pk=participation.solution_id as modal_action %}
{% include "base_modal.html" with modal_id="uploadVideo" %}
{% endblock %}
{% block extrajavascript %}
<script>
$(document).ready(function() {
$('button[data-target="#uploadVideoModal"]').click(function() {
let modalBody = $("#uploadVideoModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "participation:upload_video" pk=participation.solution_id %} #form-content");
});
});
</script>
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends "base.html" %}
{% load crispy_forms_filters i18n %}
{% block content %}
<form method="post">
<div id="form-content">
{% csrf_token %}
{{ form|crispy }}
</div>
<button class="btn btn-success" type="submit">{% trans "Upload" %}</button>
</form>
{% endblock content %}

View File

@ -0,0 +1,8 @@
<div style="position: relative; width: 100%; padding-bottom: 56.25%;">
<iframe src="https://www.youtube.com/embed/{{ youtube_code }}"
frameborder="0"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>

View File

@ -1,6 +1,7 @@
from django.urls import path
from .views import CreateTeamView, JoinTeamView, MyTeamDetailView, TeamDetailView, TeamUpdateView
from .views import CreateTeamView, JoinTeamView, MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView,\
TeamDetailView, TeamUpdateView, UploadVideoView
app_name = "participation"
@ -11,4 +12,7 @@ urlpatterns = [
path("team/", MyTeamDetailView.as_view(), name="my_team_detail"),
path("team/<int:pk>/", TeamDetailView.as_view(), name="team_detail"),
path("team/<int:pk>/update/", TeamUpdateView.as_view(), name="update_team"),
path("detail/", MyParticipationDetailView.as_view(), name="my_participation_detail"),
path("detail/<int:pk>/", ParticipationDetailView.as_view(), name="participation_detail"),
path("detail/upload-video/<int:pk>/", UploadVideoView.as_view(), name="upload_video"),
]

View File

@ -5,8 +5,8 @@ from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, FormView, RedirectView, UpdateView
from .forms import JoinTeamForm, ParticipationForm, TeamForm
from .models import Team
from .forms import JoinTeamForm, ParticipationForm, TeamForm, UploadVideoForm
from .models import Participation, Team, Video
class CreateTeamView(LoginRequiredMixin, CreateView):
@ -99,3 +99,27 @@ class TeamUpdateView(LoginRequiredMixin, UpdateView):
def get_success_url(self):
return reverse_lazy("participation:team_detail", args=(self.object.pk,))
class MyParticipationDetailView(LoginRequiredMixin, RedirectView):
def get_redirect_url(self, *args, **kwargs):
user = self.request.user
registration = user.registration
if registration.participates:
if registration.team:
return reverse_lazy("participation:participation_detail", args=(registration.team.participation.id,))
raise PermissionDenied(_("You are not in a team."))
raise PermissionDenied(_("You don't participate, so you don't have any team."))
class ParticipationDetailView(LoginRequiredMixin, DetailView):
model = Participation
class UploadVideoView(LoginRequiredMixin, UpdateView):
model = Video
form_class = UploadVideoForm
template_name = "participation/upload_video.html"
def get_success_url(self):
return reverse_lazy("participation:participation_detail", args=(self.object.participation.pk,))