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
7dfd567c
Commit
7dfd567c
authored
Jun 23, 2015
by
muzaffaryousaf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Using youtube api (v3) instead of v2 to get the video duration .
TNL-2413
parent
69a1a069
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
119 additions
and
74 deletions
+119
-74
cms/envs/acceptance.py
+2
-2
cms/envs/aws.py
+1
-0
cms/envs/bok_choy.py
+2
-2
cms/envs/common.py
+7
-4
cms/templates/ux/reference/container.html
+1
-1
common/djangoapps/terrain/setup_prereqs.py
+1
-2
common/djangoapps/terrain/stubs/youtube.py
+12
-10
common/lib/xmodule/xmodule/js/fixtures/video.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_all.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_no_captions.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_with_bumper.html
+1
-1
common/lib/xmodule/xmodule/js/fixtures/video_yt_multiple.html
+3
-3
common/lib/xmodule/xmodule/js/js_test.yml
+1
-0
common/lib/xmodule/xmodule/js/spec/helper.js
+31
-19
common/lib/xmodule/xmodule/js/spec/video/general_spec.js
+6
-0
common/lib/xmodule/xmodule/js/spec/video/initialize_spec.js
+2
-2
common/lib/xmodule/xmodule/js/src/video/01_initialize.js
+0
-0
common/lib/xmodule/xmodule/js/src/video/10_main.js
+2
-0
common/lib/xmodule/xmodule/tests/test_video.py
+2
-2
common/lib/xmodule/xmodule/video_module/video_module.py
+13
-1
common/test/acceptance/tests/helpers.py
+1
-2
lms/djangoapps/courseware/features/video.feature
+4
-4
lms/djangoapps/courseware/tests/test_video_mongo.py
+12
-8
lms/envs/acceptance.py
+2
-2
lms/envs/aws.py
+1
-0
lms/envs/bok_choy.py
+2
-2
lms/envs/common.py
+4
-3
lms/static/js_test.yml
+1
-0
lms/static/lms/js/require-config.js
+1
-0
No files found.
cms/envs/acceptance.py
View file @
7dfd567c
...
...
@@ -118,8 +118,8 @@ except ImportError:
pass
# Point the URL used to test YouTube availability to our stub YouTube server
YOUTUBE
[
'API'
]
=
"127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
TEST_URL'
]
=
"
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'API'
]
=
"
http://
127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
METADATA_URL'
]
=
"http://
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'TEXT_API'
][
'url'
]
=
"127.0.0.1:{0}/test_transcripts_youtube/"
.
format
(
YOUTUBE_PORT
)
# Generate a random UUID so that different runs of acceptance tests don't break each other
...
...
cms/envs/aws.py
View file @
7dfd567c
...
...
@@ -348,3 +348,4 @@ if FEATURES['ENABLE_COURSEWARE_INDEX'] or FEATURES['ENABLE_LIBRARY_INDEX']:
XBLOCK_SETTINGS
=
ENV_TOKENS
.
get
(
'XBLOCK_SETTINGS'
,
{})
XBLOCK_SETTINGS
.
setdefault
(
"VideoDescriptor"
,
{})[
"licensing_enabled"
]
=
FEATURES
.
get
(
"LICENSING"
,
False
)
XBLOCK_SETTINGS
.
setdefault
(
"VideoModule"
,
{})[
'YOUTUBE_API_KEY'
]
=
AUTH_TOKENS
.
get
(
'YOUTUBE_API_KEY'
,
YOUTUBE_API_KEY
)
cms/envs/bok_choy.py
View file @
7dfd567c
...
...
@@ -103,8 +103,8 @@ FEATURES['ENTRANCE_EXAMS'] = True
# Point the URL used to test YouTube availability to our stub YouTube server
YOUTUBE_PORT
=
9080
YOUTUBE
[
'API'
]
=
"127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
TEST_URL'
]
=
"
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'API'
]
=
"
http://
127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
METADATA_URL'
]
=
"http://
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'TEXT_API'
][
'url'
]
=
"127.0.0.1:{0}/test_transcripts_youtube/"
.
format
(
YOUTUBE_PORT
)
FEATURES
[
'ENABLE_COURSEWARE_INDEX'
]
=
True
...
...
cms/envs/common.py
View file @
7dfd567c
...
...
@@ -44,7 +44,7 @@ from lms.envs.common import (
PROFILE_IMAGE_SECRET_KEY
,
PROFILE_IMAGE_MIN_BYTES
,
PROFILE_IMAGE_MAX_BYTES
,
# The following setting is included as it is used to check whether to
# display credit eligibility table on the CMS or not.
ENABLE_CREDIT_ELIGIBILITY
ENABLE_CREDIT_ELIGIBILITY
,
YOUTUBE_API_KEY
)
from
path
import
path
from
warnings
import
simplefilter
...
...
@@ -654,10 +654,10 @@ CELERY_QUEUES = {
YOUTUBE
=
{
# YouTube JavaScript API
'API'
:
'www.youtube.com/iframe_api'
,
'API'
:
'
https://
www.youtube.com/iframe_api'
,
# URL to
test YouTube availability
'
TEST_URL'
:
'gdata.youtube.com/feeds/api/videos/
'
,
# URL to
get YouTube metadata
'
METADATA_URL'
:
'https://www.googleapis.com/youtube/v3/videos
'
,
# Current youtube api for requesting transcripts.
# For example: http://video.google.com/timedtext?lang=en&v=j_jEn79vS3g.
...
...
@@ -996,6 +996,9 @@ ELASTIC_FIELD_MAPPINGS = {
XBLOCK_SETTINGS
=
{
"VideoDescriptor"
:
{
"licensing_enabled"
:
FEATURES
.
get
(
"LICENSING"
,
False
)
},
'VideoModule'
:
{
'YOUTUBE_API_KEY'
:
YOUTUBE_API_KEY
}
}
...
...
cms/templates/ux/reference/container.html
View file @
7dfd567c
...
...
@@ -137,7 +137,7 @@
<h2>
Video
</h2>
<div
id=
"video_i4x-AndyA-ABT101-video-72b5a0d74e8c4ed4a4d4e6bf67837c09"
class=
"video closed is-initialized"
data-streams=
"1.00:OEoXaMPEzfM"
data-save-state-url=
"/preview/xblock/i4x:;_;_AndyA;_ABT101;_video;_72b5a0d74e8c4ed4a4d4e6bf67837c09/handler/xmodule_handler/save_user_state"
data-caption-data-dir=
"None"
data-show-captions=
"true"
data-general-speed=
"1.0"
data-speed=
"null"
data-start=
"0.0"
data-end=
"0.0"
data-caption-asset-path=
"/c4x/AndyA/ABT101/asset/subs_"
data-autoplay=
"False"
data-yt-test-timeout=
"1500"
data-yt-test-url=
"https://
gdata.youtube.com/feeds/api
/videos/"
data-autohide-html5=
"False"
tabindex=
"-1"
>
<div
id=
"video_i4x-AndyA-ABT101-video-72b5a0d74e8c4ed4a4d4e6bf67837c09"
class=
"video closed is-initialized"
data-streams=
"1.00:OEoXaMPEzfM"
data-save-state-url=
"/preview/xblock/i4x:;_;_AndyA;_ABT101;_video;_72b5a0d74e8c4ed4a4d4e6bf67837c09/handler/xmodule_handler/save_user_state"
data-caption-data-dir=
"None"
data-show-captions=
"true"
data-general-speed=
"1.0"
data-speed=
"null"
data-start=
"0.0"
data-end=
"0.0"
data-caption-asset-path=
"/c4x/AndyA/ABT101/asset/subs_"
data-autoplay=
"False"
data-yt-test-timeout=
"1500"
data-yt-test-url=
"https://
www.googleapis.com/youtube/v3
/videos/"
data-autohide-html5=
"False"
tabindex=
"-1"
>
<div
class=
"focus_grabber first"
tabindex=
"-1"
></div>
<div
class=
"tc-wrapper"
>
...
...
common/djangoapps/terrain/setup_prereqs.py
View file @
7dfd567c
...
...
@@ -28,8 +28,7 @@ SERVICES = {
YOUTUBE_API_URLS
=
{
'main'
:
'https://www.youtube.com/'
,
'player'
:
'http://www.youtube.com/iframe_api'
,
'metadata'
:
'http://gdata.youtube.com/feeds/api/videos/'
,
'player'
:
'https://www.youtube.com/iframe_api'
,
# For transcripts, you need to check an actual video, so we will
# just specify our default video and see if that one is available.
'transcript'
:
'http://video.google.com/timedtext?lang=en&v=OEoXaMPEzfM'
,
...
...
common/djangoapps/terrain/stubs/youtube.py
View file @
7dfd567c
...
...
@@ -95,6 +95,9 @@ class StubYouTubeHandler(StubHttpRequestHandler):
if
self
.
server
.
config
.
get
(
'youtube_api_blocked'
):
self
.
send_response
(
404
,
content
=
''
,
headers
=
{
'Content-type'
:
'text/plain'
})
else
:
# Delay the response to simulate network latency
time
.
sleep
(
self
.
server
.
config
.
get
(
'time_to_response'
,
self
.
DEFAULT_DELAY_SEC
))
# Get the response to send from YouTube.
# We need to do this every time because Google sometimes sends different responses
# as part of their own experiments, which has caused our tests to become "flaky"
...
...
@@ -117,17 +120,16 @@ class StubYouTubeHandler(StubHttpRequestHandler):
# Construct the response content
callback
=
self
.
get_params
[
'callback'
]
youtube_metadata
=
json
.
loads
(
requests
.
get
(
"http://gdata.youtube.com/feeds/api/videos/{id}?v=2&alt=jsonc"
.
format
(
id
=
youtube_id
)
)
.
text
)
data
=
OrderedDict
({
'data'
:
OrderedDict
({
'id'
:
youtube_id
,
'message'
:
message
,
'duration'
:
youtube_metadata
[
'data'
][
'duration'
],
})
'items'
:
list
(
OrderedDict
({
'contentDetails'
:
OrderedDict
({
'id'
:
youtube_id
,
'duration'
:
'PT2M20S'
,
})
})
)
})
response
=
"{cb}({data})"
.
format
(
cb
=
callback
,
data
=
json
.
dumps
(
data
))
...
...
common/lib/xmodule/xmodule/js/fixtures/video.html
View file @
7dfd567c
...
...
@@ -4,7 +4,7 @@
<div
id=
"video_id"
class=
"video closed"
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": "[]", "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/"}'
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": "[]", "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/"}'
>
<div
class=
"focus_grabber first"
></div>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_all.html
View file @
7dfd567c
...
...
@@ -4,7 +4,7 @@
<div
id=
"video_id"
class=
"video closed"
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/"}'
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/"}'
>
<div
class=
"focus_grabber first"
></div>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_html5.html
View file @
7dfd567c
...
...
@@ -4,7 +4,7 @@
<div
id=
"video_id"
class=
"video closed"
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"]}'
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/", "source": "", "html5_sources": ["http://youtu.be/3_yD_cEKoCk.mp4"]}'
>
<div
class=
"focus_grabber first"
></div>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_no_captions.html
View file @
7dfd567c
...
...
@@ -4,7 +4,7 @@
<div
id=
"video_id"
class=
"video closed"
data-metadata=
'{"streams":"0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "showCaptions": false, "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "speed": "1.5", "startTime": "", "end": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/"}'
data-metadata=
'{"streams":"0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "showCaptions": false, "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "speed": "1.5", "startTime": "", "end": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/"}'
>
<div
class=
"focus_grabber first"
></div>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_with_bumper.html
View file @
7dfd567c
...
...
@@ -4,7 +4,7 @@
<div
id=
"video_id"
class=
"video closed"
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/"}'
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "", "sub": "Z5KLxerq05Y", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/"}'
data-bumper-metadata=
'{"transcriptLanguage": "en", "showCaptions": "true", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "transcriptTranslationUrl": "/transcript/translation/__lang__/?is_bumper=1", "transcriptAvailableTranslationsUrl": "/transcript/available_translations/?is_bumper=1", "streams": "", "saveStateUrl": "/save_user_state"}'
data-poster=
'{"url": "xmodule/include/fixtures/poster.jpg", "type": "youtube"}'
>
...
...
common/lib/xmodule/xmodule/js/fixtures/video_yt_multiple.html
View file @
7dfd567c
...
...
@@ -4,7 +4,7 @@
<div
id=
"video_id1"
class=
"video closed"
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/"}'
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.5", "startTime": "", "streams": "0.5:7tqY6eQzVhE,1.0:cogebirgzzM,1.5:abcdefghijkl", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/"}'
>
<div
class=
"focus_grabber first"
></div>
...
...
@@ -38,7 +38,7 @@
<div
id=
"video_id2"
class=
"video"
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/"}'
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/"}'
>
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
...
...
@@ -68,7 +68,7 @@
<div
id=
"video_id3"
class=
"video"
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
TestUrl": "gdata.youtube.com/feeds/api
/videos/"}'
data-metadata=
'{"autohideHtml5": "true", "autoplay": "false", "captionDataDir": "", "endTime": "", "generalSpeed": "1.0", "saveStateUrl": "/save_user_state", "savedVideoPosition": "0", "showCaptions": "true", "sources": ["xmodule/include/fixtures/test.mp4","xmodule/include/fixtures/test.webm","xmodule/include/fixtures/test.ogv"], "speed": "1.0", "startTime": "", "streams": "0.75:7tqY6eQzVhE,1.0:cogebirgzzM", "sub": "", "transcriptAvailableTranslationsUrl": "/transcript/available_translations", "transcriptLanguage": "en", "transcriptLanguages": {"en": "English", "de": "Deutsch", "zh": "普通话"}, "transcriptTranslationUrl": "/transcript/translation/__lang__", "ytApiUrl": "www.youtube.com/iframe_api", "ytImageUrl": "", "ytTestTimeout": "1500", "yt
MetadataUrl": "www.googleapis.com/youtube/v3
/videos/"}'
>
<div
class=
"tc-wrapper"
>
<article
class=
"video-wrapper"
>
...
...
common/lib/xmodule/xmodule/js/js_test.yml
View file @
7dfd567c
...
...
@@ -59,6 +59,7 @@ lib_paths:
-
common_static/js/src/utility.js
-
public/js/split_test_staff.js
-
common_static/js/src/accessibility_tools.js
-
common_static/js/vendor/moment.min.js
# Paths to spec (test) JavaScript files
spec_paths
:
...
...
common/lib/xmodule/xmodule/js/spec/helper.js
View file @
7dfd567c
...
...
@@ -36,7 +36,7 @@
return
f
();
}
};
jasmine
.
YT
=
stubbedYT
;
// Stub YouTube API.
window
.
YT
=
stubbedYT
;
...
...
@@ -76,19 +76,27 @@
jasmine
.
stubbedMetadata
=
{
'7tqY6eQzVhE'
:
{
id
:
'7tqY6eQzVhE'
,
duration
:
300
contentDetails
:
{
id
:
'7tqY6eQzVhE'
,
duration
:
'PT5M0S'
}
},
'cogebirgzzM'
:
{
id
:
'cogebirgzzM'
,
duration
:
200
contentDetails
:
{
id
:
'cogebirgzzM'
,
duration
:
'PT3M20S'
}
},
'abcdefghijkl'
:
{
id
:
'abcdefghijkl'
,
duration
:
400
contentDetails
:
{
id
:
'abcdefghijkl'
,
duration
:
'PT6M40S'
}
},
bogus
:
{
duration
:
100
contentDetails
:
{
duration
:
'PT1M40S'
}
}
};
...
...
@@ -122,7 +130,7 @@
}
return
spy
.
andCallFake
(
function
(
settings
)
{
var
match
=
settings
.
url
.
match
(
/
youtube
\.
com
\/
.+
\/
videos
\/(
.+
)\?
v=2&alt=jsonc
/
),
.
match
(
/
googleapis
\.
com
\/
.+
\/
videos
\/\?
id=
(
.+
)
&part=contentDetails
/
),
status
,
callCallback
;
if
(
match
)
{
status
=
match
[
1
].
split
(
'_'
);
...
...
@@ -138,7 +146,7 @@
};
}
else
if
(
settings
.
success
)
{
return
settings
.
success
({
data
:
jasmine
.
stubbedMetadata
[
match
[
1
]]
items
:
jasmine
.
stubbedMetadata
[
match
[
1
]]
});
}
else
{
return
{
...
...
@@ -168,15 +176,6 @@
return
;
}
else
if
(
settings
.
url
===
'/save_user_state'
)
{
return
{
success
:
true
};
}
else
if
(
settings
.
url
===
'http://www.youtube.com/iframe_api'
)
{
// Stub YouTube API.
window
.
YT
=
stubbedYT
;
// Call the callback that must be called when YouTube API is
// loaded. By specification.
window
.
onYouTubeIframeAPIReady
();
return
{
success
:
true
};
}
else
{
throw
'External request attempted for '
+
settings
.
url
+
...
...
@@ -224,6 +223,19 @@
// Stub jQuery.scrollTo module.
$
.
fn
.
scrollTo
=
jasmine
.
createSpy
(
'jQuery.scrollTo'
);
// Stub window.Video.loadYouTubeIFrameAPI()
window
.
Video
.
loadYouTubeIFrameAPI
=
jasmine
.
createSpy
(
'window.Video.loadYouTubeIFrameAPI'
).
andReturn
(
function
(
scriptTag
)
{
var
event
=
document
.
createEvent
(
'Event'
);
if
(
fixture
===
"video.html"
)
{
event
.
initEvent
(
'load'
,
false
,
false
);
}
else
{
event
.
initEvent
(
'error'
,
false
,
false
);
}
scriptTag
.
dispatchEvent
(
event
);
}
);
jasmine
.
initializePlayer
=
function
(
fixture
,
params
)
{
var
state
;
...
...
common/lib/xmodule/xmodule/js/spec/video/general_spec.js
View file @
7dfd567c
...
...
@@ -115,6 +115,12 @@
return
state
.
youtubeApiAvailable
===
true
;
},
'YouTube API is loaded'
,
3000
);
window
.
YT
=
jasmine
.
YT
;
// Call the callback that must be called when YouTube API is
// loaded. By specification.
window
.
onYouTubeIframeAPIReady
();
runs
(
function
()
{
// If YouTube API is not loaded, then the code will should create
// a global callback that will be called by API once it is loaded.
...
...
common/lib/xmodule/xmodule/js/spec/video/initialize_spec.js
View file @
7dfd567c
...
...
@@ -71,10 +71,10 @@ function (Initialize) {
speed
:
'1.50'
,
metadata
:
{
'testId'
:
{
duration
:
400
duration
:
'PT6M40S'
},
'videoId'
:
{
duration
:
100
duration
:
'PT1M40S'
}
},
videos
:
{
...
...
common/lib/xmodule/xmodule/js/src/video/01_initialize.js
View file @
7dfd567c
This diff is collapsed.
Click to expand it.
common/lib/xmodule/xmodule/js/src/video/10_main.js
View file @
7dfd567c
...
...
@@ -160,6 +160,8 @@
youtubeXhr
=
null
;
};
window
.
Video
.
loadYouTubeIFrameAPI
=
initialize
.
prototype
.
loadYouTubeIFrameAPI
;
// Invoke the mock Video constructor so that the elements stored within it can be processed by the real
// `window.Video` constructor.
oldVideo
(
null
,
true
);
...
...
common/lib/xmodule/xmodule/tests/test_video.py
View file @
7dfd567c
...
...
@@ -736,8 +736,8 @@ class VideoDescriptorIndexingTestCase(unittest.TestCase):
# YouTube JavaScript API
'API'
:
'www.youtube.com/iframe_api'
,
# URL to
test YouTube availability
'
TEST_URL'
:
'gdata.youtube.com/feeds/api
/videos/'
,
# URL to
get YouTube metadata
'
METADATA_URL'
:
'www.googleapis.com/youtube/v3
/videos/'
,
# Current youtube api for requesting transcripts.
# For example: http://video.google.com/timedtext?lang=en&v=j_jEn79vS3g.
...
...
common/lib/xmodule/xmodule/video_module/video_module.py
View file @
7dfd567c
...
...
@@ -86,6 +86,7 @@ log = logging.getLogger(__name__)
_
=
lambda
text
:
text
@XBlock.wants
(
'settings'
)
class
VideoModule
(
VideoFields
,
VideoTranscriptsMixin
,
VideoStudentViewHandlers
,
XModule
,
LicenseMixin
):
"""
XML source example:
...
...
@@ -261,6 +262,15 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
cdn_exp_group
=
None
self
.
youtube_streams
=
youtube_streams
or
create_youtube_string
(
self
)
# pylint: disable=W0201
settings_service
=
self
.
runtime
.
service
(
self
,
'settings'
)
yt_api_key
=
None
if
settings_service
:
xblock_settings
=
settings_service
.
get_settings_bucket
(
self
)
if
xblock_settings
and
'YOUTUBE_API_KEY'
in
xblock_settings
:
yt_api_key
=
xblock_settings
[
'YOUTUBE_API_KEY'
]
metadata
=
{
'saveStateUrl'
:
self
.
system
.
ajax_url
+
'/save_user_state'
,
'autoplay'
:
settings
.
FEATURES
.
get
(
'AUTOPLAY_VIDEOS'
,
False
),
...
...
@@ -286,7 +296,9 @@ class VideoModule(VideoFields, VideoTranscriptsMixin, VideoStudentViewHandlers,
'ytTestTimeout'
:
1500
,
'ytApiUrl'
:
settings
.
YOUTUBE
[
'API'
],
'ytTestUrl'
:
settings
.
YOUTUBE
[
'TEST_URL'
],
'ytMetadataUrl'
:
settings
.
YOUTUBE
[
'METADATA_URL'
],
'ytKey'
:
yt_api_key
,
'transcriptTranslationUrl'
:
self
.
runtime
.
handler_url
(
self
,
'transcript'
,
'translation/__lang__'
)
.
rstrip
(
'/?'
),
...
...
common/test/acceptance/tests/helpers.py
View file @
7dfd567c
...
...
@@ -67,8 +67,7 @@ def is_youtube_available():
youtube_api_urls
=
{
'main'
:
'https://www.youtube.com/'
,
'player'
:
'http://www.youtube.com/iframe_api'
,
'metadata'
:
'http://gdata.youtube.com/feeds/api/videos/'
,
'player'
:
'https://www.youtube.com/iframe_api'
,
# For transcripts, you need to check an actual video, so we will
# just specify our default video and see if that one is available.
'transcript'
:
'http://video.google.com/timedtext?lang=en&v=3_yD_cEKoCk'
,
...
...
lms/djangoapps/courseware/features/video.feature
View file @
7dfd567c
...
...
@@ -3,7 +3,7 @@ Feature: LMS.Video component
As a student, I want to view course videos in LMS
# 1
Scenario
:
Verify that each video in
each sub-section includes a transcript for
non-Youtube countries
Scenario
:
Verify that each video in
sub-section includes a transcript for Youtube and
non-Youtube countries
Given
youtube server is up and response time is 2 seconds
And
I am registered for the course
"test_course"
And
I have a
"subs_3_yD_cEKoCk.srt.sjson"
transcript file in assets
...
...
@@ -24,9 +24,9 @@ Feature: LMS.Video component
|
Welcome
to
edX.
|
|
Equal
transcripts
|
When
I open video
"C"
Then
the video has rendered in
"
HTML5
"
mode
Then
the video has rendered in
"
YOUTUBE
"
mode
And
I make sure captions are opened
And
I see
"好 各位同学"
text in the captions
When
I open video
"D"
Then
the video has rendered in
"
HTML5
"
mode
And
the video does not show the captions
Then
the video has rendered in
"
YOUTUBE
"
mode
And
I make sure captions are opened
lms/djangoapps/courseware/tests/test_video_mongo.py
View file @
7dfd567c
...
...
@@ -62,8 +62,9 @@ class TestVideoYouTube(TestVideo):
"transcriptLanguage"
:
"en"
,
"transcriptLanguages"
:
OrderedDict
({
"en"
:
"English"
,
"uk"
:
u"Українська"
}),
"ytTestTimeout"
:
1500
,
"ytApiUrl"
:
"www.youtube.com/iframe_api"
,
"ytTestUrl"
:
"gdata.youtube.com/feeds/api/videos/"
,
"ytApiUrl"
:
"https://www.youtube.com/iframe_api"
,
"ytMetadataUrl"
:
"https://www.googleapis.com/youtube/v3/videos/"
,
"ytKey"
:
None
,
"transcriptTranslationUrl"
:
self
.
item_descriptor
.
xmodule_runtime
.
handler_url
(
self
.
item_descriptor
,
'transcript'
,
'translation/__lang__'
)
.
rstrip
(
'/?'
),
...
...
@@ -139,8 +140,9 @@ class TestVideoNonYouTube(TestVideo):
"transcriptLanguage"
:
"en"
,
"transcriptLanguages"
:
OrderedDict
({
"en"
:
"English"
}),
"ytTestTimeout"
:
1500
,
"ytApiUrl"
:
"www.youtube.com/iframe_api"
,
"ytTestUrl"
:
"gdata.youtube.com/feeds/api/videos/"
,
"ytApiUrl"
:
"https://www.youtube.com/iframe_api"
,
"ytMetadataUrl"
:
"https://www.googleapis.com/youtube/v3/videos/"
,
"ytKey"
:
None
,
"transcriptTranslationUrl"
:
self
.
item_descriptor
.
xmodule_runtime
.
handler_url
(
self
.
item_descriptor
,
'transcript'
,
'translation/__lang__'
)
.
rstrip
(
'/?'
),
...
...
@@ -192,8 +194,9 @@ class TestGetHtmlMethod(BaseTestXmodule):
"transcriptLanguage"
:
"en"
,
"transcriptLanguages"
:
OrderedDict
({
"en"
:
"English"
}),
"ytTestTimeout"
:
1500
,
"ytApiUrl"
:
"www.youtube.com/iframe_api"
,
"ytTestUrl"
:
"gdata.youtube.com/feeds/api/videos/"
,
"ytApiUrl"
:
"https://www.youtube.com/iframe_api"
,
"ytMetadataUrl"
:
"https://www.googleapis.com/youtube/v3/videos/"
,
"ytKey"
:
None
,
"transcriptTranslationUrl"
:
self
.
item_descriptor
.
xmodule_runtime
.
handler_url
(
self
.
item_descriptor
,
'transcript'
,
'translation/__lang__'
)
.
rstrip
(
'/?'
),
...
...
@@ -1181,8 +1184,9 @@ class TestVideoWithBumper(TestVideo):
"transcriptLanguage"
:
"en"
,
"transcriptLanguages"
:
OrderedDict
({
"en"
:
"English"
,
"uk"
:
u"Українська"
}),
"ytTestTimeout"
:
1500
,
"ytApiUrl"
:
"www.youtube.com/iframe_api"
,
"ytTestUrl"
:
"gdata.youtube.com/feeds/api/videos/"
,
"ytApiUrl"
:
"https://www.youtube.com/iframe_api"
,
"ytMetadataUrl"
:
"https://www.googleapis.com/youtube/v3/videos/"
,
"ytKey"
:
None
,
"transcriptTranslationUrl"
:
self
.
item_descriptor
.
xmodule_runtime
.
handler_url
(
self
.
item_descriptor
,
'transcript'
,
'translation/__lang__'
)
.
rstrip
(
'/?'
),
...
...
lms/envs/acceptance.py
View file @
7dfd567c
...
...
@@ -175,8 +175,8 @@ XQUEUE_INTERFACE = {
}
# Point the URL used to test YouTube availability to our stub YouTube server
YOUTUBE
[
'API'
]
=
"127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
TEST_URL'
]
=
"
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'API'
]
=
"
http://
127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
METADATA_URL'
]
=
"http://
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'TEXT_API'
][
'url'
]
=
"127.0.0.1:{0}/test_transcripts_youtube/"
.
format
(
YOUTUBE_PORT
)
if
FEATURES
.
get
(
'ENABLE_COURSEWARE_SEARCH'
)
or
\
...
...
lms/envs/aws.py
View file @
7dfd567c
...
...
@@ -632,6 +632,7 @@ FACEBOOK_APP_ID = AUTH_TOKENS.get("FACEBOOK_APP_ID")
XBLOCK_SETTINGS
=
ENV_TOKENS
.
get
(
'XBLOCK_SETTINGS'
,
{})
XBLOCK_SETTINGS
.
setdefault
(
"VideoDescriptor"
,
{})[
"licensing_enabled"
]
=
FEATURES
.
get
(
"LICENSING"
,
False
)
XBLOCK_SETTINGS
.
setdefault
(
"VideoModule"
,
{})[
'YOUTUBE_API_KEY'
]
=
AUTH_TOKENS
.
get
(
'YOUTUBE_API_KEY'
,
YOUTUBE_API_KEY
)
##### CDN EXPERIMENT/MONITORING FLAGS #####
CDN_VIDEO_URLS
=
ENV_TOKENS
.
get
(
'CDN_VIDEO_URLS'
,
CDN_VIDEO_URLS
)
...
...
lms/envs/bok_choy.py
View file @
7dfd567c
...
...
@@ -131,8 +131,8 @@ FEATURES['ENTRANCE_EXAMS'] = True
# Point the URL used to test YouTube availability to our stub YouTube server
YOUTUBE_PORT
=
9080
YOUTUBE
[
'API'
]
=
"127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
TEST_URL'
]
=
"
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'API'
]
=
"
http://
127.0.0.1:{0}/get_youtube_api/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'
METADATA_URL'
]
=
"http://
127.0.0.1:{0}/test_youtube/"
.
format
(
YOUTUBE_PORT
)
YOUTUBE
[
'TEXT_API'
][
'url'
]
=
"127.0.0.1:{0}/test_transcripts_youtube/"
.
format
(
YOUTUBE_PORT
)
############################# SECURITY SETTINGS ################################
...
...
lms/envs/common.py
View file @
7dfd567c
...
...
@@ -1751,10 +1751,10 @@ EMAIL_OPTIN_MINIMUM_AGE = PARENTAL_CONSENT_AGE_LIMIT
YOUTUBE
=
{
# YouTube JavaScript API
'API'
:
'www.youtube.com/iframe_api'
,
'API'
:
'
https://
www.youtube.com/iframe_api'
,
# URL to
test YouTube availability
'
TEST_URL'
:
'gdata.youtube.com/feeds/api
/videos/'
,
# URL to
get YouTube metadata
'
METADATA_URL'
:
'https://www.googleapis.com/youtube/v3
/videos/'
,
# Current youtube api for requesting transcripts.
# For example: http://video.google.com/timedtext?lang=en&v=j_jEn79vS3g.
...
...
@@ -1768,6 +1768,7 @@ YOUTUBE = {
'IMAGE_API'
:
'http://img.youtube.com/vi/{youtube_id}/0.jpg'
,
# /maxresdefault.jpg for 1920*1080
}
YOUTUBE_API_KEY
=
None
################################### APPS ######################################
INSTALLED_APPS
=
(
...
...
lms/static/js_test.yml
View file @
7dfd567c
...
...
@@ -61,6 +61,7 @@ lib_paths:
-
xmodule_js/common_static/js/vendor/edxnotes/annotator-full.min.js
-
xmodule_js/common_static/js/test/i18n.js
-
xmodule_js/common_static/js/vendor/date.js
-
xmodule_js/common_static/js/vendor/moment.min.js
# Paths to source JavaScript files
src_paths
:
...
...
lms/static/lms/js/require-config.js
View file @
7dfd567c
...
...
@@ -50,6 +50,7 @@
"URI"
:
"js/vendor/URI.min"
,
"string_utils"
:
"js/src/string_utils"
,
"utility"
:
"js/src/utility"
,
"moment"
:
"js/vendor/moment.min"
,
// Files needed by OVA
"annotator"
:
"js/vendor/ova/annotator-full"
,
...
...
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