-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Video editor supports transcripts [FC-0076] #36058
base: master
Are you sure you want to change the base?
feat: Video editor supports transcripts [FC-0076] #36058
Conversation
* Add error handler on save video to avoid create sjson * Support transcripts without edx_video_id in definition_to_xml
Thanks for the pull request, @ChrisChV! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.
|
This is used to be retroactive in copy-paste videos from Library to Course and Course to Library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @ChrisChV , this is working well for the most part, good job dealing with the old transcript code!
But I found a bug with the upstream/downstream syncing, and left a few nits/change requests too.
@@ -616,6 +630,24 @@ def _import_file_into_course( | |||
if thumbnail_content is not None: | |||
content.thumbnail_location = thumbnail_location | |||
contentstore().save(content) | |||
if usage_key.block_type == 'video': | |||
# Adding transcripts to VAL using the nex edx_video_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: typo
# Adding transcripts to VAL using the nex edx_video_id | |
# Adding transcripts to VAL using the new edx_video_id |
response = self.replace_transcript(self.library_block.usage_key, self.youtube_id) | ||
|
||
# Verify the response | ||
self.assert_response(response, expected_status_code=200, expected_message='Success') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also test that the transcript is replaced as expected?
@@ -81,13 +84,17 @@ def link_video_to_component(video_component, user): | |||
edx_video_id = clean_video_id(video_component.edx_video_id) | |||
if not edx_video_id: | |||
edx_video_id = create_external_video(display_name='external video') | |||
|
|||
if isinstance(video_component.usage_key, UsageKeyV2): | |||
return edx_video_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why we're returning early here.. Could you add a comment to clarify?
except NotFoundError: | ||
log.debug("Can't find transcripts in storage for youtube id: %s", youtube_id) | ||
|
||
#check youtube local and server transcripts for equality |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: pylint should have caught this?
#check youtube local and server transcripts for equality | |
# check youtube local and server transcripts for equality |
edx_video_id, | ||
input_format, | ||
transcript_content, | ||
language_code='en', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you're dealing with the old transcripts code here, which is really convoluted.. but why is the language code hard-coded here (and below on save_video_transcript
)? A comment would help :)
@@ -1952,3 +1952,6 @@ def import_blocks_create_task(library_key, course_key, use_course_key_as_block_i | |||
log.info(f"Import block task created: import_task={import_task} " | |||
f"celery_task={result.id}") | |||
return import_task | |||
|
|||
# To enable use content library permissions as public API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: grammar
# To enable use content library permissions as public API | |
# Allow content library permissions to be used in the public API |
except AttributeError: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this error need to be caught now? Seems a little dangerous.
@@ -497,6 +498,7 @@ def studio_transcript(self, request, dispatch): | |||
""" | |||
_ = self.runtime.service(self, "i18n").ugettext | |||
|
|||
# pylint: disable=too-many-nested-blocks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: pylint is not wrong :/
Could this massive method be refactored into _studio_transcript_upload
, _studio_transcript_delete
, and _studio_transcript_get
? Unless that means we have to add more tests..
transcript_file_path = f"static/{self.transcripts.pop(language, None)}" | ||
lib_api.delete_library_block_static_asset_file(self.scope_ids.usage_id, transcript_file_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If transcript_file_path == "static/None"
, I think delete_library_block_static_asset_file
raises a validation error. By contrast, the remove_subs_from_store
method just passes if the transcript file isn't found.
So maybe we should check for that here (at the risk of enraging pylint further..):
transcript_file_path = f"static/{self.transcripts.pop(language, None)}" | |
lib_api.delete_library_block_static_asset_file(self.scope_ids.usage_id, transcript_file_path) | |
transcript_path = self.transcripts.pop(language, None) | |
if transcript_path: | |
lib_api.delete_library_block_static_asset_file(self.scope_ids.usage_id, f"static/{transcript_path}") |
@@ -10,6 +10,7 @@ | |||
import re |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm seeing a bug when I sync a LibraryBlock video with transcripts from an upstream video.
Steps to reproduce:
- Create a library video with transcripts (here, I imported them from the example youtube video).
- Publish the library video.
- Copy it to the clipboard.
- Paste into a course.
Note that the transcripts are displaying fine here. - Re-edit the library video, and replace a transcript. (Here, I replaced the English one, I don't know if replacing others causes the same issue).
- Return to the course LibraryBlock, and refresh to see the "updates available" button. Click it.
Note that the upstream video preview shows its transcripts fine, but the downstream (course) video preview doesn't show its transcripts anymore. - Accept changes.
Note that the course video no longer shows its transcripts, but if you edit it, you can see they're still there.
Description
edx_video_id
indefinition_to_xml
edx_video_id
Supporting information
Testing instructions
Follow the testing instructions at: openedx/frontend-app-authoring#1596
Deadline
No rush
Other information
library component
in a course. This will be fixed in Copy static assets when using a library component in a course (via Problem Bank or Library Content) modular-learning#246