diff options
-rw-r--r-- | requirements/requirements-common.txt | 1 | ||||
-rw-r--r-- | yaksh/demo_templates/yaml_question_template | 90 | ||||
-rw-r--r-- | yaksh/static/yaksh/js/show_question.js | 4 | ||||
-rw-r--r-- | yaksh/templates/yaksh/showquestions.html | 86 | ||||
-rw-r--r-- | yaksh/urls.py | 4 | ||||
-rw-r--r-- | yaksh/views.py | 17 |
6 files changed, 188 insertions, 14 deletions
diff --git a/requirements/requirements-common.txt b/requirements/requirements-common.txt index 53a44a4..6169c9b 100644 --- a/requirements/requirements-common.txt +++ b/requirements/requirements-common.txt @@ -6,3 +6,4 @@ tornado selenium==2.53.6 coverage psutil +pyyaml
\ No newline at end of file diff --git a/yaksh/demo_templates/yaml_question_template b/yaksh/demo_templates/yaml_question_template new file mode 100644 index 0000000..4de9274 --- /dev/null +++ b/yaksh/demo_templates/yaml_question_template @@ -0,0 +1,90 @@ +--- +# Yaml Template for writing questions +# Always keep the name of this file as questions_dump.yaml +# Zip this file with necessary dependent files. + +active: true +# question status = true or false + +description: "Write a function <code>product(a,b)</code> which will take + two integers and return the product of it.<br> + " +# Entire question description. + +files: [] +# [[file name, zip_extract_status=true or false]] + +language: python +# bash, scilab, python, c/c++, java + +points: 1.0 +# marks in float + +snippet: "def sum(a,b):" +# adds in the student's code area + +summary: Product of two numbers +# one line short Summary +testcase: +- test_case_type: standardtestcase + test_case: assert sum(3,5) == 15 + test_case_args: "" + weight: 1.0 +#testcase 1 + +- test_case_type: standardtestcase + test_case: assert sum(10,10) == 100 + test_case_args: "" + weight: 1.0 +#testcase 2 + +# for standard testcase: + # - test_case_type: standardtestcase + # test_case: test case in the selected language + # test_case_args: command line args (only for bash) + # weight: weightage for each course + +# for stdIO testcase: + # - test_case_type: stdiobasedtestcase + # expected_input: Standard input given to the students' code. (Optional) + # expected_input: Standard output expected from the students' code. + # weight: weightage for each course + +# for MCQ/MCC testcase: + # - test_case_type: mcqtestcase + # options: MCQ/MCC option. + # correct: true or false. + +# for Hook testcase: + # - test_case_type: hooktestcase + # hook_code: Selected language code written by moderator (Optional) + # weight: weightage for each course + +# for Integer testcase: + # - test_case_type: integertestcase + # correct: Correct integer value + +# for Float testcase: + # - test_case_type: floattestcase + # correct: Correct float value + # error_margin: Margin of error allowed + +# for String testcase: + # - test_case_type: stringtestcase + # correct: Exact string to be compared + # string_check: lower or exact.(case insensitive or sensitive) + +type: code +# mcq, Single Correct Choice, +# mcc, Multiple Correct Choices, +# code, Code Question, +# upload, Assignment Upload, +# integer, Answer in Integer, +# string, Answer in String, +# float, Answer in Float + +grade_assignment_upload: false +# Grade uploaded assignment (works with hook)true or false + +partial_grading: false +# partial grading with respect to each testcase. diff --git a/yaksh/static/yaksh/js/show_question.js b/yaksh/static/yaksh/js/show_question.js index e3ed1cc..7cfbf4c 100644 --- a/yaksh/static/yaksh/js/show_question.js +++ b/yaksh/static/yaksh/js/show_question.js @@ -37,3 +37,7 @@ function confirm_edit(frm) else return true; } +$(document).ready(function() + { + $("#questions-table").tablesorter({sortList: [[]]}); + });
\ No newline at end of file diff --git a/yaksh/templates/yaksh/showquestions.html b/yaksh/templates/yaksh/showquestions.html index a136ddf..78be301 100644 --- a/yaksh/templates/yaksh/showquestions.html +++ b/yaksh/templates/yaksh/showquestions.html @@ -2,31 +2,62 @@ {% block title %} Questions {% endblock %} -{% block pagetitle %} List of Questions {% endblock pagetitle %} +{% block pagetitle %} Questions {% endblock pagetitle %} {% block script %} <script src="{{ URL_ROOT }}/static/yaksh/js/show_question.js"></script> <script src="{{ URL_ROOT }}/static/yaksh/js/question_filter.js"></script> +<script src="{{ URL_ROOT }}/static/yaksh/js/jquery.tablesorter.min.js"></script> {% endblock %} {% block content %} - -<h4>Upload ZIP file for adding questions</h4> +<div class="row"> + <div class="col-sm-3 col-md-2 sidebar"> + <ul class="nav nav-sidebar nav-stacked"> + <li class="active"><a href="#show" data-toggle="pill" > Show all Questions</a></li> + <li><a href="#updown" data-toggle="pill" > Upload and Download Questions</a></li> + </ul> + </div> +<div class="tab-content"> +<!-- Upload Questions --> +<div id="updown" class="tab-pane fade"> +<a class="btn btn-primary" href="{{URL_ROOT}}/exam/manage/courses/download_yaml_template/"> Download Template</a> +<br/> +<h4> Or </h4> <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} -{{ upload_form.as_p }} -<button class="btn btn-primary" type="submit" name="upload" value="upload"> -Upload File <span class="glyphicon glyphicon-open"></span></button> + {{ upload_form.as_p }} +<br/> +<h4> And </h4> +<button class="btn btn-success" type="submit" name="upload" value="upload"> +Upload File <span class="glyphicon glyphicon-open"/></button> </form> +</div> +<!-- End of upload questions --> + +<!-- Show questions --> +<div id="show" class= "tab-pane fade in active"> +<form name=frm action="" method="post"> +{% csrf_token %} {% if message %} -<h4>{{ message }}</h4> +{%if message == "Questions Uploaded Successfully"%} +<div class="alert alert-success alert-dismissable"> +<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a> + {{ message }} +</div> +{%else %} +<div class="alert alert-danger alert-dismissable"> + <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a> + {{ message }} +</div> +{% endif %} {% endif %} {% if msg %} -<h4>{{ msg }}</h4> +<div class="alert alert-danger alert-dismissable"> + <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a> + {{ msg }} +</div> {% endif %} -<br><br> -<form name=frm action="" method="post"> -{% csrf_token %} <div class="row" id="selectors"> <h5 style="padding-left: 20px;">Filters</h5> <div class="col-md-3"> @@ -46,17 +77,46 @@ Upload File <span class="glyphicon glyphicon-open"></span></button> <div id="filtered-questions"> {% if questions %} <h5><input id="checkall" type="checkbox"> Select All </h5> + +<table id="questions-table" class="tablesorter table table table-striped"> + <thead> + <tr> + <th> Select </th> + <th> Summary </th> + <th> Language </th> + <th> Type </th> + <th> Marks </th> + </tr> + </thead> + <tbody> + {% for i in questions %} -<input type="checkbox" name="question" value="{{ i.id }}"> <a href="{{URL_ROOT}}/exam/manage/addquestion/{{ i.id }}">{{ i }}</a><br> +<tr> +<td> +<input type="checkbox" name="question" value="{{ i.id }}"> +</td> +<td><a href="{{URL_ROOT}}/exam/manage/addquestion/{{ i.id }}">{{i.summary|capfirst}}</a></td> +<td>{{i.language|capfirst}}</td> +<td>{{i.type|capfirst}}</td> +<td>{{i.points}}</td> +</tr> {% endfor %} +</tbody> +</table> {% endif %} </div> <br> +<center> <button class="btn btn-primary" type="button" onclick='location.replace("{{URL_ROOT}}/exam/manage/addquestion/");'>Add Question <span class="glyphicon glyphicon-plus"></span></button> {% if questions %} <button class="btn btn-primary" type="submit" name='download' value='download'>Download Selected <span class="glyphicon glyphicon-save"></span></button> <button class="btn btn-primary" type="submit" name="test" value="test">Test Selected</button> {% endif %} <button class="btn btn-danger" type="submit" onClick="return confirm_delete(frm);" name='delete' value='delete'>Delete Selected <span class="glyphicon glyphicon-minus"></span></button> +</center> </form> -{% endblock %} +</div> +</div> +</div> +<!-- End of Show questions --> +{% endblock %}
\ No newline at end of file diff --git a/yaksh/urls.py b/yaksh/urls.py index 5270068..87ee655 100644 --- a/yaksh/urls.py +++ b/yaksh/urls.py @@ -105,5 +105,7 @@ urlpatterns = [ url(r'^manage/download/user_assignment/(?P<question_id>\d+)/(?P<user_id>\d+)/(?P<quiz_id>\d+)/$', views.download_assignment_file, name="download_user_assignment"), url(r'^manage/download/quiz_assignments/(?P<quiz_id>\d+)/$', - views.download_assignment_file, name="download_quiz_assignment") + views.download_assignment_file, name="download_quiz_assignment"), + url(r'^manage/courses/download_yaml_template/', + views.download_yaml_template, name="download_yaml_template"), ] diff --git a/yaksh/views.py b/yaksh/views.py index 7e73a28..68253bc 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -1590,3 +1590,20 @@ def duplicate_course(request, course_id): 'instructor/administrator.' return complete(request, msg, attempt_num=None, questionpaper_id=None) return my_redirect('/exam/manage/courses/') + +@login_required +@email_verified +def download_yaml_template(request): + user = request.user + if not is_moderator(user): + raise Http404('You are not allowed to view this page!') + template_path = os.path.join(os.path.dirname(__file__), "demo_templates", + "yaml_question_template" + ) + with open(template_path, 'r') as f: + yaml_str = f.read() + response = HttpResponse(yaml_str, content_type='text/yaml') + response['Content-Disposition'] = 'attachment; filename="questions_dump.yaml"' + + return response + |