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
23f02d94
Commit
23f02d94
authored
Mar 24, 2015
by
Daniel Friedman
Committed by
Andy Armstrong
Apr 17, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Configurations for filesystem and s3 backends.
TNL-1789
parent
44c78c60
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
48 additions
and
24 deletions
+48
-24
cms/envs/common.py
+2
-2
lms/envs/aws.py
+8
-0
lms/envs/common.py
+12
-9
lms/envs/test.py
+7
-3
lms/urls.py
+2
-1
openedx/core/djangoapps/user_api/accounts/image_helpers.py
+4
-3
openedx/core/djangoapps/user_api/accounts/tests/test_image_helpers.py
+1
-1
openedx/core/djangoapps/user_api/accounts/tests/test_views.py
+12
-5
No files found.
cms/envs/common.py
View file @
23f02d94
...
@@ -40,8 +40,8 @@ from lms.envs.common import (
...
@@ -40,8 +40,8 @@ from lms.envs.common import (
# The following PROFILE_IMAGE_* settings are included as they are
# The following PROFILE_IMAGE_* settings are included as they are
# indirectly accessed through the email opt-in API, which is
# indirectly accessed through the email opt-in API, which is
# technically accessible through the CMS via legacy URLs.
# technically accessible through the CMS via legacy URLs.
PROFILE_IMAGE_BACKEND
,
PROFILE_IMAGE_D
OMAIN
,
PROFILE_IMAGE_URL_PATH
,
PROFILE_IMAGE_DEFAULT_FILENAME
,
PROFILE_IMAGE_BACKEND
,
PROFILE_IMAGE_D
EFAULT_FILENAME
,
PROFILE_IMAGE_DEFAULT_FILE_EXTENSION
,
PROFILE_IMAGE_
DEFAULT_FILE_EXTENSION
,
PROFILE_IMAGE_
SECRET_KEY
,
PROFILE_IMAGE_SECRET_KEY
,
)
)
from
path
import
path
from
path
import
path
from
warnings
import
simplefilter
from
warnings
import
simplefilter
...
...
lms/envs/aws.py
View file @
23f02d94
...
@@ -131,6 +131,10 @@ if STATIC_URL_BASE:
...
@@ -131,6 +131,10 @@ if STATIC_URL_BASE:
if
not
STATIC_URL
.
endswith
(
"/"
):
if
not
STATIC_URL
.
endswith
(
"/"
):
STATIC_URL
+=
"/"
STATIC_URL
+=
"/"
# MEDIA_ROOT specifies the directory where user-uploaded files are stored.
MEDIA_ROOT
=
ENV_TOKENS
.
get
(
'MEDIA_ROOT'
,
MEDIA_ROOT
)
MEDIA_URL
=
ENV_TOKENS
.
get
(
'MEDIA_URL'
,
MEDIA_URL
)
PLATFORM_NAME
=
ENV_TOKENS
.
get
(
'PLATFORM_NAME'
,
PLATFORM_NAME
)
PLATFORM_NAME
=
ENV_TOKENS
.
get
(
'PLATFORM_NAME'
,
PLATFORM_NAME
)
# For displaying on the receipt. At Stanford PLATFORM_NAME != MERCHANT_NAME, but PLATFORM_NAME is a fine default
# For displaying on the receipt. At Stanford PLATFORM_NAME != MERCHANT_NAME, but PLATFORM_NAME is a fine default
PLATFORM_TWITTER_ACCOUNT
=
ENV_TOKENS
.
get
(
'PLATFORM_TWITTER_ACCOUNT'
,
PLATFORM_TWITTER_ACCOUNT
)
PLATFORM_TWITTER_ACCOUNT
=
ENV_TOKENS
.
get
(
'PLATFORM_TWITTER_ACCOUNT'
,
PLATFORM_TWITTER_ACCOUNT
)
...
@@ -594,3 +598,7 @@ if FEATURES.get('INDIVIDUAL_DUE_DATES'):
...
@@ -594,3 +598,7 @@ if FEATURES.get('INDIVIDUAL_DUE_DATES'):
FIELD_OVERRIDE_PROVIDERS
+=
(
FIELD_OVERRIDE_PROVIDERS
+=
(
'courseware.student_field_overrides.IndividualStudentOverrideProvider'
,
'courseware.student_field_overrides.IndividualStudentOverrideProvider'
,
)
)
# PROFILE IMAGE CONFIG
PROFILE_IMAGE_BACKEND
=
ENV_TOKENS
.
get
(
'PROFILE_IMAGE_BACKEND'
,
PROFILE_IMAGE_BACKEND
)
lms/envs/common.py
View file @
23f02d94
...
@@ -780,6 +780,10 @@ STATICFILES_DIRS = [
...
@@ -780,6 +780,10 @@ STATICFILES_DIRS = [
FAVICON_PATH
=
'images/favicon.ico'
FAVICON_PATH
=
'images/favicon.ico'
# User-uploaded content
MEDIA_ROOT
=
'/edx/var/edxapp/media/'
MEDIA_URL
=
'/media/'
# Locale/Internationalization
# Locale/Internationalization
TIME_ZONE
=
'America/New_York'
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
TIME_ZONE
=
'America/New_York'
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
LANGUAGE_CODE
=
'en'
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE
=
'en'
# http://www.i18nguy.com/unicode/language-identifiers.html
...
@@ -2258,20 +2262,19 @@ CHECKPOINT_PATTERN = r'(?P<checkpoint_name>\w+)'
...
@@ -2258,20 +2262,19 @@ CHECKPOINT_PATTERN = r'(?P<checkpoint_name>\w+)'
FIELD_OVERRIDE_PROVIDERS
=
()
FIELD_OVERRIDE_PROVIDERS
=
()
# PROFILE IMAGE CONFIG
# PROFILE IMAGE CONFIG
# TODO: add these settings to aws.py as well
# WARNING: Certain django storage backends do not support atomic
# WARNING: Certain django storage backends do not support atomic
# file overwrites (including the default,
specified below
) - instead
# file overwrites (including the default,
OverwriteStorage
) - instead
# there are separate calls to delete and then write a new file in the
# there are separate calls to delete and then write a new file in the
# storage backend. This introduces the risk of a race condition
# storage backend. This introduces the risk of a race condition
# occurring when a user uploads a new profile image to replace an
# occurring when a user uploads a new profile image to replace an
# earlier one (the file will temporarily be deleted).
# earlier one (the file will temporarily be deleted).
PROFILE_IMAGE_BACKEND
=
'storages.backends.overwrite.OverwriteStorage'
PROFILE_IMAGE_BACKEND
=
{
# PROFILE_IMAGE_DOMAIN points to the domain from which we serve image
'class'
:
'storages.backends.overwrite.OverwriteStorage'
,
# files from. When this is '/', it refers to the same domain as the
'options'
:
{
# app server. If serving from a different domain, specify that here
'location'
:
os
.
path
.
join
(
MEDIA_ROOT
,
'profile-images/'
),
# i.e. 'http://www.example-image-server.com/'
'base_url'
:
os
.
path
.
join
(
MEDIA_URL
,
'profile-images/'
),
PROFILE_IMAGE_DOMAIN
=
'/'
},
PROFILE_IMAGE_URL_PATH
=
'media/profile_images/'
}
PROFILE_IMAGE_DEFAULT_FILENAME
=
(
PROFILE_IMAGE_DEFAULT_FILENAME
=
(
'images/edx-theme/default-profile'
if
FEATURES
[
'IS_EDX_DOMAIN'
]
else
'images/default-theme/default-profile'
'images/edx-theme/default-profile'
if
FEATURES
[
'IS_EDX_DOMAIN'
]
else
'images/default-theme/default-profile'
)
)
...
...
lms/envs/test.py
View file @
23f02d94
...
@@ -478,9 +478,13 @@ MIDDLEWARE_CLASSES += ('ccx.overrides.CcxMiddleware',)
...
@@ -478,9 +478,13 @@ MIDDLEWARE_CLASSES += ('ccx.overrides.CcxMiddleware',)
FEATURES
[
'CUSTOM_COURSES_EDX'
]
=
True
FEATURES
[
'CUSTOM_COURSES_EDX'
]
=
True
# Set dummy values for profile image settings.
# Set dummy values for profile image settings.
PROFILE_IMAGE_BACKEND
=
'django.core.files.storage.FileSystemStorage'
PROFILE_IMAGE_BACKEND
=
{
PROFILE_IMAGE_DOMAIN
=
'http://example-storage.com/'
'class'
:
'storages.backends.overwrite.OverwriteStorage'
,
PROFILE_IMAGE_URL_PATH
=
'profile_images/'
'options'
:
{
'location'
:
MEDIA_ROOT
,
'base_url'
:
'http://example-storage.com/profile-images/'
,
},
}
PROFILE_IMAGE_DEFAULT_FILENAME
=
'default'
PROFILE_IMAGE_DEFAULT_FILENAME
=
'default'
PROFILE_IMAGE_DEFAULT_FILE_EXTENSION
=
'png'
PROFILE_IMAGE_DEFAULT_FILE_EXTENSION
=
'png'
PROFILE_IMAGE_SECRET_KEY
=
'secret'
PROFILE_IMAGE_SECRET_KEY
=
'secret'
...
...
lms/urls.py
View file @
23f02d94
...
@@ -639,7 +639,8 @@ urlpatterns = patterns(*urlpatterns)
...
@@ -639,7 +639,8 @@ urlpatterns = patterns(*urlpatterns)
if
settings
.
DEBUG
:
if
settings
.
DEBUG
:
urlpatterns
+=
static
(
settings
.
STATIC_URL
,
document_root
=
settings
.
STATIC_ROOT
)
urlpatterns
+=
static
(
settings
.
STATIC_URL
,
document_root
=
settings
.
STATIC_ROOT
)
urlpatterns
+=
static
(
urlpatterns
+=
static
(
settings
.
PROFILE_IMAGE_DOMAIN
+
settings
.
PROFILE_IMAGE_URL_PATH
,
document_root
=
settings
.
MEDIA_ROOT
settings
.
PROFILE_IMAGE_BACKEND
[
'options'
][
'base_url'
],
document_root
=
settings
.
PROFILE_IMAGE_BACKEND
[
'options'
][
'location'
]
)
)
# in debug mode, allow any template to be rendered (most useful for UX reference templates)
# in debug mode, allow any template to be rendered (most useful for UX reference templates)
...
...
openedx/core/djangoapps/user_api/accounts/image_helpers.py
View file @
23f02d94
...
@@ -27,8 +27,9 @@ def get_profile_image_storage():
...
@@ -27,8 +27,9 @@ def get_profile_image_storage():
Configures and returns a django Storage instance that can be used
Configures and returns a django Storage instance that can be used
to physically locate, read and write profile images.
to physically locate, read and write profile images.
"""
"""
storage_class
=
get_storage_class
(
settings
.
PROFILE_IMAGE_BACKEND
)
config
=
settings
.
PROFILE_IMAGE_BACKEND
return
storage_class
(
base_url
=
(
settings
.
PROFILE_IMAGE_DOMAIN
+
settings
.
PROFILE_IMAGE_URL_PATH
))
storage_class
=
get_storage_class
(
config
[
'class'
])
return
storage_class
(
**
config
[
'options'
])
def
_make_profile_image_name
(
username
):
def
_make_profile_image_name
(
username
):
...
@@ -75,7 +76,7 @@ def get_profile_image_urls_for_user(user):
...
@@ -75,7 +76,7 @@ def get_profile_image_urls_for_user(user):
callers will use `_get_default_profile_image_urls` instead to provide
callers will use `_get_default_profile_image_urls` instead to provide
a set of urls that point to placeholder images, when there are no user-
a set of urls that point to placeholder images, when there are no user-
submitted images.
submitted images.
- based on the value of django.conf.settings.PROFILE_IMAGE_
DOMAIN
,
- based on the value of django.conf.settings.PROFILE_IMAGE_
BACKEND
,
the URL may be relative, and in that case the caller is responsible for
the URL may be relative, and in that case the caller is responsible for
constructing the full URL if needed.
constructing the full URL if needed.
...
...
openedx/core/djangoapps/user_api/accounts/tests/test_image_helpers.py
View file @
23f02d94
...
@@ -34,7 +34,7 @@ class ProfileImageUrlTestCase(TestCase):
...
@@ -34,7 +34,7 @@ class ProfileImageUrlTestCase(TestCase):
"""
"""
self
.
assertEqual
(
self
.
assertEqual
(
actual_url
,
actual_url
,
'http://example-storage.com/profile
_
images/{name}_{size}.jpg'
.
format
(
'http://example-storage.com/profile
-
images/{name}_{size}.jpg'
.
format
(
name
=
expected_name
,
size
=
expected_pixels
name
=
expected_name
,
size
=
expected_pixels
)
)
)
)
...
...
openedx/core/djangoapps/user_api/accounts/tests/test_views.py
View file @
23f02d94
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
import
datetime
import
datetime
from
copy
import
deepcopy
import
ddt
import
ddt
import
hashlib
import
hashlib
import
json
import
json
...
@@ -19,6 +20,12 @@ from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
...
@@ -19,6 +20,12 @@ from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
from
..
import
PRIVATE_VISIBILITY
,
ALL_USERS_VISIBILITY
from
..
import
PRIVATE_VISIBILITY
,
ALL_USERS_VISIBILITY
# this is used in one test to check the behavior of profile image url
# generation with a relative url in the config.
TEST_PROFILE_IMAGE_BACKEND
=
deepcopy
(
settings
.
PROFILE_IMAGE_BACKEND
)
TEST_PROFILE_IMAGE_BACKEND
[
'options'
][
'base_url'
]
=
'/profile-images/'
class
UserAPITestCase
(
APITestCase
):
class
UserAPITestCase
(
APITestCase
):
"""
"""
The base class for all tests of the User API
The base class for all tests of the User API
...
@@ -117,7 +124,7 @@ class TestAccountAPI(UserAPITestCase):
...
@@ -117,7 +124,7 @@ class TestAccountAPI(UserAPITestCase):
image.
image.
"""
"""
if
has_profile_image
:
if
has_profile_image
:
url_root
=
'http://example-storage.com/profile
_
images'
url_root
=
'http://example-storage.com/profile
-
images'
filename
=
hashlib
.
md5
(
'secret'
+
self
.
user
.
username
)
.
hexdigest
()
filename
=
hashlib
.
md5
(
'secret'
+
self
.
user
.
username
)
.
hexdigest
()
file_extension
=
'jpg'
file_extension
=
'jpg'
else
:
else
:
...
@@ -593,12 +600,12 @@ class TestAccountAPI(UserAPITestCase):
...
@@ -593,12 +600,12 @@ class TestAccountAPI(UserAPITestCase):
)
)
self
.
assertIsNone
(
error_response
.
data
[
"user_message"
])
self
.
assertIsNone
(
error_response
.
data
[
"user_message"
])
@override_settings
(
PROFILE_IMAGE_
DOMAIN
=
'/'
)
@override_settings
(
PROFILE_IMAGE_
BACKEND
=
TEST_PROFILE_IMAGE_BACKEND
)
def
test_convert_relative_profile_url
(
self
):
def
test_convert_relative_profile_url
(
self
):
"""
"""
Test that when
PROFILE_IMAGE_DOMAIN is set to '/', the API
Test that when
TEST_PROFILE_IMAGE_BACKEND['base_url'] begins
generates the full URL to profile images based on the URL
with a '/', the API generates the full URL to profile images based on
of the request.
the URL
of the request.
"""
"""
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
self
.
test_password
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
self
.
test_password
)
response
=
self
.
send_get
(
self
.
client
)
response
=
self
.
send_get
(
self
.
client
)
...
...
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