Commit 08c100fa by muhammad-ammar

view to update auto generated images

parent f5f6f36e
......@@ -253,7 +253,7 @@ class ListField(models.TextField):
if len(value) > LIST_MAX_ITEMS:
raise ValidationError(u'list must not contain more than {} items.'.format(LIST_MAX_ITEMS))
if all(isinstance(item, str) for item in value) is False:
if all(isinstance(item, basestring) for item in value) is False:
raise ValidationError(u'list must only contain strings.')
return value
......@@ -268,18 +268,21 @@ class VideoImage(TimeStampedModel):
generated_images = ListField()
@classmethod
def create_or_update(cls, course_video, file_name, image_data=None):
def create_or_update(cls, course_video, file_name=None, image_data=None, generated_images=None):
"""
Create a VideoImage object for a CourseVideo.
NOTE: If `image_data` is None then `file_name` value will be used as it is, otherwise
a new file name is constructed based on uuid and extension from `file_name` value.
`image_data` will be None in case of course re-run and export.
`image_data` will be None in case of course re-run and export. `generated_images` list
contains names of images auto generated by VEDA. If an image is not already set then first
image name from `generated_images` list will be used.
Arguments:
course_video (CourseVideo): CourseVideo instance
file_name (str): File name of the image
image_data (InMemoryUploadedFile): Image data to be saved.
generated_images (list): auto generated image names
Returns:
Returns a tuple of (video_image, created).
......@@ -305,6 +308,11 @@ class VideoImage(TimeStampedModel):
)
raise
else:
if generated_images:
video_image.generated_images = generated_images
if not video_image.image.name:
file_name = generated_images[0]
video_image.image.name = file_name
video_image.save()
......
......@@ -2,6 +2,8 @@
"""
Tests for Video Abstraction Layer views
"""
from ddt import ddt, data, unpack
from django.core.urlresolvers import reverse
from rest_framework import status
......@@ -794,3 +796,76 @@ class SubtitleDetailTest(APIAuthTestCase):
url, video_subtitles, format='json'
)
self.assertEqual(self.client.get(video_subtitles['content_url']).content, '{"start": "00:00:00"}')
@ddt
class VideoImagesViewTest(APIAuthTestCase):
"""
Tests VideoImage update requests.
"""
def setUp(self):
"""
Used for manually creating profile objects which EncodedVideos require.
"""
self.course_id = 'test_course_id'
self.video = Video.objects.create(**constants.VIDEO_DICT_FISH)
self.course_video = CourseVideo.objects.create(video=self.video, course_id=self.course_id)
super(VideoImagesViewTest, self).setUp()
def test_update_auto_generated_images(self):
"""
Tests POSTing generated images successfully.
"""
generated_images = ['video-images/a.png', 'video-images/b.png', 'video-images/c.png']
url = reverse('update-video-images')
response = self.client.post(
url,
{'course_id': self.course_id, 'generated_images': generated_images},
format='json'
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.course_video.video_image.image.name, generated_images[0])
self.assertEqual(self.course_video.video_image.generated_images, generated_images)
# verify that if we post again then `VideoImage.image.name` should not be updated
# but `VideoImage.generated_images` should be updated with new names.
new_generated_images = ['a.png', 'b.png', 'c.png']
response = self.client.post(
url,
{'course_id': self.course_id, 'generated_images': new_generated_images},
format='json'
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.course_video.video_image.image.name, generated_images[0])
course_video = CourseVideo.objects.get(video=self.video, course_id=self.course_id)
self.assertEqual(course_video.video_image.generated_images, new_generated_images)
@data(
{
'post_data': {},
'message': u'course_id and generated_images must be specified to update a video image.'
},
{
'post_data': {'course_id': 'does_not_exit_course', 'generated_images': []},
'message': u'CourseVideo not found for course_id: does_not_exit_course'
},
{
'post_data': {'course_id': 'test_course_id', 'generated_images': [1, 2, 3]},
'message': "[u'list must only contain strings.']"
},
)
@unpack
def test_update_error_responses(self, post_data, message):
"""
Tests error responses occurred during POSTing.
"""
url = reverse('update-video-images')
response = self.client.post(url, post_data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
response.data['message'],
message
)
......@@ -28,4 +28,9 @@ urlpatterns = patterns(
views.get_subtitle,
name="subtitle-content"
),
url(
r'^videos/video-images/update/$',
views.VideoImagesView.as_view(),
name='update-video-images'
),
)
"""
Views file for django app edxval.
"""
from rest_framework.views import APIView
from rest_framework import generics
from rest_framework.authentication import SessionAuthentication
from rest_framework_oauth.authentication import OAuth2Authentication
from rest_framework.permissions import DjangoModelPermissions
from rest_framework.response import Response
from rest_framework import status
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.core.exceptions import ValidationError
from django.views.decorators.http import last_modified
from edxval.models import Video, Profile, Subtitle
from edxval.models import Video, Profile, Subtitle, CourseVideo, VideoImage
from edxval.serializers import (
VideoSerializer,
SubtitleSerializer
......@@ -99,6 +103,52 @@ class SubtitleDetail(MultipleFieldLookupMixin, generics.RetrieveUpdateDestroyAPI
serializer_class = SubtitleSerializer
class VideoImagesView(APIView):
"""
View to update course video images.
"""
authentication_classes = (OAuth2Authentication, SessionAuthentication)
def post(self, request):
"""
Update a course video image instance with auto generated image names.
"""
attrs = ('course_id', 'generated_images')
missing = [attr for attr in attrs if attr not in request.data]
if missing:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
'message': u'{missing} must be specified to update a video image.'.format(
missing=' and '.join(missing)
)
}
)
course_id = request.data['course_id']
generated_images = request.data['generated_images']
try:
course_video = CourseVideo.objects.select_related('video_image').get(
course_id=unicode(course_id)
)
except CourseVideo.DoesNotExist:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={'message': u'CourseVideo not found for course_id: {course_id}'.format(course_id=course_id)}
)
try:
VideoImage.create_or_update(course_video, generated_images=generated_images)
except ValidationError as ex:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={'message': str(ex)}
)
return Response()
def _last_modified_subtitle(request, edx_video_id, language): # pylint: disable=W0613
"""
Returns the last modified subtitle
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment