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
2175b5ba
Commit
2175b5ba
authored
Jun 15, 2015
by
Will Daly
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8509 from edx/will/deprecate-course-about-v0
Deprecate course details API v0
parents
98213239
c31a5106
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
0 additions
and
614 deletions
+0
-614
cms/envs/aws.py
+0
-4
cms/envs/common.py
+0
-2
common/djangoapps/course_about/__init__.py
+0
-0
common/djangoapps/course_about/api.py
+0
-81
common/djangoapps/course_about/data.py
+0
-76
common/djangoapps/course_about/errors.py
+0
-23
common/djangoapps/course_about/models.py
+0
-6
common/djangoapps/course_about/serializers.py
+0
-67
common/djangoapps/course_about/tests/__init__.py
+0
-0
common/djangoapps/course_about/tests/test_api.py
+0
-54
common/djangoapps/course_about/tests/test_data.py
+0
-66
common/djangoapps/course_about/tests/test_views.py
+0
-149
common/djangoapps/course_about/urls.py
+0
-15
common/djangoapps/course_about/views.py
+0
-63
lms/envs/aws.py
+0
-3
lms/envs/common.py
+0
-2
lms/urls.py
+0
-3
No files found.
cms/envs/aws.py
View file @
2175b5ba
...
...
@@ -332,10 +332,6 @@ VIDEO_UPLOAD_PIPELINE = ENV_TOKENS.get('VIDEO_UPLOAD_PIPELINE', VIDEO_UPLOAD_PIP
PARSE_KEYS
=
AUTH_TOKENS
.
get
(
"PARSE_KEYS"
,
{})
#date format the api will be formatting the datetime values
API_DATE_FORMAT
=
'
%
Y-
%
m-
%
d'
API_DATE_FORMAT
=
ENV_TOKENS
.
get
(
'API_DATE_FORMAT'
,
API_DATE_FORMAT
)
# Video Caching. Pairing country codes with CDN URLs.
# Example: {'CN': 'http://api.xuetangx.com/edx/video?s3_url='}
VIDEO_CDN_URL
=
ENV_TOKENS
.
get
(
'VIDEO_CDN_URL'
,
{})
...
...
cms/envs/common.py
View file @
2175b5ba
...
...
@@ -951,8 +951,6 @@ ADVANCED_PROBLEM_TYPES = [
}
]
#date format the api will be formatting the datetime values
API_DATE_FORMAT
=
'
%
Y-
%
m-
%
d'
# Files and Uploads type filter values
...
...
common/djangoapps/course_about/__init__.py
deleted
100644 → 0
View file @
98213239
common/djangoapps/course_about/api.py
deleted
100644 → 0
View file @
98213239
"""
The Python API layer of the Course About API. Essentially the middle tier of the project, responsible for all
business logic that is not directly tied to the data itself.
Data access is managed through the configured data module, or defaults to the project's data.py module.
This API is exposed via the RESTful layer (views.py) but may be used directly in-process.
"""
import
logging
from
django.conf
import
settings
from
django.utils
import
importlib
from
django.core.cache
import
cache
from
course_about
import
errors
DEFAULT_DATA_API
=
'course_about.data'
COURSE_ABOUT_API_CACHE_PREFIX
=
'course_about_api_'
log
=
logging
.
getLogger
(
__name__
)
def
get_course_about_details
(
course_id
):
"""Get course about details for the given course ID.
Given a Course ID, retrieve all the metadata necessary to fully describe the Course.
First its checks the default cache for given course id if its exists then returns
the course otherwise it get the course from module store and set the cache.
By default cache expiry set to 5 minutes.
Args:
course_id (str): The String representation of a Course ID. Used to look up the requested
course.
Returns:
A JSON serializable dictionary of metadata describing the course.
Example:
>>> get_course_about_details('edX/Demo/2014T2')
{
"advertised_start": "FALL",
"announcement": "YYYY-MM-DD",
"course_id": "edx/DemoCourse",
"course_number": "DEMO101",
"start": "YYYY-MM-DD",
"end": "YYYY-MM-DD",
"effort": "HH:MM",
"display_name": "Demo Course",
"is_new": true,
"media": {
"course_image": "/some/image/location.png"
},
}
"""
cache_key
=
"{}_{}"
.
format
(
course_id
,
COURSE_ABOUT_API_CACHE_PREFIX
)
cache_course_info
=
cache
.
get
(
cache_key
)
if
cache_course_info
:
return
cache_course_info
course_info
=
_data_api
()
.
get_course_about_details
(
course_id
)
time_out
=
getattr
(
settings
,
'COURSE_INFO_API_CACHE_TIME_OUT'
,
300
)
cache
.
set
(
cache_key
,
course_info
,
time_out
)
return
course_info
def
_data_api
():
"""Returns a Data API.
This relies on Django settings to find the appropriate data API.
We retrieve the settings in-line here (rather than using the
top-level constant), so that @override_settings will work
in the test suite.
"""
api_path
=
getattr
(
settings
,
"COURSE_ABOUT_DATA_API"
,
DEFAULT_DATA_API
)
try
:
return
importlib
.
import_module
(
api_path
)
except
(
ImportError
,
ValueError
):
log
.
exception
(
u"Could not load module at '{path}'"
.
format
(
path
=
api_path
))
raise
errors
.
CourseAboutApiLoadError
(
api_path
)
common/djangoapps/course_about/data.py
deleted
100644 → 0
View file @
98213239
"""Data Aggregation Layer for the Course About API.
This is responsible for combining data from the following resources:
* CourseDescriptor
* CourseAboutDescriptor
"""
import
logging
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
course_about.serializers
import
serialize_content
from
course_about.errors
import
CourseNotFoundError
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
log
=
logging
.
getLogger
(
__name__
)
ABOUT_ATTRIBUTES
=
[
'effort'
,
'overview'
,
'title'
,
'university'
,
'number'
,
'short_description'
,
'description'
,
'key_dates'
,
'video'
,
'course_staff_short'
,
'course_staff_extended'
,
'requirements'
,
'syllabus'
,
'textbook'
,
'faq'
,
'more_info'
,
'ocw_links'
,
]
def
get_course_about_details
(
course_id
):
# pylint: disable=unused-argument
"""
Return course information for a given course id.
Args:
course_id(str) : The course id to retrieve course information for.
Returns:
Serializable dictionary of the Course About Information.
Raises:
CourseNotFoundError
"""
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
course_descriptor
=
modulestore
()
.
get_course
(
course_key
)
if
course_descriptor
is
None
:
raise
CourseNotFoundError
(
"course not found"
)
except
InvalidKeyError
as
err
:
raise
CourseNotFoundError
(
err
.
message
)
about_descriptor
=
{
attribute
:
_fetch_course_detail
(
course_key
,
attribute
)
for
attribute
in
ABOUT_ATTRIBUTES
}
course_info
=
serialize_content
(
course_descriptor
=
course_descriptor
,
about_descriptor
=
about_descriptor
)
return
course_info
def
_fetch_course_detail
(
course_key
,
attribute
):
"""
Fetch the course about attribute for the given course's attribute from persistence and return its value.
"""
usage_key
=
course_key
.
make_usage_key
(
'about'
,
attribute
)
try
:
value
=
modulestore
()
.
get_item
(
usage_key
)
.
data
except
ItemNotFoundError
:
value
=
None
return
value
common/djangoapps/course_about/errors.py
deleted
100644 → 0
View file @
98213239
"""
Contains all the errors associated with the Course About API.
"""
class
CourseAboutError
(
Exception
):
"""Generic Course About Error"""
def
__init__
(
self
,
msg
,
data
=
None
):
super
(
CourseAboutError
,
self
)
.
__init__
(
msg
)
# Corresponding information to help resolve the error.
self
.
data
=
data
class
CourseAboutApiLoadError
(
CourseAboutError
):
"""The data API could not be loaded. """
pass
class
CourseNotFoundError
(
CourseAboutError
):
"""The Course Not Found. """
pass
common/djangoapps/course_about/models.py
deleted
100644 → 0
View file @
98213239
"""
A models.py is required to make this an app (until we move to Django 1.7)
The Course About API is responsible for aggregating descriptive course information into a single response.
This should eventually hold some initial Marketing Meta Data objects that are platform-specific.
"""
common/djangoapps/course_about/serializers.py
deleted
100644 → 0
View file @
98213239
"""
Serializers for all Course Descriptor and Course About Descriptor related return objects.
"""
from
xmodule.contentstore.content
import
StaticContent
from
django.conf
import
settings
DATE_FORMAT
=
getattr
(
settings
,
'API_DATE_FORMAT'
,
'
%
Y-
%
m-
%
d'
)
def
serialize_content
(
course_descriptor
,
about_descriptor
):
"""
Returns a serialized representation of the course_descriptor and about_descriptor
Args:
course_descriptor(CourseDescriptor) : course descriptor object
about_descriptor(dict) : Dictionary of CourseAboutDescriptor objects
return:
serialize data for course information.
"""
data
=
{
'media'
:
{},
'display_name'
:
getattr
(
course_descriptor
,
'display_name'
,
None
),
'course_number'
:
course_descriptor
.
location
.
course
,
'course_id'
:
None
,
'advertised_start'
:
getattr
(
course_descriptor
,
'advertised_start'
,
None
),
'is_new'
:
getattr
(
course_descriptor
,
'is_new'
,
None
),
'start'
:
_formatted_datetime
(
course_descriptor
,
'start'
),
'end'
:
_formatted_datetime
(
course_descriptor
,
'end'
),
'announcement'
:
None
,
}
data
.
update
(
about_descriptor
)
content_id
=
unicode
(
course_descriptor
.
id
)
data
[
"course_id"
]
=
unicode
(
content_id
)
if
getattr
(
course_descriptor
,
'course_image'
,
False
):
data
[
'media'
][
'course_image'
]
=
course_image_url
(
course_descriptor
)
announcement
=
getattr
(
course_descriptor
,
'announcement'
,
None
)
data
[
"announcement"
]
=
announcement
.
strftime
(
DATE_FORMAT
)
if
announcement
else
None
return
data
def
course_image_url
(
course
):
"""
Return url of course image.
Args:
course(CourseDescriptor) : The course id to retrieve course image url.
Returns:
Absolute url of course image.
"""
loc
=
StaticContent
.
compute_location
(
course
.
id
,
course
.
course_image
)
url
=
StaticContent
.
serialize_asset_key_with_slash
(
loc
)
return
url
def
_formatted_datetime
(
course_descriptor
,
date_type
):
"""
Return formatted date.
Args:
course_descriptor(CourseDescriptor) : The CourseDescriptor Object.
date_type (str) : Either start or end.
Returns:
formatted date or None .
"""
course_date_
=
getattr
(
course_descriptor
,
date_type
,
None
)
return
course_date_
.
strftime
(
DATE_FORMAT
)
if
course_date_
else
None
common/djangoapps/course_about/tests/__init__.py
deleted
100644 → 0
View file @
98213239
common/djangoapps/course_about/tests/test_api.py
deleted
100644 → 0
View file @
98213239
"""
Tests the logical Python API layer of the Course About API.
"""
import
ddt
import
json
import
unittest
from
django.core.urlresolvers
import
reverse
from
rest_framework.test
import
APITestCase
from
rest_framework
import
status
from
django.conf
import
settings
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
CourseAboutFactory
from
student.tests.factories
import
UserFactory
@ddt.ddt
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
class
CourseInfoTest
(
ModuleStoreTestCase
,
APITestCase
):
"""
Test course information.
"""
USERNAME
=
"Bob"
EMAIL
=
"bob@example.com"
PASSWORD
=
"edx"
def
setUp
(
self
):
""" Create a course"""
super
(
CourseInfoTest
,
self
)
.
setUp
()
self
.
course
=
CourseFactory
.
create
()
self
.
user
=
UserFactory
.
create
(
username
=
self
.
USERNAME
,
email
=
self
.
EMAIL
,
password
=
self
.
PASSWORD
)
self
.
client
.
login
(
username
=
self
.
USERNAME
,
password
=
self
.
PASSWORD
)
def
test_get_course_details_from_cache
(
self
):
kwargs
=
dict
()
kwargs
[
"course_id"
]
=
self
.
course
.
id
kwargs
[
"course_runtime"
]
=
self
.
course
.
runtime
kwargs
[
"user_id"
]
=
self
.
user
.
id
CourseAboutFactory
.
create
(
**
kwargs
)
resp
=
self
.
client
.
get
(
reverse
(
'courseabout'
,
kwargs
=
{
"course_id"
:
unicode
(
self
.
course
.
id
)})
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
resp_data
=
json
.
loads
(
resp
.
content
)
self
.
assertIsNotNone
(
resp_data
)
resp
=
self
.
client
.
get
(
reverse
(
'courseabout'
,
kwargs
=
{
"course_id"
:
unicode
(
self
.
course
.
id
)})
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
resp_data
=
json
.
loads
(
resp
.
content
)
self
.
assertIsNotNone
(
resp_data
)
common/djangoapps/course_about/tests/test_data.py
deleted
100644 → 0
View file @
98213239
"""
Tests specific to the Data Aggregation Layer of the Course About API.
"""
import
unittest
from
datetime
import
datetime
from
django.conf
import
settings
from
nose.tools
import
raises
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
student.tests.factories
import
UserFactory
from
course_about
import
data
from
course_about.errors
import
CourseNotFoundError
from
xmodule.modulestore.django
import
modulestore
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
class
CourseAboutDataTest
(
ModuleStoreTestCase
):
"""
Test course enrollment data aggregation.
"""
USERNAME
=
"Bob"
EMAIL
=
"bob@example.com"
PASSWORD
=
"edx"
def
setUp
(
self
):
"""Create a course and user, then log in. """
super
(
CourseAboutDataTest
,
self
)
.
setUp
()
self
.
course
=
CourseFactory
.
create
()
self
.
user
=
UserFactory
.
create
(
username
=
self
.
USERNAME
,
email
=
self
.
EMAIL
,
password
=
self
.
PASSWORD
)
self
.
client
.
login
(
username
=
self
.
USERNAME
,
password
=
self
.
PASSWORD
)
def
test_get_course_about_details
(
self
):
course_info
=
data
.
get_course_about_details
(
unicode
(
self
.
course
.
id
))
self
.
assertIsNotNone
(
course_info
)
def
test_get_course_about_valid_date
(
self
):
module_store
=
modulestore
()
self
.
course
.
start
=
datetime
.
now
()
self
.
course
.
end
=
datetime
.
now
()
self
.
course
.
announcement
=
datetime
.
now
()
module_store
.
update_item
(
self
.
course
,
self
.
user
.
id
)
course_info
=
data
.
get_course_about_details
(
unicode
(
self
.
course
.
id
))
self
.
assertIsNotNone
(
course_info
[
"start"
])
self
.
assertIsNotNone
(
course_info
[
"end"
])
self
.
assertIsNotNone
(
course_info
[
"announcement"
])
def
test_get_course_about_none_date
(
self
):
module_store
=
modulestore
()
self
.
course
.
start
=
None
self
.
course
.
end
=
None
self
.
course
.
announcement
=
None
module_store
.
update_item
(
self
.
course
,
self
.
user
.
id
)
course_info
=
data
.
get_course_about_details
(
unicode
(
self
.
course
.
id
))
self
.
assertIsNone
(
course_info
[
"start"
])
self
.
assertIsNone
(
course_info
[
"end"
])
self
.
assertIsNone
(
course_info
[
"announcement"
])
@raises
(
CourseNotFoundError
)
def
test_non_existent_course
(
self
):
data
.
get_course_about_details
(
"this/is/bananas"
)
@raises
(
CourseNotFoundError
)
def
test_invalid_key
(
self
):
data
.
get_course_about_details
(
"invalid:key:k"
)
common/djangoapps/course_about/tests/test_views.py
deleted
100644 → 0
View file @
98213239
"""
Tests for user enrollment.
"""
import
ddt
import
json
import
unittest
from
django.test.utils
import
override_settings
from
django.core.urlresolvers
import
reverse
from
rest_framework.test
import
APITestCase
from
rest_framework
import
status
from
django.conf
import
settings
from
datetime
import
datetime
from
mock
import
patch
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
CourseAboutFactory
from
student.tests.factories
import
UserFactory
from
course_about.serializers
import
course_image_url
from
course_about
import
api
from
course_about.errors
import
CourseNotFoundError
,
CourseAboutError
from
xmodule.modulestore.django
import
modulestore
@ddt.ddt
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
class
CourseInfoTest
(
ModuleStoreTestCase
,
APITestCase
):
"""
Test course information.
"""
USERNAME
=
"Bob"
EMAIL
=
"bob@example.com"
PASSWORD
=
"edx"
def
setUp
(
self
):
""" Create a course"""
super
(
CourseInfoTest
,
self
)
.
setUp
()
self
.
course
=
CourseFactory
.
create
()
self
.
user
=
UserFactory
.
create
(
username
=
self
.
USERNAME
,
email
=
self
.
EMAIL
,
password
=
self
.
PASSWORD
)
self
.
client
.
login
(
username
=
self
.
USERNAME
,
password
=
self
.
PASSWORD
)
def
test_user_not_authenticated
(
self
):
# Log out, so we're no longer authenticated
self
.
client
.
logout
()
resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertEqual
(
status_code
,
status
.
HTTP_200_OK
)
self
.
assertIsNotNone
(
resp_data
)
def
test_with_valid_course_id
(
self
):
_resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertEqual
(
status_code
,
status
.
HTTP_200_OK
)
def
test_with_invalid_course_id
(
self
):
resp
=
self
.
client
.
get
(
reverse
(
'courseabout'
,
kwargs
=
{
"course_id"
:
'not/a/validkey'
})
)
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_404_NOT_FOUND
)
def
test_get_course_details_all_attributes
(
self
):
kwargs
=
dict
()
kwargs
[
"course_id"
]
=
self
.
course
.
id
kwargs
[
"course_runtime"
]
=
self
.
course
.
runtime
CourseAboutFactory
.
create
(
**
kwargs
)
resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
all_attributes
=
[
'display_name'
,
'start'
,
'end'
,
'announcement'
,
'advertised_start'
,
'is_new'
,
'course_number'
,
'course_id'
,
'effort'
,
'media'
,
'course_image'
]
for
attr
in
all_attributes
:
self
.
assertIn
(
attr
,
str
(
resp_data
))
self
.
assertEqual
(
status_code
,
status
.
HTTP_200_OK
)
def
test_get_course_about_valid_date
(
self
):
module_store
=
modulestore
()
self
.
course
.
start
=
datetime
.
now
()
self
.
course
.
end
=
datetime
.
now
()
self
.
course
.
announcement
=
datetime
.
now
()
module_store
.
update_item
(
self
.
course
,
self
.
user
.
id
)
resp_data
,
_status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertIsNotNone
(
resp_data
[
"start"
])
self
.
assertIsNotNone
(
resp_data
[
"end"
])
self
.
assertIsNotNone
(
resp_data
[
"announcement"
])
def
test_get_course_about_none_date
(
self
):
module_store
=
modulestore
()
self
.
course
.
start
=
None
self
.
course
.
end
=
None
self
.
course
.
announcement
=
None
module_store
.
update_item
(
self
.
course
,
self
.
user
.
id
)
resp_data
,
_status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertIsNone
(
resp_data
[
"start"
])
self
.
assertIsNone
(
resp_data
[
"end"
])
self
.
assertIsNone
(
resp_data
[
"announcement"
])
def
test_get_course_details
(
self
):
kwargs
=
dict
()
kwargs
[
"course_id"
]
=
self
.
course
.
id
kwargs
[
"course_runtime"
]
=
self
.
course
.
runtime
kwargs
[
"user_id"
]
=
self
.
user
.
id
CourseAboutFactory
.
create
(
**
kwargs
)
resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertEqual
(
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
unicode
(
self
.
course
.
id
),
resp_data
[
'course_id'
])
self
.
assertIn
(
'Run'
,
resp_data
[
'display_name'
])
url
=
course_image_url
(
self
.
course
)
self
.
assertEquals
(
url
,
resp_data
[
'media'
][
'course_image'
])
@patch.object
(
api
,
"get_course_about_details"
)
def
test_get_enrollment_course_not_found_error
(
self
,
mock_get_course_about_details
):
mock_get_course_about_details
.
side_effect
=
CourseNotFoundError
(
"Something bad happened."
)
_resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertEqual
(
status_code
,
status
.
HTTP_404_NOT_FOUND
)
@patch.object
(
api
,
"get_course_about_details"
)
def
test_get_enrollment_invalid_key_error
(
self
,
mock_get_course_about_details
):
mock_get_course_about_details
.
side_effect
=
CourseNotFoundError
(
'a/a/a'
,
"Something bad happened."
)
resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertEqual
(
status_code
,
status
.
HTTP_404_NOT_FOUND
)
self
.
assertIn
(
'An error occurred'
,
resp_data
[
"message"
])
@patch.object
(
api
,
"get_course_about_details"
)
def
test_get_enrollment_internal_error
(
self
,
mock_get_course_about_details
):
mock_get_course_about_details
.
side_effect
=
CourseAboutError
(
'error'
)
resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertEqual
(
status_code
,
status
.
HTTP_500_INTERNAL_SERVER_ERROR
)
self
.
assertIn
(
'An error occurred'
,
resp_data
[
"message"
])
@override_settings
(
COURSE_ABOUT_DATA_API
=
'foo'
)
def
test_data_api_config_error
(
self
):
# Retrive the invalid course
resp_data
,
status_code
=
self
.
_get_course_about
(
self
.
course
.
id
)
self
.
assertEqual
(
status_code
,
status
.
HTTP_500_INTERNAL_SERVER_ERROR
)
self
.
assertIn
(
'An error occurred'
,
resp_data
[
"message"
])
def
_get_course_about
(
self
,
course_id
):
"""
helper function to get retrieve course about information.
args course_id (str): course id
"""
resp
=
self
.
client
.
get
(
reverse
(
'courseabout'
,
kwargs
=
{
"course_id"
:
unicode
(
course_id
)})
)
return
json
.
loads
(
resp
.
content
),
resp
.
status_code
common/djangoapps/course_about/urls.py
deleted
100644 → 0
View file @
98213239
"""
URLs for exposing the RESTful HTTP endpoints for the Course About API.
"""
from
django.conf
import
settings
from
django.conf.urls
import
patterns
,
url
from
course_about.views
import
CourseAboutView
urlpatterns
=
patterns
(
'course_about.views'
,
url
(
r'^{course_key}'
.
format
(
course_key
=
settings
.
COURSE_ID_PATTERN
),
CourseAboutView
.
as_view
(),
name
=
"courseabout"
),
)
common/djangoapps/course_about/views.py
deleted
100644 → 0
View file @
98213239
"""
Implementation of the RESTful endpoints for the Course About API.
"""
from
rest_framework.throttling
import
UserRateThrottle
from
rest_framework.views
import
APIView
from
course_about
import
api
from
rest_framework
import
status
from
rest_framework.response
import
Response
from
course_about.errors
import
CourseNotFoundError
,
CourseAboutError
class
CourseAboutThrottle
(
UserRateThrottle
):
"""Limit the number of requests users can make to the Course About API."""
# TODO Limit based on expected throughput # pylint: disable=fixme
rate
=
'50/second'
class
CourseAboutView
(
APIView
):
""" RESTful Course About API view.
Used to retrieve JSON serialized Course About information.
"""
authentication_classes
=
[]
permission_classes
=
[]
throttle_classes
=
CourseAboutThrottle
,
def
get
(
self
,
request
,
course_id
=
None
):
# pylint: disable=unused-argument
"""Read course information.
HTTP Endpoint for course info api.
Args:
Course Id = URI element specifying the course location. Course information will be
returned for this particular course.
Return:
A JSON serialized representation of the course information
"""
try
:
return
Response
(
api
.
get_course_about_details
(
course_id
))
except
CourseNotFoundError
:
return
Response
(
status
=
status
.
HTTP_404_NOT_FOUND
,
data
=
{
"message"
:
(
u"An error occurred while retrieving course information"
u" for course '{course_id}' no course found"
)
.
format
(
course_id
=
course_id
)
}
)
except
CourseAboutError
:
return
Response
(
status
=
status
.
HTTP_500_INTERNAL_SERVER_ERROR
,
data
=
{
"message"
:
(
u"An error occurred while retrieving course information"
u" for course '{course_id}'"
)
.
format
(
course_id
=
course_id
)
}
)
lms/envs/aws.py
View file @
2175b5ba
...
...
@@ -566,9 +566,6 @@ COURSE_ABOUT_VISIBILITY_PERMISSION = ENV_TOKENS.get(
COURSE_ABOUT_VISIBILITY_PERMISSION
)
#date format the api will be formatting the datetime values
API_DATE_FORMAT
=
'
%
Y-
%
m-
%
d'
API_DATE_FORMAT
=
ENV_TOKENS
.
get
(
'API_DATE_FORMAT'
,
API_DATE_FORMAT
)
# Enrollment API Cache Timeout
ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT
=
ENV_TOKENS
.
get
(
'ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT'
,
60
)
...
...
lms/envs/common.py
View file @
2175b5ba
...
...
@@ -2360,8 +2360,6 @@ COURSE_CATALOG_VISIBILITY_PERMISSION = 'see_exists'
# visible. We default this to the legacy permission 'see_exists'.
COURSE_ABOUT_VISIBILITY_PERMISSION
=
'see_exists'
#date format the api will be formatting the datetime values
API_DATE_FORMAT
=
'
%
Y-
%
m-
%
d'
# Enrollment API Cache Timeout
ENROLLMENT_COURSE_DETAILS_CACHE_TIMEOUT
=
60
...
...
lms/urls.py
View file @
2175b5ba
...
...
@@ -75,9 +75,6 @@ urlpatterns = (
# Enrollment API RESTful endpoints
url
(
r'^api/enrollment/v1/'
,
include
(
'enrollment.urls'
)),
# CourseInfo API RESTful endpoints
url
(
r'^api/course/details/v0/'
,
include
(
'course_about.urls'
)),
# Courseware search endpoints
url
(
r'^search/'
,
include
(
'search.urls'
)),
...
...
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