コード例 #1
0
class RepositoryDocumentListApi(ApiRequestHandler):
    """Handle Document listing requests

    """
    path = resource.endpoint('/dashboard/repository/<studentId>/files')

    @path.operation(
        type_="DocumentList",
        alias="getRepositoryByStudentId",
        parameters=[
            swagger.String(name="cursor",
                           description="Cursor to query the next page",
                           param_type="query"),
            swagger.String(name="studentId",
                           param_type="path",
                           description="Id of student details to edit",
                           required=True)
        ],
        responses=[
            swagger.Message(200, "Ok"),
            swagger.Message(400, "Bad Request"),
            swagger.Message(401, "Unauthorized"),
            swagger.Message(403, "Forbidden"),
            swagger.Message(404, "Not Found")
        ])
    def get(self, studentId):
        """List all the files at destination to a specific student

        """
        student = Student.get_by_id(studentId)
        if not student:
            self.abort(404)

        current_user = self.login_required()
        if (not current_user.is_staff and not current_user.is_admin
                and not current_user.is_domain_admin
                and current_user.student_id != student.key.id()):
            self.abort(403)
            return

        cursor_key = self.request.GET.get('cursor')

        # using cheap request and ndb entities cache
        file_keys, cursor, _ = models.Document.get_files(student.key,
                                                         cursor_key,
                                                         keys_only=True)
        ffiles = [k.get_async() for k in file_keys]

        self.render_json({
            'files':
            map(self.file_dict, [ff.get_result() for ff in ffiles]),
            'cursor':
            cursor.urlsafe() if cursor else ''
        })

    def file_dict(self, file_):
        data = file_.summary()
        data['url'] = self.uri_for('dashboard_download_file',
                                   keyId=file_.key.id())
        return data
コード例 #2
0
class AssessmentExamListApi(ApiRequestHandler):
    """Handle operations on the exam lists

    """
    path = assessment_resource.endpoint('/dashboard/assessments/exams')

    @path.operation(
        type_='AssessmentExamList',
        alias='listExams',
        parameters=[
            swagger.String(
                name="studentId",
                description="Id of student details to list exam for",
                param_type="query"),
            swagger.String(name="cursor",
                           description="Cursor to query the next page",
                           param_type="query"),
        ],
        responses=[
            swagger.Message(200, "Ok"),
            swagger.Message(401, "Unauthorized"),
            swagger.Message(403, "Forbidden"),
            swagger.Message(404, "Not Found")
        ])
    def get(self):
        """Return a list exams.

        """
        student_id = self.request.GET.get('studentId')
        if student_id:
            self._get_exams_by_student_id(student_id)
        else:
            self._get_exams()

    def _get_exams(self):
        self.staff_required()

        exams = models.AssessmentExam.get_exams()
        self.render_json({
            'cursor': '',
            'exams': [e.summary() for e in exams],
        })

    def _get_exams_by_student_id(self, student_id):
        student = Student.get_by_id(student_id)
        if not student:
            self.abort(404, 'User not found')

        current_user = self.login_required()
        if (not current_user.is_staff and not current_user.is_admin
                and not current_user.is_domain_admin
                and student.key.id() != current_user.student_id):
            self.abort(403)

        exams = models.AssessmentExam.get_by_student_id(student.key.id())
        self.render_json({
            'cursor': '',
            'exams': [e.summary() for e in exams],
            'student': student.summary()
        })
コード例 #3
0
class AssessmentExamApi(ApiRequestHandler):
    """Handle request for an exam resource

    """
    path = assessment_resource.endpoint(
        '/dashboard/assessments/exams/<examId:\d+>')

    @path.operation(type_='AssessmentExam',
                    alias='getExamDetails',
                    parameters=[
                        swagger.String(
                            name="examId",
                            description="Id of exam to show details for",
                            param_type="path",
                            required=True),
                    ],
                    responses=[
                        swagger.Message(200, "Ok"),
                        swagger.Message(401, "Unauthorized"),
                        swagger.Message(403, "Forbidden"),
                        swagger.Message(404, "Not Found")
                    ])
    def get(self, examId):
        """Retrieve detailed informations about an exam

        """
        self.staff_required()

        exam = models.AssessmentExam.get_by_id(int(examId))
        if exam is None:
            self.abort(404)
        self.render_json(exam.details())
コード例 #4
0
class UploadUrlHandler(ApiRequestHandler):
    path = resource.endpoint('/dashboard/uploadurl/repository/<studentId>')

    @path.operation(type_='BlobStoreUploadInfo',
                    alias='newUploadUrl',
                    parameters=[
                        swagger.String(
                            name="studentId",
                            param_type="path",
                            description="Id of student details to edit",
                            required=True)
                    ],
                    responses=[
                        swagger.Message(200, "Ok"),
                        swagger.Message(401, "Unauthorized"),
                        swagger.Message(403, "Forbidden")
                    ])
    def post(self, studentId):
        """Create a new blobstore upload url.

        The student id is currently not used with this implementation.
        The student id should be sent with uploaded file.

        """
        self.staff_required()
        self.render_json(
            {"url": blobstore.create_upload_url(config.UPLOAD_CB_URL)})
コード例 #5
0
class UserListApi(ApiRequestHandler):
    """Handle user list resource.

    """
    path = student_resource.endpoint("/dashboard/users")

    @path.operation(type_="UserList",
                    alias="listUsers",
                    parameters=[
                        swagger.String(
                            name="cursor",
                            description="Cursor to query the next page",
                            param_type="query")
                    ],
                    responses=[
                        swagger.Message(200, "Ok"),
                        swagger.Message(401, "Unauthorized"),
                        swagger.Message(403, "Forbidden"),
                    ])
    def get(self):
        """List all Users (20 per page).

        The current user must be logged in as staff to see
        the list of users.

        """
        self.staff_required()

        cursor_key = self.request.GET.get('cursor')
        users, cursor = models.User.get_users(cursor_key)
        return self.render_json({
            'type': 'users',
            'users': [s.summary() for s in users],
            'cursor': cursor if cursor else ''
        })
コード例 #6
0
class RepositoryDocumentApi(ApiRequestHandler):
    """Handle requests on a document

    """

    path = resource.endpoint(
        '/dashboard/repository/<studentId>/files/<fileId>')

    @path.operation(
        type_="DocumentList",
        alias="deleteDocument",
        parameters=[
            swagger.String(name="studentId",
                           param_type="path",
                           description="Id of student details to edit",
                           required=True),
            swagger.String(name="fileId",
                           param_type="path",
                           description="Id of the document to delete",
                           required=True)
        ],
        responses=[
            swagger.Message(200, "Ok"),
            swagger.Message(401, "Unauthorized"),
            swagger.Message(403, "Forbidden"),
            swagger.Message(404, "Not Found")
        ])
    def delete(self, studentId, fileId):
        """Delete a document.

        """
        self.admin_required()

        student = Student.get_by_id(studentId)
        document = models.Document.get_by_id(fileId)
        if (not student or not document
                or document.dest_ref.id() != student.key.id()):
            self.abort(404)

        document.delete()
        self.render_json({'success': True})
コード例 #7
0
class FirstAidStatsApi(ApiRequestHandler):
    """Handle request for First Aid stats listing.

    """

    path = firstaid_resource.endpoint('/dashboard/firstaid/stats')

    @path.operation(
        type_='FirstAidUserStatsList',
        alias='listFirstAidStats',
        # TODO: add filters
        parameters=[
            swagger.String(name="cursor",
                           description="Cursor to query the next page",
                           param_type="query")
        ],
        responses=[
            swagger.Message(200, "Ok"),
            swagger.Message(401, "Unauthorized"),
            swagger.Message(403, "Forbidden"),
            swagger.Message(404, "Not Found")
        ])
    def get(self):
        """List student stats.

        """
        self.staff_required()
        cursor_key = self.request.GET.get('cursor')
        topic_id = self.request.GET.get('topic')
        sort_by = self.request.GET.get('sortBy')

        if topic_id == 'all':
            topic_id = None

        sort_by_options = {
            'performance': 'performance',
            'questionTaken': 'question_taken'
        }
        sort_by = sort_by_options.get(sort_by, 'performance')

        try:
            limit = int(self.request.GET.get('limit'))
        except (
                ValueError,
                TypeError,
        ):
            limit = None

        try:
            residents = self.request.GET.get('residents')
            if residents == 'all':
                residents = None
            else:
                residents = int(residents)
        except (
                ValueError,
                TypeError,
        ):
            residents = None

        stats, cursor = FirstAidUserStats.get_stats(cursor_key=cursor_key,
                                                    limit=limit,
                                                    year=residents,
                                                    topic_id=topic_id,
                                                    sort_by=sort_by)
        self.render_json({
            'stats': [s.summary() for s in stats],
            'cursor': cursor if cursor else ''
        })
