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
d32a434d
Commit
d32a434d
authored
Nov 23, 2017
by
muhammad-ammar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
video component basic tab upload transcript to S3
EDUCATOR-1758
parent
dd2f90fb
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
42 additions
and
17 deletions
+42
-17
cms/djangoapps/contentstore/views/tests/test_transcripts.py
+26
-11
cms/djangoapps/contentstore/views/transcripts_ajax.py
+16
-6
No files found.
cms/djangoapps/contentstore/views/tests/test_transcripts.py
View file @
d32a434d
...
@@ -21,6 +21,7 @@ from xmodule.contentstore.django import contentstore
...
@@ -21,6 +21,7 @@ from xmodule.contentstore.django import contentstore
from
xmodule.exceptions
import
NotFoundError
from
xmodule.exceptions
import
NotFoundError
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.video_module
import
transcripts_utils
from
xmodule.video_module
import
transcripts_utils
from
edxval
import
api
as
edxval_api
TEST_DATA_CONTENTSTORE
=
copy
.
deepcopy
(
settings
.
CONTENTSTORE
)
TEST_DATA_CONTENTSTORE
=
copy
.
deepcopy
(
settings
.
CONTENTSTORE
)
TEST_DATA_CONTENTSTORE
[
'DOC_STORE_CONFIG'
][
'db'
]
=
'test_xcontent_
%
s'
%
uuid4
()
.
hex
TEST_DATA_CONTENTSTORE
[
'DOC_STORE_CONFIG'
][
'db'
]
=
'test_xcontent_
%
s'
%
uuid4
()
.
hex
...
@@ -106,11 +107,11 @@ class TestUploadTranscripts(BaseTranscripts):
...
@@ -106,11 +107,11 @@ class TestUploadTranscripts(BaseTranscripts):
self
.
good_srt_file
=
tempfile
.
NamedTemporaryFile
(
suffix
=
'.srt'
)
self
.
good_srt_file
=
tempfile
.
NamedTemporaryFile
(
suffix
=
'.srt'
)
self
.
good_srt_file
.
write
(
textwrap
.
dedent
(
"""
self
.
good_srt_file
.
write
(
textwrap
.
dedent
(
"""
1
0
00:00:10,500 --> 00:00:13,000
00:00:10,500 --> 00:00:13,000
Elephant's Dream
Elephant's Dream
2
1
00:00:15,000 --> 00:00:18,000
00:00:15,000 --> 00:00:18,000
At the left we can see...
At the left we can see...
"""
))
"""
))
...
@@ -134,6 +135,25 @@ class TestUploadTranscripts(BaseTranscripts):
...
@@ -134,6 +135,25 @@ class TestUploadTranscripts(BaseTranscripts):
self
.
ufeff_srt_file
=
tempfile
.
NamedTemporaryFile
(
suffix
=
'.srt'
)
self
.
ufeff_srt_file
=
tempfile
.
NamedTemporaryFile
(
suffix
=
'.srt'
)
def
assert_transcript_upload
(
self
,
filename
,
expected_transcript_content
):
"""
Verify that transcript is uploaded as expected
"""
# verify that transcript should not be in contentstore
content_location
=
StaticContent
.
compute_location
(
self
.
course
.
id
,
'subs_{0}.srt.sjson'
.
format
(
filename
))
with
self
.
assertRaises
(
NotFoundError
)
as
item_not_found
:
contentstore
()
.
find
(
content_location
)
# verify uploaded transcript content
transcript_data
=
edxval_api
.
get_video_transcript_data
([
filename
],
'en'
)
sjson_transcript
=
transcript_data
[
'content'
]
uploaded_transcript_content
=
transcripts_utils
.
Transcript
.
convert
(
sjson_transcript
,
input_format
=
'sjson'
,
output_format
=
'srt'
)
self
.
assertIn
(
expected_transcript_content
.
strip
(),
uploaded_transcript_content
.
strip
())
def
test_success_video_module_source_subs_uploading
(
self
):
def
test_success_video_module_source_subs_uploading
(
self
):
self
.
item
.
data
=
textwrap
.
dedent
(
"""
self
.
item
.
data
=
textwrap
.
dedent
(
"""
<video youtube="">
<video youtube="">
...
@@ -161,9 +181,9 @@ class TestUploadTranscripts(BaseTranscripts):
...
@@ -161,9 +181,9 @@ class TestUploadTranscripts(BaseTranscripts):
item
=
modulestore
()
.
get_item
(
self
.
video_usage_key
)
item
=
modulestore
()
.
get_item
(
self
.
video_usage_key
)
self
.
assertEqual
(
item
.
sub
,
filename
)
self
.
assertEqual
(
item
.
sub
,
filename
)
content_location
=
StaticContent
.
compute_location
(
# move the file pointer to start of the file
self
.
course
.
id
,
'subs_{0}.srt.sjson'
.
format
(
filename
)
)
self
.
good_srt_file
.
seek
(
0
)
self
.
assert
True
(
contentstore
()
.
find
(
content_location
))
self
.
assert
_transcript_upload
(
filename
,
self
.
good_srt_file
.
read
(
))
def
test_fail_data_without_id
(
self
):
def
test_fail_data_without_id
(
self
):
link
=
reverse
(
'upload_transcripts'
)
link
=
reverse
(
'upload_transcripts'
)
...
@@ -346,12 +366,7 @@ class TestUploadTranscripts(BaseTranscripts):
...
@@ -346,12 +366,7 @@ class TestUploadTranscripts(BaseTranscripts):
})
})
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
content_location
=
StaticContent
.
compute_location
(
self
.
assert_transcript_upload
(
filename
,
'Test ufeff characters'
)
self
.
course
.
id
,
'subs_{0}.srt.sjson'
.
format
(
filename
))
self
.
assertTrue
(
contentstore
()
.
find
(
content_location
))
subs_text
=
json
.
loads
(
contentstore
()
.
find
(
content_location
)
.
data
)
.
get
(
'text'
)
self
.
assertIn
(
"Test ufeff characters"
,
subs_text
)
def
tearDown
(
self
):
def
tearDown
(
self
):
super
(
TestUploadTranscripts
,
self
)
.
tearDown
()
super
(
TestUploadTranscripts
,
self
)
.
tearDown
()
...
...
cms/djangoapps/contentstore/views/transcripts_ajax.py
View file @
d32a434d
...
@@ -14,6 +14,7 @@ import requests
...
@@ -14,6 +14,7 @@ import requests
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.core.exceptions
import
PermissionDenied
from
django.core.exceptions
import
PermissionDenied
from
django.core.files.base
import
ContentFile
from
django.http
import
Http404
,
HttpResponse
from
django.http
import
Http404
,
HttpResponse
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
...
@@ -40,6 +41,7 @@ from xmodule.video_module.transcripts_utils import (
...
@@ -40,6 +41,7 @@ from xmodule.video_module.transcripts_utils import (
TranscriptsRequestValidationException
,
TranscriptsRequestValidationException
,
youtube_video_transcript_name
,
youtube_video_transcript_name
,
)
)
from
edxval
import
api
as
edxval_api
__all__
=
[
__all__
=
[
'upload_transcripts'
,
'upload_transcripts'
,
...
@@ -119,16 +121,24 @@ def upload_transcripts(request):
...
@@ -119,16 +121,24 @@ def upload_transcripts(request):
if
video_list
:
if
video_list
:
sub_attr
=
source_subs_name
sub_attr
=
source_subs_name
try
:
try
:
# Generate
and save for 1.0 speed, will create subs_sub_attr.srt.sjson subtitles file in storage.
# Generate
sjson subtitles from srt substitles
generate_subs_from_source
({
1
:
sub_attr
},
source_subs_ext
,
source_subs_filedata
,
item
)
sjson_subs
=
generate_subs_from_source
({
},
source_subs_ext
,
source_subs_filedata
,
item
)
for
video_dict
in
video_list
:
for
video_dict
in
video_list
:
video_name
=
video_dict
[
'video'
]
video_name
=
video_dict
[
'video'
]
# We are creating transcripts for every video source, if in future some of video sources would be deleted.
# We are creating transcripts for every video source in case a video source is deleted in future.
# Updates item.sub with `video_name` on success.
edxval_api
.
create_or_update_video_transcript
(
copy_or_rename_transcript
(
video_name
,
sub_attr
,
item
,
user
=
request
.
user
)
video_id
=
video_name
,
language_code
=
'en'
,
file_name
=
'subs.sjson'
,
# S3 filename will be `uuid.sjson` like 5d30d3e44cebacf6163976388cae.sjson
file_format
=
'sjson'
,
provider
=
'Custom'
,
file_data
=
ContentFile
(
json
.
dumps
(
sjson_subs
)),
)
response
[
'subs'
]
=
item
.
sub
item
.
sub
=
video_name
item
.
save_with_metadata
(
request
.
user
)
response
[
'subs'
]
=
video_name
response
[
'status'
]
=
'Success'
response
[
'status'
]
=
'Success'
except
Exception
as
ex
:
except
Exception
as
ex
:
return
error_response
(
response
,
ex
.
message
)
return
error_response
(
response
,
ex
.
message
)
...
...
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