コード例 #1
0
 def test_reject_bad_number(self):
     schema = wrap_properties({'field': {'type': 'number'}})
     source = {'field': 'cat'}
     try:
         transforms.json_to_dict(source, schema)
         self.fail('Expected ValueException')
     except ValueError as e:
         self.assertEqual(str(e), 'could not convert string to float: cat')
コード例 #2
0
 def test_reject_bad_boolean(self):
     schema = wrap_properties({'field': {'type': 'boolean'}})
     source = {'field': 'cat'}
     try:
         transforms.json_to_dict(source, schema)
         self.fail('Expected ValueException')
     except ValueError as e:
         self.assertEqual(str(e), 'Bad boolean value for field: cat')
コード例 #3
0
    def test_convert_date(self):
        schema = wrap_properties({'field': {'type': 'date'}})

        source = {'field': '2005/03/01'}
        result = transforms.json_to_dict(source, schema)
        self.assertEqual(len(result), 1)
        self.assertEqual(result['field'], datetime.date(2005, 3, 1))

        source = {'field': '2005-03-01'}
        result = transforms.json_to_dict(source, schema)
        self.assertEqual(result['field'], datetime.date(2005, 3, 1))
コード例 #4
0
    def put(self):
        """A PUT REST method shared by all unit types."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'put-unit', {'key': key}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        unit = courses.Course(self).find_unit_by_id(key)
        if not unit:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        updated_unit_dict = transforms.json_to_dict(
            transforms.loads(payload), self.SCHEMA_DICT)

        errors = []
        self.apply_updates(unit, updated_unit_dict, errors)
        if not errors:
            course = courses.Course(self)
            assert course.update_unit(unit)
            course.save()
            common_utils.run_hooks(self.POST_SAVE_HOOKS, unit)
            transforms.send_json_response(self, 200, 'Saved.')
        else:
            transforms.send_json_response(self, 412, '\n'.join(errors))
コード例 #5
0
ファイル: question.py プロジェクト: thejeshgn/seek
    def put(self):
        """A PUT REST method shared by all unit types."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(request, 'put-unit',
                                              {'key': key}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        course = courses.Course(self)
        unit = course.find_unit_by_id(key)
        if not unit:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'key': key})
            return

        payload = request.get('payload')
        updated_unit_dict = transforms.json_to_dict(transforms.loads(payload),
                                                    self.get_schema_dict())

        errors = []
        self.apply_updates(course, unit, updated_unit_dict, errors)
        if not errors:
            transforms.send_json_response(self, 200, 'Saved.')
        else:
            transforms.send_json_response(self, 412, '\n'.join(errors))
コード例 #6
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(request, 'announcement-put',
                                              {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'key': key})
            return

        payload = request.get('payload')
        transforms.dict_to_entity(
            entity,
            transforms.json_to_dict(transforms.loads(payload),
                                    AnnouncementsItemRESTHandler.SCHEMA_DICT))
        entity.put()

        transforms.send_json_response(self, 200, 'Saved.')
コード例 #7
0
    def put(self):
        """A PUT REST method shared by all unit types."""
        request = transforms.loads(self.request.get("request"))
        key = request.get("key")

        if not self.assert_xsrf_token_or_fail(request, "put-unit", {"key": key}):
            return

        if not self.can_edit(self.app_context):
            transforms.send_json_response(self, 401, "Access denied.", {"key": key})
            return

        unit = courses.Course(self).find_unit_by_id(key)
        if not unit:
            transforms.send_json_response(self, 404, "Object not found.", {"key": key})
            return

        payload = request.get("payload")
        errors = []

        course = courses.Course(self)
        try:
            schema = self.get_schema(course, key)
            updated_unit_dict = transforms.json_to_dict(transforms.loads(payload), schema.get_json_schema_dict())
            schema.redact_entity_to_schema(updated_unit_dict)
            self.apply_updates(unit, updated_unit_dict, errors)
        except (TypeError, ValueError), ex:
            errors.append(str(ex))
コード例 #8
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})
コード例 #9
0
    def put(self):
        """A PUT REST method shared by all unit types."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'put-unit', {'key': key}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        unit = courses.Course(self).find_unit_by_id(key)
        if not unit:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        errors = []

        try:
            updated_unit_dict = transforms.json_to_dict(
                transforms.loads(payload), self.SCHEMA_DICT)
            self.apply_updates(unit, updated_unit_dict, errors)
        except (TypeError, ValueError), ex:
            errors.append(str(ex))
コード例 #10
0
    def put(self):
        """A PUT REST method shared by all unit types."""
        request = transforms.loads(self.request.get("request"))
        key = request.get("key")

        if not self.assert_xsrf_token_or_fail(request, "put-unit", {"key": key}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(self, 401, "Access denied.", {"key": key})
            return

        unit = courses.Course(self).find_unit_by_id(key)
        if not unit:
            transforms.send_json_response(self, 404, "Object not found.", {"key": key})
            return

        payload = request.get("payload")
        updated_unit_dict = transforms.json_to_dict(transforms.loads(payload), self.SCHEMA_DICT)

        errors = []
        self.apply_updates(unit, updated_unit_dict, errors)
        if not errors:
            course = courses.Course(self)
            assert course.update_unit(unit)
            course.save()
            transforms.send_json_response(self, 200, "Saved.")
        else:
            transforms.send_json_response(self, 412, "\n".join(errors))
コード例 #11
0
    def _add_query_filters(cls, source_context, schema, page_number, query):
        for filter_spec in source_context.filters:
            parts = cls.FILTER_RE.match(filter_spec)
            if not parts:
                raise ValueError(
                    'Filter specification "%s" ' % filter_spec +
                    'is not of the form: <name><op><value>')
            name, op, value = parts.groups()
            if op not in cls.SUPPORTED_OPERATIONS:
                raise ValueError(
                    'Filter specification "%s" ' % filter_spec +
                    'uses an unsupported comparison operation "%s"' % op)

            if name not in schema:
                raise ValueError(
                    'Filter specification "%s" ' % filter_spec +
                    'calls for field "%s" ' % name +
                    'which is not in the schema for '
                    'type "%s"' % cls.get_entity_class().__name__)
            if value == '':
                converted_value = None
            else:
                converted_value = transforms.json_to_dict(
                    {name: value},
                    {'properties': {name: schema[name]}})[name]
            query.filter('%s %s' % (name, op), converted_value)
コード例 #12
0
    def put(self):
        """Handles PUT REST verb to save lesson and associated activity."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'lesson-edit', {'key': key}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        course = courses.Course(self)
        lesson = course.find_lesson_by_id(None, key)
        if not lesson:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        updates_dict = transforms.json_to_dict(
            transforms.loads(payload),
            self.get_schema(course, key).get_json_schema_dict())

        lesson.title = updates_dict['title']
        lesson.unit_id = updates_dict['unit_id']
        lesson.scored = (updates_dict['scored'] == 'scored')
        lesson.objectives = updates_dict['objectives']
        lesson.video = updates_dict['video']
        lesson.notes = updates_dict['notes']
        lesson.auto_index = updates_dict['auto_index']
        lesson.activity_title = updates_dict['activity_title']
        lesson.activity_listed = updates_dict['activity_listed']
        lesson.manual_progress = updates_dict['manual_progress']

        activity = updates_dict.get('activity', '').strip()
        errors = []
        if activity:
            if lesson.has_activity:
                course.set_activity_content(lesson, activity, errors=errors)
            else:
                errors.append('Old-style activities are not supported.')
        else:
            lesson.has_activity = False
            fs = self.app_context.fs
            path = fs.impl.physical_to_logical(course.get_activity_filename(
                lesson.unit_id, lesson.lesson_id))
            if fs.isfile(path):
                fs.delete(path)

        if not errors:
            common_utils.run_hooks(self.PRE_SAVE_HOOKS, lesson, updates_dict)
            assert course.update_lesson(lesson)
            course.save()
            common_utils.run_hooks(self.POST_SAVE_HOOKS, lesson)
            transforms.send_json_response(self, 200, 'Saved.')
        else:
            transforms.send_json_response(self, 412, '\n'.join(errors))
コード例 #13
0
    def test_bidirectional_transforms_succeed(self):
        """Tests that transforms entity<->dict<->json round trips correctly."""
        referenced_model_key = ReferencedModel().put()
        entity = UnvalidatedReference(
            referenced_model_key=referenced_model_key)
        entity.put()

        transformed = transforms.entity_to_dict(entity)
        self.assertEqual(referenced_model_key, entity.referenced_model_key)
        self.assertEqual(referenced_model_key,
                         transformed['referenced_model_key'])

        new_key = ReferencedModel().put()
        transformed['referenced_model_key'] = new_key
        restored = transforms.dict_to_entity(entity, transformed)
        self.assertEqual(new_key, restored.referenced_model_key)

        json = transforms.dict_to_json(transformed)
        self.assertEqual(str(new_key), json['referenced_model_key'])

        from_json = transforms.json_to_dict(
            json, {'properties': {
                'referenced_model_key': {
                    'type': 'string'
                }
            }})
        self.assertEqual({'referenced_model_key': str(new_key)}, from_json)
コード例 #14
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(self, 401, "Access denied.", {})
            return

        request = transforms.loads(self.request.get("request"))
        payload = request.get("payload")
        course_raw = transforms.json_to_dict(transforms.loads(payload), self.SCHEMA_DICT)["course"]

        source = None
        for acourse in sites.get_all_courses():
            if acourse.raw == course_raw:
                source = acourse
                break

        if not source:
            transforms.send_json_response(self, 404, "Object not found.", {"raw": course_raw})
            return

        course = courses.Course(self)
        errors = []
        try:
            course.import_from(source, errors)
        except Exception as e:  # pylint: disable-msg=broad-except
            logging.exception(e)
            errors.append("Import failed: %s" % e)

        if errors:
            transforms.send_json_response(self, 412, "\n".join(errors))
            return

        course.save()
        transforms.send_json_response(self, 200, "Imported.")
コード例 #15
0
    def _import_and_validate15(self, unvalidated_dict, key):
        errors = []
        try:
            question_dict = transforms.json_to_dict(
                unvalidated_dict, self.get_schema().get_json_schema_dict())
        except ValueError as err:
            errors.append(str(err))
            return (None, errors)

        if not question_dict['question'].strip():
            errors.append('The question must have a non-empty body.')

        if not question_dict['description']:
            errors.append('The description must be non-empty.')

        self.validate_no_description_collision(
            question_dict['description'], key, errors)

        if not question_dict['graders']:
            errors.append('The question must have at least one answer.')

        graders = question_dict['graders']
        for index in range(0, len(graders)):
            grader = graders[index]
            assert grader['matcher'] in [
                matcher for (matcher, unused_text) in self.GRADER_TYPES]
            if not grader['response'].strip():
                errors.append('Answer %s has no response text.' % (index + 1))
            try:
                float(grader['score'])
            except ValueError:
                errors.append(
                    'Answer %s must have a numeric score.' % (index + 1))

        return (question_dict, errors)
コード例 #16
0
    def _import_and_validate15(self, unvalidated_dict, key):
        errors = []
        try:
            question_dict = transforms.json_to_dict(
                unvalidated_dict, self.get_schema().get_json_schema_dict())
        except ValueError as err:
            errors.append(str(err))
            return (None, errors)

        if not question_dict['question'].strip():
            errors.append('The question must have a non-empty body.')

        if not question_dict['description']:
            errors.append('The description must be non-empty.')

        self.validate_no_description_collision(
            question_dict['description'], key, errors)

        if not question_dict['choices']:
            errors.append('The question must have at least one choice.')

        choices = question_dict['choices']
        for index in range(0, len(choices)):
            choice = choices[index]
            if not choice['text'].strip():
                errors.append('Choice %s has no response text.' % (index + 1))
            try:
                # Coefrce the score attrib into a python float
                choice['score'] = float(choice['score'])
            except ValueError:
                errors.append(
                    'Choice %s must have a numeric score.' % (index + 1))

        return (question_dict, errors)
コード例 #17
0
    def test_missing_required_fields_are_rejected(self):
        schema = wrap_properties(
            {'req_field': {'type': 'boolean', 'optional': 'false'}})
        try:
            transforms.json_to_dict({}, schema)
            self.fail('Expected ValueError')
        except ValueError as e:
            self.assertEqual(str(e), 'Missing required attribute: req_field')

        schema = wrap_properties(
            {'req_field': {'type': 'boolean'}})
        try:
            transforms.json_to_dict({}, schema)
            self.fail('Expected ValueError')
        except ValueError as e:
            self.assertEqual(str(e), 'Missing required attribute: req_field')
コード例 #18
0
ファイル: announcements.py プロジェクト: Letractively/cb4oru
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = json.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'announcement-put', {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        transforms.dict_to_entity(entity, transforms.json_to_dict(
            json.loads(payload), SCHEMA_DICT))
        entity.put()

        transforms.send_json_response(self, 200, 'Saved.')
コード例 #19
0
 def test_missing_optional_fields_are_allowed(self):
     schema = wrap_properties(
         {'opt_field': {
             'type': 'boolean',
             'optional': 'true'
         }})
     result = transforms.json_to_dict({}, schema)
     self.assertEqual(len(result), 0)
コード例 #20
0
    def test_reject_bad_dates(self):
        schema = wrap_properties({'field': {'type': 'date'}})
        source = {'field': '2005/02/31'}
        try:
            transforms.json_to_dict(source, schema)
            self.fail('Expected ValueException')
        except ValueError as e:
            self.assertEqual(str(e), 'day is out of range for month')

        schema = wrap_properties({'field': {'type': 'date'}})
        source = {'field': 'cat'}
        try:
            transforms.json_to_dict(source, schema)
            self.fail('Expected ValueException')
        except ValueError as e:
            self.assertEqual(
                str(e), 'time data \'cat\' does not match format \'%Y/%m/%d\'')
コード例 #21
0
ファイル: news.py プロジェクト: google/coursebuilder-core
 def json_to_list(cls, json_str):
     if not json_str:
         return []
     json_dicts = transforms.loads(json_str)
     parsed_dicts = [
         transforms.json_to_dict(d, cls.SCHEMA.get_json_schema_dict())
         for d in json_dicts]
     return [cls(**kwargs) for kwargs in parsed_dicts]
コード例 #22
0
 def test_nulls(self):
     for type_name in transforms.JSON_TYPES:
         schema = wrap_properties({'field': {'type': type_name}})
         source = {'field': None}
         ret = transforms.json_to_dict(source, schema,
                                       permit_none_values=True)
         self.assertIn('field', ret)
         self.assertIsNone(ret['field'])
コード例 #23
0
    def test_reject_bad_dates(self):
        schema = wrap_properties({'field': {'type': 'date'}})
        source = {'field': '2005/02/31'}
        try:
            transforms.json_to_dict(source, schema)
            self.fail('Expected ValueException')
        except ValueError as e:
            self.assertEqual(str(e), 'day is out of range for month')

        schema = wrap_properties({'field': {'type': 'date'}})
        source = {'field': 'cat'}
        try:
            transforms.json_to_dict(source, schema)
            self.fail('Expected ValueException')
        except ValueError as e:
            self.assertEqual(
                str(e), 'time data \'cat\' does not match format \'%Y/%m/%d\'')
コード例 #24
0
ファイル: settings.py プロジェクト: blckt/lib
    def post(self):
        name = COURSE_EXPLORER_SETTINGS.name
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, self.ACTION, {}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.', {})
            return

        raw_data = transforms.loads(request.get('payload'))
        raw_data.pop('logo', None)
        try:
            data = transforms.json_to_dict(
                raw_data,
                schema_provider(None).get_json_schema_dict())
        except (TypeError, ValueError) as err:
            self.validation_error(err.replace('\n', ' '))
            return

        logo = self.request.POST.get('logo')
        logo_uploaded = isinstance(logo, cgi.FieldStorage)
        if logo_uploaded:
            data['logo_bytes_base64'] = base64.b64encode(logo.file.read())
            data['logo_mime_type'] = logo.type

        with common_utils.Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            entity = config.ConfigPropertyEntity.get_by_key_name(name)

            if entity is None:
                entity = config.ConfigPropertyEntity(key_name=name)
                old_value = None
            else:
                old_value = entity.value

            # Don't delete the logo.
            if not logo_uploaded and old_value:
                old_dict = transforms.loads(old_value)
                if ('logo_bytes_base64' in old_dict
                        and 'logo_mime_type' in old_dict):
                    data['logo_bytes_base64'] = old_dict['logo_bytes_base64']
                    data['logo_mime_type'] = old_dict['logo_mime_type']

            entity.value = transforms.dumps(data)
            entity.is_draft = False
            entity.put()

            # is this necessary?
            models.EventEntity.record(
                'put-property', users.get_current_user(),
                transforms.dumps({
                    'name': name,
                    'before': str(old_value),
                    'after': str(entity.value)
                }))

        transforms.send_file_upload_response(self, 200, 'Saved.')
コード例 #25
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(request, 'announcement-put',
                                              {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'key': key})
            return

        payload = request.get('payload')
        transforms.dict_to_entity(
            entity,
            transforms.json_to_dict(transforms.loads(payload),
                                    AnnouncementsItemRESTHandler.SCHEMA_DICT))
        entity.put()

        email_sent = False
        if entity.send_email and not entity.is_draft:
            # get all students email
            all_students = self.get_students()
            email_list = []
            recipient = ""
            for s in all_students:
                if s.is_enrolled and s.email != "*****@*****.**":
                    recipient = s.name + "<" + s.email + ">"
                    email_list.append(recipient)

            # send an announcement email
            sender_address = "MOOC <*****@*****.**>"
            user_address = email_list
            subject = "MOOC Announcement: " + entity.title
            body = ""
            html = entity.html
            mail.send_mail(sender_address,
                           "*****@*****.**",
                           subject,
                           body,
                           html=html,
                           bcc=user_address)

        if entity.send_email:
            message = 'Saved and sent.'
        else:
            message = 'Saved.'

        transforms.send_json_response(self, 200, message)
コード例 #26
0
    def test_missing_required_fields_are_rejected(self):
        schema = wrap_properties(
            {'req_field': {
                'type': 'boolean',
                'optional': 'false'
            }})
        try:
            transforms.json_to_dict({}, schema)
            self.fail('Expected ValueError')
        except ValueError as e:
            self.assertEqual(str(e), 'Missing required attribute: req_field')

        schema = wrap_properties({'req_field': {'type': 'boolean'}})
        try:
            transforms.json_to_dict({}, schema)
            self.fail('Expected ValueError')
        except ValueError as e:
            self.assertEqual(str(e), 'Missing required attribute: req_field')
コード例 #27
0
 def json_to_list(cls, json_str):
     if not json_str:
         return []
     json_dicts = transforms.loads(json_str)
     parsed_dicts = [
         transforms.json_to_dict(d, cls.SCHEMA.get_json_schema_dict())
         for d in json_dicts
     ]
     return [cls(**kwargs) for kwargs in parsed_dicts]
コード例 #28
0
    def put(self):
        """Handles PUT REST verb to save lesson and associated activity."""
        request = transforms.loads(self.request.get("request"))
        key = request.get("key")

        if not self.assert_xsrf_token_or_fail(request, "lesson-edit", {"key": key}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, "Access denied.", {"key": key})
            return

        course = courses.Course(self)
        lesson = course.find_lesson_by_id(None, key)
        if not lesson:
            transforms.send_json_response(self, 404, "Object not found.", {"key": key})
            return

        payload = request.get("payload")
        updates_dict = transforms.json_to_dict(
            transforms.loads(payload), self.get_schema(course, key).get_json_schema_dict()
        )

        lesson.title = updates_dict["title"]
        lesson.unit_id = updates_dict["unit_id"]
        lesson.scored = updates_dict["scored"] == "scored"
        lesson.objectives = updates_dict["objectives"]
        lesson.video = updates_dict["video"]
        lesson.notes = updates_dict["notes"]
        lesson.auto_index = updates_dict["auto_index"]
        lesson.activity_title = updates_dict["activity_title"]
        lesson.activity_listed = updates_dict["activity_listed"]
        lesson.manual_progress = updates_dict["manual_progress"]
        lesson.now_available = not updates_dict["is_draft"]

        activity = updates_dict.get("activity", "").strip()
        errors = []
        if activity:
            if lesson.has_activity:
                course.set_activity_content(lesson, activity, errors=errors)
            else:
                errors.append("Old-style activities are not supported.")
        else:
            lesson.has_activity = False
            fs = self.app_context.fs
            path = fs.impl.physical_to_logical(course.get_activity_filename(lesson.unit_id, lesson.lesson_id))
            if fs.isfile(path):
                fs.delete(path)

        if not errors:
            common_utils.run_hooks(self.PRE_SAVE_HOOKS, lesson, updates_dict)
            assert course.update_lesson(lesson)
            course.save()
            common_utils.run_hooks(self.POST_SAVE_HOOKS, lesson)
            transforms.send_json_response(self, 200, "Saved.")
        else:
            transforms.send_json_response(self, 412, "\n".join(errors))
コード例 #29
0
ファイル: settings.py プロジェクト: google/coursebuilder-core
    def post(self):
        name = COURSE_EXPLORER_SETTINGS.name
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(
                request, self.ACTION, {}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(
                self, 401, 'Access denied.', {})
            return

        raw_data = transforms.loads(request.get('payload'))
        raw_data.pop('logo', None)
        try:
            data = transforms.json_to_dict(
                raw_data, schema_provider(None).get_json_schema_dict())
        except (TypeError, ValueError) as err:
            self.validation_error(err.replace('\n', ' '))
            return

        logo = self.request.POST.get('logo')
        logo_uploaded = isinstance(logo, cgi.FieldStorage)
        if logo_uploaded:
            data['logo_bytes_base64'] = base64.b64encode(logo.file.read())
            data['logo_mime_type'] = logo.type

        with common_utils.Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
            entity = config.ConfigPropertyEntity.get_by_key_name(name)

            if entity is None:
                entity = config.ConfigPropertyEntity(key_name=name)
                old_value = None
            else:
                old_value = entity.value

            # Don't delete the logo.
            if not logo_uploaded and old_value:
                old_dict = transforms.loads(old_value)
                if (
                        'logo_bytes_base64' in old_dict and
                        'logo_mime_type' in old_dict):
                    data['logo_bytes_base64'] = old_dict['logo_bytes_base64']
                    data['logo_mime_type'] = old_dict['logo_mime_type']

            entity.value = transforms.dumps(data)
            entity.is_draft = False
            entity.put()

            # is this necessary?
            models.EventEntity.record(
                'put-property', users.get_current_user(), transforms.dumps({
                    'name': name,
                    'before': str(old_value), 'after': str(entity.value)}))

        transforms.send_file_upload_response(self, 200, 'Saved.')
コード例 #30
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')
        edit_mode = request.get('mode')

        if GLOBAL_DEBUG:
            logging.warning('***RAM*** put request = ' + str(request))

        if not self.assert_xsrf_token_or_fail(
                request, 'teacher-put', {'key': key}):
            return

        if not TeacherRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'MobileCSP: Admin access denied.', {'key': key})
            return

        entity = TeacherEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'MobileCSP: Teacher Entity not found.', {'key': key})
            return

        schema = TeacherItemRESTHandler.SCHEMA()

        payload = request.get('payload')
        update_dict = transforms.json_to_dict(
            transforms.loads(payload), schema.get_json_schema_dict())

        #  Get the teacher's user_id
        user = Student.get_first_by_email(update_dict['email'])[0]  # returns a tuple
        if not user:
            transforms.send_json_response(
                self, 404, 'MobileCSP: No registered user found for ' + update_dict['email'], {'key': key})
            return

        # Check that the teacher isn't already registered
        if update_dict['mode'] == 'Add':
            teachers = TeacherEntity.get_teachers()
            for teacher in teachers:
                if teacher.email == update_dict['email']:
                    transforms.send_json_response(
                        self, 404, 'MobileCSP: User is already registered as a teacher ' + update_dict['email'], {'key': key})
                    return

        if GLOBAL_DEBUG:
            logging.debug('****RAM**** teacher id ' + str(user.user_id))

        # Store the user_id
        update_dict['user_id'] = user.user_id

        transforms.dict_to_entity(entity, update_dict)

        entity.put()

        transforms.send_json_response(self, 200, 'Saved.')
コード例 #31
0
    def put(self):
        """Store a DTO in the datastore in response to a PUT."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not key and not self.CAN_CREATE:
            transforms.send_json_response(self, 404, 'Key is required in URL.',
                                          {})
            return

        if not self.assert_xsrf_token_or_fail(request, self.XSRF_TOKEN,
                                              {'key': key}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        payload = request.get('payload')
        json_dict = transforms.loads(payload)
        self.sanitize_input_dict(json_dict)

        errors = []
        try:
            python_dict = transforms.json_to_dict(
                json_dict,
                self.get_schema().get_json_schema_dict())

            version = python_dict.get('version')
            if version not in self.SCHEMA_VERSIONS:
                errors.append('Version %s not supported.' % version)
            else:
                python_dict = self.transform_after_editor_hook(python_dict)
                self.validate(python_dict, key, version, errors)
                common_utils.run_hooks(self.VALIDATE_HOOKS, python_dict, key,
                                       version, errors)
        except (TypeError, ValueError) as err:
            errors.append(str(err))
        if errors:
            self.validation_error('\n'.join(
                error.replace('\n', ' ') for error in errors),
                                  key=key)
            return

        item = self.get_and_populate_dto(key, python_dict)
        self.pre_save_hook(item)
        common_utils.run_hooks(self.PRE_SAVE_HOOKS, item, python_dict)
        key_after_save = self.DAO.save(item)
        self.after_save_hook()

        transforms.send_json_response(self,
                                      200,
                                      'Saved.',
                                      payload_dict={'key': key_after_save})
コード例 #32
0
    def _import_and_validate15(self, unvalidated_dict, key):
        errors = []
        try:
            question_dict = transforms.json_to_dict(
                unvalidated_dict,
                self.get_schema().get_json_schema_dict())
        except ValueError as err:
            errors.append(str(err))
            return (None, errors)

        if not question_dict['question'].strip():
            errors.append('The question must have a non-empty body.')

        if not question_dict['description']:
            errors.append('The description must be non-empty.')

        self.validate_no_description_collision(question_dict['description'],
                                               key, errors)

        try:
            # Coerce the rows attrib into a python int
            question_dict['rows'] = int(question_dict['rows'])
            if question_dict['rows'] <= 0:
                errors.append('Rows must be a positive whole number')
        except ValueError:
            errors.append('Rows must be a whole number')

        try:
            # Coerce the cols attrib into a python int
            question_dict['columns'] = int(question_dict['columns'])
            if question_dict['columns'] <= 0:
                errors.append('Columns must be a positive whole number')
        except ValueError:
            errors.append('Columns must be a whole number')

        if not question_dict['graders']:
            errors.append('The question must have at least one answer.')

        graders = question_dict['graders']
        for index in range(0, len(graders)):
            grader = graders[index]
            assert grader['matcher'] in [
                matcher for (matcher, unused_text) in self.GRADER_TYPES
            ]
            if not grader['response'].strip():
                errors.append('Answer %s has no response text.' % (index + 1))
            try:
                float(grader['score'])
            except ValueError:
                errors.append('Answer %s must have a numeric score.' %
                              (index + 1))

        return (question_dict, errors)
コード例 #33
0
ファイル: unit_lesson_editor.py プロジェクト: eliesmr4/ULearn
    def put(self):
        """Handles PUT REST verb to save lesson and associated activity."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(request, 'lesson-edit',
                                              {'key': key}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        course = courses.Course(self)
        lesson = course.find_lesson_by_id(None, key)
        if not lesson:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'key': key})
            return

        payload = request.get('payload')
        updates_dict = transforms.json_to_dict(transforms.loads(payload),
                                               self.SCHEMA_DICT)

        lesson.title = updates_dict['title']
        lesson.unit_id = updates_dict['unit_id']
        lesson.objectives = updates_dict['objectives']
        lesson.video = updates_dict['video']
        lesson.notes = updates_dict['notes']
        lesson.activity_title = updates_dict['activity_title']
        lesson.activity_listed = updates_dict['activity_listed']
        lesson.now_available = not updates_dict['is_draft']

        activity = updates_dict.get('activity', '').strip()
        errors = []
        if activity:
            lesson.has_activity = True
            course.set_activity_content(lesson, activity, errors=errors)
        else:
            lesson.has_activity = False
            fs = self.app_context.fs
            path = fs.impl.physical_to_logical(
                course.get_activity_filename(lesson.unit_id, lesson.lesson_id))
            if fs.isfile(path):
                fs.delete(path)

        if not errors:
            assert course.update_lesson(lesson)
            course.save()
            transforms.send_json_response(self, 200, 'Saved.')
        else:
            transforms.send_json_response(self, 412, '\n'.join(errors))
コード例 #34
0
    def put(self):
        """Handles PUT REST verb to save lesson and associated activity."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'lesson-edit', {'key': key}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        course = courses.Course(self)
        lesson = course.find_lesson_by_id(None, key)
        if not lesson:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        updates_dict = transforms.json_to_dict(
            transforms.loads(payload), self.SCHEMA_DICT)

        lesson.title = updates_dict['title']
        lesson.unit_id = updates_dict['unit_id']
        lesson.objectives = updates_dict['objectives']
        lesson.video = updates_dict['video']
        lesson.notes = updates_dict['notes']
        lesson.activity_title = updates_dict['activity_title']
        lesson.activity_listed = updates_dict['activity_listed']
        lesson.now_available = not updates_dict['is_draft']

        activity = updates_dict.get('activity', '').strip()
        errors = []
        if activity:
            lesson.has_activity = True
            course.set_activity_content(lesson, activity, errors=errors)
        else:
            lesson.has_activity = False
            fs = self.app_context.fs
            path = fs.impl.physical_to_logical(course.get_activity_filename(
                lesson.unit_id, lesson.lesson_id))
            if fs.isfile(path):
                fs.delete(path)

        if not errors:
            assert course.update_lesson(lesson)
            course.save()
            transforms.send_json_response(self, 200, 'Saved.')
        else:
            transforms.send_json_response(self, 412, '\n'.join(errors))
コード例 #35
0
ファイル: announcements.py プロジェクト: thejeshgn/seek
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(request, 'announcement-put',
                                              {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'key': key})
            return

        schema = AnnouncementsItemRESTHandler.SCHEMA(
            'Announcement',
            self.get_course().get_course_announcement_list_email())

        payload = request.get('payload')
        update_dict = transforms.json_to_dict(transforms.loads(payload),
                                              schema.get_json_schema_dict())

        entity.labels = utils.list_to_text(
            LabelGroupsHelper.decode_labels_group(
                update_dict.get('label_groups')))

        transforms.dict_to_entity(entity, update_dict)

        entity.put()
        AnnouncementUtil.update_course_with_last_announcement(
            self.app_context.get_namespace_name())

        email_sent = False
        if entity.send_email:
            email_manager = notify.EmailManager(self.get_course())
            email_sent = email_manager.send_announcement(
                entity.title, entity.html, intent=ANNOUNCEMENTS_INTENT)

        if entity.send_email and not email_sent:
            if not self.get_course().get_course_announcement_list_email():
                message = 'Saved. Announcement list not configured.'
            else:
                message = 'Saved, but there was an error sending email.'
        else:
            message = 'Saved.'
        transforms.send_json_response(self, 200, message)
コード例 #36
0
    def put(self):
        """Store a DTO in the datastore in response to a PUT."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not key and not self.CAN_CREATE:
            transforms.send_json_response(
                self, 404, 'Key is required in URL.', {})
            return

        if not self.assert_xsrf_token_or_fail(
                request, self.XSRF_TOKEN, {'key': key}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        payload = request.get('payload')
        json_dict = transforms.loads(payload)
        self.sanitize_input_dict(json_dict)

        errors = []
        try:
            python_dict = transforms.json_to_dict(
                json_dict, self.get_schema().get_json_schema_dict())

            version = python_dict.get('version')
            if version not in self.SCHEMA_VERSIONS:
                errors.append('Version %s not supported.' % version)
            else:
                python_dict = self.transform_after_editor_hook(python_dict)
                self.validate(python_dict, key, version, errors)
                common_utils.run_hooks(
                    self.VALIDATE_HOOKS, python_dict, key, version, errors)
        except (TypeError, ValueError) as err:
            errors.append(str(err))
        if errors:
            self.validation_error('\n'.join(
                error.replace('\n', ' ') for error in errors), key=key)
            return

        item = self.get_and_populate_dto(key, python_dict)
        self.pre_save_hook(item)
        common_utils.run_hooks(self.PRE_SAVE_HOOKS, item, python_dict)
        key_after_save = self.DAO.save(item)
        self.after_save_hook()

        transforms.send_json_response(
            self, 200, 'Saved.', payload_dict={'key': key_after_save})
コード例 #37
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'announcement-put', {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        transforms.dict_to_entity(entity, transforms.json_to_dict(
            transforms.loads(payload),
            AnnouncementsItemRESTHandler.SCHEMA_DICT))
        entity.put()

        email_sent = False
        if entity.send_email and not entity.is_draft:
            # get all students email
            all_students = self.get_students()
            email_list = []
            recipient = ""
            for s in all_students:
                if s.is_enrolled and s.email != "*****@*****.**":
                    recipient = s.name + "<" + s.email + ">"
                    email_list.append(recipient)

            # send an announcement email
            sender_address = "MOOC <*****@*****.**>"
            user_address = email_list
            subject = "MOOC Announcement: " + entity.title
            body = ""
            html = entity.html
            mail.send_mail(sender_address, "*****@*****.**", subject, body, html=html, bcc=user_address)

        if entity.send_email:
            message = 'Saved and sent.'
        else:
            message = 'Saved.'

        transforms.send_json_response(self, 200, message)
コード例 #38
0
    def test_convert_datetime(self):
        schema = wrap_properties({'field': {'type': 'datetime'}})

        source = {'field': '2005/03/01 20:30'}
        result = transforms.json_to_dict(source, schema)
        self.assertEqual(len(result), 1)
        self.assertEqual(
            result['field'], datetime.datetime(2005, 3, 1, 20, 30, 0))

        source = {'field': '2005-03-01 20:30:19'}
        result = transforms.json_to_dict(source, schema)
        self.assertEqual(
            result['field'], datetime.datetime(2005, 3, 1, 20, 30, 19))

        source = {'field': '2005-03-01 20:30:19Z'}
        result = transforms.json_to_dict(source, schema)
        self.assertEqual(
            result['field'], datetime.datetime(2005, 3, 1, 20, 30, 19))

        source = {'field': '2005-03-01T20:30:19.123456Z'}
        result = transforms.json_to_dict(source, schema)
        self.assertEqual(
            result['field'], datetime.datetime(2005, 3, 1, 20, 30, 19, 123456))
コード例 #39
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'announcement-put', {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        schema = AnnouncementsItemRESTHandler.SCHEMA(
            'Announcement',
            self.get_course().get_course_announcement_list_email())

        payload = request.get('payload')
        update_dict = transforms.json_to_dict(
            transforms.loads(payload), schema.get_json_schema_dict())

        entity.labels = utils.list_to_text(
            LabelGroupsHelper.decode_labels_group(
                update_dict.get('label_groups')))

        transforms.dict_to_entity(entity, update_dict)

        entity.put()

        email_sent = False
        if entity.send_email:
            email_manager = notify.EmailManager(self.get_course())
            email_sent = email_manager.send_announcement(
                entity.title, entity.html)

        if entity.send_email and not email_sent:
            if not self.get_course().get_course_announcement_list_email():
                message = 'Saved. Announcement list not configured.'
            else:
                message = 'Saved, but there was an error sending email.'
        else:
            message = 'Saved.'
        transforms.send_json_response(self, 200, message)
コード例 #40
0
    def test_array_of_string(self):
        reg = schema_fields.FieldRegistry('Test')
        reg.add_property(schema_fields.FieldArray(
            'string_array', 'String Array',
            item_type=schema_fields.SchemaField(None, None, 'string'),
            select_data=(('one', 'One'), ('two', 'Two'), ('three', 'Three'))))
        json_schema = reg.get_json_schema_dict()

        source = {'string_array': ['one', 'two']}

        self.assertEqual(transforms.validate_object_matches_json_schema(
            source, json_schema), [])

        self.assertEqual(transforms.json_to_dict(source, json_schema), source)
コード例 #41
0
ファイル: dto_editor.py プロジェクト: ncivil/course-builder
    def put(self):
        """Store a DTO 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 roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        payload = request.get('payload')
        json_dict = transforms.loads(payload)
        self.sanitize_input_dict(json_dict)

        errors = []
        try:
            python_dict = transforms.json_to_dict(
                json_dict,
                self.get_schema().get_json_schema_dict())

            version = python_dict.get('version')
            if version not in self.SCHEMA_VERSIONS:
                errors.append('Version %s not supported.' % version)
            else:
                python_dict = self.transform_after_editor_hook(python_dict)
                self.validate(python_dict, key, version, errors)
        except ValueError as err:
            errors.append(str(err))
        if errors:
            self.validation_error('\n'.join(errors), key=key)
            return

        if key:
            item = self.DAO.DTO(key, python_dict)
        else:
            item = self.DAO.DTO(None, python_dict)

        self.pre_save_hook(item)
        key_after_save = self.DAO.save(item)
        self.after_save_hook()

        transforms.send_json_response(self,
                                      200,
                                      'Saved.',
                                      payload_dict={'key': key_after_save})
コード例 #42
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'announcement-put', {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        transforms.dict_to_entity(entity, transforms.json_to_dict(
            transforms.loads(payload),
            AnnouncementsItemRESTHandler.SCHEMA_DICT))
        entity.put()

        email_sent = False
        if entity.send_email:
            email_manager = notify.EmailManager(self.get_course())
            email_sent = email_manager.send_announcement(
                entity.title, entity.html)

        if entity.send_email and not email_sent:
            if not self.get_course().get_course_announcement_list_email():
                message = 'Saved. Announcement list not configured.'
            else:
                message = 'Saved, but there was an error sending email.'
        else:
            
            #if message is public
            if entity.is_draft == False:
                message = 'Saved and notifications sent correctly.'
                send_push_notification(self.app_context.get_environ()['course']['title'], entity.title, entity.html)
            else:
                message = 'Saved.'


        transforms.send_json_response(self, 200, message)
コード例 #43
0
 def test_bidirectional_transforms_succeed(self):
     """Tests that transforms entity<->dict<->json round trips correctly."""
     referenced_model_key = ReferencedModel().put()
     entity = UnvalidatedReference(referenced_model_key=referenced_model_key)
     entity.put()
     transformed = transforms.entity_to_dict(entity)
     self.assertEqual(referenced_model_key, entity.referenced_model_key)
     self.assertEqual(referenced_model_key, transformed["referenced_model_key"])
     new_key = ReferencedModel().put()
     transformed["referenced_model_key"] = new_key
     restored = transforms.dict_to_entity(entity, transformed)
     self.assertEqual(new_key, restored.referenced_model_key)
     json = transforms.dict_to_json(transformed, None)
     self.assertEqual(str(new_key), json["referenced_model_key"])
     from_json = transforms.json_to_dict(json, {"properties": {"referenced_model_key": {"type": "string"}}})
     self.assertEqual({"referenced_model_key": str(new_key)}, from_json)
コード例 #44
0
    def put(self):
        """Handles PUT REST verb to save lesson and associated activity."""
        request = transforms.loads(self.request.get("request"))
        key = request.get("key")

        if not self.assert_xsrf_token_or_fail(request, "lesson-edit", {"key": key}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(self, 401, "Access denied.", {"key": key})
            return

        course = courses.Course(self)
        lesson = course.find_lesson_by_id(None, key)
        if not lesson:
            transforms.send_json_response(self, 404, "Object not found.", {"key": key})
            return

        payload = request.get("payload")
        updates_dict = transforms.json_to_dict(transforms.loads(payload), self.SCHEMA_DICT)

        lesson.title = updates_dict["title"]
        lesson.unit_id = updates_dict["unit_id"]
        lesson.objectives = updates_dict["objectives"]
        lesson.video = updates_dict["video"]
        lesson.notes = updates_dict["notes"]
        lesson.activity_title = updates_dict["activity_title"]
        lesson.now_available = not updates_dict["is_draft"]

        activity = updates_dict.get("activity", "").strip()
        errors = []
        if activity:
            lesson.has_activity = True
            course.set_activity_content(lesson, activity, errors=errors)
        else:
            lesson.has_activity = False
            fs = self.app_context.fs
            path = fs.impl.physical_to_logical(course.get_activity_filename(lesson.unit_id, lesson.lesson_id))
            if fs.isfile(path):
                fs.delete(path)

        if not errors:
            assert course.update_lesson(lesson)
            course.save()
            transforms.send_json_response(self, 200, "Saved.")
        else:
            transforms.send_json_response(self, 412, "\n".join(errors))
コード例 #45
0
ファイル: announcements.py プロジェクト: twiffy/eabooc
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'announcement-put', {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        payload = request.get('payload')
        transforms.dict_to_entity(entity, transforms.json_to_dict(
            transforms.loads(payload),
            AnnouncementsItemRESTHandler.SCHEMA_DICT))
        entity.put()

        if not (entity.is_draft or entity.already_notified):
            Notification.notify_all_students(url='/announcements',
                    text=entity.title)
            entity.already_notified = True
            entity.put()

        email_sent = False
        if entity.send_email:
            email_manager = notify.EmailManager(self.get_course())
            email_sent = email_manager.send_announcement(
                entity.title, entity.html)

        if entity.send_email and not email_sent:
            if not self.get_course().get_course_announcement_list_email():
                message = 'Saved. Announcement list not configured.'
            else:
                message = 'Saved, but there was an error sending email.'
        else:
            message = 'Saved.'
        transforms.send_json_response(self, 200, message)
コード例 #46
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, self.ACTION,
                                              {'key': None}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.', {})
            return

        payload = request.get('payload')
        course_raw = transforms.json_to_dict(transforms.loads(payload),
                                             self.SCHEMA_DICT)['course']

        source = None
        for acourse in sites.get_all_courses():
            if acourse.raw == course_raw:
                source = acourse
                break

        if not source:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'raw': course_raw})
            return

        import_job = ImportCourseBackgroundJob(self.app_context,
                                               source.get_namespace_name())
        if import_job.is_active():
            transforms.send_json_response(self, 503,
                                          'Import already in progress.',
                                          {'raw': course_raw})
            return
        try:
            status = import_job.submit()
            error_starting = (status < 0)
        except Exception:  # pylint: disable=broad-except
            error_starting = True
        if error_starting:
            transforms.send_json_response(self, 500, 'Could not start import.',
                                          {'raw': course_raw})
            return

        transforms.send_json_response(self, 200, 'Importing.')
コード例 #47
0
    def put(self):
        """Store a QuestionGroupDTO and QuestionDTO in the datastore."""
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, self.XSRF_TOKEN,
                                              {'key': None}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.')
            return

        payload = request.get('payload')
        json_dict = transforms.loads(payload)

        errors = []
        try:
            python_dict = transforms.json_to_dict(
                json_dict,
                self.get_schema().get_json_schema_dict())
            questions = gift.GiftParser.parse_questions(
                python_dict['questions'])
            self.validate_question_descriptions(questions, errors)
            description = python_dict['description']
            if description:
                self.validate_group_description(description, errors)
            if not errors:
                dtos = self.convert_to_dtos(questions)
                question_ids = models.QuestionDAO.save_all(dtos)
                if description:
                    self.create_group(description, question_ids)
        except ValueError as e:
            errors.append(str(e))
        except gift.ParseError as e:
            errors.append(str(e))
        except models.CollisionError as e:
            errors.append(str(e))
        if errors:
            self.validation_error('\n'.join(errors))
            return

        msg = 'Saved: %s.' % python_dict['description']
        transforms.send_json_response(self, 200, msg)
        return
コード例 #48
0
    def put(self):
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(request, self.XSRF_TOKEN, {}):
            return

        if not roles.Roles.is_course_admin(self.app_context):
            transforms.send_json_response(self, 401, 'Access denied.',
                                          {'key': key})
            return

        payload = request.get('payload')
        json_dict = transforms.loads(payload)
        python_dict = transforms.json_to_dict(
            json_dict,
            self.get_schema().get_json_schema_dict(),
            permit_none_values=True)

        version = python_dict.get('version')
        if version not in self.SCHEMA_VERSIONS:
            self.validation_error('Version %s not supported.' % version)
            return

        errors = []

        if key:
            key_after_save = SkillGraph.load().update(key, python_dict, errors)
        else:
            skill = Skill.build(python_dict.get('name'),
                                python_dict.get('description'),
                                python_dict.get('prerequisites'))
            key_after_save = SkillGraph.load().add(skill, errors=errors).id

        if errors:
            self.validation_error('\n'.join(errors), key=key)
            return

        transforms.send_json_response(self,
                                      200,
                                      'Saved.',
                                      payload_dict={'key': key_after_save})
コード例 #49
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, 'unit-lesson-reorder',
                                              {'key': None}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.', {})
            return

        payload = request.get('payload')
        payload_dict = transforms.json_to_dict(transforms.loads(payload),
                                               self.SCHEMA_DICT)
        course = courses.Course(self)
        course.reorder_units(payload_dict['outline'])
        course.save()

        transforms.send_json_response(self, 200, 'Saved.')
コード例 #50
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, 'import-course',
                                              {'key': None}):
            return

        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(self, 401, 'Access denied.', {})
            return

        payload = request.get('payload')
        course_raw = transforms.json_to_dict(transforms.loads(payload),
                                             self.SCHEMA_DICT)['course']

        source = None
        for acourse in sites.get_all_courses():
            if acourse.raw == course_raw:
                source = acourse
                break

        if not source:
            transforms.send_json_response(self, 404, 'Object not found.',
                                          {'raw': course_raw})
            return

        course = courses.Course(self)
        errors = []
        try:
            course.import_from(source, errors)
        except Exception as e:  # pylint: disable=broad-except
            logging.exception(e)
            errors.append('Import failed: %s' % e)

        if errors:
            transforms.send_json_response(self, 412, '\n'.join(errors))
            return

        course.save()
        transforms.send_json_response(self, 200, 'Imported.')
コード例 #51
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, self.ACTION, {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        schema = AnnouncementsItemRESTHandler.SCHEMA()

        payload = request.get('payload')
        update_dict = transforms.json_to_dict(
            transforms.loads(payload), schema.get_json_schema_dict())
        if entity.is_draft and not update_dict.get('set_draft'):
            item = news.NewsItem(
                str(TranslatableResourceAnnouncement.key_for_entity(entity)),
                AnnouncementsStudentHandler.URL.lstrip('/'))
            news.CourseNewsDao.add_news_item(item)

        # The datetime widget returns a datetime object and we need a UTC date.
        update_dict['date'] = update_dict['date'].date()
        del update_dict['key']  # Don't overwrite key member method in entity.
        transforms.dict_to_entity(entity, update_dict)

        entity.put()

        transforms.send_json_response(self, 200, 'Saved.')
コード例 #52
0
ファイル: email_settings.py プロジェクト: thejeshgn/seek
    def put(self):
        """A PUT REST method shared by all unit types."""
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, 'update_queue_settings',
                                              {}):
            return

        if not roles.Roles.is_super_admin():
            transforms.send_json_response(self, 401, 'Access denied.')
            return

        payload = request.get('payload')
        updated_dict = transforms.json_to_dict(transforms.loads(payload),
                                               self.get_schema_dict())

        errors = []
        self.apply_updates(updated_dict, errors)
        if not errors:
            transforms.send_json_response(self, 200, 'Saved.')
        else:
            transforms.send_json_response(self, 412, '\n'.join(errors))
コード例 #53
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))
        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, 'announcement-put', {'key': key}):
            return

        if not AnnouncementsRights.can_edit(self):
            transforms.send_json_response(
                self, 401, 'Access denied.', {'key': key})
            return

        entity = AnnouncementEntity.get(key)
        if not entity:
            transforms.send_json_response(
                self, 404, 'Object not found.', {'key': key})
            return

        schema = AnnouncementsItemRESTHandler.SCHEMA()

        payload = request.get('payload')
        update_dict = transforms.json_to_dict(
            transforms.loads(payload), schema.get_json_schema_dict())

        # The datetime widget returns a datetime object and we need a UTC date.
        update_dict['date'] = update_dict['date'].date()

        entity.labels = common_utils.list_to_text(
            resources_display.LabelGroupsHelper.field_data_to_labels(
                update_dict))
        resources_display.LabelGroupsHelper.remove_label_field_data(update_dict)

        transforms.dict_to_entity(entity, update_dict)

        entity.put()

        transforms.send_json_response(self, 200, 'Saved.')
コード例 #54
0
    def _add_query_filters(cls, source_context, schema, page_number, query):
        for filter_spec in source_context.filters:
            parts = cls.FILTER_RE.match(filter_spec)
            if not parts:
                raise ValueError('Filter specification "%s" ' % filter_spec +
                                 'is not of the form: <name><op><value>')
            name, op, value = parts.groups()
            if op not in cls.SUPPORTED_OPERATIONS:
                raise ValueError(
                    'Filter specification "%s" ' % filter_spec +
                    'uses an unsupported comparison operation "%s"' % op)

            if name not in schema:
                raise ValueError('Filter specification "%s" ' % filter_spec +
                                 'calls for field "%s" ' % name +
                                 'which is not in the schema for '
                                 'type "%s"' % cls.get_entity_class().__name__)
            converted_value = transforms.json_to_dict(
                {name: value}, {'properties': {
                    name: schema[name]
                }})[name]
            query.filter('%s %s' % (name, op), converted_value)
コード例 #55
0
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        request = transforms.loads(self.request.get('request'))

        if not self.assert_xsrf_token_or_fail(request, self.XSRF_TOKEN,
                                              {'key': None}):
            return

        if not roles.Roles.is_user_allowed(
                self.app_context, custom_module,
                constants.COURSE_OUTLINE_REORDER_PERMISSION):

            transforms.send_json_response(self, 401, 'Access denied.', {})
            return

        payload = request.get('payload')
        payload_dict = transforms.json_to_dict(transforms.loads(payload),
                                               self.SCHEMA_DICT)
        course = courses.Course(self)
        course.reorder_units(payload_dict['outline'])
        course.save()

        transforms.send_json_response(self, 200, 'Saved.')
コード例 #56
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})
コード例 #57
0
    def post(self):
        """POST method called when the student submits answers."""

        # I18N: Message to show the user was not allowed to access to resource
        access_denied = self.gettext('Access denied.')

        # I18N: Message to acknowledge successful submission of the
        # questionnaire
        response_submitted = self.gettext('Response submitted.')

        request = transforms.loads(self.request.get('request'))

        key = request.get('key')

        if not self.assert_xsrf_token_or_fail(
                request, QUESTIONNAIRE_XSRF_TOKEN_NAME, {}):
            return

        user = self.get_user()
        if user is None:
            transforms.send_json_response(self, 401, access_denied, {})
            return

        student = models.Student.get_enrolled_student_by_user(user)
        if student is None:
            transforms.send_json_response(self, 401, access_denied, {})
            return

        payload_json = request.get('payload')
        payload_dict = transforms.json_to_dict(payload_json, self.SCHEMA)

        form_data = StudentFormEntity.load_or_default(student, key)
        form_data.value = transforms.dumps(payload_dict)
        form_data.put()

        transforms.send_json_response(self, 200, response_submitted)