]> git.parisson.com Git - teleforma.git/commitdiff
Add ConferencePublication code from crfpa
authorYoan Le Clanche <yoanl@pilotsystems.net>
Wed, 25 Sep 2024 09:28:28 +0000 (11:28 +0200)
committerGuillaume Pellerin <guillaume.pellerin@parisson.com>
Mon, 21 Oct 2024 21:15:46 +0000 (23:15 +0200)
teleforma/admin.py
teleforma/management/commands/teleforma-publish-notify-conferences.py
teleforma/migrations/0012_auto_20240925_0929.py [new file with mode: 0644]
teleforma/models/core.py
teleforma/templates/teleforma/inc/conference_list.html
teleforma/templates/teleforma/inc/media_list.html
teleforma/templatetags/teleforma_tags.py
teleforma/views/core.py

index 41ed60e1fb3b09797c5947e12016ed354fc0b250..f0e198020030bb7dcef39b0f81a59d6f07c97d94 100644 (file)
@@ -25,7 +25,7 @@ from .models.appointment import (Appointment, AppointmentJury,
 from .models.core import (Conference, Course, CourseType, Department, Document,
                           DocumentSimple, DocumentType, LiveStream, Media,
                           MediaTranscoded, Organization, Period, Professor,
-                          Room, StreamingServer)
+                          Room, StreamingServer, ConferencePublication)
 from .models.crfpa import (IEJ, Corrector, Discount, Home, NewsItem,
                            OptionalFee, Parameters, Payback, Payment, Profile,
                            Student, Training)
@@ -374,6 +374,9 @@ class MediaInline(admin.StackedInline):
     model = Media
     exclude = ['readers', ]
 
+class ConferenceInline(admin.StackedInline):
+    model = ConferencePublication
+
 @admin.action(description='Publish selected conferences')
 def publish_conferences(modeladmin, request, queryset):
     for conference in queryset:
@@ -399,7 +402,7 @@ def duplicate_conferences(modeladmin, request, queryset):
 
 
 class ConferenceAdmin(admin.ModelAdmin):
-    inlines = [MediaInline,]
+    inlines = [MediaInline, ConferenceInline]
     exclude = ['readers']
     list_per_page = 30
     list_filter = ('course', 'period', 'date_begin', 'session', 'course_type')
index 2e5bbc98f5c3617f354e7fbcad565243f21e4f8f..6300f40d086bbca85b238afdcedc0bac724ba57e 100644 (file)
@@ -10,7 +10,7 @@ from django.core.management.base import BaseCommand, CommandError
 from django.contrib.auth.models import User
 from django.template.defaultfilters import slugify
 from django.urls import reverse
-from teleforma.models.core import Conference, Period
+from teleforma.models.core import Conference, ConferencePublication, Period
 from teleforma.models.crfpa import Student
 from teleforma.models.notification import notify
 from teleforma.views.core import get_courses
@@ -75,6 +75,12 @@ class Command(BaseCommand):
         now_plus = now + datetime.timedelta(minutes=minute_high_range)
 
         publications = list(Conference.objects.filter(
+                        period=period,
+                        status=2,
+                        notified=False,
+                        date_publish__lte=now_plus,
+                        date_publish__gte=now_minus,
+                        )) + list(ConferencePublication.objects.filter(
                         period=period,
                         status=2,
                         notified=False,
@@ -87,7 +93,10 @@ class Command(BaseCommand):
 
         for publication in publications:
 
-            conference = publication            
+            if type(publication) == ConferencePublication:
+                conference = publication.conference
+            else:
+                conference = publication
 
             medias = conference.media.all()
 
diff --git a/teleforma/migrations/0012_auto_20240925_0929.py b/teleforma/migrations/0012_auto_20240925_0929.py
new file mode 100644 (file)
index 0000000..107d189
--- /dev/null
@@ -0,0 +1,35 @@
+# Generated by Django 3.2.25 on 2024-09-25 09:29
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('teleforma', '0011_auto_20240311_2202'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='student',
+            name='confirmation_sent',
+            field=models.BooleanField(default=False, verbose_name='confirmation sent'),
+        ),
+        migrations.AlterField(
+            model_name='student',
+            name='is_subscribed',
+            field=models.BooleanField(default=False, verbose_name='subscribed'),
+        ),
+        migrations.CreateModel(
+            name='ConferencePublication',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('date_publish', models.DateTimeField(blank=True, null=True, verbose_name='publishing date')),
+                ('status', models.IntegerField(choices=[(0, 'Hidden'), (1, 'Private'), (2, 'Draft'), (3, 'Public')], default=2, verbose_name='status')),
+                ('notified', models.BooleanField(default=False, verbose_name='notified')),
+                ('conference', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='publications', to='teleforma.conference', verbose_name='conference')),
+                ('period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teleforma.period', verbose_name='period')),
+            ],
+        ),
+    ]
index a1d360ff02114c0e0266f9605ee44d26074386c0..a20fa0821d661aee5d8481833d11ab309c005dac 100755 (executable)
@@ -371,6 +371,15 @@ class Room(models.Model):
         db_table = app_label + '_' + 'room'
         verbose_name = _('room')
 
+class ConferencePublication(models.Model):
+    conference = models.ForeignKey('Conference', related_name='publications', verbose_name=_('conference'),
+                                    on_delete=models.CASCADE)
+    period = models.ForeignKey('Period', verbose_name=_('period'),
+                               on_delete=models.CASCADE)
+    date_publish = models.DateTimeField(_('publishing date'), null=True, blank=True)
+    status = models.IntegerField(
+        _('status'), choices=STATUS_CHOICES, default=2)
+    notified = models.BooleanField(_('notified'), default=False)
 
 class Conference(models.Model):
 
@@ -406,6 +415,13 @@ class Conference(models.Model):
     @property
     def description(self):
         return str(self)
+    
+    @property
+    def session_as_int(self):
+        try:
+            return int(self.session)
+        except ValueError:
+            return 0
 
     @property
     def slug(self):
@@ -427,13 +443,6 @@ class Conference(models.Model):
                     str(self.date_begin)]
         return ' - '.join(list)
 
-    @property
-    def slug(self):
-        slug = '-'.join([self.course.department.slug,
-                         self.course.slug,
-                         self.course_type.name.lower()])
-        return slug
-
     def save(self, *args, **kwargs):
         if not self.public_id:
             self.public_id = get_random_hash()
@@ -547,6 +556,37 @@ class Conference(models.Model):
                 self.web_class_group = WebClassGroup.objet.get(
                     name=data['web_class_group'])
 
+    def video(self):
+        """
+        get media video
+        """
+        try:
+            videos = self.media.filter(type='mp4')
+            if videos:
+                return videos[0]
+        except Media.DoesNotExist:
+            try:
+                return self.media.filter(type='webm')[0]
+            except Media.DoesNotExist:
+                pass
+        return None
+
+    def publication_info(self, period):
+        """
+        Get publication info according to period.
+        """
+        publication = self.publications.filter(period=period).first()
+        if not publication and self.period == period:
+            publication = self
+        elif not publication:
+            return None
+        
+        return {
+            'status': publication.status,
+            'published': publication.status == 3,
+            'publication_date': publication.date_publish,
+            'notified': publication.notified
+        }
     class Meta(MetaCore):
         db_table = app_label + '_' + 'conference'
         verbose_name = _('conference')
index 96cc81660046c55bec674d2fadb397279f7463cc..f3c57682af21982caacfeec94a1faa56f72fc841 100644 (file)
@@ -1,22 +1,23 @@
 {% load teleforma_tags %}
 {% load i18n %}
 
-{% with course.conference.all|from_course_type:type|streaming_only as conferences %}
-{% if conferences|from_periods:period %}
+{% course_ingoing_conferences as conferences %}
+
+{% if conferences %}
 <div class="course_content content_video">
 <div class="course_subtitle">
     <h3><img src="/static/teleforma/images/item_title.png" width="10px" alt="" /> {% trans "Live conferences"%}</h3>
 </div>
     <table class="listing" width="100%">
     <tbody>
-       {% for conference in conferences|from_periods:period %}
+       {% for conference in conferences %}
         {% for stream in conference.livestream.all %}
          {% if stream.stream_type == 'webm' %}
             <tr>
             {% if stream.streaming %}
             <td {% if forloop.first %}class="border-top"{% endif %} width="230px">
                <a href="{% url 'teleforma-conference-detail' period.id stream.conference.id %}" title="{% trans "View" %}">
-               <img id="snapshot-{{ stream.course.code }}-{{ stream.course_type }}" src="{{ stream.snapshot_url }}" width="100%" alt="{% trans 'Click here' %}" />
+               <img src="/static/teleforma/images/play_168.png" width="100%" style="background: black;" alt="{% trans 'Click here' %}" />
                </a>
             </td>
             <td {% if forloop.first %}class="border-top"{% endif %} width="60%" style="padding-left: 1em;">
@@ -25,7 +26,7 @@
                     <dt>{% trans "Title" %}</dt><dd>{{ stream.conference.course.title }}</dd>
                     <dt>{% trans "Session" %}</dt><dd>{{ stream.conference.session }}</dd>
                     {% if stream.conference.professor.user.username %}
-                    <dt>{% trans "Professor" %}</dt><dd><a href="{% url 'teleforma-profile-detail' stream.conference.professor.user.username %}" target="_blank">{{ stream.conference.professor }}</a></dd>
+                    <dt>{% trans "Professor" %}</dt><dd>{{ stream.conference.professor }}</dd>
                     {% endif %}
                     <dt>{% trans "Begin" %}</dt><dd>{{ stream.conference.date_begin }}</dd>
                     </dl>
@@ -45,9 +46,8 @@
             </tr>
             {% endif %}
         {% endfor %}
-        {% endfor %}
+       {% endfor %}
     </tbody>
     </table>
 </div>
 {% endif %}
-{% endwith %}
index b83a75561515e24eaa039815837508fb1d84990b..720994b79e982649f073902d50d0fc43ff31d311 100644 (file)
@@ -2,54 +2,67 @@
 {% load thumbnail %}
 {% load i18n %}
 
-{% if course.media.all|from_course_type:type %}
+{% course_past_conferences as all_conferences %}
+
+{% if all_conferences %}
 <div class="course_content content_video">
 <div class="course_subtitle">
-    <h3><img src="/static/teleforma/images/item_title.png" width="10px" alt="" /> {% trans title %}</h3>
+    <h3><img src="/static/teleforma/images/item_title.png" width="10px" alt="" /> {% trans "Conférences en différé" %}</h3>
 </div>
     <table class="listing" width="100%">
     <tbody>
-        {% for media in course.media.all|from_course_type:type|from_periods:period %}
-         {% if media.is_published or user.is_staff and not list_view %}
-          {% if media.type == 'webm' or media.type == 'mp4' %}
+        {% for conference in all_conferences %}
+          {% if conference.video %}
             <tr>
             <td {% if forloop.first %}class="border-top"{% endif %} width="230px" style="vertical-align:middle">
-            <a href="{% url 'teleforma-media-detail' period.id media.id %}" title="{% trans "Play" %}">
-            {% if media.poster_file %}
-               {% thumbnail media.poster_file "168x96" as im %}
+            <a href="{% url 'teleforma-media-detail' period.id conference.video.id %}" title="{% trans "Play" %}">
+            {% if conference.video.poster_file %}
+               {% thumbnail conference.video.poster_file "168x96" as im %}
                 <div style="background: no-repeat url('{{ im.url }}') 0 1px; background-size: 100%; background-color: #dfdfdf;">
-                 <img src="{{ STATIC_URL }}teleforma/images/play_168.png" width="100%" alt="{% trans 'Click here' %}" />
+                 <img src="/static/teleforma/images/play_168.png" width="100%" alt="{% trans 'Click here' %}" />
                 </div>
                {% endthumbnail %}
             {% else %}
-              {% trans 'Click here' %}
+              <div>{% trans 'Click here' %}</div>
             {% endif %}
+            {% comment %}<div>{% trans 'Click here' %}</div>{% endcomment %}
             </a>
             </td>
+            {% conference_publication conference as publication %}
             <td {% if forloop.first %}class="border-top"{% endif %} width="60%" style="padding-left: 1em;">
                 <div>
                     <dl class="listing" style="font-size: 1.2em;">
-                    <dt>{% trans "Title" %}</dt><dd>{{ media.conference.course.title }}</dd>
-                    <dt>{% trans "Session" %}</dt><dd>{{ media.conference.session }}</dd>
-                    {% if media.conference.professor %}
-                    <dt>{% trans "Professor" %}</dt><dd><a href="{% url 'teleforma-profile-detail' media.conference.professor.user.username %}" target="_blank">{{ media.conference.professor }}</a></dd>
+                    <dt>{% trans "Title" %}</dt><dd>{{ conference.course.title }}</dd>
+                    <dt>{% trans "Session" %}</dt><dd>{{ conference.session }}</dd>
+                    {% if conference.professor %}
+                    <dt>{% trans "Professor" %}</dt><dd>{{ conference.professor }}</dd>
+                    {% endif %}
+                    {% if conference.streaming %}
+                        <dt>{% trans "Begin date" %}</dt><dd>{{ conference.date_begin }}</dd>
+                    {% else %}
+                        <dt>{% trans "Publishing date" %}</dt><dd>{{ publication.publication_date }}</dd>
                     {% endif %}
-                    <dt>{% trans "Begin" %}</dt><dd>{{ media.conference.date_begin }}</dd>
-                    {% if media.conference.comment %}
-                    <dt>{% trans "Comment" %}</dt><dd>{{ media.conference.comment }}</dd>
+                    {% if conference.duration %}
+                        <dt>{% trans "Duration" %}</dt><dd>{{ conference.duration }}</dd>
+                    {% endif %}
+                    {% if conference.comment %}
+                    <dt>{% trans "Comment" %}</dt><dd>{{ conference.comment }}</dd>
                     {% endif %}
                     </dl>
                  </div>
             </td>
