]> git.parisson.com Git - teleforma.git/commitdiff
Fix conference notifications
authorYoan Le Clanche <yoanl@pilotsystems.net>
Mon, 4 Dec 2023 16:05:27 +0000 (17:05 +0100)
committerYoan Le Clanche <yoanl@pilotsystems.net>
Mon, 4 Dec 2023 16:05:27 +0000 (17:05 +0100)
teleforma/management/commands/teleforma-publish-notify-conferences.py [new file with mode: 0644]
teleforma/migrations/0007_auto_20231204_1650.py [new file with mode: 0644]
teleforma/models/core.py

diff --git a/teleforma/management/commands/teleforma-publish-notify-conferences.py b/teleforma/management/commands/teleforma-publish-notify-conferences.py
new file mode 100644 (file)
index 0000000..2e5bbc9
--- /dev/null
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+
+from optparse import make_option
+import logging
+import os
+from copy import deepcopy
+
+from django.conf import settings
+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.crfpa import Student
+from teleforma.models.notification import notify
+from teleforma.views.core import get_courses
+import datetime
+
+
+MINUTES_LOW_RANGE = 5
+MINUTES_HIGH_RANGE = 25
+
+class Logger:
+    """A logging object"""
+
+    def __init__(self, file):
+        self.logger = logging.getLogger('myapp')
+        if file:
+            self.hdlr = logging.FileHandler(file)
+        else:
+            self.hdlr = None
+        self.formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+        if self.hdlr:
+            self.hdlr.setFormatter(self.formatter)
+            self.logger.addHandler(self.hdlr)
+        self.logger.setLevel(logging.INFO)
+
+
+class Command(BaseCommand):
+    help = """Publish conferences and notify users when \
+            conference.date_publish is equal or greater \
+            than current date """
+
+    def add_arguments(self, parser):
+        parser.add_argument('--logfile', type=str, required=False,
+                            help='log file to use')
+
+        parser.add_argument('--period', type=str, required=True,
+                            help='period to process')
+
+        parser.add_argument('--minute-low-range', type=int, required=False,
+                            help='minute low range')
+
+        parser.add_argument('--minute-high-range', type=int, required=False,
+                            help='minute high range')
+
+    def handle(self, *args, **options):
+        logpath = options['logfile']
+        logger = Logger(logpath)
+
+
+        period_name = options['period']
+        period = Period.objects.get(name=period_name)
+
+        minute_low_range = options['minute_low_range']
+        if not minute_low_range:
+            minute_low_range = MINUTES_LOW_RANGE
+
+        minute_high_range = options['minute_high_range']
+        if not minute_high_range:
+            minute_high_range = MINUTES_HIGH_RANGE
+
+        now = datetime.datetime.now()
+        now_minus = now - datetime.timedelta(minutes=minute_low_range)
+        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,
+                        ))
+        print(publications)
+    
+        logger.logger.info("Starting conference publication process")
+
+        for publication in publications:
+
+            conference = publication            
+
+            medias = conference.media.all()
+
+            if medias:
+                publication.status = 3
+
+                for media in medias:
+                    media.is_published = True
+                    media.save()
+
+                    linked_media = media
+
+                publication.save()
+                logger.logger.info("Conference published: " + conference.public_id)
+
+                # media = conference.media.filter(mime_type='video/mp4')[0]
+                url = reverse('teleforma-media-detail', args=[conference.period.id, linked_media.id])
+
+                if conference.professor:
+                    elm = [conference.course.title,
+                        conference.course_type.name, conference.session,
+                        conference.professor.user.first_name,
+                        conference.professor.user.last_name]
+                else:
+                    elm = [conference.course.title,
+                        conference.course_type.name, conference.session]
+                message = "Nouvelle conférence publiée : " + ' - '.join(elm)
+
+                students = Student.objects.filter(period=publication.period, platform_only=True)
+                for student in students:
+                    try:
+                        if student.user:
+                            courses = get_courses(student.user, period=publication.period)
+                            for course in courses:
+                                if conference.course == course['course'] and \
+                                        conference.course_type in course['types']:
+                                    notify(student.user, message, url)
+                                    logger.logger.info("Student notified: " + student.user.username)
+                                    print("notify", student)
+                    except:
+                        #logger.logger.info("Student NOT notified: " + str(student.id))
+                        print("can't notify", student)
+                        continue
+
+                for user in User.objects.filter(is_staff=True):
+                    notify(user, message, url)
+
+                publication.notified = True
+                publication.save()
+
+        # streaming published end conference should have a streaming propery set to False
+        for conference in Conference.objects.filter(
+                                period=period,
+                                status=3,
+                                streaming=True,
+                                date_end__lt=now):
+            conference.streaming = False
+            conference.save()
+
diff --git a/teleforma/migrations/0007_auto_20231204_1650.py b/teleforma/migrations/0007_auto_20231204_1650.py
new file mode 100644 (file)
index 0000000..fdc7ba3
--- /dev/null
@@ -0,0 +1,28 @@
+# Generated by Django 3.2.13 on 2023-12-04 16:50
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('teleforma', '0006_groupedmessage_studentgroup'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='conference',
+            name='date_publish',
+            field=models.DateTimeField(blank=True, null=True, verbose_name='publishing date'),
+        ),
+        migrations.AddField(
+            model_name='conference',
+            name='notified',
+            field=models.BooleanField(default=False, verbose_name='notified'),
+        ),
+        migrations.AddField(
+            model_name='conference',
+            name='notified_live',
+            field=models.BooleanField(default=False, verbose_name='Notifié live'),
+        ),
+    ]
index 401dab67706ed152548885e607e1cc5db820128d..8ae8e5845629a521082af305daa208ff94311f4b 100755 (executable)
@@ -47,8 +47,9 @@ from django.core.paginator import InvalidPage
 from django.db import models
 from django.forms.fields import FileField
 from django.template.defaultfilters import random, slugify
-from django.urls import reverse_lazy
+from django.urls import reverse_lazy, reverse
 from django.utils.translation import ugettext_lazy as _
+import requests
 # from quiz.models import Quiz
 from sorl.thumbnail import default as sorl_default
 
@@ -387,6 +388,7 @@ class Conference(models.Model):
     comment = ShortTextField(_('comment'), max_length=255, blank=True)
     date_begin = models.DateTimeField(_('begin date'), null=True, blank=True)
     date_end = models.DateTimeField(_('end date'), null=True, blank=True)
+    date_publish = models.DateTimeField(_('publishing date'), null=True, blank=True)
     readers = models.ManyToManyField(User, related_name="conference", verbose_name=_('readers'),
                                      blank=True)
     status = models.IntegerField(
@@ -394,6 +396,8 @@ class Conference(models.Model):
     streaming = models.BooleanField(_('streaming'), default=True)
     # web_class_group = models.ForeignKey('WebClassGroup', related_name='conferences', verbose_name=_('web class group'),
     #                                     blank=True, null=True, on_delete=models.SET_NULL)
+    notified = models.BooleanField(_('notified'), default=False)
+    notified_live = models.BooleanField("Notifié live", default=False)
 
     @property
     def description(self):
@@ -430,6 +434,14 @@ class Conference(models.Model):
         if not self.public_id:
             self.public_id = get_random_hash()
         self.course.save()
+        
+        if self.streaming and not self.notified_live:
+            # Notify live conferences by sending a signal to websocket.
+            # This signal will be catched by the channel instance to notify students
+            from teleforma.models.notification import notify
+            requests.post(f"{settings.CHANNEL_URL}{reverse('teleforma-live-conference-notify')}", {'id': self.id})
+            self.notified_live = True
+        
         super(Conference, self).save(*args, **kwargs)
 
     def to_dict(self):