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
Пример #3
0
    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
Пример #4
0
    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
Пример #6
0
    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))
Пример #7
0
    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
Пример #8
0
 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)
Пример #9
0
    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
Пример #11
0
    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('&nbsp;')
                ).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
Пример #12
0
    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
Пример #13
0
    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
Пример #14
0
 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.')