Пример #1
0
 def upload_new(cls, registry: Registry, local_quiz, args):
     canvas = registry.get_service(args.service, "canvas")
     quiz_data = cls._make_canvas_upload(registry, local_quiz, args)
     created_quiz = canvas.api.post('quizzes/', data=quiz_data)
     if 'errors' in created_quiz:
         pprint(created_quiz['errors'])
         raise WaltzException("Error loading data, see above.")
     print("Created quiz", local_quiz['title'], "on canvas")
     # Create the groups
     group_name_to_id = {}
     for group in local_quiz['groups'].values():
         group_data = QuizGroup._make_canvas_upload(registry, group, args)
         created_group = canvas.api.post(
             'quizzes/{quiz_id}/groups'.format(quiz_id=created_quiz['id']),
             data=group_data)
         created_group = created_group['quiz_groups'][
             0]  # acbart: Weird response type
         # acbart: Okay because names are strings and IDs are ints
         group_name_to_id[created_group['name']] = created_group['id']
         group_name_to_id[created_group['id']] = created_group['id']
     if local_quiz['groups']:
         print("Created quiz", local_quiz['title'], "groups on canvas")
     # Create the questions
     for question in local_quiz['questions']:
         if 'quiz_group_id' in question and question[
                 'quiz_group_id'] is not None:
             question['quiz_group_id'] = group_name_to_id[
                 question['quiz_group_id']]
         question_data = QuizQuestion._make_canvas_upload(
             registry, question, args)
         created_question = canvas.api.post(
             'quizzes/{quiz_id}/questions'.format(
                 quiz_id=created_quiz['id']),
             data=question_data)
     print("Created quiz", local_quiz['title'], "questions on canvas")
Пример #2
0
 def encode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.encode_question_common(registry, data, args)
     result['answers'] = [{
         'comments_html': m2h(answer.get('comment', "")),
         'text': answer['text']
     } for answer in data['answers']]
     return result
Пример #3
0
 def _make_canvas_upload_raw(cls, registry: Registry, data, args):
     result = QuizQuestion._make_canvas_upload_common(registry, data, args)
     for index, answer in enumerate(data['answers']):
         base = 'question[answers][{index}]'.format(index=index)
         result[base + "[answer_text]"] = answer['text']
         result[base + "[answer_comment_html]"] = answer['comments_html']
         result[base + "[answer_weight]"] = 100
     return result
Пример #4
0
 def encode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.encode_question_common(registry, data, args)
     result['answers'] = [{
         'comments_html': m2h(answer.get('comment', "")),
         'text': answer['text'],
         'blank_id': blank_id
     } for blank_id, answers in data['answers'].items()
                          for answer in answers]
     return result
Пример #5
0
 def encode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.encode_question_common(registry, data, args)
     result['matching_answer_incorrect_matches'] = "\n".join(
         data.get('distractors', []))
     result['answers'] = [{
         'comments_html': m2h(answer.get('comment', '')),
         'left': answer['left'],
         'right': answer['right']
     } for answer in data['answers']]
     return result
Пример #6
0
 def decode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.decode_question_common(registry, data, args)
     if not args.hide_answers:
         result['answers'] = []
         for answer in data['answers']:
             a = CommentedMap()
             a['text'] = answer['text']
             if answer['comments_html']:
                 a['comment'] = h2m(answer['comments_html'])
             result['answers'].append(a)
     return result
Пример #7
0
 def _make_canvas_upload_raw(cls, registry: Registry, data, args):
     result = QuizQuestion._make_canvas_upload_common(registry, data, args)
     result['question[matching_answer_incorrect_matches]'] = data[
         'matching_answer_incorrect_matches']
     for index, answer in enumerate(data['answers']):
         base = 'question[answers][{index}]'.format(index=index)
         result[base + "[answer_match_left]"] = answer['left']
         result[base + "[answer_match_right]"] = answer['right']
         result[base + "[answer_comment_html]"] = answer['comments_html']
         result[base + "[answer_weight]"] = 100  # TODO: Unnecessary?
         result[base + "[answer_precision]"] = 10  # TODO: Unnecessary?
     return result
Пример #8
0
 def encode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.encode_question_common(registry, data, args)
     result['answers'] = [{
         'comments_html':
         m2h(answer.get('comment', "")),
         'weight':
         100 if 'correct' in answer else 0,
         'text':
         answer['correct'] if 'correct' in answer else answer['wrong'],
         'html':
         m2h(answer['correct'] if 'correct' in answer else answer['wrong'])
     } for answer in data['answers']]
     return result
Пример #9
0
 def decode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.decode_question_common(registry, data, args)
     if not args.hide_answers:
         result['answers'] = CommentedMap()
         for answer in data['answers']:
             blank_id = answer['blank_id']
             if blank_id not in result['answers']:
                 result['answers'][blank_id] = []
             a = CommentedMap()
             a['text'] = answer['text']
             if 'comments_html' in answer and answer['comments_html']:
                 a['comment'] = h2m(answer['comments_html'])
             result['answers'][blank_id].append(a)
     return result
Пример #10
0
 def decode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.decode_question_common(registry, data, args)
     if not args.hide_answers:
         comments = CommentedMap()
         for answer in data['answers']:
             if answer['text'] == 'True':
                 result['answer'] = True if answer['weight'] else False
                 if answer.get('comments_html'):
                     comments['if_true_chosen'] = h2m(
                         answer['comments_html'])
             elif answer.get('comments_html'):
                 comments['if_false_chosen'] = h2m(answer['comments_html'])
         if comments and any(comments.values()):
             result['comments'] = comments
     return result
Пример #11
0
 def decode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.decode_question_common(registry, data, args)
     result['answers'] = []
     for answer in data['answers']:
         a = CommentedMap()
         html = h2m(answer['html'])
         if args.hide_answers:
             a['possible'] = html
         else:
             if answer['weight']:
                 a['correct'] = html
             else:
                 a['wrong'] = html
             if answer['comments_html']:
                 a['comment'] = h2m(answer['comments_html'])
         result['answers'].append(a)
     return result
Пример #12
0
 def _make_canvas_upload_raw(cls, registry: Registry, data, args):
     result = QuizQuestion._make_canvas_upload_common(registry, data, args)
     for index, answer in enumerate(data['answers']):
         base = 'question[answers][{index}]'.format(index=index)
         result[base + "[answer_comment_html]"] = answer['comments_html']
         result[base +
                "[numerical_answer_type]"] = answer['numerical_answer_type']
         if answer['numerical_answer_type'] == 'exact_answer':
             result[base + "[answer_exact]"] = answer['exact']
             result[base + "[answer_error_margin]"] = answer.get(
                 'margin', 0)
         elif answer['numerical_answer_type'] == 'range_answer':
             result[base + "[answer_range_start]"] = answer['start']
             result[base + "[answer_range_end]"] = answer['end']
         elif answer['numerical_answer_type'] == 'precision_answer':
             result[base + "[answer_precision]"] = answer['precision']
             result[base + "[answer_approximate]"] = answer['approximate']
     return result
Пример #13
0
 def encode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.encode_question_common(registry, data, args)
     comments = data.get('comments', {})
     result['answers'] = [{
         'comments_html':
         m2h(comments.get('if_true_chosen', "")),
         'weight':
         100 if data['answer'] else 0,
         'text':
         'True'
     }, {
         'comments_html':
         m2h(comments.get('if_false_chosen', "")),
         'weight':
         100 if not data['answer'] else 0,
         'text':
         'False'
     }]
     return result
Пример #14
0
 def decode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.decode_question_common(registry, data, args)
     if not args.hide_answers:
         result['answers'] = []
         for answer in data['answers']:
             a = CommentedMap()
             if answer['numerical_answer_type'] == 'exact_answer':
                 a['exact'] = answer['exact']
                 a['margin'] = answer['margin']
             elif answer['numerical_answer_type'] == 'range_answer':
                 a['start'] = answer['start']
                 a['end'] = answer['end']
             elif answer['numerical_answer_type'] == 'precision_answer':
                 a['precision'] = answer['precision']
                 a['approximate'] = answer['approximate']
             if answer.get('comments_html'):
                 a['comment'] = h2m(answer['comments_html'])
             result['answers'].append(a)
     return result
Пример #15
0
 def decode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.decode_question_common(registry, data, args)
     result['answers'] = CommentedMap()
     for answer in data['answers']:
         blank_id = answer['blank_id']
         if blank_id not in result['answers']:
             result['answers'][blank_id] = []
         a = CommentedMap()
         text = answer['text']
         if args.hide_answers:
             a['possible'] = text
         else:
             if answer['weight']:
                 a['correct'] = text
             else:
                 a['wrong'] = text
             if answer['comments_html']:
                 a['comment'] = h2m(answer['comments_html'])
         result['answers'][blank_id].append(a)
     return result
Пример #16
0
 def encode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.encode_question_common(registry, data, args)
     text_mode = data['mode'] == 'text' if 'mode' in data else False
     result['answers'] = []
     for answer in data['answers']:
         result_answer = {
             'comments_html':
             m2h(answer.get('comment', "")),
             'weight':
             100 if 'correct' in answer else 0,
             'text':
             answer['correct'] if 'correct' in answer else answer['wrong'],
             'html':
             m2h(answer['correct'] if 'correct' in
                 answer else answer['wrong'])
         }
         if text_mode:
             del result_answer['html']
         result['answers'].append(result_answer)
     return result
Пример #17
0
 def encode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.encode_question_common(registry, data, args)
     result['answers'] = []
     for answer in data['answers']:
         numerical_answer_type = (
             'exact_answer' if 'exact' in answer else
             'range_answer' if 'start' in answer else 'precision_answer')
         a = {
             'comments_html': m2h(answer.get('comment', "")),
             'numerical_answer_type': numerical_answer_type
         }
         if numerical_answer_type == 'exact_answer':
             a['exact'] = answer['exact']
             a['margin'] = answer.get('margin', 0)
         elif numerical_answer_type == 'range_answer':
             a['start'] = answer['start']
             a['end'] = answer['end']
         elif numerical_answer_type == 'precision_answer':
             a['precision'] = answer['precision']
             a['approximate'] = answer['approximate']
         result['answers'].append(a)
     return result
Пример #18
0
 def decode_json_raw(cls, registry: Registry, data, args):
     result = QuizQuestion.decode_question_common(registry, data, args)
     if args.hide_answers:
         result['answers'] = CommentedMap()
         result['answers']['lefts'] = list(
             sorted(set([answer['left'] for answer in data['answers']])))
         result['answers']['rights'] = (
             list(
                 sorted(set([answer['right']
                             for answer in data['answers']]))) +
             data['matching_answer_incorrect_matches'].split("\n"))
     else:
         result['answers'] = []
         for answer in data['answers']:
             a = CommentedMap()
             a['left'] = answer['left']
             a['right'] = answer['right']
             if answer.get('comments_html'):
                 a['comment'] = h2m(answer['comments_html'])
             result['answers'].append(a)
         result["distractors"] = data[
             'matching_answer_incorrect_matches'].split("\n")
     return result
Пример #19
0
from waltz.resources.quizzes.essay_question import EssayQuestion
from waltz.resources.quizzes.matching_question import MatchingQuestion
from waltz.resources.quizzes.numerical_question import NumericalQuestion
from waltz.resources.quizzes.quiz_question import QuizQuestion
from waltz.resources.quizzes.fill_in_multiple_blanks_question import FillInMultipleBlanksQuestion
from waltz.resources.quizzes.multiple_answers_question import MultipleAnswersQuestion
from waltz.resources.quizzes.multiple_dropdowns_question import MultipleDropDownsQuestion
from waltz.resources.quizzes.multiple_choice_question import MultipleChoiceQuestion
from waltz.resources.quizzes.short_answer_question import ShortAnswerQuestion
from waltz.resources.quizzes.text_only_question import TextOnlyQuestion
from waltz.resources.quizzes.true_false_question import TrueFalseQuestion

