Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 00f1209

Browse files
Completed events and quiz
1 parent cf3c092 commit 00f1209

File tree

7 files changed

+140
-6
lines changed

7 files changed

+140
-6
lines changed

‎src/Curriculum/api/base/serializers.py‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,25 @@ class Meta:
174174

175175
class TopicQuizSerializer(serializers.ModelSerializer):
176176
quiz = QuizSerializer(many=True)
177+
mark = serializers.SerializerMethodField()
178+
remaining_time = serializers.SerializerMethodField()
179+
completed = serializers.SerializerMethodField()
177180

178181
class Meta:
179182
model = SyllabiTopic
180-
fields = ['quiz']
183+
fields = ['quiz', 'mark', 'remaining_time', 'completed']
184+
185+
def get_mark(self, obj):
186+
obj = self.context.get("quiz_mark")
187+
return obj.get('mark')
188+
189+
def get_remaining_time(self, obj):
190+
obj = self.context.get("quiz_mark")
191+
return obj.get('remaining_time')
192+
193+
def get_completed(self, obj):
194+
obj = self.context.get("quiz_mark")
195+
return obj.get('completed')
181196

182197

183198
class SubmitQuizOptionSerializer(serializers.Serializer):
@@ -197,10 +212,23 @@ class SubmitQuizResponseSerializer(serializers.Serializer):
197212
class SubmitQuizMarkResponseSerializer(serializers.Serializer):
198213
quiz = SubmitQuizResponseSerializer(many=True)
199214
mark = serializers.IntegerField(help_text="In percentage")
215+
remaining_time = serializers.IntegerField(help_text="In seconds")
200216

201217

202218
class ReviewSerializer(serializers.ModelSerializer):
203219

204220
class Meta:
205221
model = CurriculumReview
206222
fields = ["rating", "review"]
223+
224+
225+
class EventSerializer(serializers.Serializer):
226+
title = serializers.CharField()
227+
start = serializers.DateTimeField()
228+
end = serializers.DateTimeField()
229+
url = serializers.CharField()
230+
upvotes = serializers.IntegerField()
231+
views = serializers.IntegerField()
232+
reading_time = serializers.CharField()
233+
image = serializers.URLField()
234+
projectSummary = serializers.CharField()

‎src/Curriculum/api/base/urls.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
app_name = 'curriculum'
66
urlpatterns = [
77
path('', views.CurriculumList.as_view(), name='list-curriculum'),
8+
path(
9+
'upcoming-events/',
10+
views.GetUpcomingEvents.as_view(),
11+
name='upcoming-events'),
812
path(
913
'enrolled/', views.GetEnrolledCurriculums.as_view(),
1014
name='get-enrolled-curriculums'),

‎src/Curriculum/api/base/views.py‎

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from django.conf import settings
44
from django.http import HttpResponseBadRequest, HttpResponseNotFound
5+
from django.utils.decorators import method_decorator
6+
from django.views.decorators.cache import cache_page
57
from drf_yasg.utils import swagger_auto_schema
68
from rest_framework import generics, status
79
from rest_framework.response import Response
@@ -10,6 +12,7 @@
1012
from Quiz.models import QOption, Quiz
1113
from utils.base.date import dt_now
1214
from utils.base.mindsdb import classify_text, sentiment_text
15+
from utils.base.showwcase import show_get
1316

1417
from . import serializers
1518

@@ -118,6 +121,45 @@ class GetTopicQuiz(generics.RetrieveAPIView):
118121
serializer_class = serializers.TopicQuizSerializer
119122
lookup_field = "slug"
120123

124+
def get_quiz_mark(self):
125+
"""
126+
Get the mark of the quiz if it exists
127+
"""
128+
try:
129+
syllabi_progress: SyllabiProgress = SyllabiProgress.objects\
130+
.get_by_user_and_topic(
131+
self.request.user, self.kwargs.get(self.lookup_field)
132+
)
133+
except SyllabiProgress.DoesNotExist:
134+
return HttpResponseNotFound("Quiz does not exists")
135+
136+
rem_time = 0
137+
if syllabi_progress.last_attempted:
138+
rem_time = (
139+
dt_now() - syllabi_progress.last_attempted).seconds
140+
rem_time = settings.TEST_INTERVAL_SECONDS - rem_time
141+
142+
return {
143+
"completed": syllabi_progress.completed,
144+
"mark": syllabi_progress.quiz_mark,
145+
"remaining_time": max(rem_time, 0)
146+
}
147+
148+
def retrieve(self, request, *args, **kwargs):
149+
instance = self.get_object()
150+
quiz_mark = self.get_quiz_mark()
151+
if isinstance(quiz_mark, HttpResponseNotFound):
152+
return quiz_mark
153+
154+
serializer_class = self.get_serializer_class()
155+
serializer = serializer_class(
156+
instance, context={
157+
"request": request,
158+
"quiz_mark": quiz_mark
159+
}
160+
)
161+
return Response(serializer.data)
162+
121163
def get_queryset(self):
122164
return SyllabiTopic.objects.all()
123165

@@ -139,6 +181,7 @@ def validate_request(self):
139181

140182
if syllabi_progress.last_attempted:
141183
diff = dt_now() - syllabi_progress.last_attempted
184+
print(diff.total_seconds())
142185
if (diff.total_seconds() < settings.TEST_INTERVAL_SECONDS):
143186
return Response("Time interval for \
144187
test retake not reached", status=status.HTTP_400_BAD_REQUEST)
@@ -199,7 +242,8 @@ def post(self, request, *args, **kwargs):
199242

200243
data = {
201244
"quiz": quiz_response,
202-
"mark": syllabi_progress.quiz_mark
245+
"mark": syllabi_progress.quiz_mark,
246+
"remaining_time": settings.TEST_INTERVAL_SECONDS
203247
}
204248
return Response(data)
205249

@@ -301,3 +345,33 @@ def perform_create(self, serializer):
301345
)
302346
def post(self, request, *args, **kwargs):
303347
return super().post(request, *args, **kwargs)
348+
349+
350+
class GetUpcomingEvents(generics.ListAPIView):
351+
serializer_class = serializers.EventSerializer
352+
permission_classes = []
353+
354+
def get_queryset(self):
355+
results = show_get("/events/upcoming")
356+
if not results:
357+
results = []
358+
359+
def _mapper(data):
360+
return {
361+
"title": data.get("name"),
362+
"start": data.get("start_date"),
363+
"end": data.get("end_date"),
364+
"url": data.get("project").get("_self"),
365+
"upvotes": data.get("project").get("totalUpvotes"),
366+
"views": data.get("project").get("totalViews"),
367+
"reading_time": data.get("project")
368+
.get("readingStats").get("text"),
369+
"image": data.get("project").get("coverImageUrl"),
370+
"projectSummary": data.get("project").get("projectSummary"),
371+
}
372+
373+
return list(map(_mapper, results))
374+
375+
@method_decorator(cache_page(settings.SHOWWCASE_API_CACHE_TIME))
376+
def get(self, request, *args, **kwargs):
377+
return super().get(request, *args, **kwargs)

‎src/Curriculum/models.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django.db import models
66
from django.db.models.signals import pre_save
77
from django.dispatch import receiver
8+
from sqlalchemy import all_
89

910
from Curriculum.managers import SyllabiProgressManager
1011
from Quiz.models import Quiz
@@ -217,3 +218,15 @@ def set_syllabi_order(sender, instance, **kwargs):
217218
def set_topic_order(sender, instance, **kwargs):
218219
if not instance.id and instance.order == 0:
219220
instance.order = instance.syllabi.get_next_order()
221+
222+
223+
@receiver(pre_save, sender=SyllabiProgress)
224+
def set_enrollment_progress(sender, instance: SyllabiProgress, **kwargs):
225+
enrollment = instance.enrollment
226+
all_syllabi = SyllabiProgress.objects.filter(
227+
enrollment=enrollment
228+
)
229+
completed_syllabi = all_syllabi.filter(completed=True)
230+
enrollment.progress = round(
231+
(completed_syllabi.count() / all_syllabi.count()) * 100, 2)
232+
enrollment.save()

‎src/Curriculum/views.py‎

Lines changed: 0 additions & 3 deletions
This file was deleted.

‎src/config/settings/base.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,11 @@
240240
OTP_CACHE_TIMEOUT = 30 * 60 # 30 minutes
241241
DEFAULT_OTP = "123456"
242242

243-
TEST_INTERVAL_SECONDS = 0 * 24 * 60 * 60
243+
TEST_INTERVAL_SECONDS = 10# 1 * 24 * 60 * 60
244244

245245
MINDSDB_SERVER_USERNAME = config("MINDSDB_SERVER_USERNAME")
246246
MINDSDB_SERVER_PASSWORD = config("MINDSDB_SERVER_PASSWORD")
247+
248+
SHOWWCASE_API_KEY = config("SHOWWCASE_API_KEY")
249+
SHOWWCASE_BASE_URL = "https://cache.showwcase.com"
250+
SHOWWCASE_API_CACHE_TIME = 60 * 60 * 2 # 2 hours

‎src/utils/base/showwcase.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from urllib.parse import urljoin
2+
from django.conf import settings
3+
import requests
4+
5+
HEADERS = {
6+
"x-api-key": settings.SHOWWCASE_API_KEY
7+
}
8+
9+
10+
def show_get(endpoint: str):
11+
url = urljoin(settings.SHOWWCASE_BASE_URL, endpoint)
12+
response = requests.get(url, headers=HEADERS)
13+
if response.status_code == 200:
14+
return response.json()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /