forked from openedx/edx-val
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Created models for Video, EncodedVideo, and Profile. Added function to return a serialized video object, with it's associated EncodedVideo objects. Other Notes: -Added djangorestframework==2.3.5 -Added Travis -Added mock==1.0.1 -Added django-nose==1.2 -Added coverage==3.7.1
- Loading branch information
christopher lee
committed
Aug 4, 2014
1 parent
15736e0
commit 2bb8cd0
Showing
17 changed files
with
725 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
*.py[cod] | ||
|
||
*.db | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Packages | ||
*.egg | ||
*.egg-info | ||
dist | ||
build | ||
eggs | ||
parts | ||
bin | ||
var | ||
sdist | ||
develop-eggs | ||
.installed.cfg | ||
lib64 | ||
__pycache__ | ||
|
||
# Various common editor backups | ||
*.orig | ||
.*.swp | ||
|
||
# Installer logs | ||
pip-log.txt | ||
|
||
# Unit test / coverage reports | ||
.coverage | ||
.tox | ||
nosetests.xml | ||
htmlcov | ||
coverage.xml | ||
|
||
# Mr Developer | ||
.mr.developer.cfg | ||
.project | ||
.pydevproject | ||
|
||
# Sass/Codekit | ||
.sass-cache/ | ||
config.codekit | ||
|
||
# some mac thing | ||
.DS_Store | ||
|
||
# PyCharm | ||
.idea | ||
|
||
# node | ||
node_modules | ||
npm-debug.log | ||
coverage | ||
|
||
# tim-specific | ||
ora2db | ||
storage/* | ||
openassessment/xblock/static/js/fixtures/*.html | ||
|
||
# logging | ||
logs/*/*.log* | ||
|
||
# Vagrant | ||
.vagrant |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from django.contrib import admin | ||
from .models import Video, Profile, EncodedVideo | ||
|
||
admin.site.register(Video) | ||
admin.site.register(Profile) | ||
admin.site.register(EncodedVideo) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
The internal API for VAL | ||
""" | ||
import logging | ||
|
||
from edxval.models import Video | ||
from edxval.serializers import EncodedVideoSetSerializer | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ValError(Exception): | ||
""" | ||
An error that occurs during VAL actions. | ||
This error is raised when the VAL API cannot perform a requested | ||
action. | ||
""" | ||
pass | ||
|
||
|
||
class ValInternalError(ValError): | ||
""" | ||
An error internal to the VAL API has occurred. | ||
This error is raised when an error occurs that is not caused by incorrect | ||
use of the API, but rather internal implementation of the underlying | ||
services. | ||
""" | ||
pass | ||
|
||
|
||
class ValVideoNotFoundError(ValError): | ||
""" | ||
This error is raised when a video is not found | ||
If a state is specified in a call to the API that results in no matching | ||
entry in database, this error may be raised. | ||
""" | ||
pass | ||
|
||
|
||
def get_video_info(edx_video_id, location=None): | ||
""" | ||
Retrieves all encoded videos of a video found with given video edx_video_id | ||
Args: | ||
location (str): geographic locations used determine CDN | ||
edx_video_id (str): id for video content. | ||
Returns: | ||
result (dict): Deserialized Video Object with related field EncodedVideo | ||
Returns all the Video object fields, and it's related EncodedVideo | ||
objects in a list. | ||
{ | ||
edx_video_id: ID of the video | ||
duration: Length of video in seconds | ||
client_title: human readable ID | ||
encoded_video: a list of EncodedVideo dicts | ||
url: url of the video | ||
file_size: size of the video in bytes | ||
profile: a dict of encoding details | ||
profile_name: ID of the profile | ||
extension: 3 letter extension of video | ||
width: horizontal pixel resolution | ||
height: vertical pixel resolution | ||
} | ||
Raises: | ||
ValVideoNotFoundError: Raised if video doesn't exist | ||
ValInternalError: Raised for unknown errors | ||
Example: | ||
Given one EncodedVideo with edx_video_id "thisis12char-thisis7" | ||
>>> | ||
>>> get_video_info("thisis12char-thisis7",location) | ||
Returns (dict): | ||
>>>{ | ||
>>> 'edx_video_id': u'thisis12char-thisis7', | ||
>>> 'duration': 111.0, | ||
>>> 'client_title': u'Thunder Cats S01E01', | ||
>>> 'encoded_video': [ | ||
>>> { | ||
>>> 'url': u'http://www.meowmix.com', | ||
>>> 'file_size': 25556, | ||
>>> 'bitrate': 9600, | ||
>>> 'profile': { | ||
>>> 'profile_name': u'mobile', | ||
>>> 'extension': u'avi', | ||
>>> 'width': 100, | ||
>>> 'height': 101 | ||
>>> } | ||
>>> }, | ||
>>> ] | ||
>>>} | ||
""" | ||
try: | ||
v = Video.objects.get(edx_video_id=edx_video_id) | ||
result = EncodedVideoSetSerializer(v) | ||
except Video.DoesNotExist: | ||
error_message = u"Video not found for edx_video_id: {0}".format(edx_video_id) | ||
raise ValVideoNotFoundError(error_message) | ||
except Exception: | ||
error_message = u"Could not get edx_video_id: {0}".format(edx_video_id) | ||
logger.exception(error_message) | ||
raise ValInternalError(error_message) | ||
return result.data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
""" | ||
Django models for videos for Video Abstraction Layer (VAL) | ||
""" | ||
|
||
from django.db import models | ||
|
||
|
||
class Profile(models.Model): | ||
""" | ||
Details for pre-defined encoding format | ||
""" | ||
profile_name = models.CharField(max_length=50, unique=True) | ||
extension = models.CharField(max_length=10) | ||
width = models.PositiveIntegerField() | ||
height = models.PositiveIntegerField() | ||
|
||
def __repr__(self): | ||
return ( | ||
u"Profile(profile_name={0.profile_name})" | ||
).format(self) | ||
|
||
def __unicode__(self): | ||
return repr(self) | ||
|
||
|
||
class Video(models.Model): | ||
""" | ||
Model for a Video group with the same content. | ||
A video can have multiple formats. This model is the collection of those | ||
videos with fields that do not change across formats. | ||
""" | ||
edx_video_id = models.CharField(max_length=50, unique=True) | ||
client_title = models.CharField(max_length=255, db_index=True) | ||
duration = models.FloatField() | ||
|
||
def __repr__(self): | ||
return ( | ||
u"Video(client_title={0.client_title}, duration={0.duration})" | ||
).format(self) | ||
|
||
def __unicode__(self): | ||
return repr(self) | ||
|
||
|
||
class CourseVideos(models.Model): | ||
""" | ||
Model for the course_id associated with the video content. | ||
Every course-semester has a unique course_id. A video can be paired with multiple | ||
course_id's but each pair is unique together. | ||
""" | ||
course_id = models.CharField(max_length=255) | ||
video = models.ForeignKey(Video) | ||
|
||
class Meta: | ||
unique_together = ("course_id", "video") | ||
|
||
|
||
class EncodedVideo(models.Model): | ||
""" | ||
Video/encoding pair | ||
""" | ||
created = models.DateTimeField(auto_now_add=True) | ||
modified = models.DateTimeField(auto_now=True) | ||
url = models.URLField(max_length=200) | ||
file_size = models.PositiveIntegerField() | ||
bitrate = models.PositiveIntegerField() | ||
|
||
profile = models.ForeignKey(Profile, related_name="+") | ||
video = models.ForeignKey(Video, related_name="encoded_videos") | ||
|
||
def __repr__(self): | ||
return ( | ||
u"EncodedVideo(video={0.video.client_title}, " | ||
u"profile={0.profile.profile_name})" | ||
).format(self) | ||
|
||
def __unicode__(self): | ||
return repr(self) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
""" | ||
Serializers for Video Abstraction Layer | ||
""" | ||
from rest_framework import serializers | ||
from django.core.validators import MinValueValidator | ||
|
||
from edxval.models import Profile | ||
|
||
|
||
class VideoSerializer(serializers.Serializer): | ||
edx_video_id = serializers.CharField(required=True, max_length=50) | ||
duration = serializers.FloatField() | ||
client_title = serializers.CharField(max_length=255) | ||
|
||
|
||
class ProfileSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = Profile | ||
fields = ( | ||
"profile_name", | ||
"extension", | ||
"width", | ||
"height" | ||
) | ||
|
||
|
||
class OnlyEncodedVideoSerializer(serializers.Serializer): | ||
""" | ||
Used to serialize the EncodedVideo fir the EncodedVideoSetSerializer | ||
""" | ||
url = serializers.URLField(max_length=200) | ||
file_size = serializers.IntegerField(validators=[MinValueValidator(1)]) | ||
bitrate = serializers.IntegerField(validators=[MinValueValidator(1)]) | ||
profile = ProfileSerializer() | ||
|
||
|
||
class EncodedVideoSetSerializer(serializers.Serializer): | ||
""" | ||
Used to serialize a list of EncodedVideo objects it's foreign key Video Object. | ||
""" | ||
edx_video_id = serializers.CharField(max_length=50) | ||
client_title = serializers.CharField(max_length=255) | ||
duration = serializers.FloatField(validators=[MinValueValidator(1)]) | ||
encoded_videos = OnlyEncodedVideoSerializer() |
Oops, something went wrong.