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
dca12d65
Commit
dca12d65
authored
7 years ago
by
Muhammad Ammar
Committed by
Mushtaq Ali
7 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Save or update course video image - TNL-6762
parent
7b910953
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
152 additions
and
53 deletions
+152
-53
cms/djangoapps/contentstore/tests/test_contentstore.py
+1
-1
cms/djangoapps/contentstore/views/tests/test_videos.py
+0
-0
cms/djangoapps/contentstore/views/videos.py
+97
-45
cms/envs/aws.py
+4
-0
cms/envs/common.py
+6
-0
cms/envs/test.py
+10
-0
cms/urls.py
+7
-0
common/lib/xmodule/xmodule/tests/test_video.py
+4
-2
common/lib/xmodule/xmodule/video_module/video_module.py
+4
-1
lms/djangoapps/courseware/tests/test_video_mongo.py
+4
-3
lms/envs/common.py
+14
-0
requirements/edx/github.txt
+1
-1
No files found.
cms/djangoapps/contentstore/tests/test_contentstore.py
View file @
dca12d65
...
@@ -1975,7 +1975,7 @@ class RerunCourseTest(ContentStoreTestCase):
...
@@ -1975,7 +1975,7 @@ class RerunCourseTest(ContentStoreTestCase):
create_video
(
create_video
(
dict
(
dict
(
edx_video_id
=
"tree-hugger"
,
edx_video_id
=
"tree-hugger"
,
courses
=
[
source_course
.
id
],
courses
=
[
unicode
(
source_course
.
id
)
],
status
=
'test'
,
status
=
'test'
,
duration
=
2
,
duration
=
2
,
encoded_videos
=
[]
encoded_videos
=
[]
...
...
This diff is collapsed.
Click to expand it.
cms/djangoapps/contentstore/views/tests/test_videos.py
View file @
dca12d65
This diff is collapsed.
Click to expand it.
cms/djangoapps/contentstore/views/videos.py
View file @
dca12d65
"""
"""
Views related to the video upload feature
Views related to the video upload feature
"""
"""
from
contextlib
import
closing
from
datetime
import
datetime
,
timedelta
import
logging
from
boto
import
s3
import
csv
import
csv
import
logging
import
logging
from
datetime
import
datetime
,
timedelta
from
datetime
import
datetime
,
timedelta
...
@@ -10,17 +15,19 @@ import rfc6266
...
@@ -10,17 +15,19 @@ import rfc6266
from
boto
import
s3
from
boto
import
s3
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.decorators
import
login_required
from
django.contrib.auth.decorators
import
login_required
from
django.contrib.staticfiles.storage
import
staticfiles_storage
from
django.http
import
HttpResponse
,
HttpResponseNotFound
from
django.http
import
HttpResponse
,
HttpResponseNotFound
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext_noop
from
django.utils.translation
import
ugettext_noop
from
django.views.decorators.http
import
require_GET
,
require_http_methods
from
django.views.decorators.http
import
require_GET
,
require_
POST
,
require_
http_methods
from
edxval.api
import
(
from
edxval.api
import
(
SortDirection
,
SortDirection
,
VideoSortField
,
VideoSortField
,
create_video
,
create_video
,
get_videos_for_course
,
get_videos_for_course
,
remove_video_for_course
,
remove_video_for_course
,
update_video_status
update_video_status
,
update_video_image
)
)
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
...
@@ -31,7 +38,8 @@ from util.json_request import JsonResponse, expect_json
...
@@ -31,7 +38,8 @@ from util.json_request import JsonResponse, expect_json
from
.course
import
get_course_and_check_access
from
.course
import
get_course_and_check_access
__all__
=
[
"videos_handler"
,
"video_encodings_download"
]
__all__
=
[
'videos_handler'
,
'video_encodings_download'
,
'video_images_handler'
]
LOGGER
=
logging
.
getLogger
(
__name__
)
LOGGER
=
logging
.
getLogger
(
__name__
)
...
@@ -145,6 +153,26 @@ def videos_handler(request, course_key_string, edx_video_id=None):
...
@@ -145,6 +153,26 @@ def videos_handler(request, course_key_string, edx_video_id=None):
return
videos_post
(
course
,
request
)
return
videos_post
(
course
,
request
)
@expect_json
@login_required
@require_POST
def
video_images_handler
(
request
,
course_key_string
,
edx_video_id
=
None
):
if
'file'
not
in
request
.
FILES
:
return
JsonResponse
({
"error"
:
_
(
u'No file provided for video image'
)},
status
=
400
)
image_file
=
request
.
FILES
[
'file'
]
file_name
=
request
.
FILES
[
'file'
]
.
name
# TODO: Image file validation
with
closing
(
image_file
):
image_url
=
update_video_image
(
edx_video_id
,
course_key_string
,
image_file
,
file_name
)
LOGGER
.
info
(
'VIDEOS: Video image uploaded for edx_video_id [
%
s] in course [
%
s]'
,
edx_video_id
,
course_key_string
)
return
JsonResponse
({
'image_url'
:
image_url
})
@login_required
@login_required
@require_GET
@require_GET
def
video_encodings_download
(
request
,
course_key_string
):
def
video_encodings_download
(
request
,
course_key_string
):
...
@@ -296,17 +324,39 @@ def _get_videos(course):
...
@@ -296,17 +324,39 @@ def _get_videos(course):
return
videos
return
videos
def
_get_default_video_image_url
():
"""
Returns default video image url
"""
return
staticfiles_storage
.
url
(
settings
.
VIDEO_IMAGE_DEFAULT_FILENAME
)
def
_get_index_videos
(
course
):
def
_get_index_videos
(
course
):
"""
"""
Returns the information about each video upload required for the video list
Returns the information about each video upload required for the video list
"""
"""
return
list
(
course_id
=
unicode
(
course
.
id
)
{
default_video_image_url
=
_get_default_video_image_url
()
attr
:
video
[
attr
]
attrs
=
[
'edx_video_id'
,
'client_video_id'
,
'created'
,
'duration'
,
'status'
,
'courses'
]
for
attr
in
[
"edx_video_id"
,
"client_video_id"
,
"created"
,
"duration"
,
"status"
]
}
def
_get_values
(
video
):
for
video
in
_get_videos
(
course
)
"""
)
Get data for predefined video attributes.
"""
values
=
{}
for
attr
in
attrs
:
if
attr
==
'courses'
:
course
=
filter
(
lambda
c
:
course_id
in
c
,
video
[
'courses'
])
(
__
,
image_url
),
=
course
[
0
]
.
items
()
values
[
'course_video_image_url'
]
=
image_url
or
default_video_image_url
else
:
values
[
attr
]
=
video
[
attr
]
return
values
return
[
_get_values
(
video
)
for
video
in
_get_videos
(
course
)
]
def
videos_index_html
(
course
):
def
videos_index_html
(
course
):
...
@@ -314,15 +364,16 @@ def videos_index_html(course):
...
@@ -314,15 +364,16 @@ def videos_index_html(course):
Returns an HTML page to display previous video uploads and allow new ones
Returns an HTML page to display previous video uploads and allow new ones
"""
"""
return
render_to_response
(
return
render_to_response
(
"videos_index.html"
,
'videos_index.html'
,
{
{
"context_course"
:
course
,
'context_course'
:
course
,
"video_handler_url"
:
reverse_course_url
(
"videos_handler"
,
unicode
(
course
.
id
)),
'image_upload_url'
:
reverse_course_url
(
'video_images_handler'
,
unicode
(
course
.
id
)),
"encodings_download_url"
:
reverse_course_url
(
"video_encodings_download"
,
unicode
(
course
.
id
)),
'video_handler_url'
:
reverse_course_url
(
'videos_handler'
,
unicode
(
course
.
id
)),
"previous_uploads"
:
_get_index_videos
(
course
),
'encodings_download_url'
:
reverse_course_url
(
'video_encodings_download'
,
unicode
(
course
.
id
)),
"concurrent_upload_limit"
:
settings
.
VIDEO_UPLOAD_PIPELINE
.
get
(
"CONCURRENT_UPLOAD_LIMIT"
,
0
),
'previous_uploads'
:
_get_index_videos
(
course
),
"video_supported_file_formats"
:
VIDEO_SUPPORTED_FILE_FORMATS
.
keys
(),
'concurrent_upload_limit'
:
settings
.
VIDEO_UPLOAD_PIPELINE
.
get
(
'CONCURRENT_UPLOAD_LIMIT'
,
0
),
"video_upload_max_file_size"
:
VIDEO_UPLOAD_MAX_FILE_SIZE_GB
'video_supported_file_formats'
:
VIDEO_SUPPORTED_FILE_FORMATS
.
keys
(),
'video_upload_max_file_size'
:
VIDEO_UPLOAD_MAX_FILE_SIZE_GB
}
}
)
)
...
@@ -331,12 +382,13 @@ def videos_index_json(course):
...
@@ -331,12 +382,13 @@ def videos_index_json(course):
"""
"""
Returns JSON in the following format:
Returns JSON in the following format:
{
{
"videos": [{
'videos': [{
"edx_video_id": "aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa",
'edx_video_id': 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa',
"client_video_id": "video.mp4",
'client_video_id': 'video.mp4',
"created": "1970-01-01T00:00:00Z",
'created': '1970-01-01T00:00:00Z',
"duration": 42.5,
'duration': 42.5,
"status": "upload"
'status': 'upload',
'course_video_image_url': 'https://video/images/1234.jpg'
}]
}]
}
}
"""
"""
...
@@ -364,29 +416,29 @@ def videos_post(course, request):
...
@@ -364,29 +416,29 @@ def videos_post(course, request):
The returned array corresponds exactly to the input array.
The returned array corresponds exactly to the input array.
"""
"""
error
=
None
error
=
None
if
"files"
not
in
request
.
json
:
if
'files'
not
in
request
.
json
:
error
=
"Request object is not JSON or does not contain 'files'"
error
=
"Request object is not JSON or does not contain 'files'"
elif
any
(
elif
any
(
"file_name"
not
in
file
or
"content_type"
not
in
file
'file_name'
not
in
file
or
'content_type'
not
in
file
for
file
in
request
.
json
[
"files"
]
for
file
in
request
.
json
[
'files'
]
):
):
error
=
"Request 'files' entry does not contain 'file_name' and 'content_type'"
error
=
"Request 'files' entry does not contain 'file_name' and 'content_type'"
elif
any
(
elif
any
(
file
[
'content_type'
]
not
in
VIDEO_SUPPORTED_FILE_FORMATS
.
values
()
file
[
'content_type'
]
not
in
VIDEO_SUPPORTED_FILE_FORMATS
.
values
()
for
file
in
request
.
json
[
"files"
]
for
file
in
request
.
json
[
'files'
]
):
):
error
=
"Request 'files' entry contain unsupported content_type"
error
=
"Request 'files' entry contain unsupported content_type"
if
error
:
if
error
:
return
JsonResponse
({
"error"
:
error
},
status
=
400
)
return
JsonResponse
({
'error'
:
error
},
status
=
400
)
bucket
=
storage_service_bucket
()
bucket
=
storage_service_bucket
()
course_video_upload_token
=
course
.
video_upload_pipeline
[
"course_video_upload_token"
]
course_video_upload_token
=
course
.
video_upload_pipeline
[
'course_video_upload_token'
]
req_files
=
request
.
json
[
"files"
]
req_files
=
request
.
json
[
'files'
]
resp_files
=
[]
resp_files
=
[]
for
req_file
in
req_files
:
for
req_file
in
req_files
:
file_name
=
req_file
[
"file_name"
]
file_name
=
req_file
[
'file_name'
]
try
:
try
:
file_name
.
encode
(
'ascii'
)
file_name
.
encode
(
'ascii'
)
...
@@ -397,30 +449,30 @@ def videos_post(course, request):
...
@@ -397,30 +449,30 @@ def videos_post(course, request):
edx_video_id
=
unicode
(
uuid4
())
edx_video_id
=
unicode
(
uuid4
())
key
=
storage_service_key
(
bucket
,
file_name
=
edx_video_id
)
key
=
storage_service_key
(
bucket
,
file_name
=
edx_video_id
)
for
metadata_name
,
value
in
[
for
metadata_name
,
value
in
[
(
"course_video_upload_token"
,
course_video_upload_token
),
(
'course_video_upload_token'
,
course_video_upload_token
),
(
"client_video_id"
,
file_name
),
(
'client_video_id'
,
file_name
),
(
"course_key"
,
unicode
(
course
.
id
)),
(
'course_key'
,
unicode
(
course
.
id
)),
]:
]:
key
.
set_metadata
(
metadata_name
,
value
)
key
.
set_metadata
(
metadata_name
,
value
)
upload_url
=
key
.
generate_url
(
upload_url
=
key
.
generate_url
(
KEY_EXPIRATION_IN_SECONDS
,
KEY_EXPIRATION_IN_SECONDS
,
"PUT"
,
'PUT'
,
headers
=
{
"Content-Type"
:
req_file
[
"content_type"
]}
headers
=
{
'Content-Type'
:
req_file
[
'content_type'
]}
)
)
# persist edx_video_id in VAL
# persist edx_video_id in VAL
create_video
({
create_video
({
"edx_video_id"
:
edx_video_id
,
'edx_video_id'
:
edx_video_id
,
"status"
:
"upload"
,
'status'
:
'upload'
,
"client_video_id"
:
file_name
,
'client_video_id'
:
file_name
,
"duration"
:
0
,
'duration'
:
0
,
"encoded_videos"
:
[],
'encoded_videos'
:
[],
"courses"
:
[
course
.
id
]
'courses'
:
[
unicode
(
course
.
id
)
]
})
})
resp_files
.
append
({
"file_name"
:
file_name
,
"upload_url"
:
upload_url
,
"edx_video_id"
:
edx_video_id
})
resp_files
.
append
({
'file_name'
:
file_name
,
'upload_url'
:
upload_url
,
'edx_video_id'
:
edx_video_id
})
return
JsonResponse
({
"files"
:
resp_files
},
status
=
200
)
return
JsonResponse
({
'files'
:
resp_files
},
status
=
200
)
def
storage_service_bucket
():
def
storage_service_bucket
():
...
...
This diff is collapsed.
Click to expand it.
cms/envs/aws.py
View file @
dca12d65
...
@@ -440,6 +440,10 @@ ADVANCED_PROBLEM_TYPES = ENV_TOKENS.get('ADVANCED_PROBLEM_TYPES', ADVANCED_PROBL
...
@@ -440,6 +440,10 @@ ADVANCED_PROBLEM_TYPES = ENV_TOKENS.get('ADVANCED_PROBLEM_TYPES', ADVANCED_PROBL
VIDEO_UPLOAD_PIPELINE
=
ENV_TOKENS
.
get
(
'VIDEO_UPLOAD_PIPELINE'
,
VIDEO_UPLOAD_PIPELINE
)
VIDEO_UPLOAD_PIPELINE
=
ENV_TOKENS
.
get
(
'VIDEO_UPLOAD_PIPELINE'
,
VIDEO_UPLOAD_PIPELINE
)
################ VIDEO IMAGE STORAGE ###############
VIDEO_IMAGE_SETTINGS
=
ENV_TOKENS
.
get
(
'VIDEO_IMAGE_SETTINGS'
,
VIDEO_IMAGE_SETTINGS
)
################ PUSH NOTIFICATIONS ###############
################ PUSH NOTIFICATIONS ###############
PARSE_KEYS
=
AUTH_TOKENS
.
get
(
"PARSE_KEYS"
,
{})
PARSE_KEYS
=
AUTH_TOKENS
.
get
(
"PARSE_KEYS"
,
{})
...
...
This diff is collapsed.
Click to expand it.
cms/envs/common.py
View file @
dca12d65
...
@@ -103,6 +103,8 @@ from lms.envs.common import (
...
@@ -103,6 +103,8 @@ from lms.envs.common import (
CONTACT_EMAIL
,
CONTACT_EMAIL
,
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH
,
DISABLE_ACCOUNT_ACTIVATION_REQUIREMENT_SWITCH
,
# Video Image settings
VIDEO_IMAGE_SETTINGS
,
)
)
from
path
import
Path
as
path
from
path
import
Path
as
path
from
warnings
import
simplefilter
from
warnings
import
simplefilter
...
@@ -1344,3 +1346,7 @@ PROFILE_IMAGE_SIZES_MAP = {
...
@@ -1344,3 +1346,7 @@ PROFILE_IMAGE_SIZES_MAP = {
'medium'
:
50
,
'medium'
:
50
,
'small'
:
30
'small'
:
30
}
}
###################### VIDEO IMAGE STORAGE ######################
VIDEO_IMAGE_DEFAULT_FILENAME
=
'default_video_image.png'
This diff is collapsed.
Click to expand it.
cms/envs/test.py
View file @
dca12d65
...
@@ -335,3 +335,13 @@ FEATURES['CUSTOM_COURSES_EDX'] = True
...
@@ -335,3 +335,13 @@ FEATURES['CUSTOM_COURSES_EDX'] = True
# API access management -- needed for simple-history to run.
# API access management -- needed for simple-history to run.
INSTALLED_APPS
+=
(
'openedx.core.djangoapps.api_admin'
,)
INSTALLED_APPS
+=
(
'openedx.core.djangoapps.api_admin'
,)
########################## VIDEO IMAGE STORAGE ############################
VIDEO_IMAGE_SETTINGS
=
dict
(
STORAGE_KWARGS
=
dict
(
location
=
MEDIA_ROOT
,
base_url
=
MEDIA_URL
,
),
DIRECTORY_PREFIX
=
'videoimage/'
,
)
VIDEO_IMAGE_DEFAULT_FILENAME
=
'default_video_image.png'
This diff is collapsed.
Click to expand it.
cms/urls.py
View file @
dca12d65
from
django.conf
import
settings
from
django.conf
import
settings
from
django.conf.urls
import
include
,
patterns
,
url
from
django.conf.urls
import
include
,
patterns
,
url
from
django.conf.urls.static
import
static
# There is a course creators admin table.
# There is a course creators admin table.
from
ratelimitbackend
import
admin
from
ratelimitbackend
import
admin
...
@@ -112,6 +113,7 @@ urlpatterns += patterns(
...
@@ -112,6 +113,7 @@ urlpatterns += patterns(
url
(
r'^textbooks/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'textbooks_list_handler'
),
url
(
r'^textbooks/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'textbooks_list_handler'
),
url
(
r'^textbooks/{}/(?P<textbook_id>\d[^/]*)$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'textbooks_detail_handler'
),
url
(
r'^textbooks/{}/(?P<textbook_id>\d[^/]*)$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'textbooks_detail_handler'
),
url
(
r'^videos/{}(?:/(?P<edx_video_id>[-\w]+))?$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'videos_handler'
),
url
(
r'^videos/{}(?:/(?P<edx_video_id>[-\w]+))?$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'videos_handler'
),
url
(
r'^video_images/{}(?:/(?P<edx_video_id>[-\w]+))?$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'video_images_handler'
),
url
(
r'^video_encodings_download/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'video_encodings_download'
),
url
(
r'^video_encodings_download/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'video_encodings_download'
),
url
(
r'^group_configurations/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'group_configurations_list_handler'
),
url
(
r'^group_configurations/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'group_configurations_list_handler'
),
url
(
r'^group_configurations/{}/(?P<group_configuration_id>\d+)(/)?(?P<group_id>\d+)?$'
.
format
(
url
(
r'^group_configurations/{}/(?P<group_configuration_id>\d+)(/)?(?P<group_id>\d+)?$'
.
format
(
...
@@ -189,6 +191,11 @@ if settings.DEBUG:
...
@@ -189,6 +191,11 @@ if settings.DEBUG:
except
ImportError
:
except
ImportError
:
pass
pass
urlpatterns
+=
static
(
settings
.
VIDEO_IMAGE_SETTINGS
[
'STORAGE_KWARGS'
][
'base_url'
],
document_root
=
settings
.
VIDEO_IMAGE_SETTINGS
[
'STORAGE_KWARGS'
][
'location'
]
)
if
'debug_toolbar'
in
settings
.
INSTALLED_APPS
:
if
'debug_toolbar'
in
settings
.
INSTALLED_APPS
:
import
debug_toolbar
import
debug_toolbar
urlpatterns
+=
(
urlpatterns
+=
(
...
...
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/tests/test_video.py
View file @
dca12d65
...
@@ -18,7 +18,7 @@ import datetime
...
@@ -18,7 +18,7 @@ import datetime
from
uuid
import
uuid4
from
uuid
import
uuid4
from
lxml
import
etree
from
lxml
import
etree
from
mock
import
ANY
,
Mock
,
patch
from
mock
import
ANY
,
Mock
,
patch
,
MagicMock
import
ddt
import
ddt
from
django.conf
import
settings
from
django.conf
import
settings
...
@@ -673,7 +673,7 @@ class VideoExportTestCase(VideoDescriptorTestBase):
...
@@ -673,7 +673,7 @@ class VideoExportTestCase(VideoDescriptorTestBase):
"""
"""
Test that we write the correct XML on export.
Test that we write the correct XML on export.
"""
"""
def
mock_val_export
(
edx_video_id
):
def
mock_val_export
(
edx_video_id
,
course_id
):
"""Mock edxval.api.export_to_xml"""
"""Mock edxval.api.export_to_xml"""
return
etree
.
Element
(
return
etree
.
Element
(
'video_asset'
,
'video_asset'
,
...
@@ -695,6 +695,7 @@ class VideoExportTestCase(VideoDescriptorTestBase):
...
@@ -695,6 +695,7 @@ class VideoExportTestCase(VideoDescriptorTestBase):
self
.
descriptor
.
download_video
=
True
self
.
descriptor
.
download_video
=
True
self
.
descriptor
.
transcripts
=
{
'ua'
:
'ukrainian_translation.srt'
,
'ge'
:
'german_translation.srt'
}
self
.
descriptor
.
transcripts
=
{
'ua'
:
'ukrainian_translation.srt'
,
'ge'
:
'german_translation.srt'
}
self
.
descriptor
.
edx_video_id
=
'test_edx_video_id'
self
.
descriptor
.
edx_video_id
=
'test_edx_video_id'
self
.
descriptor
.
runtime
.
course_id
=
MagicMock
()
xml
=
self
.
descriptor
.
definition_to_xml
(
None
)
# We don't use the `resource_fs` parameter
xml
=
self
.
descriptor
.
definition_to_xml
(
None
)
# We don't use the `resource_fs` parameter
parser
=
etree
.
XMLParser
(
remove_blank_text
=
True
)
parser
=
etree
.
XMLParser
(
remove_blank_text
=
True
)
...
@@ -718,6 +719,7 @@ class VideoExportTestCase(VideoDescriptorTestBase):
...
@@ -718,6 +719,7 @@ class VideoExportTestCase(VideoDescriptorTestBase):
mock_val_api
.
ValVideoNotFoundError
=
_MockValVideoNotFoundError
mock_val_api
.
ValVideoNotFoundError
=
_MockValVideoNotFoundError
mock_val_api
.
export_to_xml
=
Mock
(
side_effect
=
mock_val_api
.
ValVideoNotFoundError
)
mock_val_api
.
export_to_xml
=
Mock
(
side_effect
=
mock_val_api
.
ValVideoNotFoundError
)
self
.
descriptor
.
edx_video_id
=
'test_edx_video_id'
self
.
descriptor
.
edx_video_id
=
'test_edx_video_id'
self
.
descriptor
.
runtime
.
course_id
=
MagicMock
()
xml
=
self
.
descriptor
.
definition_to_xml
(
None
)
xml
=
self
.
descriptor
.
definition_to_xml
(
None
)
parser
=
etree
.
XMLParser
(
remove_blank_text
=
True
)
parser
=
etree
.
XMLParser
(
remove_blank_text
=
True
)
...
...
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/video_module/video_module.py
View file @
dca12d65
...
@@ -653,7 +653,10 @@ class VideoDescriptor(VideoFields, VideoTranscriptsMixin, VideoStudioViewHandler
...
@@ -653,7 +653,10 @@ class VideoDescriptor(VideoFields, VideoTranscriptsMixin, VideoStudioViewHandler
if
self
.
edx_video_id
and
edxval_api
:
if
self
.
edx_video_id
and
edxval_api
:
try
:
try
:
xml
.
append
(
edxval_api
.
export_to_xml
(
self
.
edx_video_id
))
xml
.
append
(
edxval_api
.
export_to_xml
(
self
.
edx_video_id
,
unicode
(
self
.
runtime
.
course_id
.
for_branch
(
None
)))
)
except
edxval_api
.
ValVideoNotFoundError
:
except
edxval_api
.
ValVideoNotFoundError
:
pass
pass
...
...
This diff is collapsed.
Click to expand it.
lms/djangoapps/courseware/tests/test_video_mongo.py
View file @
dca12d65
...
@@ -1261,7 +1261,7 @@ class TestVideoDescriptorStudentViewJson(TestCase):
...
@@ -1261,7 +1261,7 @@ class TestVideoDescriptorStudentViewJson(TestCase):
'duration'
:
self
.
TEST_DURATION
,
'duration'
:
self
.
TEST_DURATION
,
'status'
:
'dummy'
,
'status'
:
'dummy'
,
'encoded_videos'
:
[
self
.
TEST_ENCODED_VIDEO
],
'encoded_videos'
:
[
self
.
TEST_ENCODED_VIDEO
],
'courses'
:
[
self
.
video
.
location
.
course_key
]
if
associate_course_in_val
else
[],
'courses'
:
[
unicode
(
self
.
video
.
location
.
course_key
)
]
if
associate_course_in_val
else
[],
})
})
self
.
val_video
=
get_video_info
(
self
.
TEST_EDX_VIDEO_ID
)
# pylint: disable=attribute-defined-outside-init
self
.
val_video
=
get_video_info
(
self
.
TEST_EDX_VIDEO_ID
)
# pylint: disable=attribute-defined-outside-init
...
@@ -1391,6 +1391,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
...
@@ -1391,6 +1391,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
def
setUp
(
self
):
def
setUp
(
self
):
super
(
VideoDescriptorTest
,
self
)
.
setUp
()
super
(
VideoDescriptorTest
,
self
)
.
setUp
()
self
.
descriptor
.
runtime
.
handler_url
=
MagicMock
()
self
.
descriptor
.
runtime
.
handler_url
=
MagicMock
()
self
.
descriptor
.
runtime
.
course_id
=
MagicMock
()
def
test_get_context
(
self
):
def
test_get_context
(
self
):
""""
""""
...
@@ -1438,7 +1439,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
...
@@ -1438,7 +1439,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
actual
=
self
.
descriptor
.
definition_to_xml
(
resource_fs
=
None
)
actual
=
self
.
descriptor
.
definition_to_xml
(
resource_fs
=
None
)
expected_str
=
"""
expected_str
=
"""
<video download_video="false" url_name="SampleProblem">
<video download_video="false" url_name="SampleProblem">
<video_asset client_video_id="test_client_video_id" duration="111.0">
<video_asset client_video_id="test_client_video_id" duration="111.0"
image=""
>
<encoded_video profile="mobile" url="http://example.com/video" file_size="222" bitrate="333"/>
<encoded_video profile="mobile" url="http://example.com/video" file_size="222" bitrate="333"/>
</video_asset>
</video_asset>
</video>
</video>
...
@@ -1474,7 +1475,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
...
@@ -1474,7 +1475,7 @@ class VideoDescriptorTest(TestCase, VideoDescriptorTestBase):
self
.
assertEqual
(
video_data
[
'client_video_id'
],
'test_client_video_id'
)
self
.
assertEqual
(
video_data
[
'client_video_id'
],
'test_client_video_id'
)
self
.
assertEqual
(
video_data
[
'duration'
],
111
)
self
.
assertEqual
(
video_data
[
'duration'
],
111
)
self
.
assertEqual
(
video_data
[
'status'
],
'imported'
)
self
.
assertEqual
(
video_data
[
'status'
],
'imported'
)
self
.
assertEqual
(
video_data
[
'courses'
],
[
id_generator
.
target_course_id
])
self
.
assertEqual
(
video_data
[
'courses'
],
[
{
id_generator
.
target_course_id
:
None
}
])
self
.
assertEqual
(
video_data
[
'encoded_videos'
][
0
][
'profile'
],
'mobile'
)
self
.
assertEqual
(
video_data
[
'encoded_videos'
][
0
][
'profile'
],
'mobile'
)
self
.
assertEqual
(
video_data
[
'encoded_videos'
][
0
][
'url'
],
'http://example.com/video'
)
self
.
assertEqual
(
video_data
[
'encoded_videos'
][
0
][
'url'
],
'http://example.com/video'
)
self
.
assertEqual
(
video_data
[
'encoded_videos'
][
0
][
'file_size'
],
222
)
self
.
assertEqual
(
video_data
[
'encoded_videos'
][
0
][
'file_size'
],
222
)
...
...
This diff is collapsed.
Click to expand it.
lms/envs/common.py
View file @
dca12d65
...
@@ -2564,6 +2564,20 @@ MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = 15 * 60
...
@@ -2564,6 +2564,20 @@ MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = 15 * 60
TIME_ZONE_DISPLAYED_FOR_DEADLINES
=
'UTC'
TIME_ZONE_DISPLAYED_FOR_DEADLINES
=
'UTC'
########################## VIDEO IMAGE STORAGE ############################
VIDEO_IMAGE_SETTINGS
=
dict
(
# Backend storage
# STORAGE_CLASS='storages.backends.s3boto.S3BotoStorage',
# STORAGE_KWARGS=dict(bucket='video-image-bucket'),
STORAGE_KWARGS
=
dict
(
location
=
MEDIA_ROOT
,
base_url
=
MEDIA_URL
,
),
DIRECTORY_PREFIX
=
'videoimage/'
,
)
# Source:
# Source:
# http://loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt according to http://en.wikipedia.org/wiki/ISO_639-1
# http://loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt according to http://en.wikipedia.org/wiki/ISO_639-1
# Note that this is used as the set of choices to the `code` field of the
# Note that this is used as the set of choices to the `code` field of the
...
...
This diff is collapsed.
Click to expand it.
requirements/edx/github.txt
View file @
dca12d65
...
@@ -77,7 +77,7 @@ git+https://github.com/edx/lettuce.git@0.2.20.002#egg=lettuce==0.2.20.002
...
@@ -77,7 +77,7 @@ git+https://github.com/edx/lettuce.git@0.2.20.002#egg=lettuce==0.2.20.002
git+https://github.com/edx/edx-ora2.git@1.4.3#egg=ora2==1.4.3
git+https://github.com/edx/edx-ora2.git@1.4.3#egg=ora2==1.4.3
-e git+https://github.com/edx/edx-submissions.git@2.0.0#egg=edx-submissions==2.0.0
-e git+https://github.com/edx/edx-submissions.git@2.0.0#egg=edx-submissions==2.0.0
git+https://github.com/edx/ease.git@release-2015-07-14#egg=ease==0.1.3
git+https://github.com/edx/ease.git@release-2015-07-14#egg=ease==0.1.3
git+https://github.com/edx/edx-val.git@0.0.1
3#egg=edxval==0.0.13
git+https://github.com/edx/edx-val.git@0.0.1
4#egg=edxval==0.0.14
git+https://github.com/pmitros/RecommenderXBlock.git@v1.2#egg=recommender-xblock==1.2
git+https://github.com/pmitros/RecommenderXBlock.git@v1.2#egg=recommender-xblock==1.2
git+https://github.com/solashirai/crowdsourcehinter.git@518605f0a95190949fe77bd39158450639e2e1dc#egg=crowdsourcehinter-xblock==0.1
git+https://github.com/solashirai/crowdsourcehinter.git@518605f0a95190949fe77bd39158450639e2e1dc#egg=crowdsourcehinter-xblock==0.1
-e git+https://github.com/pmitros/RateXBlock.git@367e19c0f6eac8a5f002fd0f1559555f8e74bfff#egg=rate-xblock
-e git+https://github.com/pmitros/RateXBlock.git@367e19c0f6eac8a5f002fd0f1559555f8e74bfff#egg=rate-xblock
...
...
This diff is collapsed.
Click to expand it.
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