|
|
|
@ -1,9 +1,14 @@ |
|
|
|
import logging |
|
|
|
from django.utils import timezone |
|
|
|
from apps.course.models import Course |
|
|
|
from apps.chat.models import RoomMessage |
|
|
|
from apps.course.models.course import Course, extract_text_from_json |
|
|
|
from apps.course.models.lesson import CourseLesson |
|
|
|
from apps.course.models.live_session import LiveSessionRecording |
|
|
|
from django.db.models import Q |
|
|
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
from django.db.models.signals import post_save, post_delete, pre_save |
|
|
|
from django.dispatch import receiver |
|
|
|
from django.core.cache import cache |
|
|
|
@ -124,3 +129,71 @@ def sync_lessons_count_on_course_lesson_save(sender, instance, **kwargs): |
|
|
|
@receiver(post_delete, sender=CourseLesson) |
|
|
|
def sync_lessons_count_on_course_lesson_delete(sender, instance, **kwargs): |
|
|
|
_recalculate_course_lessons_count(instance.course_id) |
|
|
|
|
|
|
|
|
|
|
|
@receiver(post_save, sender=LiveSessionRecording) |
|
|
|
def create_course_lesson_from_recording(sender, instance, **kwargs): |
|
|
|
""" |
|
|
|
Automatically creates a CourseChapter (if not exists) and CourseLesson |
|
|
|
whenever a LiveSessionRecording is saved with a valid file. |
|
|
|
""" |
|
|
|
if not instance.file: |
|
|
|
return |
|
|
|
|
|
|
|
# To avoid duplicate creation if save is called multiple times |
|
|
|
from apps.course.models.lesson import Lesson, CourseChapter, CourseLesson |
|
|
|
if Lesson.objects.filter(content_file=instance.file.name).exists(): |
|
|
|
return |
|
|
|
|
|
|
|
session = instance.session |
|
|
|
course = session.course |
|
|
|
|
|
|
|
# 1. Determine chapter title as recording date (YYYY-MM-DD) |
|
|
|
date_val = instance.created_at or timezone.now() |
|
|
|
recording_date_str = date_val.strftime('%Y-%m-%d') |
|
|
|
|
|
|
|
# 2. Get or create CourseChapter for this date |
|
|
|
from apps.course.models.course import extract_text_from_json |
|
|
|
chapter = None |
|
|
|
for ch in CourseChapter.objects.filter(course=course): |
|
|
|
if extract_text_from_json(ch.title) == recording_date_str: |
|
|
|
chapter = ch |
|
|
|
break |
|
|
|
|
|
|
|
if not chapter: |
|
|
|
chapter = CourseChapter.objects.create( |
|
|
|
course=course, |
|
|
|
title=recording_date_str, |
|
|
|
is_active=True |
|
|
|
) |
|
|
|
|
|
|
|
# 3. Calculate next part number based on total lessons in the course |
|
|
|
lessons_count = CourseLesson.objects.filter(course=course).count() |
|
|
|
part_num = lessons_count + 1 |
|
|
|
lesson_title = f"Part {part_num}" |
|
|
|
|
|
|
|
# 4. Calculate duration in minutes |
|
|
|
duration_minutes = 0 |
|
|
|
if instance.file_time: |
|
|
|
duration_minutes = int(instance.file_time.total_seconds() / 60) |
|
|
|
if duration_minutes == 0 and instance.file_time.total_seconds() > 0: |
|
|
|
duration_minutes = 1 |
|
|
|
|
|
|
|
# 5. Create the Lesson object |
|
|
|
lesson = Lesson.objects.create( |
|
|
|
title=lesson_title, |
|
|
|
content_type="video_file", |
|
|
|
content_file=instance.file, |
|
|
|
duration=duration_minutes |
|
|
|
) |
|
|
|
|
|
|
|
# 6. Create the CourseLesson object linking it to the chapter |
|
|
|
course_lesson = CourseLesson.objects.create( |
|
|
|
course=course, |
|
|
|
chapter=chapter, |
|
|
|
lesson=lesson, |
|
|
|
title=lesson_title, |
|
|
|
is_active=True |
|
|
|
) |
|
|
|
|
|
|
|
logger.info(f"✨ [Signal] Automatically created CourseLesson {course_lesson.id} ({lesson_title}) for course {course.id} from recording {instance.id}") |