summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormahesh2017-07-31 17:22:54 +0530
committermahesh2017-07-31 17:22:54 +0530
commit66e8f39bb390b3ec2547d82512349fabf67e3d7c (patch)
treeeebf8ed4a88672e53b6db60797586c1b63b43cb7
parentebc8a2af6d4fdf52a9703701a97a3abfaf66ed06 (diff)
downloadonline_test-66e8f39bb390b3ec2547d82512349fabf67e3d7c.tar.gz
online_test-66e8f39bb390b3ec2547d82512349fabf67e3d7c.tar.bz2
online_test-66e8f39bb390b3ec2547d82512349fabf67e3d7c.zip
Adds yaml serialization to download and upload questions
-rw-r--r--yaksh/fixtures/demo_questions.zipbin4430 -> 3893 bytes
-rw-r--r--yaksh/models.py78
-rw-r--r--yaksh/test_models.py21
-rw-r--r--yaksh/test_views.py2
-rw-r--r--yaksh/views.py2
5 files changed, 50 insertions, 53 deletions
diff --git a/yaksh/fixtures/demo_questions.zip b/yaksh/fixtures/demo_questions.zip
index c68e7ef..e2ec37e 100644
--- a/yaksh/fixtures/demo_questions.zip
+++ b/yaksh/fixtures/demo_questions.zip
Binary files differ
diff --git a/yaksh/models.py b/yaksh/models.py
index 2fa34e4..f6504d7 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -1,6 +1,7 @@
from __future__ import unicode_literals
from datetime import datetime, timedelta
import json
+import yaml
from random import sample
from collections import Counter
from django.db import models
@@ -26,6 +27,7 @@ from textwrap import dedent
from .file_utils import extract_files, delete_files
from yaksh.xmlrpc_clients import code_server
from django.conf import settings
+from django.forms.models import model_to_dict
languages = (
@@ -386,43 +388,38 @@ class Question(models.Model):
for question in questions:
test_case = question.get_test_cases()
file_names = question._add_and_get_files(zip_file)
- q_dict = {
- 'summary': question.summary,
- 'description': question.description,
- 'points': question.points, 'language': question.language,
- 'type': question.type, 'active': question.active,
- 'snippet': question.snippet,
- 'testcase': [case.get_field_value() for case in test_case],
- 'files': file_names
- }
+ q_dict = model_to_dict(question, exclude=['id', 'user','tags'])
+ q_dict['testcase']= [case.get_field_value() for case in test_case]
+ q_dict['files'] = file_names
+
questions_dict.append(q_dict)
- question._add_json_to_zip(zip_file, questions_dict)
+ question._add_yaml_to_zip(zip_file, questions_dict)
return zip_file_name
def load_questions(self, questions_list, user, file_path=None,
files_list=None):
try:
- questions = json.loads(questions_list)
- except ValueError as exc_msg:
- msg = "Error Parsing Json: {0}".format(exc_msg)
- return msg
- for question in questions:
- question['user'] = user
- file_names = question.pop('files')
- test_cases = question.pop('testcase')
- que, result = Question.objects.get_or_create(**question)
- if file_names:
- que._add_files_to_db(file_names, file_path)
- for test_case in test_cases:
- test_case_type = test_case.pop('test_case_type')
- model_class = get_model_class(test_case_type)
- new_test_case, obj_create_status = \
- model_class.objects.get_or_create(
- question=que, **test_case
- )
+ questions = yaml.safe_load_all(questions_list)
+ for question in questions:
+ question['user'] = user
+ file_names = question.pop('files')
+ test_cases = question.pop('testcase')
+ que, result = Question.objects.get_or_create(**question)
+ if file_names:
+ que._add_files_to_db(file_names, file_path)
+ for test_case in test_cases:
+ test_case_type = test_case.pop('test_case_type')
+ model_class = get_model_class(test_case_type)
+ new_test_case, obj_create_status = \
+ model_class.objects.get_or_create(
+ question=que, **test_case
+ )
new_test_case.type = test_case_type
new_test_case.save()
- return "Questions Uploaded Successfully"
+ msg = "Questions Uploaded Successfully"
+ except yaml.scanner.ScannerError as exc_msg:
+ msg = "Error Parsing Yaml: {0}".format(exc_msg)
+ return msg
def get_test_cases(self, **kwargs):
tc_list = []
@@ -478,25 +475,24 @@ class Question(models.Model):
file_upload.extract = extract
file_upload.file.save(file_name, django_file, save=True)
- def _add_json_to_zip(self, zip_file, q_dict):
- json_data = json.dumps(q_dict, indent=2)
+ def _add_yaml_to_zip(self, zip_file, q_dict):
tmp_file_path = tempfile.mkdtemp()
- json_path = os.path.join(tmp_file_path, "questions_dump.json")
- with open(json_path, "w") as json_file:
- json_file.write(json_data)
- zip_file.write(json_path, os.path.basename(json_path))
+ yaml_path = os.path.join(tmp_file_path, "questions_dump.yaml")
+ with open(yaml_path, "w") as yaml_file:
+ yaml.safe_dump_all(q_dict, yaml_file, default_flow_style=False)
+ zip_file.write(yaml_path, os.path.basename(yaml_path))
zip_file.close()
shutil.rmtree(tmp_file_path)
- def read_json(self, file_path, user, files=None):
- json_file = os.path.join(file_path, "questions_dump.json")
+ def read_yaml(self, file_path, user, files=None):
+ yaml_file = os.path.join(file_path, "questions_dump.yaml")
msg = ""
- if os.path.exists(json_file):
- with open(json_file, 'r') as q_file:
+ if os.path.exists(yaml_file):
+ with open(yaml_file, 'r') as q_file:
questions_list = q_file.read()
msg = self.load_questions(questions_list, user, file_path, files)
else:
- msg = "Please upload zip file with questions_dump.json in it."
+ msg = "Please upload zip file with questions_dump.yaml in it."
if files:
delete_files(files, file_path)
@@ -507,7 +503,7 @@ class Question(models.Model):
settings.FIXTURE_DIRS, 'demo_questions.zip'
)
files, extract_path = extract_files(zip_file_path)
- self.read_json(extract_path, user, files)
+ self.read_yaml(extract_path, user, files)
def __str__(self):
return self.summary
diff --git a/yaksh/test_models.py b/yaksh/test_models.py
index c86d9a3..8dc3244 100644
--- a/yaksh/test_models.py
+++ b/yaksh/test_models.py
@@ -3,6 +3,7 @@ from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\
QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\
StdIOBasedTestCase, FileUpload, McqTestCase, AssignmentUpload
import json
+import yaml
from datetime import datetime, timedelta
from django.utils import timezone
import pytz
@@ -111,7 +112,7 @@ class QuestionTestCases(unittest.TestCase):
user=self.user1
)
- self.question2 = Question.objects.create(summary='Demo Json',
+ self.question2 = Question.objects.create(summary='Yaml Json',
language='python',
type='code',
active=True,
@@ -159,8 +160,8 @@ class QuestionTestCases(unittest.TestCase):
"language": "Python", "type": "Code",
"testcase": self.test_case_upload_data,
"files": [[file1, 0]],
- "summary": "Json Demo"}]
- self.json_questions_data = json.dumps(questions_data)
+ "summary": "Yaml Demo"}]
+ self.yaml_questions_data = yaml.safe_dump_all(questions_data)
def tearDown(self):
shutil.rmtree(self.load_tmp_path)
@@ -191,7 +192,7 @@ class QuestionTestCases(unittest.TestCase):
self.assertIn(tag, ['python', 'function'])
def test_dump_questions(self):
- """ Test dump questions into json """
+ """ Test dump questions into Yaml """
question = Question()
question_id = [self.question2.id]
questions_zip = question.dump_questions(question_id, self.user2)
@@ -200,8 +201,8 @@ class QuestionTestCases(unittest.TestCase):
tmp_path = tempfile.mkdtemp()
zip_file.extractall(tmp_path)
test_case = self.question2.get_test_cases()
- with open("{0}/questions_dump.json".format(tmp_path), "r") as f:
- questions = json.loads(f.read())
+ with open("{0}/questions_dump.yaml".format(tmp_path), "r") as f:
+ questions = yaml.safe_load_all(f.read())
for q in questions:
self.assertEqual(self.question2.summary, q['summary'])
self.assertEqual(self.question2.language, q['language'])
@@ -216,13 +217,13 @@ class QuestionTestCases(unittest.TestCase):
os.remove(os.path.join(tmp_path, file))
def test_load_questions(self):
- """ Test load questions into database from json """
+ """ Test load questions into database from Yaml """
question = Question()
- result = question.load_questions(self.json_questions_data, self.user1)
- question_data = Question.objects.get(summary="Json Demo")
+ result = question.load_questions(self.yaml_questions_data, self.user1)
+ question_data = Question.objects.get(summary="Yaml Demo")
file = FileUpload.objects.get(question=question_data)
test_case = question_data.get_test_cases()
- self.assertEqual(question_data.summary, 'Json Demo')
+ self.assertEqual(question_data.summary, 'Yaml Demo')
self.assertEqual(question_data.language, 'Python')
self.assertEqual(question_data.type, 'Code')
self.assertEqual(question_data.description, 'factorial of a no')
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index ef222e2..e5308fc 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -2983,7 +2983,7 @@ class TestShowQuestions(TestCase):
zip_file = string_io(response.content)
zipped_file = zipfile.ZipFile(zip_file, 'r')
self.assertIsNone(zipped_file.testzip())
- self.assertIn('questions_dump.json', zipped_file.namelist())
+ self.assertIn('questions_dump.yaml', zipped_file.namelist())
zip_file.close()
zipped_file.close()
diff --git a/yaksh/views.py b/yaksh/views.py
index c10ba6a..7e73a28 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -1015,7 +1015,7 @@ def show_all_questions(request):
if file_name[-1] == "zip":
ques = Question()
files, extract_path = extract_files(questions_file)
- context['message'] = ques.read_json(extract_path, user,
+ context['message'] = ques.read_yaml(extract_path, user,
files)
else:
message = "Please Upload a ZIP file"