From 438ce5f7a4bbe27c4c740f98787a8b8d7e427dab Mon Sep 17 00:00:00 2001 From: Greg Price Date: Mon, 23 Mar 2015 14:45:17 -0400 Subject: [PATCH] Add web-only setting to video module This is needed for courses that license video content where the license allows only for viewing on the web, not on mobile apps. JIRA: MA-307 --- .../contentstore/features/video_editor.py | 1 + .../xmodule/video_module/video_xfields.py | 9 ++++ .../acceptance/pages/studio/video/video.py | 1 + .../mobile_api/video_outlines/serializers.py | 26 +++++++++-- .../mobile_api/video_outlines/tests.py | 43 +++++++++++++++++++ 5 files changed, 76 insertions(+), 4 deletions(-) diff --git a/cms/djangoapps/contentstore/features/video_editor.py b/cms/djangoapps/contentstore/features/video_editor.py index a26e4bfbcc..353d716708 100644 --- a/cms/djangoapps/contentstore/features/video_editor.py +++ b/cms/djangoapps/contentstore/features/video_editor.py @@ -152,6 +152,7 @@ def correct_video_settings(_step): ['Show Transcript', 'True', False], ['Transcript Languages', '', False], ['Upload Handout', '', False], + ['Video Available on Web Only', 'False', False], ['Video Download Allowed', 'False', False], ['Video File URLs', '', False], ['Video Start Time', '00:00:00', False], diff --git a/common/lib/xmodule/xmodule/video_module/video_xfields.py b/common/lib/xmodule/xmodule/video_module/video_xfields.py index 47f6383d28..c943e32a2e 100644 --- a/common/lib/xmodule/xmodule/video_module/video_xfields.py +++ b/common/lib/xmodule/xmodule/video_module/video_xfields.py @@ -150,6 +150,15 @@ class VideoFields(object): display_name=_("Upload Handout"), scope=Scope.settings, ) + only_on_web = Boolean( + help=_( + "Specify whether access to this video is limited to browsers only, or if it can be " + "accessed from other applications including mobile apps." + ), + display_name="Video Available on Web Only", + scope=Scope.settings, + default=False + ) edx_video_id = String( help=_("If you were assigned a Video ID by edX for the video to play in this component, enter the ID here. In this case, do not enter values in the Default Video URL, the Video File URLs, and the YouTube ID fields. If you were not assigned an edX Video ID, enter values in those other fields and ignore this field."), display_name=_("EdX Video ID"), diff --git a/common/test/acceptance/pages/studio/video/video.py b/common/test/acceptance/pages/studio/video/video.py index 9d5dd6abb2..10fdfe1cae 100644 --- a/common/test/acceptance/pages/studio/video/video.py +++ b/common/test/acceptance/pages/studio/video/video.py @@ -64,6 +64,7 @@ DEFAULT_SETTINGS = [ ['Show Transcript', 'True', False], ['Transcript Languages', '', False], ['Upload Handout', '', False], + ['Video Available on Web Only', 'False', False], ['Video Download Allowed', 'False', False], ['Video File URLs', '', False], ['Video Start Time', '00:00:00', False], diff --git a/lms/djangoapps/mobile_api/video_outlines/serializers.py b/lms/djangoapps/mobile_api/video_outlines/serializers.py index 76ed9b972e..e5c6b24dae 100644 --- a/lms/djangoapps/mobile_api/video_outlines/serializers.py +++ b/lms/djangoapps/mobile_api/video_outlines/serializers.py @@ -179,6 +179,25 @@ def video_summary(course, course_id, video_descriptor, request, local_cache): """ returns summary dict for the given video module """ + always_available_data = { + "name": video_descriptor.display_name, + "category": video_descriptor.category, + "id": unicode(video_descriptor.scope_ids.usage_id), + "only_on_web": video_descriptor.only_on_web, + } + + if video_descriptor.only_on_web: + ret = { + "video_url": None, + "video_thumbnail_url": None, + "duration": 0, + "size": 0, + "transcripts": {}, + "language": None, + } + ret.update(always_available_data) + return ret + # First try to check VAL for the URLs we want. val_video_info = local_cache['course_videos'].get(video_descriptor.edx_video_id, {}) if val_video_info: @@ -209,14 +228,13 @@ def video_summary(course, course_id, video_descriptor, request, local_cache): for lang in transcript_langs } - return { + ret = { "video_url": video_url, "video_thumbnail_url": None, "duration": duration, "size": size, - "name": video_descriptor.display_name, "transcripts": transcripts, "language": video_descriptor.get_default_transcript_language(), - "category": video_descriptor.category, - "id": unicode(video_descriptor.scope_ids.usage_id), } + ret.update(always_available_data) + return ret diff --git a/lms/djangoapps/mobile_api/video_outlines/tests.py b/lms/djangoapps/mobile_api/video_outlines/tests.py index c9ec4a7bc9..45707bbcf2 100644 --- a/lms/djangoapps/mobile_api/video_outlines/tests.py +++ b/lms/djangoapps/mobile_api/video_outlines/tests.py @@ -362,6 +362,46 @@ class TestVideoSummaryList(TestVideoAPITestCase, MobileAuthTestMixin, MobileEnro """ REVERSE_INFO = {'name': 'video-summary-list', 'params': ['course_id']} + def test_only_on_web(self): + self.login_and_enroll() + + course_outline = self.api_response().data + self.assertEqual(len(course_outline), 0) + + subid = uuid4().hex + transcripts_utils.save_subs_to_store( + { + 'start': [100], + 'end': [200], + 'text': [ + 'subs #1', + ] + }, + subid, + self.course) + + ItemFactory.create( + parent=self.unit, + category="video", + display_name=u"test video", + only_on_web=True, + subid=subid + ) + + course_outline = self.api_response().data + + self.assertEqual(len(course_outline), 1) + + self.assertIsNone(course_outline[0]["summary"]["video_url"]) + self.assertIsNone(course_outline[0]["summary"]["video_thumbnail_url"]) + self.assertEqual(course_outline[0]["summary"]["duration"], 0) + self.assertEqual(course_outline[0]["summary"]["size"], 0) + self.assertEqual(course_outline[0]["summary"]["name"], "test video") + self.assertEqual(course_outline[0]["summary"]["transcripts"], {}) + self.assertIsNone(course_outline[0]["summary"]["language"]) + self.assertEqual(course_outline[0]["summary"]["category"], "video") + self.assertTrue(course_outline[0]["summary"]["only_on_web"]) + def test_course_list(self): self.login_and_enroll() self._create_video_with_subs() @@ -394,13 +434,16 @@ class TestVideoSummaryList(TestVideoAPITestCase, MobileAuthTestMixin, MobileEnro self.assertEqual(vid['summary']['video_url'], self.video_url) self.assertEqual(vid['summary']['size'], 12345) self.assertTrue('en' in vid['summary']['transcripts']) + self.assertFalse(vid['summary']['only_on_web']) self.assertEqual(course_outline[1]['summary']['video_url'], self.html5_video_url) self.assertEqual(course_outline[1]['summary']['size'], 0) + self.assertFalse(course_outline[1]['summary']['only_on_web']) self.assertEqual(course_outline[1]['path'][2]['name'], self.other_unit.display_name) self.assertEqual(course_outline[1]['path'][2]['id'], unicode(self.other_unit.location)) self.assertEqual(course_outline[2]['summary']['video_url'], self.html5_video_url) self.assertEqual(course_outline[2]['summary']['size'], 0) + self.assertFalse(course_outline[2]['summary']['only_on_web']) def test_with_nameless_unit(self): self.login_and_enroll()