import urllib.parse from django.utils.translation import gettext as _ from rest_framework.response import Response from rest_framework.exceptions import NotFound, PermissionDenied from rest_framework.permissions import AllowAny, IsAuthenticated from university.api.base import Endpoint from university.api.bases.course import CourseEndpoint from university.api.bases.chapter import ChapterEndpoint from university.api.bases.lesson import LessonEndpoint from university.models import Lesson, Question from university.user_behavior_track import report_event class AllRecommendEndpoint(Endpoint): permission_classes = (AllowAny, ) def get(self, request, *args, **kwargs): datas = [] recommend_lessons_id = [1, 2, 45] for lesson in Lesson.objects.select_related( 'chapter', 'chapter__course', 'cover_image')\ .filter(id__in=recommend_lessons_id)[:6]: chapter = lesson.chapter course = chapter.course datas.append({ 'title': lesson.title, 'short_title': lesson.short_title, 'slug': lesson.slug, 'description': lesson.description, 'speaker': lesson.speaker, 'periods': lesson.periods, 'cover_url': lesson.cover_image.url if lesson.cover_image else None, 'types': lesson.types, 'course': { 'slug': course.slug, 'title': course.title, 'description': course.description, 'cover_url': course.cover_image.url, 'license': course.license }, 'chapter': { 'title': chapter.title, 'slug': chapter.slug, 'description': chapter.description } }) return Response({'detail': _('success'), 'datas': datas}) class CourseRecommendEndpoint(CourseEndpoint): permission_classes = (AllowAny, ) def get(self, request, *args, **kwargs): course = kwargs['course'] datas = [] recommend_lessons_id = [] if course.slug == 'PCTA': recommend_lessons_id = [3, 4, 11] elif course.slug == 'PCTP': recommend_lessons_id = [5, 6, 7] for lesson in Lesson.objects.select_related('chapter', 'cover_image')\ .filter(id__in=recommend_lessons_id, cover_image__isnull=False)[:3]: chapter = lesson.chapter datas.append({ 'title': lesson.title, 'short_title': lesson.short_title, 'slug': lesson.slug, 'description': lesson.description, 'speaker': lesson.speaker, 'periods': lesson.periods, 'cover_url': lesson.cover_image.url if lesson.cover_image else None, 'types': lesson.types, 'course': { 'slug': course.slug, 'title': course.title, 'description': course.description, 'cover_url': course.cover_image.url, 'license': course.license }, 'chapter': { 'title': chapter.title, 'slug': chapter.slug, 'description': chapter.description } }) return Response({'detail': _('success'), 'datas': datas}) class ChapterLessonListEndpoint(ChapterEndpoint): permission_classes = (AllowAny, ) def get(self, request, *args, **kwargs): chapter = kwargs['chapter'] datas = [] has_course = request.user.has_course(chapter.course) for lesson in chapter.lesson_set.all().order_by('sequence'): datas.append({ 'title': lesson.title, 'short_title': lesson.short_title, 'slug': lesson.slug, 'description': lesson.description, 'speaker': lesson.speaker, 'periods': lesson.periods, 'cover_url': lesson.cover_image.url if lesson.cover_image else None, 'types': lesson.types, # For reduce request to database, do not use `has_lesson` 'has_permission': has_course or lesson.is_free }) return Response({'detail': _('success'), 'datas': datas}) class LessonDetailEndpoint(LessonEndpoint): permission_classes = (AllowAny, ) def get(self, request, lesson, chapter, course, *args, **kwargs): datas = { 'title': lesson.title, 'short_title': lesson.short_title, 'slug': lesson.slug, 'description': lesson.description, 'objectives': lesson.objectives, 'key_points': lesson.key_points, 'speaker': lesson.speaker, 'periods': lesson.periods, 'cover_url': lesson.cover_image.url if lesson.cover_image else None, 'types': lesson.types, 'is_authenticated': True if request.user.is_authenticated else False, 'has_permission': False, 'syllabus': None, 'quiz': None } if request.user.has_lesson(lesson): if request.user.is_authenticated: report_event( request.user, 'pu.view_lesson', { 'lesson_id': lesson.id, 'lesson_slug': lesson.slug, 'lesson_title': lesson.title, 'chapter_id': chapter.id, 'chapter_slug': chapter.slug, 'course_id': course.id, 'course_slug': course.slug }, request, '学习了课程 [{lesson_title}]({lesson_url})'.format( lesson_title=lesson.title, lesson_url='https://university.pingcap.com/courses/{}/chapter/{}/lesson/{}'.format( urllib.parse.quote(course.slug), urllib.parse.quote(chapter.slug), urllib.parse.quote(lesson.slug))) ) # Mark lesson as read when user access lesson details request.user.mark_lesson_as_read(lesson) if lesson.has_quiz(): questions, is_passed = lesson.get_quiz(request.user) quiz = { 'questions': questions, 'is_passed': is_passed } else: quiz = None datas.update({ 'has_permission': True, 'syllabus': lesson.get_syllabus(request.user), 'quiz': quiz }) return Response({ 'detail': _('success'), 'datas': datas }) class QuizEndpint(LessonEndpoint): permission_classes = (IsAuthenticated, ) def post(self, request, lesson, chapter, course, *args, **kwargs): if not request.user.has_lesson(lesson): raise PermissionDenied if not lesson.has_quiz(): raise NotFound try: data = dict() for question in lesson.quiz.questions.all(): question_id = str(question.id) data[question_id] = request.data['answers'][question_id] == question.answer user_quiz, is_created = request.user.userquiz_set.get_or_create( quiz=lesson.quiz, lesson=lesson, chapter=chapter, course=course) user_quiz.answer = request.data['answers'] user_quiz.is_passed = all(data.values()) user_quiz.save() report_event( request.user, 'pu.submit_quiz', { 'lesson_id': lesson.id, 'lesson_slug': lesson.slug, 'lesson_title': lesson.title, 'quiz_id': lesson.quiz.id, 'is_passed': user_quiz.is_passed }, request, '在课程 {lesson_title} 提交了课后练习题, 结果: {result}'.format( lesson_title=lesson.title, result='通过' if user_quiz.is_passed else '未通过' ) ) return Response({ 'detail': _('success'), 'datas': data }) except Exception: return Response({ 'detail': _('params error') }, status=400) class QuizHintEndpint(LessonEndpoint): permission_classes = (IsAuthenticated, ) def get(self, request, lesson, *args, **kwargs): if not request.user.has_lesson(lesson): raise PermissionDenied if not lesson.has_quiz(): raise NotFound try: hint = lesson.quiz.questions.get(pk=kwargs['question_id']).hint return Response({ 'detail': _('success'), 'datas': { 'hint': hint } }) except Question.DoesNotExist: raise NotFound