summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--requirements/requirements-common.txt1
-rw-r--r--yaksh/demo_templates/yaml_question_template90
-rw-r--r--yaksh/static/yaksh/js/show_question.js4
-rw-r--r--yaksh/templates/yaksh/showquestions.html86
-rw-r--r--yaksh/urls.py4
-rw-r--r--yaksh/views.py17
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">&times;</a>
+ {{ message }}
+</div>
+{%else %}
+<div class="alert alert-danger alert-dismissable">
+ <a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</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">&times;</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 }}">&nbsp;&nbsp;<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>&nbsp;&nbsp;
{% if questions %}
<button class="btn btn-primary" type="submit" name='download' value='download'>Download Selected <span class="glyphicon glyphicon-save"></span></button>&nbsp;&nbsp;
<button class="btn btn-primary" type="submit" name="test" value="test">Test Selected</button>&nbsp;&nbsp;
{% 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
+