def post_add_to_question_group(self): try: question_id = long(self.request.get('question_id')) question_dto = QuestionDAO.load(question_id) if question_dto is None: raise ValueError() except ValueError: transforms.send_json_response( self, 500, 'Invalid question id.', {'question-id': self.request.get('question_id')} ) return try: group_id = long(self.request.get('group_id')) group_dto = QuestionGroupDAO.load(group_id) if group_dto is None: raise ValueError() except ValueError: transforms.send_json_response( self, 500, 'Invalid question group id.', {'group-id': self.request.get('group_id')} ) return weight = self.request.get('weight') try: float(weight) except ValueError: transforms.send_json_response( self, 500, 'Invalid weight. Must be a numeric value.', { 'weight': weight}) return group_dto.add_question(question_id, weight) QuestionGroupDAO.save(group_dto) transforms.send_json_response( self, 200, '%s added to %s.' % ( question_dto.description, group_dto.description ), { 'group-id': group_dto.id, 'question-id': question_dto.id } ) return
def validate(self, question_group_dict, key): """Validate the question group data sent from the form.""" errors = [] assert question_group_dict['version'] == self.SCHEMA_VERSION if not question_group_dict['description'].strip(): errors.append('The question group must have a description.') descriptions = { question_group.description for question_group in QuestionGroupDAO.get_all() if not key or question_group.id != long(key) } if question_group_dict['description'] in descriptions: errors.append('The description must be different ' 'from existing question groups.') if not question_group_dict['items']: errors.append( 'The question group must contain at least one question.') items = question_group_dict['items'] for index in range(0, len(items)): item = items[index] try: float(item['weight']) except ValueError: errors.append('Item %s must have a numeric weight.' % (index + 1)) return errors
def list_question_groups(self): """Prepare a list of question groups.""" if not filer.is_editable_fs(self.app_context): return safe_dom.NodeList() all_questions = QuestionDAO.get_all() output = safe_dom.NodeList() if all_questions: output.append( safe_dom.Element('a', className='gcb-button gcb-pull-right', href='dashboard?action=add_question_group'). add_text('Add Question Group')).append( safe_dom.Element('div', style='clear: both; padding-top: 2px;')) output.append(safe_dom.Element('h3').add_text('Question Groups')) # TODO(jorr): Hook this into the datastore all_question_groups = QuestionGroupDAO.get_all() if all_question_groups: ol = safe_dom.Element('ol') for question_group in all_question_groups: edit_url = 'dashboard?action=edit_question_group&key=%s' % ( question_group.id) li = safe_dom.Element('li') li.add_text(question_group.description).add_child( safe_dom.Entity(' ')).add_child( safe_dom.Element('a', href=edit_url).add_text('[Edit]')) ol.add_child(li) output.append(ol) else: output.append(safe_dom.Element('blockquote').add_text('< none >')) return output
def put(self): """Store a question group in the datastore in response to a PUT.""" request = transforms.loads(self.request.get('request')) key = request.get('key') if not self.assert_xsrf_token_or_fail( request, self.XSRF_TOKEN, {'key': key}): return if not CourseOutlineRights.can_edit(self): transforms.send_json_response( self, 401, 'Access denied.', {'key': key}) return payload = request.get('payload') question_group_dict = transforms.json_to_dict( transforms.loads(payload), self.get_schema().get_json_schema_dict()) validation_errors = self.validate(question_group_dict, key) if validation_errors: self.validation_error('\n'.join(validation_errors), key=key) return assert self.SCHEMA_VERSION == question_group_dict.get('version') if key: question_group = QuestionGroupDTO(key, question_group_dict) else: question_group = QuestionGroupDTO(None, question_group_dict) key_after_save = QuestionGroupDAO.save(question_group) transforms.send_json_response( self, 200, 'Saved.', payload_dict={'key': key_after_save})
def validate(self, question_group_dict, key): """Validate the question group data sent from the form.""" errors = [] assert question_group_dict['version'] == self.SCHEMA_VERSION if not question_group_dict['description'].strip(): errors.append('The question group must have a description.') descriptions = {question_group.description for question_group in QuestionGroupDAO.get_all() if not key or question_group.id != long(key)} if question_group_dict['description'] in descriptions: errors.append('The description must be different ' 'from existing question groups.') if not question_group_dict['items']: errors.append( 'The question group must contain at least one question.') items = question_group_dict['items'] for index in range(0, len(items)): item = items[index] try: float(item['weight']) except ValueError: errors.append( 'Item %s must have a numeric weight.' % (index + 1)) return errors
def get(self): """Respond to the REST GET verb with the contents of the group.""" key = self.request.get('key') if not CourseOutlineRights.can_view(self): transforms.send_json_response( self, 401, 'Access denied.', {'key': key}) return if key: question_group = QuestionGroupDAO.load(key) version = question_group.dict.get('version') if self.SCHEMA_VERSION != version: transforms.send_json_response( self, 403, 'Cannot edit a Version %s group.' % version, {'key': key}) return payload_dict = question_group.dict else: payload_dict = { 'version': self.SCHEMA_VERSION, 'items': [{'weight': ''}, {'weight': ''}, {'weight': ''}]} transforms.send_json_response( self, 200, 'Success', payload_dict=payload_dict, xsrf_token=XsrfTokenManager.create_xsrf_token(self.XSRF_TOKEN))
def post_add_to_question_group(self): try: question_id = long(self.request.get('question_id')) question_dto = QuestionDAO.load(question_id) if question_dto is None: raise ValueError() except ValueError: transforms.send_json_response( self, 500, 'Invalid question id.', {'question-id': self.request.get('question_id')}) return try: group_id = long(self.request.get('group_id')) group_dto = QuestionGroupDAO.load(group_id) if group_dto is None: raise ValueError() except ValueError: transforms.send_json_response( self, 500, 'Invalid question group id.', {'group-id': self.request.get('group_id')}) return weight = self.request.get('weight') try: float(weight) except ValueError: transforms.send_json_response( self, 500, 'Invalid weight. Must be a numeric value.', {'weight': weight}) return group_dto.add_question(question_id, weight) QuestionGroupDAO.save(group_dto) transforms.send_json_response( self, 200, '%s added to %s.' % (question_dto.description, group_dto.description), { 'group-id': group_dto.id, 'question-id': question_dto.id }) return
def create_group(self, description, question_ids): group = { 'version': QuestionDAO.VERSION, 'description': description, 'introduction': '', 'items': [{ 'question': str(x), 'weight': 1.0 } for x in question_ids] } return QuestionGroupDAO.create_question_group(group)
def delete(self): """Delete the question_group in response to REST request.""" key = self.request.get('key') if not self.assert_xsrf_token_or_fail( self.request, self.XSRF_TOKEN, {'key': key}): return if not CourseOutlineRights.can_delete(self): transforms.send_json_response( self, 401, 'Access denied.', {'key': key}) return question_group = QuestionGroupDAO.load(key) if not question_group: transforms.send_json_response( self, 404, 'Question Group not found.', {'key': key}) return QuestionGroupDAO.delete(question_group) transforms.send_json_response(self, 200, 'Deleted.')
def _get_questions_by_question_id(cls, questions_by_usage_id): ret = {} ret['single'] = {} ret['grouped'] = {} for question in questions_by_usage_id.values(): question_single = QuestionDAO.load(question['id']) if question_single: ret['single'][question['id']] = question_single else: question_group = QuestionGroupDAO.load(question['id']) if question_group: ret['grouped'][question['id']] = {} for item in question_group.items: ret['grouped'][question['id']][item['question']] = QuestionDAO.load(item['question']) return ret
def list_question_groups(self): """Prepare a list of question groups.""" if not filer.is_editable_fs(self.app_context): return safe_dom.NodeList() all_questions = QuestionDAO.get_all() output = safe_dom.NodeList() if all_questions: output.append( safe_dom.Element( 'a', className='gcb-button gcb-pull-right', href='dashboard?action=add_question_group' ).add_text('Add Question Group') ).append( safe_dom.Element( 'div', style='clear: both; padding-top: 2px;' ) ) output.append( safe_dom.Element('h3').add_text('Question Groups') ) # TODO(jorr): Hook this into the datastore all_question_groups = QuestionGroupDAO.get_all() if all_question_groups: ol = safe_dom.Element('ol') for question_group in all_question_groups: edit_url = 'dashboard?action=edit_question_group&key=%s' % ( question_group.id) li = safe_dom.Element('li') li.add_text( question_group.description ).add_child( safe_dom.Entity(' ') ).add_child( safe_dom.Element('a', href=edit_url).add_text('[Edit]')) ol.add_child(li) output.append(ol) else: output.append(safe_dom.Element('blockquote').add_text('< none >')) return output
def _get_questions_by_question_id(cls, questions_by_usage_id): ''' Retrieves every question in the course returning them in a dict: { id:questionDAO, ... } @param questions_by_usage_id.values() is a dict: {unit, lesson, sequence, weight, quid} ''' ret = {} ret['single'] = {} ret['grouped'] = {} for question in questions_by_usage_id.values(): question_single = QuestionDAO.load(question['id']) if question_single: ret['single'][question['id']] = question_single else: question_group = QuestionGroupDAO.load(question['id']) if question_group: ret['grouped'][question['id']] = {} for item in question_group.items: ret['grouped'][question['id']][item['question']] = QuestionDAO.load(item['question']) return ret
def _get_questions_by_question_id(cls, questions_by_usage_id): ''' Retrieves every question in the course returning them in a dict: { id:questionDAO, ... } @param questions_by_usage_id.values() is a dict: {unit, lesson, sequence, weight, quid} ''' ret = {} ret['single'] = {} ret['grouped'] = {} for question in questions_by_usage_id.values(): question_single = QuestionDAO.load(question['id']) if question_single: ret['single'][question['id']] = question_single else: question_group = QuestionGroupDAO.load(question['id']) if question_group: ret['grouped'][question['id']] = {} for item in question_group.items: ret['grouped'][question['id']][ item['question']] = QuestionDAO.load( item['question']) return ret
def validate_group_description(self, group_description, errors): descriptions = [gr.description for gr in QuestionGroupDAO.get_all()] if group_description in descriptions: errors.append('Non-unique group description.')