Commit 28993bd5 by Nimisha Asthagiri

Support for studio-based Video Pipeline.

Allow "colon" in edx-video_ids.
Added get_videos_for_ids method.
Added status and created fields.
parent e39fcbc8
......@@ -2,7 +2,7 @@ edx-val
=======
Note:
The naming convetion for the `profile_name` in `Profile` objects will be the
The naming convention for the `profile_name` in `Profile` objects will be the
medium of the profile (a-z), an underscore, and then the quality (a-z).
Examples:
......
......@@ -129,6 +129,7 @@ def get_video_info(edx_video_id, location=None): # pylint: disable=W0613
{
url: api url to the video
edx_video_id: ID of the video
status: Status of the video as a string
duration: Length of video in seconds
client_video_id: client ID of video
encoded_video: a list of EncodedVideo dicts
......@@ -211,6 +212,13 @@ def get_videos_for_course(course_id):
videos = Video.objects.filter(courses__course_id=unicode(course_id))
return (VideoSerializer(video).data for video in videos)
def get_videos_for_ids(edx_video_ids):
"""
Returns an iterator of videos that match the given list of ids
"""
videos = Video.objects.filter(edx_video_id__in=edx_video_ids)
return (VideoSerializer(video).data for video in videos)
def get_video_info_for_course_and_profile(course_id, profile_name):
"""Returns a dict mapping profiles to URLs.
......
......@@ -85,7 +85,7 @@ class Migration(SchemaMigration):
models = {
'edxval.coursevideos': {
'edxval.coursevideo': {
'Meta': {'unique_together': "(('course_id', 'video'),)", 'object_name': 'CourseVideo'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
......
......@@ -24,7 +24,7 @@ class Migration(DataMigration):
).delete()
models = {
'edxval.coursevideos': {
'edxval.coursevideo': {
'Meta': {'unique_together': "(('course_id', 'video'),)", 'object_name': 'CourseVideo'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
......
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Video.created'
db.add_column('edxval_video', 'created',
self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, default=datetime.datetime(2014, 11, 17, 0, 0), blank=True),
keep_default=False)
# Adding field 'Video.status'
db.add_column('edxval_video', 'status',
self.gf('django.db.models.fields.CharField')(default='File Complete', max_length=255, db_index=True),
keep_default=False)
# Changing field 'Video.edx_video_id'
db.alter_column('edxval_video', 'edx_video_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100))
# Changing field 'EncodedVideo.url'
db.alter_column('edxval_encodedvideo', 'url', self.gf('django.db.models.fields.CharField')(max_length=200))
def backwards(self, orm):
# Deleting field 'Video.created'
db.delete_column('edxval_video', 'created')
# Deleting field 'Video.status'
db.delete_column('edxval_video', 'status')
# Changing field 'Video.edx_video_id'
db.alter_column('edxval_video', 'edx_video_id', self.gf('django.db.models.fields.CharField')(max_length=50, unique=True))
# Changing field 'EncodedVideo.url'
db.alter_column('edxval_encodedvideo', 'url', self.gf('django.db.models.fields.URLField')(max_length=200))
models = {
'edxval.coursevideo': {
'Meta': {'unique_together': "(('course_id', 'video'),)", 'object_name': 'CourseVideo'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'video': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'courses'", 'to': "orm['edxval.Video']"})
},
'edxval.encodedvideo': {
'Meta': {'object_name': 'EncodedVideo'},
'bitrate': ('django.db.models.fields.PositiveIntegerField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'file_size': ('django.db.models.fields.PositiveIntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'profile': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['edxval.Profile']"}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'video': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'encoded_videos'", 'to': "orm['edxval.Video']"})
},
'edxval.profile': {
'Meta': {'object_name': 'Profile'},
'extension': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
'height': ('django.db.models.fields.PositiveIntegerField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'profile_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'}),
'width': ('django.db.models.fields.PositiveIntegerField', [], {})
},
'edxval.subtitle': {
'Meta': {'object_name': 'Subtitle'},
'content': ('django.db.models.fields.TextField', [], {'default': "''"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'fmt': ('django.db.models.fields.CharField', [], {'max_length': '20', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'max_length': '8', 'db_index': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'video': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subtitles'", 'to': "orm['edxval.Video']"})
},
'edxval.video': {
'Meta': {'object_name': 'Video'},
'client_video_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'duration': ('django.db.models.fields.FloatField', [], {}),
'edx_video_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
}
}
complete_apps = ['edxval']
\ No newline at end of file
......@@ -32,7 +32,7 @@ from django.core.validators import MinValueValidator, RegexValidator
from django.core.urlresolvers import reverse
URL_REGEX = r'^[a-zA-Z0-9\-_]*$'
URL_REGEX = r'^[a-zA-Z0-9\-_\:]*$'
class Profile(models.Model):
......@@ -68,8 +68,9 @@ class Video(models.Model):
A video can have multiple formats. This model are the fields that represent
the collection of those videos that do not change across formats.
"""
created = models.DateTimeField(auto_now_add=True)
edx_video_id = models.CharField(
max_length=50,
max_length=100,
unique=True,
validators=[
RegexValidator(
......@@ -81,6 +82,7 @@ class Video(models.Model):
)
client_video_id = models.CharField(max_length=255, db_index=True, blank=True)
duration = models.FloatField(validators=[MinValueValidator(0)])
status = models.CharField(max_length=255, db_index=True)
def get_absolute_url(self):
"""
......
......@@ -45,6 +45,7 @@ VIDEO_DICT_NEGATIVE_DURATION = dict(
client_video_id="Thunder Cats S01E01",
duration=-111,
edx_video_id="thisis12char-thisis7",
status="test",
encoded_videos=[],
subtitles=[]
)
......@@ -52,11 +53,13 @@ VIDEO_DICT_BEE_INVALID = dict(
client_video_id="Barking Bee",
duration=111.00,
edx_video_id="wa/sps",
status="test",
)
VIDEO_DICT_INVALID_ID = dict(
client_video_id="SuperSloth",
duration=42,
edx_video_id="sloppy/sloth!!",
status="test",
encoded_videos=[],
subtitles=[]
)
......@@ -77,6 +80,7 @@ VIDEO_DICT_NON_LATIN_TITLE = dict(
client_video_id=u"배고픈 햄스터",
duration=42,
edx_video_id="ID",
status="test",
encoded_videos=[],
subtitles=[]
)
......@@ -84,6 +88,7 @@ VIDEO_DICT_NON_LATIN_ID = dict(
client_video_id="Hungry Hamster",
duration=42,
edx_video_id="밥줘",
status="test",
encoded_videos=[],
subtitles=[]
)
......@@ -140,12 +145,14 @@ Fish
VIDEO_DICT_FISH = dict(
client_video_id="Shallow Swordfish",
duration=122.00,
edx_video_id="super-soaker"
edx_video_id="super-soaker",
status="test",
)
VIDEO_DICT_DIFFERENT_ID_FISH = dict(
client_video_id="Shallow Swordfish",
duration=122.00,
edx_video_id="medium-soaker"
edx_video_id="medium-soaker",
status="test",
)
ENCODED_VIDEO_DICT_FISH_MOBILE = dict(
url="https://www.swordsingers.com",
......@@ -242,6 +249,7 @@ COMPLETE_SET_INVALID_VIDEO_FISH = dict(
client_video_id="Shallow Swordfish",
duration=122.00,
edx_video_id="super/soaker",
status="test",
encoded_videos=[
ENCODED_VIDEO_DICT_FISH_MOBILE,
ENCODED_VIDEO_DICT_FISH_DESKTOP
......@@ -259,7 +267,8 @@ Star
VIDEO_DICT_STAR = dict(
client_video_id="TWINKLE TWINKLE",
duration=122.00,
edx_video_id="little-star"
edx_video_id="little-star",
status="test",
)
ENCODED_VIDEO_DICT_STAR = dict(
url="https://www.howIwonder.com",
......@@ -317,6 +326,7 @@ VIDEO_DICT_ZEBRA = dict(
client_video_id="Zesty Zebra",
duration=111.00,
edx_video_id="zestttt",
status="test",
encoded_videos=[],
subtitles=[]
)
......@@ -324,6 +334,7 @@ VIDEO_DICT_ANIMAL = dict(
client_video_id="Average Animal",
duration=111.00,
edx_video_id="mediocrity",
status="test",
encoded_videos=[],
subtitles=[]
)
......@@ -331,6 +342,7 @@ VIDEO_DICT_UPDATE_ANIMAL = dict(
client_video_id="Above Average Animal",
duration=999.00,
edx_video_id="mediocrity",
status="test",
encoded_videos=[],
subtitles=[]
)
......@@ -161,6 +161,17 @@ class GetVideoInfoTest(TestCase):
videos = list(api.get_videos_for_course('unknown'))
self.assertEqual(len(videos), 0)
def test_get_videos_for_ids(self):
"""
Tests retrieving videos for ids
"""
edx_video_id = constants.VIDEO_DICT_FISH['edx_video_id']
videos = list(api.get_videos_for_ids([edx_video_id]))
self.assertEqual(len(videos), 1)
self.assertEqual(videos[0]['edx_video_id'], edx_video_id)
videos = list(api.get_videos_for_ids(['unknown']))
self.assertEqual(len(videos), 0)
def test_no_such_video(self):
"""
Tests searching for a video that does not exist
......
......@@ -513,6 +513,7 @@ class VideoListTest(APIAuthTestCase):
"""
video = {
'edx_video_id': 'testing-youtube',
'status': 'test',
'encoded_videos': [
{
'profile': 'youtube',
......
......@@ -14,17 +14,17 @@ urlpatterns = patterns(
name="video-list"
),
url(
r'^videos/(?P<edx_video_id>[-\w]+)$',
r'^videos/(?P<edx_video_id>[-\:\w]+)$',
views.VideoDetail.as_view(),
name="video-detail"
),
url(
r'^videos/(?P<video__edx_video_id>[-\w]+)/(?P<language>[-_\w]+)$',
r'^videos/(?P<video__edx_video_id>[-\:\w]+)/(?P<language>[-_\w]+)$',
views.SubtitleDetail.as_view(),
name="subtitle-detail"
),
url(
r'^videos/(?P<edx_video_id>[-\w]+)/(?P<language>[-_\w]+)/subtitle$',
r'^videos/(?P<edx_video_id>[-\:\w]+)/(?P<language>[-_\w]+)/subtitle$',
views.get_subtitle,
name="subtitle-content"
),
......
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