Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-proctoring
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
edx-proctoring
Commits
a7e5bbea
Commit
a7e5bbea
authored
Jun 25, 2015
by
Afzal Wali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Create Exam API
parent
e577b8a6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
70 additions
and
7 deletions
+70
-7
edx_proctoring/models.py
+7
-7
edx_proctoring/urls.py
+5
-0
edx_proctoring/views.py
+58
-0
No files found.
edx_proctoring/models.py
View file @
a7e5bbea
...
...
@@ -21,16 +21,16 @@ class ProctoredExam(TimeStampedModel):
# This will be a integration specific ID - say to SoftwareSecure.
external_id
=
models
.
TextField
(
null
=
True
,
db_index
=
True
)
# This is the display name of the
course
# This is the display name of the
Exam (Midterm etc).
exam_name
=
models
.
TextField
()
# Time limit (in minutes) that a student can finish this exam
# Time limit (in minutes) that a student can finish this exam
.
time_limit_mins
=
models
.
IntegerField
()
# Whether this exam actually is proctored or not
# Whether this exam actually is proctored or not
.
is_proctored
=
models
.
BooleanField
()
#
This will be a integration specific ID - say to SoftwareSecur
e.
#
Whether this exam will be activ
e.
is_active
=
models
.
BooleanField
()
class
Meta
:
...
...
@@ -65,7 +65,7 @@ class ProctoredExamStudentAttempt(TimeStampedModel):
class
QuerySetWithUpdateOverride
(
models
.
query
.
QuerySet
):
"""
Custom QuerySet class to
send the POST_UPDATE_SIGNAL
Custom QuerySet class to
make an archive copy
every time the object is updated.
"""
def
update
(
self
,
**
kwargs
):
...
...
@@ -76,7 +76,7 @@ class QuerySetWithUpdateOverride(models.query.QuerySet):
class
ProctoredExamStudentAllowanceManager
(
models
.
Manager
):
"""
Custom manager to override with the custom queryset
to enable
the POST_UPDATE_SIGNAL
to enable
archiving on Allowance updation.
"""
def
get_query_set
(
self
):
return
QuerySetWithUpdateOverride
(
self
.
model
,
using
=
self
.
_db
)
...
...
@@ -120,7 +120,7 @@ class ProctoredExamStudentAllowanceHistory(TimeStampedModel):
value
=
models
.
CharField
(
max_length
=
255
)
# Hook up the
custom POST_UPDATE_SIGNAL signal to record upd
ations in the ProctoredExamStudentAllowanceHistory table.
# Hook up the
post_save signal to record cre
ations in the ProctoredExamStudentAllowanceHistory table.
@receiver
(
post_save
,
sender
=
ProctoredExamStudentAllowance
)
def
on_allowance_saved
(
sender
,
instance
,
created
,
**
kwargs
):
# pylint: disable=unused-argument
"""
...
...
edx_proctoring/urls.py
View file @
a7e5bbea
...
...
@@ -12,5 +12,10 @@ urlpatterns = patterns( # pylint: disable=invalid-name
views
.
StudentProctoredExamStatus
.
as_view
(),
name
=
'edx_proctoring.proctored_exam.status'
),
url
(
r'edx_proctoring/v1/proctored_exam/create$'
,
views
.
CreateExamView
.
as_view
(),
name
=
'edx_proctoring.proctored_exam.create'
),
url
(
r'^'
,
include
(
'rest_framework.urls'
,
namespace
=
'rest_framework'
))
)
edx_proctoring/views.py
View file @
a7e5bbea
...
...
@@ -3,9 +3,11 @@ Proctored Exams HTTP-based API endpoints
"""
import
logging
from
django.db
import
IntegrityError
from
rest_framework
import
status
from
rest_framework.response
import
Response
from
edx_proctoring.api
import
create_exam
from
.utils
import
AuthenticatedAPIView
...
...
@@ -33,3 +35,59 @@ class StudentProctoredExamStatus(AuthenticatedAPIView):
}
return
Response
(
response_dict
,
status
=
status
.
HTTP_200_OK
)
class
CreateExamView
(
AuthenticatedAPIView
):
"""
Creates a new Exam.
POST /edx_proctoring/v1/proctored_exam/create
{
"course_id": "edX/DemoX/Demo_Course",
"content_id": "",
"exam_name": "Midterm",
"time_limit_mins": "90",
"is_proctored": true,
"external_id": "",
"is_active": true,
}
**Post Parameters**
* course_id: The unique identifier for the course.
* content_id: This will be the pointer to the id of the piece of course_ware which is the proctored exam.
* exam_name: This is the display name of the Exam (Midterm etc).
* time_limit_mins: Time limit (in minutes) that a student can finish this exam.
* is_proctored: Whether this exam actually is proctored or not.
* external_id: This will be a integration specific ID - say to SoftwareSecure.
* is_active: Whether this exam will be active.
**Response Values**
* {'exam_id': ##}, The exam_id of the created Proctored Exam.
**Exceptions**
* HTTP_400_BAD_REQUEST, data={"message": "Trying to create a duplicate exam."}
"""
def
post
(
self
,
request
):
"""
Http POST handler.
"""
try
:
exam_id
=
create_exam
(
course_id
=
request
.
DATA
.
get
(
'course_id'
,
""
),
content_id
=
request
.
DATA
.
get
(
'content_id'
,
""
),
exam_name
=
request
.
DATA
.
get
(
'exam_name'
,
""
),
time_limit_mins
=
request
.
DATA
.
get
(
'time_limit_mins'
,
""
),
is_proctored
=
True
if
request
.
DATA
.
get
(
'is_proctored'
,
"False"
)
.
lower
()
==
'true'
else
False
,
external_id
=
request
.
DATA
.
get
(
'external_id'
,
""
),
is_active
=
True
if
request
.
DATA
.
get
(
'is_active'
,
""
)
.
lower
()
==
'true'
else
False
,
)
return
Response
({
'exam_id'
:
exam_id
})
except
IntegrityError
:
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
,
data
=
{
"message"
:
u"Trying to create a duplicate exam."
}
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment