Skip to content
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

Add ability for direct 3PlayMedia transcripts usage #251

Merged
merged 28 commits into from
Jul 11, 2017

Conversation

wowkalucky
Copy link
Collaborator

@wowkalucky wowkalucky commented Jul 4, 2017

General implementation of direct (streaming) transcripts usage from 3PlayMedia service.

Till the PR VideoXBlock already has ability to use transcripts from 3PlayMedia service. But those '3playmedia' transcripts were used by downloading them into xblock as course assets.
So, if any changes was made on the 3PlayMedia service to mirror those changes on the xblock User should manually perform downloading each time.

The Client requested ability of VideoXBlock to use 3PlayMedia's transcripts directly (so, changes on 3PM service take effect immediately).

And PR adds described functionality.

@codecov
Copy link

codecov bot commented Jul 4, 2017

Codecov Report

Merging #251 into dev will increase coverage by 0.77%.
The diff coverage is 93.36%.

Impacted file tree graph

@@            Coverage Diff            @@
##              dev    #251      +/-   ##
=========================================
+ Coverage   84.12%   84.9%   +0.77%     
=========================================
  Files          41      41              
  Lines        2381    2530     +149     
  Branches       26      26              
=========================================
+ Hits         2003    2148     +145     
- Misses        377     381       +4     
  Partials        1       1
Flag Coverage Δ
#acceptance 88.7% <93.27%> (+0.61%) ⬆️
#unit 83.04% <93.36%> (+0.89%) ⬆️
Impacted Files Coverage Δ
video_xblock/backends/base.py 88.88% <ø> (ø) ⬆️
...deo_xblock/static/js/spec/runtime-handlers-spec.js 100% <ø> (ø) ⬆️
video_xblock/static/js/runtime-handlers.js 100% <ø> (ø) ⬆️
video_xblock/tests/unit/test_backends.py 99.54% <100%> (ø) ⬆️
video_xblock/tests/unit/test_video_xblock.py 100% <100%> (ø) ⬆️
video_xblock/utils.py 97.91% <100%> (+6.61%) ⬆️
...eo_xblock/tests/unit/test_video_xblock_handlers.py 100% <100%> (ø) ⬆️
video_xblock/backends/vimeo.py 98.91% <100%> (ø) ⬆️
video_xblock/tests/unit/test_mixins.py 100% <100%> (ø) ⬆️
video_xblock/constants.py 100% <100%> (ø) ⬆️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 231ce0c...39219f2. Read the comment docs.

@wowkalucky wowkalucky requested a review from z4y4ts July 4, 2017 12:43
@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch 3 times, most recently from c4df361 to a5dfde0 Compare July 5, 2017 09:05
@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch from a5dfde0 to d7dbcea Compare July 5, 2017 09:07
@z4y4ts z4y4ts changed the base branch from master to dev July 5, 2017 12:52
@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch from f605f23 to be8f77e Compare July 5, 2017 18:51
Copy link

@z4y4ts z4y4ts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good in general, few issues need to be addressed before a merge.

@@ -132,8 +132,8 @@ def advanced_fields(self):
"""
return [
'start_time', 'end_time', 'handout', 'transcripts',
'threeplaymedia_file_id', 'threeplaymedia_apikey', 'download_transcript_allowed',
'default_transcripts', 'download_video_allowed', 'download_video_url'
'threeplaymedia_file_id', 'threeplaymedia_apikey', 'direct_enabled',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

direct_enabled -> threeplaymedia_streaming or threeplaymedia_direct_enabled

@@ -58,6 +56,31 @@ class TranscriptsMixin(XBlock):
TranscriptsMixin class to encapsulate transcripts-related logic.
"""

THREE_PLAY_MEDIA_API_DOMAIN = 'https://static.3playmedia.com/'