QuizQuestion.register_type(MultipleChoiceQuestion)
QuizQuestion.register_type(TrueFalseQuestion)
QuizQuestion.register_type(ShortAnswerQuestion)
QuizQuestion.register_type(FillInMultipleBlanksQuestion)
QuizQuestion.register_type(MultipleAnswersQuestion)
QuizQuestion.register_type(MultipleDropDownsQuestion)
QuizQuestion.register_type(MatchingQuestion)
QuizQuestion.register_type(NumericalQuestion)
QuizQuestion.register_type(EssayQuestion)
QuizQuestion.register_type(TextOnlyQuestion)
Пример #20
0
 def upload_edit(cls, registry: Registry, old_quiz, new_quiz, args):
     canvas = registry.get_service(args.service, "canvas")
     quiz_id = old_quiz['id']
     # Edit the quiz on canvas
     quiz_data = cls._make_canvas_upload(registry, new_quiz, args)
     canvas.api.put('quizzes/{quiz_id}'.format(quiz_id=quiz_id),
                    data=quiz_data)
     print("Updated quiz", old_quiz['title'], "on canvas")
     # Make a map of the old groups' names/ids to the groups
     old_group_map = {}
     for group in old_quiz['groups'].values():
         old_group_map[group['name']] = group
         old_group_map[group['id']] = group
     # Update groups with the same name and create new ones
     used_groups = {}
     for group in new_quiz['groups'].values():
         group_data = QuizGroup._make_canvas_upload(registry, group, args)
         if group['name'] in old_group_map:
             canvas_group = old_group_map[group['name']]
             canvas_group = canvas.api.put(
                 'quizzes/{quiz_id}/groups/{group_id}'.format(
                     quiz_id=quiz_id, group_id=canvas_group['id']),
                 data=group_data)
         else:
             canvas_group = canvas.api.post(
                 'quizzes/{quiz_id}/groups'.format(quiz_id=quiz_id),
                 data=group_data)
         canvas_group = canvas_group['quiz_groups'][
             0]  # acbart: Weird response type
         used_groups[canvas_group['name']] = canvas_group
         used_groups[canvas_group['id']] = canvas_group
     if new_quiz['groups']:
         print("Updated quiz", old_quiz['title'], "groups on canvas")
     # Delete any groups that no longer have a reference
     for old_group in old_quiz['groups'].values():
         if old_group['id'] not in used_groups:
             canvas.api.delete('quizzes/{quiz_id}/groups/{group_id}'.format(
                 quiz_id=quiz_id, group_id=old_group['id']))
             print("Deleted question group", old_group['name'],
                   " (ID: {})".format(old_group['id']))
     # Push all the questions
     name_map = {q['question_name']: q for q in old_quiz['questions']}
     used_questions = {}
     for new_question in new_quiz['questions']:
         if new_question.get('quiz_group_id') is not None:
             new_question['quiz_group_id'] = used_groups[
                 new_question['quiz_group_id']]['id']
         question_data = QuizQuestion._make_canvas_upload(
             registry, new_question, args)
         if new_question['question_name'] in name_map:
             canvas_question = name_map[new_question['question_name']]
             canvas_question = canvas.api.put(
                 'quizzes/{quiz_id}/questions/{question_id}'.format(
                     quiz_id=quiz_id, question_id=canvas_question['id']),
                 data=question_data)
         else:
             canvas_question = canvas.api.post(
                 'quizzes/{quiz_id}/questions'.format(quiz_id=quiz_id),
                 data=question_data)
         used_questions[canvas_question['id']] = canvas_question
     print("Updated quiz", old_quiz['title'], "questions on canvas")
     # Delete any old questions
     for question in old_quiz['questions']:
         if question['id'] not in used_questions:
             canvas.api.delete(
                 'quizzes/{quiz_id}/questions/{question_id}'.format(
                     quiz_id=quiz_id, question_id=question['id']))
             print("Deleted question", question.get('name', "NO NAME"),
                   " (ID: {})".format(question['id']))
Пример #21
0
 def decode_json(cls, registry: Registry, data: str, args):
     raw_data = json.loads(data)
     result = CommentedMap()
     result['title'] = raw_data['title']
     result['resource'] = 'quiz'
     result['url'] = raw_data['html_url']
     result['published'] = raw_data['published']
     result['settings'] = CommentedMap()
     result['settings']['quiz_type'] = raw_data['quiz_type']
     if raw_data.get('points_possible') is not None:
         result['settings']['points_possible'] = raw_data['points_possible']
     result['settings']['allowed_attempts'] = raw_data['allowed_attempts']
     result['settings']['scoring_policy'] = raw_data['scoring_policy']
     result['settings']['timing'] = CommentedMap()
     result['settings']['timing']['due_at'] = to_friendly_date(
         raw_data['due_at'])
     result['settings']['timing']['unlock_at'] = to_friendly_date(
         raw_data['unlock_at'])
     result['settings']['timing']['lock_at'] = to_friendly_date(
         raw_data['lock_at'])
     result['settings']['secrecy'] = CommentedMap()
     result['settings']['secrecy']['shuffle_answers'] = raw_data[
         'shuffle_answers']
     result['settings']['secrecy']['time_limit'] = raw_data['time_limit']
     result['settings']['secrecy']['one_question_at_a_time'] = raw_data[
         'one_question_at_a_time']
     result['settings']['secrecy']['cant_go_back'] = raw_data[
         'cant_go_back']
     result['settings']['secrecy']['show_correct_answers'] = raw_data[
         'show_correct_answers']
     result['settings']['secrecy'][
         'show_correct_answers_last_attempt'] = raw_data[
             'show_correct_answers_last_attempt']
     result['settings']['secrecy']['show_correct_answers_at'] = raw_data[
         'show_correct_answers_at']
     result['settings']['secrecy']['hide_correct_answers_at'] = raw_data[
         'hide_correct_answers_at']
     result['settings']['secrecy']['hide_results'] = raw_data[
         'hide_results']
     result['settings']['secrecy']['one_time_results'] = raw_data[
         'one_time_results']
     if raw_data['access_code']:
         result['settings']['secrecy']['access_code'] = raw_data[
             'access_code']
     if raw_data['ip_filter']:
         result['settings']['secrecy']['ip_filter'] = raw_data['ip_filter']
     # Handle questions and groups
     result['questions'] = []
     available_groups = raw_data['groups']
     used_groups = {}
     extra_files = []
     for question in raw_data['questions']:
         quiz_question, destination_path, full_body = QuizQuestion.decode_question(
             registry, question, raw_data, args)
         if destination_path is not None:
             extra_files.append((destination_path, full_body))
         quiz_group_id = question.get('quiz_group_id')
         if quiz_group_id is not None:
             quiz_group_id = str(
                 quiz_group_id)  # acbart: JSON only allows string keys
             if quiz_group_id not in used_groups:
                 used_groups[quiz_group_id] = QuizGroup.decode_group(
                     available_groups[quiz_group_id])
                 result['questions'].append(used_groups[quiz_group_id])
             used_groups[quiz_group_id]['questions'].append(quiz_question)
         else:
             result['questions'].append(quiz_question)
     return h2m(raw_data['description'], result), extra_files
Пример #22
0
 def encode_json(cls, registry: Registry, data, args):
     regular, waltz, body = extract_front_matter(data)
     settings = waltz.get('settings', {})
     timing = settings.get('timing', {})
     secrecy = settings.get('secrecy', {})
     body = hide_data_in_html(regular, m2h(body))
     questions = []
     groups = {}
     for question in waltz.get('questions', []):
         if isinstance(question, str):
             # Look up quiz question name
             questions.append(
                 QuizQuestion.encode_question_by_title(
                     registry, question, args))
         elif 'group' in question:
             # This is a question group
             group = QuizGroup.encode_group(registry, question, args)
             groups[group['name']] = group
             questions.extend(
                 QuizGroup.encode_questions(registry, question, args))
         else:
             # This is an embedded question
             questions.append(
                 QuizQuestion.encode_question(registry, question, args))
     # TODO: total_estimated_points from the questions
     return json.dumps({
         'title':
         waltz['title'],
         'published':
         waltz.get('published', False),
         'description':
         body,
         # Settings
         'quiz_type':
         settings.get('quiz_type', 'assignment'),
         'points_possible':
         settings.get('points_possible'),
         'allowed_attempts':
         settings.get('allowed_attempts'),
         'scoring_policy':
         settings.get('scoring_policy'),
         # Timing
         'due_at':
         from_friendly_date(timing.get('due_at')),
         'unlock_at':
         from_friendly_date(timing.get('unlock_at')),
         'lock_at':
         from_friendly_date(timing.get('lock_at')),
         # Secrecy
         'one_question_at_a_time':
         int(secrecy.get('one_question_at_a_time', 0)),
         'shuffle_answers':
         int(secrecy.get('shuffle_answers', 0)),
         'time_limit':
         secrecy.get('time_limit'),
         'cant_go_back':
         int(secrecy.get('cant_go_back', 0)),
         'show_correct_answers':
         int(secrecy.get('show_correct_answers', 1)),
         'show_correct_answers_last_attempt':
         secrecy.get('show_correct_answers_last_attempt'),
         'show_correct_answers_at':
         secrecy.get('show_correct_answers_at'),
         'hide_correct_answers_at':
         secrecy.get('hide_correct_answers_at'),
         'hide_results':
         secrecy.get('hide_results'),
         'one_time_results':
         int(secrecy.get('one_time_results', 0)),
         'access_code':
         secrecy.get('access_code'),
         'ip_filter':
         secrecy.get('ip_filter'),
         # Questions and Groups
         'questions':
         questions,
         'groups':
         groups
     })
Пример #23
0
 def encode_json_raw(cls, registry: Registry, data, args):
     return QuizQuestion.encode_question_common(registry, data, args)
Пример #24
0
 def _make_canvas_upload_raw(cls, registry: Registry, data, args):
     return QuizQuestion._make_canvas_upload_common(registry, data, args)