diff options
author | mahesh | 2017-07-31 17:22:54 +0530 |
---|---|---|
committer | mahesh | 2017-07-31 17:22:54 +0530 |
commit | 66e8f39bb390b3ec2547d82512349fabf67e3d7c (patch) | |
tree | eebf8ed4a88672e53b6db60797586c1b63b43cb7 | |
parent | ebc8a2af6d4fdf52a9703701a97a3abfaf66ed06 (diff) | |
download | online_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.zip | bin | 4430 -> 3893 bytes | |||
-rw-r--r-- | yaksh/models.py | 78 | ||||
-rw-r--r-- | yaksh/test_models.py | 21 | ||||
-rw-r--r-- | yaksh/test_views.py | 2 | ||||
-rw-r--r-- | yaksh/views.py | 2 |
5 files changed, 50 insertions, 53 deletions
diff --git a/yaksh/fixtures/demo_questions.zip b/yaksh/fixtures/demo_questions.zip Binary files differindex c68e7ef..e2ec37e 100644 --- a/yaksh/fixtures/demo_questions.zip +++ b/yaksh/fixtures/demo_questions.zip 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" |