+            
             <td {% if forloop.first %}class="border-top"{% endif %} width="10%" align="center">
-            {% if media.is_published and user.is_staff %}
-             <img src="/static/teleforma/images/ok.png" style="vertical-align:middle" alt="" title="{% trans ' published' %}" />
-            {% elif not media.is_published and user.is_staff %}
-             <img src="/static/teleforma/images/delete.png" style="vertical-align:middle" alt="" title="{% trans ' rejected' %}" />
+            {% if user.is_staff or user.professor.count %}
+                {% if publication.published %}
+                    <img src="/static/teleforma/images/ok.png" style="vertical-align:middle" alt="" title="{% trans ' published' %}" />
+                {% else %}
+                    <img src="/static/teleforma/images/delete.png" style="vertical-align:middle" alt="" title="{% trans ' rejected' %}" />
+                {% endif %}
             {% endif %}
-            {% if media.file and media.is_published or user.is_superuser or user.is_staff %}
-                {% if not "video" in media.mime_type or request.user_agent.os.family == 'iOS' %}
-                    <a href="{% url 'teleforma-media-download' period.id media.id %}">
+            {% if conference.video.file %}
+                {% if not "video" in conference.video.mime_type or request.user_agent.os.family == 'iOS' %}
+                    <a href="{% url 'teleforma-media-download' period.id conference.video.id %}">
                         <img src="/static/teleforma/images/download_media.png" style="vertical-align:middle" alt="" title="{% trans "Download" %}" />
                     </a>
                 {% endif %}
@@ -57,7 +70,6 @@
             </td>
             </tr>
           {% endif %}
-         {% endif %}
         {% endfor %}
     </tbody>
     </table>
index 3395c079dedfa1fb0c5468636c1e3a52e2ddef71..0fd6b753d847535170fea1560fb8ffe43df3aa53 100644 (file)
@@ -49,6 +49,7 @@ from django.utils.translation import ugettext_lazy as _
 from docutils.core import publish_parts
 
 from teleforma.models.chat import ChatMessage
+from teleforma.views.core import get_course_conferences
 
 from ..exam.models import Quota, Script
 from ..models.core import Document, Professor
@@ -439,3 +440,28 @@ def chat_room(context, period=None, course=None):
             'user_id': context.request.user.id
         }
     }
+
+@register.simple_tag(takes_context=True)
+def course_ingoing_conferences(context):
+    course = context['course']
+    confs = course.conference.filter(streaming=True,
+                                     period=context['period'],
+                                     course_type=context['type'])
+    return list(confs)
+
+@register.simple_tag(takes_context=True)
+def course_past_conferences(context):
+    user = context['user']
+    if user.is_staff or user.professor.count():
+        status_min = 2
+    else:
+        status_min = 3
+    course = context['course']
+    period = context['period']
+    course_type = context['type']
+    return get_course_conferences(period, course, course_type, status_min=status_min)
+
+@register.simple_tag(takes_context=True)
+def conference_publication(context, conference):
+    period = context['period']
+    return conference.publication_info(period)
index 15b4f9ad4998a90792e04a185a54b3ce51f21d68..1559d26a0d1e0778886d766668536112b29da9cc 100644 (file)
@@ -119,6 +119,56 @@ def get_courses(user, date_order=False, num_order=False, num_courses=False, peri
         return get_ae_courses(user, date_order, num_order, period)
 
 
+def get_trainings(user):
+    trainings = []
+
+    if not user.is_authenticated:
+        return trainings
+
+    professor = user.professor.all()
+    student = user.student.all()
+    quotas = user.quotas.all()
+
+    if professor or quotas or user.is_staff:
+        trainings = Training.objects.filter(available=True)
+
+    elif student:
+        student = user.student.get()
+        trainings = student.trainings.all()
+    return trainings
+
+
+
+def get_course_conferences(period, course, course_type, status_min=3):
+    conferences = []
+    already_added = set()
+
+    periods = [period,]
+
+    # get conference publications
+    publications = ConferencePublication.objects.filter(
+        period__in=periods,
+        conference__course=course,
+        conference__course_type=course_type,
+        status__gte=status_min).distinct()
+    for publication in publications:
+        conferences.append(publication.conference)
+        already_added.add(publication.conference.id)
+
+    cc = Conference.objects.filter(period__in=periods,
+        course=course,
+        course_type=course_type,
+        status__gte=status_min).distinct()
+
+    for conference in cc:
+        # do not include conferences with publication rules
+        if conference.id not in already_added:
+            conferences.append(conference)
+    conferences = sorted(conferences, key=lambda c:-c.session_as_int)
+    return conferences
+
+
+
 def stream_from_file(__file):
     chunk_size = 0x10000
     f = open(__file, 'r')