Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx
edx-platform
Commits
0f70b0aa
Commit
0f70b0aa
authored
May 08, 2013
by
Arthur Barrett
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactored api resource map and added total to search query
parent
894cfd1f
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
82 additions
and
51 deletions
+82
-51
lms/djangoapps/notes/api.py
+78
-49
lms/djangoapps/notes/utils.py
+4
-2
No files found.
lms/djangoapps/notes/api.py
View file @
0f70b0aa
...
@@ -10,54 +10,65 @@ import logging
...
@@ -10,54 +10,65 @@ import logging
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
API_SETTINGS
=
{
API_SETTINGS
=
{
'MAX_NOTE_LIMIT'
:
100
# Max number of annotations to retrieve at one time
# Version
'META'
:
{
'name'
:
'Notes API'
,
'version'
:
'1.0'
},
# Maps resources to HTTP methods
'RESOURCE_MAP'
:
{
'root'
:
{
'GET'
:
'root'
},
'notes'
:
{
'GET'
:
'index'
,
'POST'
:
'create'
},
'note'
:
{
'GET'
:
'read'
,
'PUT'
:
'update'
,
'DELETE'
:
'delete'
},
'search'
:
{
'GET'
:
'search'
},
},
# Cap the number of notes that can be returned in one request
'MAX_NOTE_LIMIT'
:
1000
,
}
}
#----------------------------------------------------------------------#
#----------------------------------------------------------------------#
# API requests are routed through api_request() using the resource map.
# API requests are routed through api_request() using the resource map.
def
api_resource_map
():
''' Maps API resources to (method, action) pairs. '''
(
GET
,
PUT
,
POST
,
DELETE
)
=
(
'GET'
,
'PUT'
,
'POST'
,
'DELETE'
)
return
{
'root'
:
{
GET
:
root
},
'notes'
:
{
GET
:
index
,
POST
:
create
},
'note'
:
{
GET
:
read
,
PUT
:
update
,
DELETE
:
delete
},
'search'
:
{
GET
:
search
}
}
@login_required
@login_required
def
api_request
(
request
,
course_id
,
**
kwargs
):
def
api_request
(
request
,
course_id
,
**
kwargs
):
''' Routes API requests to the appropriate action method and formats the results
(defaults to JSON).
Raises a 404 if the resource type doesn't exist, or if there is no action
method associated with the HTTP method.
'''
'''
Routes API requests to the appropriate action method and returns JSON.
Raises a 404 if the requested resource does not exist or notes are
disabled for the course.
'''
# Verify that notes are enabled for the course
course
=
get_course_with_access
(
request
.
user
,
course_id
,
'load'
)
course
=
get_course_with_access
(
request
.
user
,
course_id
,
'load'
)
if
not
notes_enabled_for_course
(
course
):
if
not
notes_enabled_for_course
(
course
):
log
.
debug
(
'Notes not enabled for course'
)
log
.
debug
(
'Notes not enabled for course'
)
raise
Http404
raise
Http404
resource_map
=
api_resource_map
()
# Locate and validate the requested resource
resource_map
=
API_SETTINGS
.
get
(
'RESOURCE_MAP'
,
{})
resource_name
=
kwargs
.
pop
(
'resource'
)
resource_name
=
kwargs
.
pop
(
'resource'
)
resource_method
=
request
.
method
resource
=
resource_map
.
get
(
resource_name
)
resource
=
resource_map
.
get
(
resource_name
)
if
resource
is
None
:
if
resource
is
None
:
log
.
debug
(
'Resource "{0}" does not exist'
.
format
(
resource_name
))
log
.
debug
(
'Resource "{0}" does not exist'
.
format
(
resource_name
))
raise
Http404
raise
Http404
if
re
quest
.
method
not
in
resource
.
keys
():
if
re
source_
method
not
in
resource
.
keys
():
log
.
debug
(
'Resource "{0}" does not support method "{1}"'
.
format
(
resource_name
,
re
quest
.
method
))
log
.
debug
(
'Resource "{0}" does not support method "{1}"'
.
format
(
resource_name
,
re
source_
method
))
raise
Http404
raise
Http404
log
.
debug
(
"API request: {0} {1}"
.
format
(
request
.
method
,
resource_name
))
# Find the associated function definition and execute the request
func
=
resource
.
get
(
resource_method
)
module
=
globals
()
if
func
not
in
module
:
log
.
debug
(
'Function "{0}" does not exist for request {1} {2}'
.
format
(
action
,
resource_method
,
resource_name
))
raise
Http404
action
=
resource
.
get
(
request
.
method
)
log
.
debug
(
'API request: {0} {1}'
.
format
(
resource_method
,
resource_name
)
)
result
=
action
(
request
,
course_id
,
**
kwargs
)
result
=
module
[
func
]
(
request
,
course_id
,
**
kwargs
)
response
=
result
[
0
]
# Format and output the results
data
=
None
data
=
None
response
=
result
[
0
]
if
len
(
result
)
==
2
:
if
len
(
result
)
==
2
:
data
=
result
[
1
]
data
=
result
[
1
]
...
@@ -65,13 +76,13 @@ def api_request(request, course_id, **kwargs):
...
@@ -65,13 +76,13 @@ def api_request(request, course_id, **kwargs):
response
[
'Content-type'
]
=
formatted
[
0
]
response
[
'Content-type'
]
=
formatted
[
0
]
response
.
content
=
formatted
[
1
]
response
.
content
=
formatted
[
1
]
log
.
debug
(
"API response: {0}"
.
format
(
formatted
))
log
.
debug
(
'API response: {0}'
.
format
(
formatted
))
return
response
return
response
def
api_format
(
request
,
response
,
data
):
def
api_format
(
request
,
response
,
data
):
'''
Returns a two-element list containing the content type and content.
'''
This method does not modify the request or response.
Returns a two-element list containing the content type and content.
'''
'''
content_type
=
'application/json'
content_type
=
'application/json'
if
data
is
None
:
if
data
is
None
:
...
@@ -84,7 +95,9 @@ def api_format(request, response, data):
...
@@ -84,7 +95,9 @@ def api_format(request, response, data):
# API actions exposed via the resource map.
# API actions exposed via the resource map.
def
index
(
request
,
course_id
):
def
index
(
request
,
course_id
):
''' Returns a list of annotation objects. '''
'''
Returns a list of annotation objects.
'''
MAX_LIMIT
=
API_SETTINGS
.
get
(
'MAX_NOTE_LIMIT'
)
MAX_LIMIT
=
API_SETTINGS
.
get
(
'MAX_NOTE_LIMIT'
)
notes
=
Note
.
objects
.
order_by
(
'id'
)
.
filter
(
course_id
=
course_id
,
notes
=
Note
.
objects
.
order_by
(
'id'
)
.
filter
(
course_id
=
course_id
,
...
@@ -93,7 +106,9 @@ def index(request, course_id):
...
@@ -93,7 +106,9 @@ def index(request, course_id):
return
[
HttpResponse
(),
[
note
.
as_dict
()
for
note
in
notes
]]
return
[
HttpResponse
(),
[
note
.
as_dict
()
for
note
in
notes
]]
def
create
(
request
,
course_id
):
def
create
(
request
,
course_id
):
''' Receives an annotation object to create and returns a 303 with the read location. '''
'''
Receives an annotation object to create and returns a 303 with the read location.
'''
note
=
Note
(
course_id
=
course_id
,
user
=
request
.
user
)
note
=
Note
(
course_id
=
course_id
,
user
=
request
.
user
)
try
:
try
:
...
@@ -109,7 +124,9 @@ def create(request, course_id):
...
@@ -109,7 +124,9 @@ def create(request, course_id):
return
[
response
,
None
]
return
[
response
,
None
]
def
read
(
request
,
course_id
,
note_id
):
def
read
(
request
,
course_id
,
note_id
):
''' Returns a single annotation object. '''
'''
Returns a single annotation object.
'''
try
:
try
:
note
=
Note
.
objects
.
get
(
id
=
note_id
)
note
=
Note
.
objects
.
get
(
id
=
note_id
)
except
:
except
:
...
@@ -121,7 +138,9 @@ def read(request, course_id, note_id):
...
@@ -121,7 +138,9 @@ def read(request, course_id, note_id):
return
[
HttpResponse
(),
note
.
as_dict
()]
return
[
HttpResponse
(),
note
.
as_dict
()]
def
update
(
request
,
course_id
,
note_id
):
def
update
(
request
,
course_id
,
note_id
):
''' Updates an annotation object and returns a 303 with the read location. '''
'''
Updates an annotation object and returns a 303 with the read location.
'''
try
:
try
:
note
=
Note
.
objects
.
get
(
id
=
note_id
)
note
=
Note
.
objects
.
get
(
id
=
note_id
)
except
:
except
:
...
@@ -144,7 +163,9 @@ def update(request, course_id, note_id):
...
@@ -144,7 +163,9 @@ def update(request, course_id, note_id):
return
[
response
,
None
]
return
[
response
,
None
]
def
delete
(
request
,
course_id
,
note_id
):
def
delete
(
request
,
course_id
,
note_id
):
''' Deletes the annotation object and returns a 204 with no content. '''
'''
Deletes the annotation object and returns a 204 with no content.
'''
try
:
try
:
note
=
Note
.
objects
.
get
(
id
=
note_id
)
note
=
Note
.
objects
.
get
(
id
=
note_id
)
except
:
except
:
...
@@ -158,39 +179,47 @@ def delete(request, course_id, note_id):
...
@@ -158,39 +179,47 @@ def delete(request, course_id, note_id):
return
[
HttpResponse
(
''
,
status
=
204
),
None
]
return
[
HttpResponse
(
''
,
status
=
204
),
None
]
def
search
(
request
,
course_id
):
def
search
(
request
,
course_id
):
''' Returns a subset of annotation objects based on a search query.. '''
'''
Returns a subset of annotation objects based on a search query.
'''
MAX_LIMIT
=
API_SETTINGS
.
get
(
'MAX_NOTE_LIMIT'
)
MAX_LIMIT
=
API_SETTINGS
.
get
(
'MAX_NOTE_LIMIT'
)
# search parameters
# search parameters
limit
=
request
.
GET
.
get
(
'limit
'
)
offset
=
request
.
GET
.
get
(
'offset'
,
'
'
)
offset
=
request
.
GET
.
get
(
'offset
'
)
limit
=
request
.
GET
.
get
(
'limit'
,
'
'
)
uri
=
request
.
GET
.
get
(
'uri'
)
uri
=
request
.
GET
.
get
(
'uri'
,
''
)
# validate search parameters
# validate search parameters
if
limit
is
not
None
and
limit
.
isdigit
():
if
offset
.
isdigit
():
offset
=
int
(
offset
)
else
:
offset
=
0
if
limit
.
isdigit
():
limit
=
int
(
limit
)
limit
=
int
(
limit
)
if
limit
==
0
or
limit
>
MAX_LIMIT
:
if
limit
==
0
or
limit
>
MAX_LIMIT
:
limit
=
MAX_LIMIT
limit
=
MAX_LIMIT
else
:
else
:
limit
=
MAX_LIMIT
limit
=
MAX_LIMIT
if
offset
is
not
None
and
offset
.
isdigit
():
# set filters
offset
=
int
(
offset
)
else
:
offset
=
0
# search filters
filters
=
{
'course_id'
:
course_id
,
'user'
:
request
.
user
}
filters
=
{
'course_id'
:
course_id
,
'user'
:
request
.
user
}
if
uri
is
not
None
:
if
uri
!=
''
:
filters
[
'uri'
]
=
uri
filters
[
'uri'
]
=
uri
start
=
offset
# retrieve notes
end
=
offset
+
limit
notes
=
Note
.
objects
.
order_by
(
'id'
)
.
filter
(
**
filters
)
notes
=
Note
.
objects
.
order_by
(
'id'
)
.
filter
(
**
filters
)[
start
:
end
]
total
=
notes
.
count
()
result
=
{
'rows'
:
[
note
.
as_dict
()
for
note
in
notes
]}
rows
=
notes
[
offset
:
offset
+
limit
]
result
=
{
'total'
:
notes
.
count
(),
'rows'
:
[
note
.
as_dict
()
for
note
in
rows
]
}
return
[
HttpResponse
(),
result
]
return
[
HttpResponse
(),
result
]
def
root
(
request
,
course_id
):
def
root
(
request
,
course_id
):
''' Returns version information about the API. '''
'''
return
[
HttpResponse
(),
{
'name'
:
'Notes API'
,
'version'
:
'1.0'
}]
Returns version information about the API.
'''
return
[
HttpResponse
(),
API_SETTINGS
.
get
(
'META'
)]
lms/djangoapps/notes/utils.py
View file @
0f70b0aa
# TODO: make a separate policy setting to enable/disable notes.
def
notes_enabled_for_course
(
course
):
def
notes_enabled_for_course
(
course
):
''' Returns True if notes are enabled for the course, False otherwise. '''
'''
Returns True if the notes app is enabled for the course, False otherwise.
'''
# TODO: create a separate policy setting to enable/disable notes
notes_tab_type
=
'notes'
notes_tab_type
=
'notes'
return
next
((
True
for
tab
in
course
.
tabs
if
tab
[
'type'
]
==
notes_tab_type
),
False
)
return
next
((
True
for
tab
in
course
.
tabs
if
tab
[
'type'
]
==
notes_tab_type
),
False
)
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