import requests from django.utils.translation import gettext as _ from django.db.models import Count, Sum from django.http.response import HttpResponse, Http404 from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated, AllowAny from university.api.base import Endpoint from university.models import Course, Lesson, UserLessonLearnHistory, Quiz, UserQuiz from university.forms import UserinfoForm class MeEndpoint(Endpoint): permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): user = request.user return Response({ 'detail': _('success'), 'datas': { 'username': user.username, 'avatar_url': user.avatar_url, 'industry': user.industry, 'job_title': user.job_title, 'tidb_relation': user.tidb_relation, 'newsql_usage_stage': user.newsql_usage_stage, 'want_try_tidb_version': user.want_try_tidb_version, 'tried_tidb_version': user.tried_tidb_version, 'accept_edm': user.accept_edm } }) def post(self, request, *args, **kwargs): form = UserinfoForm(request.user, data=request.data) if not form.is_valid(): return Response({ 'detail': _('wrong params'), 'errors': form.errors }, status=400) else: form.save() return Response({'detail': 'success'}) class AvatarProxyEndpoint(Endpoint): permission_classes = (AllowAny, ) def get(self, request, letter, color, size): avatar_url = 'https://avatars.discourse.org/v4/letter/{}/{}/{}.png'\ .format(letter, color, size) response = requests.get(avatar_url) return HttpResponse(response.content, content_type="image/png") class LearningEndpoint(Endpoint): permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): courses_history = UserLessonLearnHistory \ .objects \ .select_related('course') \ .filter(user=request.user) \ .values('course_id', 'course__slug', 'course__title') \ .annotate(Sum('progress'), Count('progress')) \ .order_by('-course_id') courses_ids = set([c['course_id'] for c in courses_history]) # TODO: Save lesson_count in `Course` model _lessons_count = Lesson.objects \ .filter(chapter__course__id__in=courses_ids) \ .values('chapter__course__id') \ .annotate(count=Count('id')) lessons_count = dict([(l['chapter__course__id'], l['count']) for l in _lessons_count]) _quiz_count = Quiz.objects \ .filter(course_id__in=courses_ids) \ .values('course_id') \ .annotate(count=Count('id')) quiz_count = dict([(q['course_id'], q['count']) for q in _quiz_count]) _passed_quiz = UserQuiz.objects \ .filter(is_passed=True, user=request.user) \ .values('course_id') \ .annotate(count=Count('id')) passed_quiz = dict([(p['course_id'], p['count']) for p in _passed_quiz]) data = {} for item in courses_history: number_of_lessons = lessons_count[item['course_id']] last_visted = UserLessonLearnHistory \ .objects \ .select_related('lesson', 'chapter') \ .filter(user=request.user, course_id=item['course_id']) \ .values('chapter__slug', 'lesson__slug', 'lesson__title', 'progress') \ .order_by('-last_visited_at').first() quiz = None if quiz_count.get(item['course_id']): quiz = { 'number_of_quiz': quiz_count[item['course_id']], 'passed_count': passed_quiz.get(item['course_id'], 0) } data[item['course_id']] = { 'slug': item['course__slug'], 'title': item['course__title'], 'number_of_lessons': number_of_lessons, 'last_visited': { 'course_slug': item['course__slug'], 'chapter_slug': last_visted['chapter__slug'], 'lesson_slug': last_visted['lesson__slug'], 'lesson_title': last_visted['lesson__title'], 'progress': last_visted['progress'] }, 'visited': { 'visited_count': item['progress__count'], 'progress': item['progress__sum'] / number_of_lessons }, 'quiz': quiz, 'exam': None } return Response({ 'detail': _('success'), 'data': data.values() }) class CourseLearningEndpoint(Endpoint): permission_classes = (IsAuthenticated, ) def get(self, request, course_slug, *args, **kwargs): try: course = Course.objects.get(slug=course_slug) except Exception: raise Http404 course_history = UserLessonLearnHistory \ .objects \ .select_related('course', 'chapter', 'lesson') \ .filter(user=request.user, course=course) \ .values( 'progress', 'course__slug', 'course__title', 'lesson__slug', 'lesson__title', 'lesson__sequence', 'chapter_id', 'chapter__slug', 'chapter__title', 'chapter__sequence') number_of_lessons = Lesson.objects.filter(chapter__course=course).count() data = { 'slug': course_history[0]['course__slug'], 'title': course_history[0]['course__title'], 'progress': 0 } chapters = {} for item in course_history: # Init chapters if item['chapter_id'] not in chapters: chapters[item['chapter_id']] = { 'slug': item['chapter__slug'], 'title': item['chapter__title'], 'sequence': item['chapter__sequence'], 'lessons': [{ 'slug': item['lesson__slug'], 'title': item['lesson__title'], 'progress': item['progress'], 'sequence': item['lesson__sequence'] }] } else: chapters[item['chapter_id']]['lessons'].append({ 'slug': item['lesson__slug'], 'title': item['lesson__title'], 'progress': item['progress'], 'sequence': item['lesson__sequence'] }) for chapter_id, chapter in chapters.items(): chapter['lessons'] = sorted( chapter['lessons'], key=lambda d: d['sequence']) data['progress'] += sum( map(lambda l: l['progress'] / number_of_lessons, chapter['lessons'])) data['chapters'] = sorted(chapters.values(), key=lambda ch: ch['sequence']) return Response({ 'detail': _('success'), 'data': data })