diff options
-rw-r--r-- | yaksh/fixtures/user_existing_email.csv | 2 | ||||
-rw-r--r-- | yaksh/fixtures/users_add_update_reject.csv | 4 | ||||
-rw-r--r-- | yaksh/static/yaksh/css/custom.css | 6 | ||||
-rw-r--r-- | yaksh/static/yaksh/js/lesson.js | 9 | ||||
-rw-r--r-- | yaksh/templates/yaksh/add_lesson.html | 28 | ||||
-rw-r--r-- | yaksh/templates/yaksh/add_module.html | 51 | ||||
-rw-r--r-- | yaksh/templates/yaksh/editprofile.html | 13 | ||||
-rw-r--r-- | yaksh/templates/yaksh/show_video.html | 6 | ||||
-rw-r--r-- | yaksh/templates/yaksh/statistics_question.html | 109 | ||||
-rw-r--r-- | yaksh/test_views.py | 27 | ||||
-rw-r--r-- | yaksh/views.py | 12 |
11 files changed, 212 insertions, 55 deletions
diff --git a/yaksh/fixtures/user_existing_email.csv b/yaksh/fixtures/user_existing_email.csv new file mode 100644 index 0000000..ee5fcd0 --- /dev/null +++ b/yaksh/fixtures/user_existing_email.csv @@ -0,0 +1,2 @@ +firstname, lastname, email +abc, abc, demo_student@test.com diff --git a/yaksh/fixtures/users_add_update_reject.csv b/yaksh/fixtures/users_add_update_reject.csv index 1990179..2b8fcf6 100644 --- a/yaksh/fixtures/users_add_update_reject.csv +++ b/yaksh/fixtures/users_add_update_reject.csv @@ -1,4 +1,4 @@ firstname, lastname, email, institute,department,roll_no,remove,password,username test, test, test@g.com, TEST, TEST, TEST101, FALSE, TEST, test -test2, test, test@g.com, TEST, TEST, TEST101, FALSE, TEST, test2 -test2, test, test@g.com, TEST, TEST, TEST101, TRUE, TEST, test2 +test2, test, test2@g.com, TEST, TEST, TEST101, FALSE, TEST, test2 +test2, test, test2@g.com, TEST, TEST, TEST101, TRUE, TEST, test2 diff --git a/yaksh/static/yaksh/css/custom.css b/yaksh/static/yaksh/css/custom.css index f995c61..7756478 100644 --- a/yaksh/static/yaksh/css/custom.css +++ b/yaksh/static/yaksh/css/custom.css @@ -131,3 +131,9 @@ body, .dropdown-menu { #question_card { border: none; } + + +iframe { + display:block; + width:100%; +} diff --git a/yaksh/static/yaksh/js/lesson.js b/yaksh/static/yaksh/js/lesson.js index 55d4846..6eaf6c6 100644 --- a/yaksh/static/yaksh/js/lesson.js +++ b/yaksh/static/yaksh/js/lesson.js @@ -32,13 +32,10 @@ $(document).ready(function(){ }); }); - function preview_text(data){ - var preview_div = $("#preview_text_div"); - if (!preview_div.is(":visible")){ - $("#preview_text_div").toggle(); - } + function preview_text(data) { $("#description_body").empty(); - $("#description_body").append(data); + $("#description_body").html(data); + MathJax.Hub.Queue(["Typeset",MathJax.Hub]); } $("#embed").click(function() { diff --git a/yaksh/templates/yaksh/add_lesson.html b/yaksh/templates/yaksh/add_lesson.html index b984db0..4211b1b 100644 --- a/yaksh/templates/yaksh/add_lesson.html +++ b/yaksh/templates/yaksh/add_lesson.html @@ -9,6 +9,8 @@ </script> <script type="text/javascript" src="{% static 'yaksh/js/jquery-ui.js' %}"> </script> +<script type="text/javascript" src="{% static 'yaksh/js/mathjax/MathJax.js' %}?config=TeX-MML-AM_CHTML"> +</script> {% endblock %} {% block css %} @@ -17,15 +19,15 @@ {% endblock %} {% block content %} -<div class="container"> +<div class="container-fluid"> {% if error %} <div class="alert alert-danger"> {{error}} </div> {% endif %} -<div class="container"> +<div class="container-fluid"> <div class="row justify-content-center form-group"> - <div class="col-md-9 col-md-offset-4"> + <div class="col-md-5 col-md-offset-4"> <a class="btn btn-primary" href="{% url 'yaksh:get_course_modules' course_id %}"> <i class="fa fa-arrow-left"></i> Back </a> @@ -137,18 +139,20 @@ </center> </form> <hr> - <div class="card" id="preview_text_div" style="display: none;"> - <div class="card-heading"> - <center> - <h3>Description Preview</h3> - </center> - </div> - <div class="card-body" id="description_body"> - </div> - </div> </fieldset> </form> </div> + <div class="col-md-6"> + <div class="card" id="preview_text_div"> + <div class="card-header"> + <center> + <h3>Description Preview</h3> + </center> + </div> + <div class="card-body" id="description_body"> + </div> + </div> + </div> </div> </div> {% endblock %}
\ No newline at end of file diff --git a/yaksh/templates/yaksh/add_module.html b/yaksh/templates/yaksh/add_module.html index 262c009..7112485 100644 --- a/yaksh/templates/yaksh/add_module.html +++ b/yaksh/templates/yaksh/add_module.html @@ -11,6 +11,8 @@ </script> <script type="text/javascript" src="{% static 'yaksh/js/jquery-ui.js' %}"> </script> +<script type="text/javascript" src="{% static 'yaksh/js/mathjax/MathJax.js' %}?config=TeX-MML-AM_CHTML"> +</script> {% endblock %} {% block css %} @@ -19,17 +21,7 @@ {% endblock %} {% block content %} -<div class="container"> -{% if messages %} - {% for message in messages %} - <div class="alert alert-dismissible alert-{{ message.tags }}"> - <button type="button" class="close" data-dismiss="alert"> - <i class="fa fa-close"></i> - </button> - <strong>{{ message }}</strong> - </div> - {% endfor %} -{% endif %} +<div class="container-fluid"> {% if course_id %} <a class="btn btn-primary" href="{% url 'yaksh:get_course_modules' course_id %}"> <i class="fa fa-arrow-left"></i> @@ -43,10 +35,23 @@ {% endif %} </div> <br> -{% if status == "add" %} <div class="container"> +{% if messages %} + {% for message in messages %} + <div class="alert alert-dismissible alert-{{ message.tags }}"> + <button type="button" class="close" data-dismiss="alert"> + <i class="fa fa-close"></i> + </button> + <strong>{{ message }}</strong> + </div> + {% endfor %} +{% endif %} +</div> +<br> +{% if status == "add" %} +<div class="container-fluid"> <div class="row justify-content-center form-group"> - <div class="col-md-9 col-md-offset-4"> + <div class="col-md-5 col-md-offset-4"> <form name=frm id=frm action="" method="post"> <fieldset> {% csrf_token %} @@ -92,18 +97,20 @@ </center> </form> <hr> - <div class="card" id="preview_text_div" style="display: none;"> - <div class="card-heading"> - <center> - <h3>Description Preview</h3> - </center> - </div> - <div class="card-body" id="description_body"> - </div> - </div> </fieldset> </form> </div> + <div class="col-md-5"> + <div class="card" id="preview_text_div"> + <div class="card-header"> + <center> + <h3>Description Preview</h3> + </center> + </div> + <div class="card-body" id="description_body"> + </div> + </div> + </div> </div> </div> {% endif %} diff --git a/yaksh/templates/yaksh/editprofile.html b/yaksh/templates/yaksh/editprofile.html index 47e74ea..c95da88 100644 --- a/yaksh/templates/yaksh/editprofile.html +++ b/yaksh/templates/yaksh/editprofile.html @@ -6,13 +6,11 @@ <br> <form action="{% url 'yaksh:edit_profile'%}" method="post" > {% csrf_token %} - <center> <div class="row justify-content-center form-group"> <div class="col-md-4 col-md-offset-4"> <form action="" method="post"> <fieldset> {% csrf_token %} - <center> {% if form.errors %} {% for field in form %} {% for error in field.errors %} @@ -34,14 +32,17 @@ {% endfor %} {% endif %} {% for field in form %} - <td>{{ field }} <small>{{ field.help_text }}</small></td> - <br> + <div class="form-group"> + <label> + {{ field.label }} + </label> + {{ field }} + </div> {% endfor %} <br> <br> - </center> <button class="btn btn-success btn-lg" type="submit">Update</button> - <a href="{% url 'yaksh:index' %}" class="btn btn-primary btn-lg">Cancel</a></center> + <a href="{% url 'yaksh:index' %}" class="btn btn-primary btn-lg">Cancel</a> </fieldset> </form> </div> diff --git a/yaksh/templates/yaksh/show_video.html b/yaksh/templates/yaksh/show_video.html index a2edbe0..9c8d133 100644 --- a/yaksh/templates/yaksh/show_video.html +++ b/yaksh/templates/yaksh/show_video.html @@ -1,8 +1,12 @@ {% extends "user.html" %} +{% load static %} {% load custom_filters %} {% block title %} {{ learning_module.name }} {% endblock %} - +{% block script %} +<script type="text/javascript" src="{% static 'yaksh/js/mathjax/MathJax.js' %}?config=TeX-MML-AM_CHTML"> +</script> +{% endblock %} {% block main %} <div class="wrapper"> <!-- Sidebar --> diff --git a/yaksh/templates/yaksh/statistics_question.html b/yaksh/templates/yaksh/statistics_question.html index 58fd8db..9a54501 100644 --- a/yaksh/templates/yaksh/statistics_question.html +++ b/yaksh/templates/yaksh/statistics_question.html @@ -19,12 +19,117 @@ {% if question_stats %} <p><b>Total number of participants: {{ total }}</b></p> <table class="table table-bordered table-responsive-sm"> - <tr class="bg-light yakshred"><th>Question</th><th>Type</th><th>Total</th><th>Answered</th></tr> + <tr class="bg-light yakshred"><th>Question</th><th>Type</th><th>Total</th><th>Answered Correctly</th></tr> {% for question, value in question_stats.items %} - <tr><td>{{ question.summary }}</td><td>{{ question.type }}</td><td>{{value.1}}</td><td>{{ value.0 }} ({% widthratio value.0 value.1 100 %}%)</td></tr> + <tr> + <td>{{ question.summary }} + <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapse_question_{{question.id}}" aria-expanded="false" aria-controls="collapseExample"> + More + </button> + <div class="collapse" id="collapse_question_{{question.id}}"> + <div class="card card-body" style="width: 18rem;"> + <strong> + Summary: + </strong> + <p> + {{ question.summary }} + </p> + <strong> + Description: + </strong> + <p> + {{ question.description }} + </p> + <strong> + Points: + </strong> + <p> + {{ question.points }} + </p> + <strong> + Type: + </strong> + <p> + {{ question.type }} + </p> + {% if question.type in 'mcq mcc' %} + <strong> + Test Cases: + </strong> + <p> + <ol> + {% for tc in question.testcase_set.all %} + <li> + {{ tc.mcqtestcase.options }} + {% if tc.mcqtestcase.correct %} + <span class="badge badge-primary">Correct</span> + {% endif %} + </li> + {% endfor %} + </ol> + </p> + {% endif %} + </div> + </div> + </td> + <td>{{ question.type }}</td> + <td>{{value.1}}</td><td>{{ value.0 }} ({% widthratio value.0 value.1 100 %}%)</td> + + + </tr> {% endfor %} </table> {% endif %} + + <!-- The Modal --> + <div class="modal" id="question_detail_modal"> + <div class="modal-dialog"> + <div class="modal-content"> + + <!-- Modal Header --> + <div class="modal-header"> + <h4 class="modal-title">Question Details</h4> + <button type="button" class="close" data-dismiss="modal">×</button> + </div> + + <!-- Modal body --> + <div class="modal-body"> + <table> + <tr> + <td>Summary</td> + <td>{{ question.summary }}</td> + </tr> + <tr> + <td>Description</td> + <td>{{ question.description }}</td> + </tr> <tr> + <td>Type</td> + <td>{{ question.type }}</td> + </tr> <tr> + <td>Points</td> + <td>{{ question.points }}</td> + </tr> + <tr> + {% for tc in question.testcase_set.all %} + tc + {% endfor %} + <br><br> + </tr> + </table> + </div> + + <!-- Modal footer --> + <div class="modal-footer"> + <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button> + </div> + + </div> + </div> + </div> + + </div> + </div> + <!-- end Modal outer --> </div> </div> </div> diff --git a/yaksh/test_views.py b/yaksh/test_views.py index a7ccac2..5876f03 100644 --- a/yaksh/test_views.py +++ b/yaksh/test_views.py @@ -2755,6 +2755,33 @@ class TestCourseDetail(TestCase): id=uploaded_users.first().id).exists() ) + def test_upload_existing_user_email(self): + # Given + self.client.login( + username=self.user1.username, password=self.user1_plaintext_pass) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + 'user_existing_email.csv') + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + csv_file.close() + + # When + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file}) + + # Then + uploaded_users = User.objects.filter(email='demo_student@test.com') + self.assertEqual(response.status_code, 302) + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertIn('demo_student', messages[0]) + self.assertTrue( + self.user1_course.students.filter( + id=uploaded_users.first().id).exists() + ) + self.assertEqual(uploaded_users.count(), 1) + def test_upload_users_add_update_reject(self): # Given self.client.login( diff --git a/yaksh/views.py b/yaksh/views.py index a1d4e05..53981b5 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -3,7 +3,7 @@ import csv from django.http import HttpResponse, JsonResponse, HttpResponseRedirect from django.contrib.auth import login, logout, authenticate from django.shortcuts import render, get_object_or_404, redirect -from django.template import Context, Template +from django.template import Context, Template, loader from django.http import Http404 from django.db.models import Max, Q, F from django.db import models @@ -23,7 +23,7 @@ from django.urls import reverse import json from textwrap import dedent import zipfile -from markdown import Markdown +import markdown try: from StringIO import StringIO as string_io except ImportError: @@ -101,7 +101,9 @@ CSV_FIELDS = ['name', 'username', 'roll_number', 'institute', 'department', def get_html_text(md_text): """Takes markdown text and converts it to html""" - return Markdown().convert(md_text) + return markdown.markdown( + md_text, extensions=['tables', 'fenced_code'] + ) def formfield_callback(field): @@ -2422,8 +2424,10 @@ def _read_user_csv(request, reader, course): messages.info(request, "{0} -- Missing Values".format(counter)) continue users = User.objects.filter(username=username) + if not users.exists(): + users = User.objects.filter(email=email) if users.exists(): - user = users[0] + user = users.last() if remove.strip().lower() == 'true': _remove_from_course(user, course) messages.info(request, "{0} -- {1} -- User rejected".format( |