summaryrefslogtreecommitdiff
path: root/testapp
diff options
context:
space:
mode:
Diffstat (limited to 'testapp')
-rw-r--r--testapp/README.rst14
-rw-r--r--testapp/exam/forms.py5
-rw-r--r--testapp/exam/models.py15
-rw-r--r--testapp/exam/templates/exam/intro.html2
-rw-r--r--testapp/exam/templates/exam/question.html42
-rw-r--r--testapp/exam/templates/exam/quit.html4
-rw-r--r--testapp/exam/urls.py35
-rw-r--r--testapp/exam/views.py273
-rw-r--r--testapp/settings.py4
-rw-r--r--testapp/urls.py2
10 files changed, 211 insertions, 185 deletions
diff --git a/testapp/README.rst b/testapp/README.rst
index f4790a3..e6f8380 100644
--- a/testapp/README.rst
+++ b/testapp/README.rst
@@ -10,7 +10,7 @@ conduct online test and monitor the test.
Quick start
------------
-1. In yourterminal run the following command::
+1. In your terminal run the following command::
$ easy_install git+https://github.com/FOSSEE/online_test.git#egg=django_exam-0.1
2. Add "testapp.exam", "taggit" and "taggit_autocomplete_modified" apps
@@ -35,10 +35,14 @@ Quick start
5. Run 'python manage.py syncdb' to create models for the new installed apps.
-6. Start the development server and visit http://localhost:8000/exam/
+6. Run 'python manage.py runserver' to start the development server
+ and visit http://localhost:8000/exam/
-7. In exam app run code_sever command as superuser as follows::
+7. Run code_server command as superuser as follows::
- $ code_server
+ $ sudo code_server
- Note: You must have a sudo access to run the above command.
+ Note: If you are using virtual python environment, then activate the environment
+ using sudo. Then simply run the code_server command as follows::
+
+ $ code_server
diff --git a/testapp/exam/forms.py b/testapp/exam/forms.py
index 843ed15..1f12a3b 100644
--- a/testapp/exam/forms.py
+++ b/testapp/exam/forms.py
@@ -27,7 +27,7 @@ question_types = (
("mcq", "Multiple Choice"),
("mcc", "Multiple Correct Choices"),
("code", "Code"),
- ("basgn", "Bash Assignment"),
+ ("upload", "Assignment Upload"),
)
UNAME_CHARS = letters + "._" + digits
@@ -35,7 +35,6 @@ PWD_CHARS = letters + punctuation + digits
attempts = [(i, i) for i in range(1, 6)]
attempts.append((-1, 'Infinite'))
-
days_between_attempts = ((j, j) for j in range(401))
@@ -138,7 +137,7 @@ class QuizForm(forms.Form):
super(QuizForm, self).__init__(*args, **kwargs)
quizzes = [('', 'Select a prerequisite quiz')]
quizzes = quizzes + \
- list(Quiz.objects.values_list('id','description'))
+ list(Quiz.objects.values_list('id', 'description'))
self.fields['prerequisite'] = forms.CharField(required=False,
widget=forms.Select(choices=quizzes))
diff --git a/testapp/exam/models.py b/testapp/exam/models.py
index 0ad6021..72fb51b 100644
--- a/testapp/exam/models.py
+++ b/testapp/exam/models.py
@@ -30,11 +30,10 @@ question_types = (
("mcq", "Multiple Choice"),
("mcc", "Multiple Correct Choices"),
("code", "Code"),
- ("basgn", "Bash Assignment"),
+ ("upload", "Assignment Upload"),
)
attempts = [(i, i) for i in range(1, 6)]
attempts.append((-1, 'Infinite'))
-
days_between_attempts = ((j, j) for j in range(401))
test_status = (
@@ -42,9 +41,11 @@ test_status = (
('completed', 'Completed'),
)
+
def get_assignment_dir(instance, filename):
return '%s/%s' % (instance.user.roll_number, instance.assignmentQuestion.id)
+
###############################################################################
class Question(models.Model):
"""Question for a quiz."""
@@ -192,9 +193,9 @@ class QuestionPaper(models.Model):
questions += question_set.get_random_questions()
return questions
- def make_answerpaper(self, user, ip, attempt_no):
+ def make_answerpaper(self, user, ip, attempt_num):
"""Creates an answer paper for the user to attempt the quiz"""
- ans_paper = AnswerPaper(user=user, user_ip=ip, attempt_number=attempt_no)
+ ans_paper = AnswerPaper(user=user, user_ip=ip, attempt_number=attempt_num)
ans_paper.start_time = datetime.datetime.now()
ans_paper.end_time = ans_paper.start_time \
+ datetime.timedelta(minutes=self.quiz.duration)
@@ -361,7 +362,7 @@ class AnswerPaper(models.Model):
Checks whether student passed or failed, as per the quiz
passing criteria.
"""
- if self.percent is not None:
+ if self.percent is not None:
if self.percent >= self.question_paper.quiz.pass_criteria:
self.passed = True
else:
@@ -388,9 +389,9 @@ class AnswerPaper(models.Model):
def __unicode__(self):
u = self.user
return u'Question paper for {0} {1}'.format(u.first_name, u.last_name)
-
-################################################################################
+
+###############################################################################
class AssignmentUpload(models.Model):
user = models.ForeignKey(Profile)
assignmentQuestion = models.ForeignKey(Question)
diff --git a/testapp/exam/templates/exam/intro.html b/testapp/exam/templates/exam/intro.html
index 58068ed..592937a 100644
--- a/testapp/exam/templates/exam/intro.html
+++ b/testapp/exam/templates/exam/intro.html
@@ -27,7 +27,7 @@
</ul>
<p> We hope you enjoy taking this exam !!!</p>
- <form action="{{URL_ROOT}}/exam/start/{{ attempt_no }}/{{ paper_id }}/" method="post" align="center">
+ <form action="{{URL_ROOT}}/exam/start/{{ attempt_num }}/{{ paper_id }}/" method="post" align="center">
{% csrf_token %}
<center><button class="btn" type="submit" name="start">Start Exam!</button></center>
</form>
diff --git a/testapp/exam/templates/exam/question.html b/testapp/exam/templates/exam/question.html
index 5d03b37..eac6792 100644
--- a/testapp/exam/templates/exam/question.html
+++ b/testapp/exam/templates/exam/question.html
@@ -10,7 +10,10 @@
{% endblock %}
{% block script %}
+<script src="/static/taggit_autocomplete_modified/jquery.min.js" type="text/javascript"></script>
+<script src="/static/taggit_autocomplete_modified/jquery.autocomplete.js" type="text/javascript"></script>
<script src="{{ URL_ROOT }}/static/exam/js/question.js"></script>
+<script src="{{ URL_ROOT }}/static/exam/js/bootstrap-modal.js"></script>
<script>
var time_left = {{ time_left }}
@@ -48,12 +51,26 @@ function setSnippetHeight()
ta.style.height = height;
autoresize();
}
+
+function validate(){
+ uploaded_file = document.getElementById("assignment").value;
+ if(uploaded_file == ""){
+ $("#upload_alert").modal("show");
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
function call_skip(url)
{
form = document.forms["code"]
form.action = url
form.submit();
}
+
</script>
{% endblock script %}
@@ -121,7 +138,7 @@ function call_skip(url)
</div>{% endif %}
<p id="status"></p>
-
+
<form id="code" action="{{URL_ROOT}}/exam/{{ question.id }}/check/{{ paper.attempt_number }}/{{ paper.question_paper.id }}/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type=hidden name="question_id" id="question_id" value={{ question.id }}></input>
@@ -131,7 +148,7 @@ function call_skip(url)
<input name="answer" type="radio" value="{{option}}" />{{option}} <br/>
{% endfor %}
{% endif %}
- {% if question.type == "basgn" %}
+ {% if question.type == "upload" %}
<p>Upload assignment file for the said question<p>
<input type=file id="assignment" name="assignment">
<hr>
@@ -157,8 +174,8 @@ function call_skip(url)
{% if question.type == "mcq" or question.type == "mcc "%}
<br><button class="btn" type="submit" name="check" id="check">Submit Answer</button>&nbsp;&nbsp;
- {% elif question.type == "basgn" %}
- <br><button class="btn" type="submit" name="check" id="check">Submit Answer</button>&nbsp;&nbsp;
+ {% elif question.type == "upload" %}
+ <br><button class="btn" type="submit" name="check" id="check" onClick="return validate();">Upload</button>&nbsp;&nbsp;
{% else %}
<button class="btn" type="submit" name="check" id="check" onClick="submitCode();">Check Answer</button>&nbsp;&nbsp;
{% endif %}
@@ -166,4 +183,21 @@ function call_skip(url)
</form>
+ <!-- Modal -->
+ <div class="modal fade " id="upload_alert" >
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h4 class="modal-title" id="myModalLabel">File not selected</h4>
+ </div>
+ <div id = "modal_body"class="modal-body">
+ <font color="brown"><b>Kindly attach a file and then click upload.</b></font>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn primary close" data-dismiss="modal">OK</button>
+ </div>
+ </div>
+ </div>
+ </div>
+
{% endblock content %}
diff --git a/testapp/exam/templates/exam/quit.html b/testapp/exam/templates/exam/quit.html
index 2c347cb..f49b62f 100644
--- a/testapp/exam/templates/exam/quit.html
+++ b/testapp/exam/templates/exam/quit.html
@@ -7,8 +7,8 @@
<center><h4>Your current answers are saved.</h4></center>
<center><h4> Are you sure you wish to quit the exam?</h4></center>
<center><h4> Be sure, as you won't be able to restart this exam.</h4></center>
- <form action="{{URL_ROOT}}/exam/complete/{{ attempt_no }}/{{ id }}/" method="post">
+ <form action="{{URL_ROOT}}/exam/complete/{{ attempt_num }}/{{ id }}/" method="post">
{% csrf_token %}
- <center><button class="btn" type="submit" name="yes">Yes!</button>&nbsp;<button class="btn" type="button" name="no" onClick="window.location='{{ URL_ROOT }}/exam/start/{{ attempt_no }}/{{ id }}/'">No!</button></center>
+ <center><button class="btn" type="submit" name="yes">Yes!</button>&nbsp;<button class="btn" type="button" name="no" onClick="window.location='{{ URL_ROOT }}/exam/start/{{ attempt_num }}/{{ id }}/'">No!</button></center>
</form>
{% endblock content %}
diff --git a/testapp/exam/urls.py b/testapp/exam/urls.py
index 62fa9e1..43970ce 100644
--- a/testapp/exam/urls.py
+++ b/testapp/exam/urls.py
@@ -1,23 +1,24 @@
-from django.conf.urls import *
+from django.conf.urls import patterns, url
urlpatterns = patterns('testapp.exam.views',
url(r'^$', 'index'),
url(r'^login/$', 'user_login'),
- url(r'^quizzes/$','quizlist_user'),
- url(r'^results/$','results_user'),
+ url(r'^quizzes/$', 'quizlist_user'),
+ url(r'^results/$', 'results_user'),
url(r'^start/$', 'start'),
- url(r'^start/(?P<attempt_no>\d+)/(?P<questionpaper_id>\d+)/$','start'),
- url(r'^quit/(?P<attempt_no>\d+)/(?P<questionpaper_id>\d+)/$', 'quit'),
- url(r'^intro/(?P<questionpaper_id>\d+)/$','intro'),
+ url(r'^start/(?P<attempt_num>\d+)/(?P<questionpaper_id>\d+)/$', 'start'),
+ url(r'^quit/(?P<attempt_num>\d+)/(?P<questionpaper_id>\d+)/$', 'quit'),
+ url(r'^intro/(?P<questionpaper_id>\d+)/$', 'intro'),
url(r'^complete/$', 'complete'),
- url(r'^complete/(?P<attempt_no>\d+)/(?P<questionpaper_id>\d+)/$', 'complete'),
- url(r'^submit-assignment(?P<question_id>\d+)/$', 'submit_assignment'),
+ url(r'^complete/(?P<attempt_num>\d+)/(?P<questionpaper_id>\d+)/$',\
+ 'complete'),
url(r'^register/$', 'user_register'),
url(r'^(?P<q_id>\d+)/$', 'question'),
url(r'^(?P<q_id>\d+)/check/$', 'check'),
- url(r'^(?P<q_id>\d+)/check/(?P<attempt_no>\d+)/(?P<questionpaper_id>\d+)/$', 'check'),
+ url(r'^(?P<q_id>\d+)/check/(?P<attempt_num>\d+)/(?P<questionpaper_id>\d+)/$',\
+ 'check'),
url(r'^intro/$', 'start'),
- url(r'^(?P<q_id>\d+)/(?P<attempt_no>\d+)/(?P<questionpaper_id>\d+)/$', 'show_question'),
+ url(r'^(?P<q_id>\d+)/(?P<attempt_num>\d+)/(?P<questionpaper_id>\d+)/$', 'show_question'),
url(r'^manage/$', 'prof_manage'),
url(r'^manage/addquestion/$', 'add_question'),
@@ -27,22 +28,22 @@ urlpatterns = patterns('testapp.exam.views',
url(r'^manage/editquestion/$', 'edit_question'),
url(r'^manage/addquiz/(?P<quiz_id>\d+)/$', 'add_quiz'),
url(r'^manage/gradeuser/$', 'show_all_users'),
- url(r'^manage/gradeuser/(?P<username>[a-zA-Z0-9_.]+)/$', 'grade_user'),
+ url(r'^manage/gradeuser/(?P<username>.*)/$', 'grade_user'),
url(r'^manage/questions/$', 'show_all_questions'),
- url(r'^manage/showquiz/$','show_all_quiz'),
+ url(r'^manage/showquiz/$', 'show_all_quiz'),
url(r'^manage/monitor/$', 'monitor'),
- url(r'^manage/showquestionpapers/$','show_all_questionpapers'),
+ url(r'^manage/showquestionpapers/$', 'show_all_questionpapers'),
url(r'^manage/showquestionpapers/(?P<questionpaper_id>\d+)/$',\
'show_all_questionpapers'),
url(r'^manage/monitor/(?P<questionpaper_id>\d+)/$', 'monitor'),
- url(r'^manage/user_data/(?P<username>[a-zA-Z0-9_.]+)/$','user_data'),
- url(r'^manage/designquestionpaper/$','design_questionpaper'),
+ url(r'^manage/user_data/(?P<username>.*)/$', 'user_data'),
+ url(r'^manage/designquestionpaper/$', 'design_questionpaper'),
url(r'^manage/designquestionpaper/(?P<questionpaper_id>\d+)/$',\
'design_questionpaper'),
url(r'^manage/designquestionpaper/automatic/(?P<questionpaper_id>\d+)/$',\
'automatic_questionpaper'),
- url(r'^manage/designquestionpaper/automatic$','automatic_questionpaper'),
- url(r'^manage/designquestionpaper/manual$','manual_questionpaper'),
+ url(r'^manage/designquestionpaper/automatic$', 'automatic_questionpaper'),
+ url(r'^manage/designquestionpaper/manual$', 'manual_questionpaper'),
url(r'^manage/designquestionpaper/manual/(?P<questionpaper_id>\d+)/$',\
'manual_questionpaper'),
url(r'^ajax/questionpaper/(?P<query>.+)/$', 'ajax_questionpaper'),
diff --git a/testapp/exam/views.py b/testapp/exam/views.py
index f4826a6..11aca06 100644
--- a/testapp/exam/views.py
+++ b/testapp/exam/views.py
@@ -165,7 +165,6 @@ def intro(request, questionpaper_id):
quest_paper = QuestionPaper.objects.get(id=questionpaper_id)
attempt_number = quest_paper.quiz.attempts_allowed
time_lag = quest_paper.quiz.time_between_attempts
-
if quest_paper.quiz.prerequisite:
try:
pre_quest = QuestionPaper.objects.get(
@@ -186,42 +185,35 @@ def intro(request, questionpaper_id):
already_attempted = attempted_papers.count()
if already_attempted == 0:
context = {'user': user, 'paper_id': questionpaper_id,\
- 'attempt_no': already_attempted + 1}
+ 'attempt_num': already_attempted + 1}
return my_render_to_response('exam/intro.html', context,
context_instance=ci)
+
if already_attempted == attempt_number:
- previous_attempt = attempted_papers[already_attempted-1]
- previous_attempt_day = previous_attempt.start_time
- today = datetime.datetime.today()
- if previous_attempt.status == 'inprogress':
- end_time = previous_attempt.end_time
- quiz_time = previous_attempt.question_paper.quiz.duration*60
- if quiz_time > (today-previous_attempt_day).seconds:
- return show_question(request,
- previous_attempt.current_question(),
- previous_attempt.attempt_number,
- previous_attempt.question_paper.id)
- else:
- return my_redirect("/exam/quizzes")
+ inprogress, previous_attempt = _check_previous_attempt(attempted_papers,
+ already_attempted)
+ if inprogress:
+ return show_question(request,
+ previous_attempt.current_question(),
+ previous_attempt.attempt_number,
+ previous_attempt.question_paper.id)
else:
- return my_redirect("/exam/quizzes/")
+ return my_redirect("/exam/quizzes")
+
if already_attempted < attempt_number or attempt_number < 0:
- previous_attempt = attempted_papers[already_attempted-1]
- previous_attempt_day = previous_attempt.start_time
- today = datetime.datetime.today()
- if previous_attempt.status == 'inprogress':
- end_time = previous_attempt.end_time
- quiz_time = previous_attempt.question_paper.quiz.duration*60
- if quiz_time > (today-previous_attempt_day).seconds:
- return show_question(request,
- previous_attempt.current_question(),
- previous_attempt.attempt_number,
- previous_attempt.question_paper.id)
- days_after_attempt = (today - previous_attempt_day).days
+ inprogress, previous_attempt = _check_previous_attempt(attempted_papers,
+ already_attempted)
+ if inprogress:
+ return show_question(request,
+ previous_attempt.current_question(),
+ previous_attempt.attempt_number,
+ previous_attempt.question_paper.id)
+ days_after_attempt = (datetime.datetime.today() - \
+ previous_attempt.start_time).days
if days_after_attempt >= time_lag:
context = {'user': user, 'paper_id': questionpaper_id,\
- 'attempt_no': already_attempted + 1}
+ 'attempt_num': already_attempted + 1}
return my_render_to_response('exam/intro.html', context,
context_instance=ci)
else:
@@ -230,6 +222,20 @@ def intro(request, questionpaper_id):
return my_redirect("/exam/quizzes/")
+def _check_previous_attempt(attempted_papers, already_attempted):
+ previous_attempt = attempted_papers[already_attempted-1]
+ previous_attempt_day = previous_attempt.start_time
+ today = datetime.datetime.today()
+ if previous_attempt.status == 'inprogress':
+ end_time = previous_attempt.end_time
+ quiz_time = previous_attempt.question_paper.quiz.duration*60
+ if quiz_time > (today-previous_attempt_day).seconds:
+ return True, previous_attempt
+ else:
+ return False, previous_attempt
+ else:
+ return False, previous_attempt
+
def results_user(request):
"""Show list of Results of Quizzes that is taken by logged-in user."""
user = request.user
@@ -644,8 +650,10 @@ rights/permissions and log in."""
users_per_paper = []
for paper in question_papers:
answer_papers = AnswerPaper.objects.filter(question_paper=paper)
- users_passed = AnswerPaper.objects.filter(question_paper=paper, passed=True).count()
- users_failed = AnswerPaper.objects.filter(question_paper=paper, passed=False).count()
+ users_passed = AnswerPaper.objects.filter(question_paper=paper,
+ passed=True).count()
+ users_failed = AnswerPaper.objects.filter(question_paper=paper,
+ passed=False).count()
temp = paper, answer_papers, users_passed, users_failed
users_per_paper.append(temp)
context = {'user': user, 'users_per_paper': users_per_paper}
@@ -682,7 +690,7 @@ def user_login(request):
context_instance=ci)
-def start(request, attempt_no=None, questionpaper_id=None):
+def start(request, attempt_num=None, questionpaper_id=None):
"""Check the user cedentials and if any quiz is available,
start the exam."""
user = request.user
@@ -695,13 +703,13 @@ def start(request, attempt_no=None, questionpaper_id=None):
except QuestionPaper.DoesNotExist:
msg = 'Quiz not found, please contact your '\
'instructor/administrator. Please login again thereafter.'
- return complete(request, msg, attempt_no, questionpaper_id)
+ return complete(request, msg, attempt_num, questionpaper_id)
try:
old_paper = AnswerPaper.objects.get(
- question_paper=questionpaper, user=user, attempt_number=attempt_no)
+ question_paper=questionpaper, user=user, attempt_number=attempt_num)
q = old_paper.current_question()
- return show_question(request, q, attempt_no, questionpaper_id)
+ return show_question(request, q, attempt_num, questionpaper_id)
except AnswerPaper.DoesNotExist:
ip = request.META['REMOTE_ADDR']
key = gen_key(10)
@@ -711,13 +719,43 @@ def start(request, attempt_no=None, questionpaper_id=None):
msg = 'You do not have a profile and cannot take the quiz!'
raise Http404(msg)
- new_paper = questionpaper.make_answerpaper(user, ip, attempt_no)
+ new_paper = questionpaper.make_answerpaper(user, ip, attempt_num)
# Make user directory.
user_dir = get_user_dir(user)
- return start(request, attempt_no, questionpaper_id)
+ return start(request, attempt_num, questionpaper_id)
+
+
+def get_questions(paper):
+ '''
+ Takes answerpaper as an argument. Returns the total questions as
+ ordered dictionary, the questions yet to attempt and the questions
+ attempted
+ '''
+ to_attempt = []
+ submitted = []
+ all_questions = []
+ questions = {}
+ if paper.questions:
+ to_attempt = (paper.questions).split('|')
+ if paper.questions_answered:
+ submitted = (paper.questions_answered).split('|')
+ if not to_attempt:
+ submitted.sort()
+ all_questions = submitted
+ if not submitted:
+ to_attempt.sort()
+ all_questions = to_attempt
+ if to_attempt and submitted:
+ q_append = to_attempt + submitted
+ q_append.sort()
+ all_questions = q_append
+ for num, value in enumerate(all_questions, 1):
+ questions[value] = num
+ questions = collections.OrderedDict(sorted(questions.items()))
+ return questions, to_attempt, submitted
-def question(request, q_id, attempt_no, questionpaper_id, success_msg=None):
+def question(request, q_id, attempt_num, questionpaper_id, success_msg=None):
"""Check the credentials of the user and start the exam."""
user = request.user
@@ -727,7 +765,7 @@ def question(request, q_id, attempt_no, questionpaper_id, success_msg=None):
try:
q_paper = QuestionPaper.objects.get(id=questionpaper_id)
paper = AnswerPaper.objects.get(
- user=request.user, attempt_number=attempt_no, question_paper=q_paper)
+ user=request.user, attempt_number=attempt_num, question_paper=q_paper)
except AnswerPaper.DoesNotExist:
return my_redirect('/exam/start/')
if not paper.question_paper.quiz.active:
@@ -740,35 +778,16 @@ def question(request, q_id, attempt_no, questionpaper_id, success_msg=None):
if time_left == 0:
return complete(request, reason='Your time is up!')
quiz_name = paper.question_paper.quiz.description
- to_attempt = []
- submitted = []
- if paper.questions:
- to_attempt = (paper.questions).split('|')
- if paper.questions_answered:
- submitted = (paper.questions_answered).split('|')
- all_questions = []
- if not to_attempt:
- submitted.sort()
- all_questions = submitted
- if not submitted:
- to_attempt.sort()
- all_questions = to_attempt
- if to_attempt and submitted:
- q_append = to_attempt + submitted
- q_append.sort()
- all_questions = q_append
- questions = {}
- for num, value in enumerate(all_questions, 1):
- questions[value] = num
- questions = collections.OrderedDict(sorted(questions.items()))
+ questions, to_attempt, submitted = get_questions(paper)
if success_msg is None:
- context = {'question': q, 'questions' : questions, 'paper': paper,
+ context = {'question': q, 'questions': questions, 'paper': paper,
'user': user, 'quiz_name': quiz_name, 'time_left': time_left,
- 'to_attempt' : to_attempt, 'submitted': submitted}
+ 'to_attempt': to_attempt, 'submitted': submitted}
else:
- context = {'question': q, 'questions' : questions, 'paper': paper,
+ context = {'question': q, 'questions': questions, 'paper': paper,
'user': user, 'quiz_name': quiz_name, 'time_left': time_left,
- 'success_msg': success_msg, 'to_attempt' : to_attempt, 'submitted' : submitted}
+ 'success_msg': success_msg, 'to_attempt': to_attempt,
+ 'submitted': submitted}
if q.type == 'code':
skipped_answer = paper.answers.filter(question=q, skipped=True)
if skipped_answer:
@@ -778,48 +797,53 @@ def question(request, q_id, attempt_no, questionpaper_id, success_msg=None):
context_instance=ci)
-def show_question(request, q_id, attempt_no, questionpaper_id, success_msg=None):
+def show_question(request, q_id, attempt_num, questionpaper_id, success_msg=None):
"""Show a question if possible."""
user = request.user
q_paper = QuestionPaper.objects.get(id=questionpaper_id)
- paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_no,
+ paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_num,
question_paper=q_paper)
if not user.is_authenticated() or paper.end_time < datetime.datetime.now():
return my_redirect('/exam/login/')
old_qid = request.POST.get('question_id')
if old_qid is not None:
-
quest = Question.objects.get(pk=old_qid)
user_code = request.POST.get('answer')
if quest.type == 'code':
- user_answer = user_code # not taking snippet here.
old_skipped = paper.answers.filter(question=quest, skipped=True)
- if old_skipped:
- skipped_answer = old_skipped[0]
- skipped_answer.answer=user_answer
- skipped_answer.save()
- else:
- skipped_answer = Answer(question=quest, answer=user_answer,
- correct=False, skipped=True)
- skipped_answer.save()
- paper.answers.add(skipped_answer)
+ _save_skipped_answer(old_skipped, user_code, paper, quest)
if len(q_id) == 0:
msg = 'Congratulations! You have successfully completed the quiz.'
- return complete(request, msg, attempt_no, questionpaper_id)
+ return complete(request, msg, attempt_num, questionpaper_id)
else:
- return question(request, q_id, attempt_no, questionpaper_id, success_msg)
+ return question(request, q_id, attempt_num, questionpaper_id, success_msg)
+
+def _save_skipped_answer(old_skipped, user_answer, paper, question):
+ """
+ Saves the answer on skip. Only the code questions are saved.
+ Snippet is not saved with the answer.
+ """
+ if old_skipped:
+ skipped_answer = old_skipped[0]
+ skipped_answer.answer=user_answer
+ skipped_answer.save()
+ else:
+ skipped_answer = Answer(question=question, answer=user_answer,
+ correct=False, skipped=True)
+ skipped_answer.save()
+ paper.answers.add(skipped_answer)
-def check(request, q_id, attempt_no=None, questionpaper_id=None):
+def check(request, q_id, attempt_num=None, questionpaper_id=None):
"""Checks the answers of the user for particular question"""
user = request.user
q_paper = QuestionPaper.objects.get(id=questionpaper_id)
- paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_no,
+ paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_num,
question_paper=q_paper)
if q_id in paper.questions_answered:
next_q = paper.skip()
- return show_question(request, next_q, attempt_no, questionpaper_id)
+ return show_question(request, next_q, attempt_num, questionpaper_id)
if not user.is_authenticated() or paper.end_time < datetime.datetime.now():
return my_redirect('/exam/login/')
@@ -831,30 +855,24 @@ def check(request, q_id, attempt_no=None, questionpaper_id=None):
success = True
if skip is not None:
if question.type == 'code':
- user_answer = user_code # not taking snippet here.
old_skipped = paper.answers.filter(question=question, skipped=True)
- if old_skipped:
- skipped_answer = old_skipped[0]
- skipped_answer.answer=user_answer
- skipped_answer.save()
- else:
- skipped_answer = Answer(question=question, answer=user_answer,
- correct=False, skipped=True)
- skipped_answer.save()
- paper.answers.add(skipped_answer)
+ _save_skipped_answer(old_skipped, user_code, paper, question)
next_q = paper.skip()
- return show_question(request, next_q, attempt_no, questionpaper_id)
+ return show_question(request, next_q, attempt_num, questionpaper_id)
# Add the answer submitted, regardless of it being correct or not.
if question.type == 'mcq':
user_answer = request.POST.get('answer')
elif question.type == 'mcc':
user_answer = request.POST.getlist('answer')
- elif question.type == 'basgn':
+ elif question.type == 'upload':
assign = AssignmentUpload()
assign.user = user.profile
assign.assignmentQuestion = question
- assign.assignmentFile = request.FILES['assignment']
+ # if time-up at upload question then the form is submitted without
+ # validation
+ if 'assignment' in request.FILES:
+ assign.assignmentFile = request.FILES['assignment']
assign.save()
user_answer = 'ASSIGNMENT UPLOADED'
else:
@@ -868,7 +886,7 @@ def check(request, q_id, attempt_no=None, questionpaper_id=None):
# If we were not skipped, we were asked to check. For any non-mcq
# questions, we obtain the results via XML-RPC with the code executed
# safely in a separate process (the code_server.py) running as nobody.
- if not question.type == 'basgn':
+ if not question.type == 'upload':
correct, success, err_msg = validate_answer(user, user_answer, question)
if correct:
new_answer.correct = correct
@@ -883,31 +901,14 @@ def check(request, q_id, attempt_no=None, questionpaper_id=None):
if not success: # Should only happen for non-mcq questions.
if time_left == 0:
reason = 'Your time is up!'
- return complete(request, reason, attempt_no, questionpaper_id)
+ return complete(request, reason, attempt_num, questionpaper_id)
if not paper.question_paper.quiz.active:
reason = 'The quiz has been deactivated!'
- return complete(request, reason, attempt_no, questionpaper_id)
- to_attempt = []
- submitted = []
- if paper.questions:
- to_attempt = (paper.questions).split('|')
- if paper.questions_answered:
- submitted = (paper.questions_answered).split('|')
- all_questions = []
- if not to_attempt:
- submitted.sort()
- all_questions = submitted
- if not submitted:
- to_attempt.sort()
- all_questions = to_attempt
- if to_attempt and submitted:
- q_append = to_attempt + submitted
- q_append.sort()
- all_questions = q_append
- questions = {}
- for num, value in enumerate(all_questions, 1):
- questions[value] = num
- questions = collections.OrderedDict(sorted(questions.items()))
+ return complete(request, reason, attempt_num, questionpaper_id)
+ if not paper.question_paper.quiz.active:
+ reason = 'The quiz has been deactivated!'
+ return complete(request, reason, attempt_num, questionpaper_id)
+ questions, to_attempt, submitted = get_questions(paper)
old_answer = paper.answers.filter(question=question, skipped=True)
if old_answer:
old_answer[0].answer = user_code
@@ -916,7 +917,8 @@ def check(request, q_id, attempt_no=None, questionpaper_id=None):
'error_message': err_msg,
'paper': paper, 'last_attempt': user_code,
'quiz_name': paper.question_paper.quiz.description,
- 'time_left': time_left, 'to_attempt' : to_attempt, 'submitted': submitted}
+ 'time_left': time_left, 'to_attempt': to_attempt,
+ 'submitted': submitted}
ci = RequestContext(request)
return my_render_to_response('exam/question.html', context,
@@ -924,10 +926,10 @@ def check(request, q_id, attempt_no=None, questionpaper_id=None):
else:
if time_left <= 0:
reason = 'Your time is up!'
- return complete(request, reason, attempt_no, questionpaper_id)
+ return complete(request, reason, attempt_num, questionpaper_id)
else:
next_q = paper.completed_question(question.id)
- return show_question(request, next_q, attempt_no,
+ return show_question(request, next_q, attempt_num,
questionpaper_id, success_msg)
@@ -963,15 +965,15 @@ def validate_answer(user, user_answer, question):
return correct, success, message
-def quit(request, attempt_no=None, questionpaper_id=None):
+def quit(request, attempt_num=None, questionpaper_id=None):
"""Show the quit page when the user logs out."""
context = {'id': questionpaper_id,
- 'attempt_no': attempt_no}
+ 'attempt_num': attempt_num}
return my_render_to_response('exam/quit.html', context,
context_instance=RequestContext(request))
-def complete(request, reason=None, attempt_no=None, questionpaper_id=None):
+def complete(request, reason=None, attempt_num=None, questionpaper_id=None):
"""Show a page to inform user that the quiz has been compeleted."""
user = request.user
@@ -983,7 +985,7 @@ def complete(request, reason=None, attempt_no=None, questionpaper_id=None):
else:
q_paper = QuestionPaper.objects.get(id=questionpaper_id)
paper = AnswerPaper.objects.get(user=user, question_paper=q_paper,
- attempt_number=attempt_no)
+ attempt_number=attempt_num)
paper.update_marks_obtained()
paper.update_percent()
paper.update_passed()
@@ -1297,7 +1299,8 @@ def design_questionpaper(request):
question_paper.fixed_questions.add(question_id)
if random_questions:
for random_question, num in zip(random_questions, random_number):
- question = Question.objects.get(id=random_question[0])
+ qid = random_question.split(',')[0]
+ question = Question.objects.get(id=int(qid))
marks = question.points
question_set = QuestionSet(marks=marks, num_questions=num)
question_set.save()
@@ -1312,19 +1315,3 @@ def design_questionpaper(request):
context = {'form': form}
return my_render_to_response('exam/design_questionpaper.html',
context, context_instance=ci)
-
-
-def submit_assignment(request, question_id=None):
- user = request.user
- skip = request.POST.get('skip', None)
- if request.method == "POST" and skip is not None:
- question = Question.objects.get(id=question_id)
- assignment = AssignmentUpload()
- assignment.user = user
- assignment.assignmentQuestion = question
- assignment.assignmentFile = request.FILES['assignment']
- assignment.save()
- #next question ke liye code idhar
- else:
- #code for skipping the question
- pass
diff --git a/testapp/settings.py b/testapp/settings.py
index 00a6b17..88d4a5a 100644
--- a/testapp/settings.py
+++ b/testapp/settings.py
@@ -72,12 +72,12 @@ USE_L10N = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
-MEDIA_ROOT = join(CURDIR, '../uploads')
+MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
-MEDIA_URL = 'upload/'
+MEDIA_URL = ''
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
diff --git a/testapp/urls.py b/testapp/urls.py
index dee297c..0d126f4 100644
--- a/testapp/urls.py
+++ b/testapp/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls import *
+from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin