From 81667305df2bc148e4ca6247ad3b2d12b30e660c Mon Sep 17 00:00:00 2001
From: adityacp
Date: Mon, 9 Mar 2020 17:10:10 +0530
Subject: Download course progress
---
yaksh/models.py | 3 +++
yaksh/templates/yaksh/course_progress.html | 13 +++++++++++--
yaksh/urls.py | 2 ++
yaksh/views.py | 25 +++++++++++++++++++++++++
4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/yaksh/models.py b/yaksh/models.py
index e161543..072c1b5 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -648,6 +648,9 @@ class LearningUnit(models.Model):
order=self.order, type="lesson", lesson=new_lesson)
return new_unit
+ def __str__(self):
+ return self.lesson.name if self.lesson else self.quiz.description
+
###############################################################################
class LearningModule(models.Model):
diff --git a/yaksh/templates/yaksh/course_progress.html b/yaksh/templates/yaksh/course_progress.html
index a833c92..826f84b 100644
--- a/yaksh/templates/yaksh/course_progress.html
+++ b/yaksh/templates/yaksh/course_progress.html
@@ -4,10 +4,19 @@
{% if student_details %}
Course Progress
-
- Number Of Students: {{ students_no }}
+
+
+
+ Number Of Students: {{ students_no }}
+
+
+
{% include "yaksh/paginator.html" %}
diff --git a/yaksh/urls.py b/yaksh/urls.py
index 49c3d4f..b53d335 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -218,4 +218,6 @@ urlpatterns = [
views.get_course_modules, name="get_course_modules"),
url(r'^manage/course/teachers/(?P\d+)',
views.course_teachers, name="course_teachers"),
+ url(r'^manage/download/course/progress/(?P\d+)',
+ views.download_course_progress, name="download_course_progress"),
]
diff --git a/yaksh/views.py b/yaksh/views.py
index 5d2d560..58fe6e2 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -3155,3 +3155,28 @@ def get_course_modules(request, course_id):
modules = course.get_learning_modules()
context = {"modules": modules, "is_modules": True, "course": course}
return my_render_to_response(request, 'yaksh/course_detail.html', context)
+
+
+@login_required
+@email_verified
+def download_course_progress(request, course_id):
+ user = request.user
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page!')
+ course = get_object_or_404(Course, pk=course_id)
+ if not course.is_creator(user) and not course.is_teacher(user):
+ raise Http404('This course does not belong to you')
+ students = course.students.order_by("-id")
+ stud_details = [(student.get_full_name(), course.get_grade(student),
+ course.get_completion_percent(student),
+ course.get_current_unit(student))
+ for student in students]
+ response = HttpResponse(content_type='text/csv')
+ response['Content-Disposition'] = 'attachment; filename="{0}.csv"'.format(
+ (course.name).lower().replace(' ', '_'))
+ header = ['Name', 'Grade', 'Completion Percent', 'Current Unit']
+ writer = csv.writer(response)
+ writer.writerow(header)
+ for student in stud_details:
+ writer.writerow(student)
+ return response
--
cgit
From 9dacf7cf2a26fb0f954f6f06cfffb65e23809ab7 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Mon, 9 Mar 2020 18:47:06 +0530
Subject: Add tests to check download course progress
---
yaksh/test_views.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 58c6633..1c7c150 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -4211,6 +4211,24 @@ class TestDownloadCsv(TestCase):
self.assertEqual(response.get('Content-Disposition'),
'attachment; filename="{0}"'.format(file_name))
+ def test_download_course_progress_csv(self):
+ """
+ Check for csv result of a course progress
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.get(
+ reverse('yaksh:download_course_progress',
+ kwargs={'course_id': self.course.id}),
+ follow=True
+ )
+ file_name = "{0}.csv".format(self.course.name.lower().replace(" ", "_"))
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.get('Content-Disposition'),
+ 'attachment; filename="{0}"'.format(file_name))
+
def test_download_quiz_csv(self):
"""
Check for csv result of a quiz
--
cgit
From 077b15c67238578a7d877a53748ce46065905ddf Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Wed, 11 Mar 2020 15:19:17 +0530
Subject: Release 0.13.0 related changes
---
CHANGELOG.txt | 8 ++++++++
online_test/__init__.py | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 4145e07..18063e5 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,11 @@
+=== 0.13.0 (11-03-2020) ===
+
+* Revamped the UI and UX for the interface and standardised with Bootstrap 4 (Lumen theme from https://bootswatch.com/)
+* Fixed a bug that caused failure when pre-existing tags for Questions have first capital letter
+* Registered CourseStatus model so that it is available on the Django admin interface
+* Added filters in the Django admin for filtering courses
+* Modified admin.py to display only specific fields of AnswerPaper
+
=== 0.12.0 (04-02-2020) ===
* Added syntax highlighting to the code answers in answerpaper
diff --git a/online_test/__init__.py b/online_test/__init__.py
index 2c7bffb..2d7893e 100644
--- a/online_test/__init__.py
+++ b/online_test/__init__.py
@@ -1 +1 @@
-__version__ = '0.12.0'
+__version__ = '0.13.0'
--
cgit
From 050ced8942abf802cf09e6a6f9d23d85a0be0d3f Mon Sep 17 00:00:00 2001
From: adityacp
Date: Thu, 12 Mar 2020 11:08:15 +0530
Subject: Avoid conditional check on foreign key
---
yaksh/models.py | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/yaksh/models.py b/yaksh/models.py
index 072c1b5..065d9cd 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -598,7 +598,12 @@ class LearningUnit(models.Model):
check_prerequisite = models.BooleanField(default=True)
def get_lesson_or_quiz(self):
- return self.lesson if self.lesson else self.quiz
+ unit = None
+ if self.type == 'lesson':
+ unit = self.lesson
+ else:
+ unit = self.quiz
+ return unit
def toggle_check_prerequisite(self):
if self.check_prerequisite:
@@ -649,7 +654,12 @@ class LearningUnit(models.Model):
return new_unit
def __str__(self):
- return self.lesson.name if self.lesson else self.quiz.description
+ name = None
+ if self.type == 'lesson':
+ name = self.lesson.name
+ else:
+ name = self.quiz.description
+ return name
###############################################################################
--
cgit
From a2186d263aa8927a47fdb9f3a23ad39841b64b33 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Thu, 12 Mar 2020 11:30:51 +0530
Subject: Fix test to get lesson or quiz for a unit
---
yaksh/test_models.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/yaksh/test_models.py b/yaksh/test_models.py
index 6e5a26d..a60a1d6 100644
--- a/yaksh/test_models.py
+++ b/yaksh/test_models.py
@@ -322,8 +322,12 @@ class LearningUnitTestCases(unittest.TestCase):
def test_learning_unit(self):
self.assertEqual(self.learning_unit_one.type, 'lesson')
self.assertEqual(self.learning_unit_two.type, 'quiz')
- self.assertEqual(self.learning_unit_one.lesson, self.lesson)
- self.assertEqual(self.learning_unit_two.quiz, self.quiz)
+ self.assertEqual(
+ self.learning_unit_one.get_lesson_or_quiz(), self.lesson
+ )
+ self.assertEqual(
+ self.learning_unit_two.get_lesson_or_quiz(), self.quiz
+ )
self.assertIsNone(self.learning_unit_one.quiz)
self.assertIsNone(self.learning_unit_two.lesson)
self.assertTrue(self.learning_unit_one.check_prerequisite)
--
cgit
From 8835afbc95c1a398cf62da7880596e7a302ae148 Mon Sep 17 00:00:00 2001
From: manojvaghela
Date: Wed, 18 Mar 2020 16:36:52 +0530
Subject: Search bar added
---
yaksh/forms.py | 19 +++++++++
yaksh/templates/yaksh/courses.html | 28 +++++++++++-
yaksh/templates/yaksh/lessons.html | 30 ++++++++++++-
yaksh/templates/yaksh/modules.html | 30 ++++++++++++-
yaksh/templates/yaksh/quizzes.html | 30 ++++++++++++-
yaksh/views.py | 87 +++++++++++++++++++++++++++++++++++---
6 files changed, 212 insertions(+), 12 deletions(-)
diff --git a/yaksh/forms.py b/yaksh/forms.py
index 7d5362b..c0f40ea 100644
--- a/yaksh/forms.py
+++ b/yaksh/forms.py
@@ -49,6 +49,12 @@ test_case_types = (
("floattestcase", "Float Testcase"),
)
+status_types = (
+ ('select','Select Status'),
+ ('active', 'Active'),
+ ('closed', 'Inactive'),
+ )
+
UNAME_CHARS = letters + "._" + digits
PWD_CHARS = letters + punctuation + digits
@@ -377,6 +383,19 @@ class QuestionFilterForm(forms.Form):
)
+class SearchFilterForm(forms.Form):
+ search_tags = forms.CharField(
+ label='Search Tags',
+ widget=forms.TextInput(attrs={'placeholder': 'Search',
+ 'class': form_input_class,}),
+ required=False
+ )
+ search_status = forms.CharField(max_length=16, widget=forms.Select(
+ choices=status_types,
+ attrs={'class': 'custom-select'}),
+ )
+
+
class CourseForm(forms.ModelForm):
""" course form for moderators """
class Meta:
diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html
index 0eb9a38..cc4c69f 100644
--- a/yaksh/templates/yaksh/courses.html
+++ b/yaksh/templates/yaksh/courses.html
@@ -61,6 +61,32 @@
{% else %}
+
+
+ {{ courses_found }} Course(s) Available
+
{% if messages %}
{% for message in messages %}