コード例 #8
0
class AdminApi(ApiRequestHandler):
    """Handle request on a admin user

    """
    path = admin_resource.endpoint("/dashboard/admin/<userId:\d+>")

    @path.operation(type_="User",
                    alias="makeAdmin",
                    parameters=[
                        swagger.String(name="userId",
                                       param_type="path",
                                       description="Id of user to make admin",
                                       required=True)
                    ],
                    responses=[
                        swagger.Message(200, "Ok"),
                        swagger.Message(401, "Unauthorized"),
                        swagger.Message(403, "Forbidden"),
                        swagger.Message(404, "Not Found"),
                    ])
    def put(self, userId):
        """Flag a user as an staff.

        """
        self.admin_required()
        user_id = int(userId)
        user = models.User.get_by_id(user_id)

        if user is None:
            self.abort(404)

        models.User.make_admin(user_id)
        self.render_json({})

    @path.operation(
        type_="User",
        alias="revokeAdmin",
        parameters=[
            swagger.String(
                name="userId",
                param_type="path",
                description="Id of user to revoke admin permission from",
                required=True)
        ],
        responses=[
            swagger.Message(200, "Ok"),
            swagger.Message(401, "Unauthorized"),
            swagger.Message(403, "Forbidden"),
            swagger.Message(404, "Not Found"),
        ])
    def delete(self, userId):
        """Remove staff flag from a user.

        """
        self.admin_required()
        user_id = int(userId)
        user = models.User.get_by_id(user_id)

        if user is None:
            self.abort(404)

        if user.is_domain_admin:
            self.abort(400)

        models.User.revoke_admin(user_id)
        self.render_json({})
コード例 #9
0
class StudentListApi(ApiRequestHandler):
    """Handle student list resource.

    """
    path = student_resource.endpoint("/dashboard/students")

    @path.operation(type_="StudentList",
                    alias="listStudents",
                    parameters=[
                        swagger.String(
                            name="cursor",
                            description="Cursor to query the next page",
                            param_type="query")
                    ],
                    responses=[
                        swagger.Message(200, "Ok"),
                        swagger.Message(401, "Unauthorized"),
                        swagger.Message(403, "Forbidden"),
                    ])
    def get(self):
        """List all students (20 per page).

        The current user must be logged in as an app admin to see
        the list of student.

        """
        self.staff_required()

        cursor_key = self.request.GET.get('cursor')
        limit = self.request.GET.get('limit')
        name = self.request.GET.get('name', '')
        raw_years = self.request.GET.getall('years')

        if limit is not None:
            try:
                limit = int(limit)
            except (ValueError, TypeError):
                limit = None

        years = []
        for y in raw_years:
            try:
                years.append(int(y))
            except (
                    ValueError,
                    TypeError,
            ):
                pass

        props = {
            "limit": limit,
            "name": name.lower(),
            "years": years,
            "cursor_key": cursor_key
        }

        if limit is 0:
            students = self.get_list()
            cursor = None
        else:
            students, cursor = models.Student.get_students(**props)

        return self.render_json({
            'type': 'students',
            'students': students,
            'cursor': cursor if cursor else ''
        })

    cache_ttl = 60 * 60

    @staticmethod
    def cache_key():
        return 'OEPSTUDENT_STUDENT_LIST'

    @classmethod
    def get_list(cls, **kw):
        key = cls.cache_key()
        cache = memcache.get(key)
        if cache is not None:
            return cache

        students, _ = models.Student.get_students(cursor_key=None, limit=0)
        memcache.set(key, students, time=cls.cache_ttl)

        return students

    @classmethod
    def reset_list_cache(cls):
        memcache.delete(cls.cache_key())

    @path.operation(type_="Student",
                    alias="newStudent",
                    parameters=[],
                    responses=[
                        swagger.Message(200, "Ok"),
                        swagger.Message(400, "Bad Request"),
                        swagger.Message(401, "Unauthorized"),
                        swagger.Message(403, "Forbidden"),
                    ])
    def post(self):
        """Create a new Student

        """
        self.admin_required()
        try:
            payload = json.loads(self.request.body)
            student = models.Student.new_student(
                payload['name']['givenName'],
                payload['displayName'],
                family_name=payload['name']['familyName'],
                email=payload['secondaryEmail'],
                student_id=payload['studentId'],
                year=payload['year'])
        except (ValidationError, ValueError, AttributeError, KeyError):
            self.abort(400)

        return self.render_json(student.details())