direct_enabled = Boolean(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

direct_enabled -> threeplaymedia_streaming or threeplaymedia_direct_enabled

direct_enabled = Boolean(
default=False,
display_name=_('Direct 3PlayMedia'),
scope=Scope.settings,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope.content

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. But what if we would like to use 3PM streaming only in one course Unit?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fields are scoped to a single xblock instance. So no problem here.

tran['url'] = self.runtime.handler_url(
self, 'srt_to_vtt', query=tran['url']
self, 'fetch_from_tree_play_media', query="{}={}".format(tran['lang_id'], tran['id'])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tree -> three

)
else:
if not tran['url'].endswith('.vtt'):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if -> elif

transcripts = json.loads(self.transcripts) if self.transcripts else []

for transcript in transcripts:
yield transcript
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This for loop looks useless.
Why don't just return transcripts?



Transcript = namedtuple('Transcript', [
'id', 'label', 'lang', 'lang_id', 'content', 'format', 'video_id', 'source', 'url'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice :)

@@ -369,7 +501,7 @@ def player_state(self):
"""
Return video player state as a dictionary.
"""
transcripts = json.loads(self.transcripts) if self.transcripts else []
transcripts = list(self.get_enabled_transcripts())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking few lines below, this conversion to a list seems redundant.

'use strict';
var isValid = [];
var $visibleLangChoiceItems = $langChoiceItem.find('li:visible');
var urls;
e.preventDefault();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -53,12 +53,11 @@ function getTranscriptUrl(transcriptsArray, langCode) {
/**
* Validate transcript data before save it to video xblock.
*/
function validateTranscripts(e, $langChoiceItem) {
function validateTranscripts($langChoiceItem) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch 5 times, most recently from 24ad935 to 2750ed8 Compare July 6, 2017 11:16
@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch from 2750ed8 to 2488f40 Compare July 6, 2017 11:17
@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch from 1ed0f96 to a37020d Compare July 6, 2017 12:27
@wowkalucky wowkalucky requested a review from auraz July 6, 2017 12:43
auraz
auraz previously requested changes Jul 6, 2017

def get_available_3pm_transcripts(self, file_id, apikey):
"""
Make API request to fetch list of available transcripts for given file ID.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add difference of return types of API in documentation

results = response.json()
else:
results = {"failed": True}
return results
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposal: return response.json(), status

raise StopIteration
for transcript_data in results:
transcript = self.fetch_3pm_translation(transcript_data)
transcript_ordered_dict = transcript._asdict()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Please add test for empty transcript
  2. Think if we need to show this error to user.

for transcript_data in results:
transcript = self.fetch_3pm_translation(transcript_data)
transcript_ordered_dict = transcript._asdict()
transcript_ordered_dict['content'] = '' # we don't want to parse it to JSON
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extend comment.

content = requests.get(external_api_url).text
except Exception: # pylint: disable=broad-except
log.exception(_("Transcript fetching failure: language [{}]").format(TPMApiLanguage(lang_id)))
return
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please think about consistency in corner cases. Here you do return, but in def init(self, language_id): you do raise.

Returns:
webob.Response: WebVTT transcripts wrapped in Response object.
"""
lang_id, tid = request.query_string.split('=')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is tid, please use better naming.


results = self.get_available_3pm_transcripts(file_id, api_key)

is_valid = False if isinstance(results, dict) else True
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix it!

data: JSON.stringify(data)
};

if (!(data.api_key && data.file_id)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add docstring and comment

options
)
.done(function(response) {
message = response.message;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you need message?

*/
function getThreePlayMediaConfig() {
var $apiKey = $('.threeplaymedia-api-key', element).val();
var $fileId = $('#xb-field-edit-threeplaymedia_file_id', element).val();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think you need $ here.

@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch from d4f3283 to c0fbacd Compare July 7, 2017 07:39
@wowkalucky wowkalucky force-pushed the 259-serve-transcripts-and-captions-from-3pm-directly branch from 1662d86 to 17316cf Compare July 7, 2017 12:32
Copy link

@z4y4ts z4y4ts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good in general.
I have only a few concerns here.


DEFAULT_LANG = 'en'

# STATUS - (instance of namedtuple) - may be used like: "STATUS.success", returns status string value.
STATUS = namedtuple('STATUS', ['success', 'error', 'warning'])._make(['success', 'error', 'warning'])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You actually need an enum here, not a namedtuple.
See here

)
}
except Exception: # pylint: disable=broad-except
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, narrow down exception catching.

@XBlock.handler
def validate_three_play_media_config(self, request, _suffix=''):
"""
Handler to validate actuality of provided API credentials.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handler to validate provided API credentials.

"""
api_key = request.json.get('api_key')
file_id = request.json.get('file_id')
streaming_enabled = bool(int(request.json.get('streaming_enabled')))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a docstring saying what values do you expect to receive here.
E.g. # streaming_enabled is expected to be 1 or 0

# Act
normalized_transcripts = normalize_transcripts(test_transcripts)
# Assert
self.assertEqual(test_transcripts, normalized_transcripts)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So essentially, you are checking, that normalization did nothing with the input data.

I think you need to add few more cases. Or change test name to better reflect your intent.

@z4y4ts z4y4ts dismissed auraz’s stale review July 11, 2017 16:38

All points have been addressed

@wowkalucky wowkalucky merged commit d750c68 into dev Jul 11, 2017
@wowkalucky wowkalucky deleted the 259-serve-transcripts-and-captions-from-3pm-directly branch July 11, 2017 18:02
z4y4ts added a commit that referenced this pull request Jul 11, 2017
…nscripts-settings-accordion' and 'feature/transcripts-settings-accordion' of github.com:raccoongang/xblock-video into feature/transcripts-settings-accordion

* 'feature/transcripts-settings-accordion' of github.com:raccoongang/xblock-video:
  Add ability for direct 3PlayMedia transcripts usage (#251)

* 'feature/transcripts-settings-accordion' of github.com:raccoongang/xblock-video:
  Add ability for direct 3PlayMedia transcripts usage (#251)

* 'feature/transcripts-settings-accordion' of github.com:raccoongang/xblock-video:
  Add ability for direct 3PlayMedia transcripts usage (#251)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants