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
OpenEdx
edx-platform
Commits
7aac4a60
Commit
7aac4a60
authored
Dec 18, 2017
by
Qubad786
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Download transcript on video upload page - EDUCATOR-1853
parent
333842a3
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
158 additions
and
6 deletions
+158
-6
cms/djangoapps/contentstore/views/tests/test_transcript_settings.py
+82
-0
cms/djangoapps/contentstore/views/transcript_settings.py
+50
-3
cms/djangoapps/contentstore/views/videos.py
+5
-1
cms/static/js/factories/videos_index.js
+2
-0
cms/static/js/views/previous_video_upload.js
+2
-1
cms/static/js/views/previous_video_upload_list.js
+1
-0
cms/static/js/views/video_transcripts.js
+2
-0
cms/templates/js/video-transcripts.underscore
+11
-1
cms/urls.py
+2
-0
requirements/edx/github.txt
+1
-0
No files found.
cms/djangoapps/contentstore/views/tests/test_transcript_settings.py
View file @
7aac4a60
...
@@ -169,3 +169,85 @@ class TranscriptCredentialsValidationTest(TestCase):
...
@@ -169,3 +169,85 @@ class TranscriptCredentialsValidationTest(TestCase):
# Assert the results.
# Assert the results.
self
.
assertEqual
(
error_message
,
expected_error_message
)
self
.
assertEqual
(
error_message
,
expected_error_message
)
self
.
assertDictEqual
(
validated_credentials
,
expected_validated_credentials
)
self
.
assertDictEqual
(
validated_credentials
,
expected_validated_credentials
)
@ddt.ddt
@patch
(
'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled'
,
Mock
(
return_value
=
True
)
)
class
TranscriptDownloadTest
(
CourseTestCase
):
"""
Tests for transcript download handler.
"""
VIEW_NAME
=
'transcript_download_handler'
def
get_url_for_course_key
(
self
,
course_id
):
return
reverse_course_url
(
self
.
VIEW_NAME
,
course_id
)
def
test_302_with_anonymous_user
(
self
):
"""
Verify that redirection happens in case of unauthorized request.
"""
self
.
client
.
logout
()
transcript_download_url
=
self
.
get_url_for_course_key
(
self
.
course
.
id
)
response
=
self
.
client
.
get
(
transcript_download_url
,
content_type
=
'application/json'
)
self
.
assertEqual
(
response
.
status_code
,
302
)
def
test_405_with_not_allowed_request_method
(
self
):
"""
Verify that 405 is returned in case of not-allowed request methods.
Allowed request methods include GET.
"""
transcript_download_url
=
self
.
get_url_for_course_key
(
self
.
course
.
id
)
response
=
self
.
client
.
post
(
transcript_download_url
,
content_type
=
'application/json'
)
self
.
assertEqual
(
response
.
status_code
,
405
)
def
test_404_with_feature_disabled
(
self
):
"""
Verify that 404 is returned if the corresponding feature is disabled.
"""
transcript_download_url
=
self
.
get_url_for_course_key
(
self
.
course
.
id
)
with
patch
(
'openedx.core.djangoapps.video_config.models.VideoTranscriptEnabledFlag.feature_enabled'
)
as
feature
:
feature
.
return_value
=
False
response
=
self
.
client
.
get
(
transcript_download_url
,
content_type
=
'application/json'
)
self
.
assertEqual
(
response
.
status_code
,
404
)
@patch
(
'contentstore.views.transcript_settings.get_video_transcript_data'
)
def
test_transcript_download_handler
(
self
,
mock_get_video_transcript_data
):
"""
Tests that transcript download handler works as expected.
"""
transcript_download_url
=
self
.
get_url_for_course_key
(
self
.
course
.
id
)
mock_get_video_transcript_data
.
return_value
=
{
'content'
:
json
.
dumps
({
"start"
:
[
10
],
"end"
:
[
100
],
"text"
:
[
"Hi, welcome to Edx."
],
}),
'file_name'
:
'edx.sjson'
}
# Make request to transcript download handler
response
=
self
.
client
.
get
(
transcript_download_url
,
data
=
{
'edx_video_id'
:
'123'
,
'language_code'
:
'en'
},
content_type
=
'application/json'
)
# Expected response
expected_content
=
u'0
\n
00:00:00,010 --> 00:00:00,100
\n
Hi, welcome to Edx.
\n\n
'
expected_headers
=
{
'Content-Disposition'
:
'attachment; filename="edx.srt"'
,
'Content-Language'
:
u'en'
,
'Content-Type'
:
'application/x-subrip; charset=utf-8'
}
# Assert the actual response
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
content
,
expected_content
)
for
attribute
,
value
in
expected_headers
.
iteritems
():
self
.
assertEqual
(
response
.
get
(
attribute
),
value
)
cms/djangoapps/contentstore/views/transcript_settings.py
View file @
7aac4a60
"""
"""
Views related to the transcript preferences feature
Views related to the transcript preferences feature
"""
"""
import
os
from
django.contrib.auth.decorators
import
login_required
from
django.contrib.auth.decorators
import
login_required
from
django.http
import
HttpResponseNotFound
from
django.http
import
HttpResponseNotFound
,
HttpResponse
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.views.decorators.http
import
require_POST
from
django.views.decorators.http
import
require_POST
,
require_GET
from
edxval.api
import
(
from
edxval.api
import
(
get_3rd_party_transcription_plans
,
get_3rd_party_transcription_plans
,
get_video_transcript_data
,
update_transcript_credentials_state_for_org
,
update_transcript_credentials_state_for_org
,
)
)
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
...
@@ -16,8 +19,9 @@ from openedx.core.djangoapps.video_pipeline.api import update_3rd_party_transcri
...
@@ -16,8 +19,9 @@ from openedx.core.djangoapps.video_pipeline.api import update_3rd_party_transcri
from
util.json_request
import
JsonResponse
,
expect_json
from
util.json_request
import
JsonResponse
,
expect_json
from
contentstore.views.videos
import
TranscriptProvider
from
contentstore.views.videos
import
TranscriptProvider
from
xmodule.video_module.transcripts_utils
import
Transcript
__all__
=
[
'transcript_credentials_handler'
]
__all__
=
[
'transcript_credentials_handler'
,
'transcript_download_handler'
]
class
TranscriptionProviderErrorType
:
class
TranscriptionProviderErrorType
:
...
@@ -108,3 +112,46 @@ def transcript_credentials_handler(request, course_key_string):
...
@@ -108,3 +112,46 @@ def transcript_credentials_handler(request, course_key_string):
response
=
JsonResponse
({
'error'
:
error_message
},
status
=
400
)
response
=
JsonResponse
({
'error'
:
error_message
},
status
=
400
)
return
response
return
response
@expect_json
@login_required
@require_GET
def
transcript_download_handler
(
request
,
course_key_string
):
"""
JSON view handler to download a transcript.
Arguments:
request: WSGI request object
course_key_string: course key
filename: Name of the to be created transcript file
Returns:
- A 200 response with SRT transcript file attached.
- A 400 if there is a validation error.
- A 404 if there is no such transcript or feature flag is disabled.
"""
course_key
=
CourseKey
.
from_string
(
course_key_string
)
if
not
VideoTranscriptEnabledFlag
.
feature_enabled
(
course_key
):
return
HttpResponseNotFound
()
edx_video_id
=
request
.
GET
.
get
(
'edx_video_id'
)
if
not
edx_video_id
:
return
JsonResponse
({
'error'
:
'edx_video_id is required.'
},
status
=
400
)
language_code
=
request
.
GET
.
get
(
'language_code'
)
if
not
language_code
:
return
JsonResponse
({
'error'
:
'language code is required.'
},
status
=
400
)
transcript
=
get_video_transcript_data
(
video_ids
=
[
edx_video_id
],
language_code
=
language_code
)
if
transcript
:
basename
,
__
=
os
.
path
.
splitext
(
transcript
[
'file_name'
])
transcript_filename
=
'{base_name}.srt'
.
format
(
base_name
=
basename
.
encode
(
'utf8'
))
transcript_content
=
Transcript
.
convert
(
transcript
[
'content'
],
input_format
=
'sjson'
,
output_format
=
'srt'
)
# Construct an HTTP response
response
=
HttpResponse
(
transcript_content
,
content_type
=
Transcript
.
mime_types
[
'srt'
])
response
[
'Content-Disposition'
]
=
'attachment; filename="{filename}"'
.
format
(
filename
=
transcript_filename
)
else
:
response
=
HttpResponseNotFound
()
return
response
cms/djangoapps/contentstore/views/videos.py
View file @
7aac4a60
...
@@ -642,7 +642,11 @@ def videos_index_html(course):
...
@@ -642,7 +642,11 @@ def videos_index_html(course):
'transcript_credentials_handler'
,
'transcript_credentials_handler'
,
unicode
(
course
.
id
)
unicode
(
course
.
id
)
),
),
'transcription_plans'
:
get_3rd_party_transcription_plans
(),
'transcript_download_handler_url'
:
reverse_course_url
(
'transcript_download_handler'
,
unicode
(
course
.
id
)
),
'transcription_plans'
:
get_3rd_party_transcription_plans
()
}
}
context
[
'active_transcript_preferences'
]
=
get_transcript_preferences
(
unicode
(
course
.
id
))
context
[
'active_transcript_preferences'
]
=
get_transcript_preferences
(
unicode
(
course
.
id
))
# Cached state for transcript providers' credentials (org-specific)
# Cached state for transcript providers' credentials (org-specific)
...
...
cms/static/js/factories/videos_index.js
View file @
7aac4a60
...
@@ -53,6 +53,7 @@ define([
...
@@ -53,6 +53,7 @@ define([
collection
:
updatedCollection
,
collection
:
updatedCollection
,
encodingsDownloadUrl
:
encodingsDownloadUrl
,
encodingsDownloadUrl
:
encodingsDownloadUrl
,
videoImageSettings
:
videoImageSettings
,
videoImageSettings
:
videoImageSettings
,
videoTranscriptSettings
:
videoTranscriptSettings
,
transcriptAvailableLanguages
:
transcriptAvailableLanguages
,
transcriptAvailableLanguages
:
transcriptAvailableLanguages
,
videoSupportedFileFormats
:
videoSupportedFileFormats
,
videoSupportedFileFormats
:
videoSupportedFileFormats
,
isVideoTranscriptEnabled
:
isVideoTranscriptEnabled
isVideoTranscriptEnabled
:
isVideoTranscriptEnabled
...
@@ -68,6 +69,7 @@ define([
...
@@ -68,6 +69,7 @@ define([
collection
:
new
Backbone
.
Collection
(
previousUploads
),
collection
:
new
Backbone
.
Collection
(
previousUploads
),
encodingsDownloadUrl
:
encodingsDownloadUrl
,
encodingsDownloadUrl
:
encodingsDownloadUrl
,
videoImageSettings
:
videoImageSettings
,
videoImageSettings
:
videoImageSettings
,
videoTranscriptSettings
:
videoTranscriptSettings
,
transcriptAvailableLanguages
:
transcriptAvailableLanguages
,
transcriptAvailableLanguages
:
transcriptAvailableLanguages
,
videoSupportedFileFormats
:
videoSupportedFileFormats
,
videoSupportedFileFormats
:
videoSupportedFileFormats
,
isVideoTranscriptEnabled
:
isVideoTranscriptEnabled
isVideoTranscriptEnabled
:
isVideoTranscriptEnabled
...
...
cms/static/js/views/previous_video_upload.js
View file @
7aac4a60
...
@@ -36,7 +36,8 @@ define(
...
@@ -36,7 +36,8 @@ define(
edxVideoID
:
this
.
model
.
get
(
'edx_video_id'
),
edxVideoID
:
this
.
model
.
get
(
'edx_video_id'
),
clientVideoID
:
this
.
model
.
get
(
'client_video_id'
),
clientVideoID
:
this
.
model
.
get
(
'client_video_id'
),
transcriptAvailableLanguages
:
options
.
transcriptAvailableLanguages
,
transcriptAvailableLanguages
:
options
.
transcriptAvailableLanguages
,
videoSupportedFileFormats
:
options
.
videoSupportedFileFormats
videoSupportedFileFormats
:
options
.
videoSupportedFileFormats
,
videoTranscriptSettings
:
options
.
videoTranscriptSettings
});
});
}
}
},
},
...
...
cms/static/js/views/previous_video_upload_list.js
View file @
7aac4a60
...
@@ -17,6 +17,7 @@ define(
...
@@ -17,6 +17,7 @@ define(
defaultVideoImageURL
:
options
.
defaultVideoImageURL
,
defaultVideoImageURL
:
options
.
defaultVideoImageURL
,
videoHandlerUrl
:
options
.
videoHandlerUrl
,
videoHandlerUrl
:
options
.
videoHandlerUrl
,
videoImageSettings
:
options
.
videoImageSettings
,
videoImageSettings
:
options
.
videoImageSettings
,
videoTranscriptSettings
:
options
.
videoTranscriptSettings
,
model
:
model
,
model
:
model
,
transcriptAvailableLanguages
:
options
.
transcriptAvailableLanguages
,
transcriptAvailableLanguages
:
options
.
transcriptAvailableLanguages
,
videoSupportedFileFormats
:
options
.
videoSupportedFileFormats
,
videoSupportedFileFormats
:
options
.
videoSupportedFileFormats
,
...
...
cms/static/js/views/video_transcripts.js
View file @
7aac4a60
...
@@ -20,6 +20,7 @@ define(
...
@@ -20,6 +20,7 @@ define(
this
.
clientVideoID
=
options
.
clientVideoID
;
this
.
clientVideoID
=
options
.
clientVideoID
;
this
.
transcriptAvailableLanguages
=
options
.
transcriptAvailableLanguages
;
this
.
transcriptAvailableLanguages
=
options
.
transcriptAvailableLanguages
;
this
.
videoSupportedFileFormats
=
options
.
videoSupportedFileFormats
;
this
.
videoSupportedFileFormats
=
options
.
videoSupportedFileFormats
;
this
.
videoTranscriptSettings
=
options
.
videoTranscriptSettings
;
this
.
template
=
HtmlUtils
.
template
(
videoTranscriptsTemplate
);
this
.
template
=
HtmlUtils
.
template
(
videoTranscriptsTemplate
);
},
},
...
@@ -90,6 +91,7 @@ define(
...
@@ -90,6 +91,7 @@ define(
transcriptAvailableLanguages
:
this
.
sortByValue
(
this
.
transcriptAvailableLanguages
),
transcriptAvailableLanguages
:
this
.
sortByValue
(
this
.
transcriptAvailableLanguages
),
edxVideoID
:
this
.
edxVideoID
,
edxVideoID
:
this
.
edxVideoID
,
transcriptClientTitle
:
this
.
getTranscriptClientTitle
(),
transcriptClientTitle
:
this
.
getTranscriptClientTitle
(),
transcriptDownloadHandlerUrl
:
this
.
videoTranscriptSettings
.
transcript_download_handler_url
,
transcriptDownloadFileFormat
:
TRANSCRIPT_DOWNLOAD_FILE_FORMAT
transcriptDownloadFileFormat
:
TRANSCRIPT_DOWNLOAD_FILE_FORMAT
})
})
);
);
...
...
cms/templates/js/video-transcripts.underscore
View file @
7aac4a60
...
@@ -21,7 +21,17 @@
...
@@ -21,7 +21,17 @@
<% }) %>
<% }) %>
</select>
</select>
<div class='transcript-actions'>
<div class='transcript-actions'>
<button class="button-link download-transcript-button" data-edx-video-id="<%- edxVideoID %>" data-language-code="<%- transcriptLanguageCode %>">
<a
class="button-link download-transcript-button"
href="<%- StringUtils.interpolate(
'{transcriptDownloadHandlerUrl}?edx_video_id={edxVideoID}&language_code={transcriptLanguageCode}',
{
transcriptDownloadHandlerUrl: transcriptDownloadHandlerUrl,
edxVideoID: edxVideoID,
transcriptLanguageCode: transcriptLanguageCode
}
) %>"
>
<%- gettext('Download') %>
<%- gettext('Download') %>
</button>
</button>
<span class='transcript-actions-separator'> | </span>
<span class='transcript-actions-separator'> | </span>
...
...
cms/urls.py
View file @
7aac4a60
...
@@ -142,6 +142,8 @@ urlpatterns = [
...
@@ -142,6 +142,8 @@ urlpatterns = [
contentstore
.
views
.
transcript_preferences_handler
,
name
=
'transcript_preferences_handler'
),
contentstore
.
views
.
transcript_preferences_handler
,
name
=
'transcript_preferences_handler'
),
url
(
r'^transcript_credentials/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
url
(
r'^transcript_credentials/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
contentstore
.
views
.
transcript_credentials_handler
,
name
=
'transcript_credentials_handler'
),
contentstore
.
views
.
transcript_credentials_handler
,
name
=
'transcript_credentials_handler'
),
url
(
r'^transcript_download/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
contentstore
.
views
.
transcript_download_handler
,
name
=
'transcript_download_handler'
),
url
(
r'^video_encodings_download/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
url
(
r'^video_encodings_download/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
contentstore
.
views
.
video_encodings_download
,
name
=
'video_encodings_download'
),
contentstore
.
views
.
video_encodings_download
,
name
=
'video_encodings_download'
),
url
(
r'^group_configurations/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
url
(
r'^group_configurations/{}$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
...
...
requirements/edx/github.txt
View file @
7aac4a60
...
@@ -101,6 +101,7 @@ git+https://github.com/edx/xblock-utils.git@v1.0.5#egg=xblock-utils==1.0.5
...
@@ -101,6 +101,7 @@ git+https://github.com/edx/xblock-utils.git@v1.0.5#egg=xblock-utils==1.0.5
git+https://github.com/edx/edx-user-state-client.git@1.0.2#egg=edx-user-state-client==1.0.2
git+https://github.com/edx/edx-user-state-client.git@1.0.2#egg=edx-user-state-client==1.0.2
git+https://github.com/edx/xblock-lti-consumer.git@v1.1.6#egg=lti_consumer-xblock==1.1.6
git+https://github.com/edx/xblock-lti-consumer.git@v1.1.6#egg=lti_consumer-xblock==1.1.6
git+https://github.com/edx/edx-proctoring.git@1.3.1#egg=edx-proctoring==1.3.1
git+https://github.com/edx/edx-proctoring.git@1.3.1#egg=edx-proctoring==1.3.1
-e git+https://github.com/edx/edx-val.git@mrehan/download-transcripts-on-upload-page#egg=edxval
# This is here because all of the other XBlocks are located here. However, it is published to PyPI and will be installed that way
# This is here because all of the other XBlocks are located here. However, it is published to PyPI and will be installed that way
xblock-review==1.1.2
xblock-review==1.1.2
...
...
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