Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tzangms committed Apr 6, 2014
0 parents commit 21016b7
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.DS_Store
*.swp
*.pyc
*.egg-info
1 change: 1 addition & 0 deletions dj_elastictranscoder/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '0.1'
7 changes: 7 additions & 0 deletions dj_elastictranscoder/admins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.contrib import admin
from .models import EncodeJob

class EncodeJobAdmin(admin.ModelAdmin):
list_display = ('id', 'state', 'message')
list_filter = ('state',)
admin.site.register(EncodeJob, EncodeJob)
12 changes: 12 additions & 0 deletions dj_elastictranscoder/endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import json

def handler(notification_type):
filename = 'fixtures/on%s.json' % notification_type
with open(filename) as f:
data = json.loads(f.read())
print data['Message']


handler('progress')
handler('error')
handler('complete')
21 changes: 21 additions & 0 deletions dj_elastictranscoder/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.generic import GenericForeignKey


class EncodeJob(models.Model):
STATE_CHOICES = (
(0, 'Waiting'),
(1, 'Progressing'),
(2, 'Error'),
(3, 'Warning'),
(4, 'Complete'),
)
id = models.CharField(max_length=100, primary_key=True)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
state = models.PositiveIntegerField(choices=STATE_CHOICES, default=0, db_index=True)
content_object = GenericForeignKey()
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
65 changes: 65 additions & 0 deletions dj_elastictranscoder/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import os.path

from django.test import TestCase
from django.db import models
from django.contrib.contenttypes.models import ContentType

from .models import EncodeJob


PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__))
FIXTURE_DIRS = os.path.join(PROJECT_ROOT, 'fixtures')


class Item(models.Model):
name = models.CharField(max_length=100)


class SNSNotificationTest(TestCase):
urls = 'dj_elastictranscoder.urls'

def setUp(self):
item = Item.objects.create(name='Hello')
content_type = ContentType.objects.get_for_model(Item)
self.job_id = '1396802241671-jkmme8'

self.job = EncodeJob.objects.create(id=self.job_id, content_type=content_type, object_id=item.id)

def test_initial(self):
job = EncodeJob.objects.get(id=self.job_id)
self.assertEqual(job.state, 0)


def test_onprogress(self):
with open(os.path.join(FIXTURE_DIRS, 'onprogress.json')) as f:
content = f.read()

resp = self.client.post('/sns_endpoint/', content, content_type="application/json")
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.content, 'Done')

job = EncodeJob.objects.get(id=self.job_id)
self.assertEqual(job.state, 1)

def test_onerror(self):
with open(os.path.join(FIXTURE_DIRS, 'onerror.json')) as f:
content = f.read()

resp = self.client.post('/sns_endpoint/', content, content_type="application/json")
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.content, 'Done')

job = EncodeJob.objects.get(id=self.job_id)
self.assertEqual(job.state, 3)


def test_oncomplete(self):
with open(os.path.join(FIXTURE_DIRS, 'oncomplete.json')) as f:
content = f.read()

resp = self.client.post('/sns_endpoint/', content, content_type="application/json")
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.content, 'Done')

job = EncodeJob.objects.get(id=self.job_id)
self.assertEqual(job.state, 4)
5 changes: 5 additions & 0 deletions dj_elastictranscoder/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.conf.urls import url, patterns

urlpatterns = patterns('dj_elastictranscoder.views',
url(r'^sns_endpoint/$', 'sns_endpoint'),
)
29 changes: 29 additions & 0 deletions dj_elastictranscoder/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from boto import elastictranscoder

from django.conf import settings
from django.contrib.contenttypes.models import ContentType

from .models import EncodeJob


def encode(obj, pipeline_id, input_name, outputs, preset_id, region=None):
"""
encode
"""
aws_access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
aws_secret_access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)

if not region:
aws_region = getattr(settings, 'AWS_REGION', None)

if not aws_access_key_id or not aws_secret_access_key or not aws_region:
assert False, 'Please provide `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`'

transcoder = elastictranscoder.connect_to_region(aws_region,
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key)

resp = transcoder.create_job(pipeline_id, input_name, outputs=outputs)

content_type = ContentType.objects.get_for_model(obj)
EncodeJob.objects.create(id=resp['Job']['Id'], content_type=content_type, object_id=obj.id)
60 changes: 60 additions & 0 deletions dj_elastictranscoder/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import json

from django.http import HttpResponse, HttpResponseBadRequest
from django.core.mail import mail_admins
from .models import EncodeJob


def sns_endpoint(request):
"""
Receive SNS notification
"""

try:
data = json.loads(request.read())
except ValueError:
return HttpResponseBadRequest('Invalid JSON')


# handle SNS subscription
if data['Type'] == 'SubscriptionConfirmation':
subscribe_url = data['SubscribeURL']
subscribe_body = """
Please visit this URL below to confirm your subscription with SNS
%s """ % subscribe_url

mail_admins('Please confirm SNS subscription', subscribe_body)
return HttpResponse('OK')


#
try:
message = json.loads(data['Message'])
except ValueError:
assert False, data['Message']

job, created = EncodeJob.objects.get_or_create(id=message['jobId'])

if message['state'] == 'PROGRESSING':
job.state = 1
elif message['state'] == 'COMPLETED':
job.state = 4
elif message['state'] == 'ERROR':
job.state = 3

job.save()

# TODO: send signal to handler

return HttpResponse('Done')


def _oncomplete(request, message):
pass

def _onerror(request, message):
pass

def _onprogress(request, message):
pass
44 changes: 44 additions & 0 deletions runtests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env python

import sys
from os.path import dirname, abspath

from django.conf import settings


settings.configure(
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:'
}
},
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'dj_elastictranscoder',
],
SITE_ID=1,
DEBUG=False,
ROOT_URLCONF='',
)



def runtests(**test_args):
from django.test.utils import get_runner

parent = dirname(abspath(__file__))
sys.path.insert(0, parent)

TestRunner = get_runner(settings)
test_runner = TestRunner(verbosity=1, interactive=True)
failures = test_runner.run_tests(['dj_elastictranscoder'], test_args)
sys.exit(failures)


if __name__ == '__main__':
runtests(*sys.argv[1:])
29 changes: 29 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from setuptools import setup, find_packages
from dj_elastictranscoder import __version__


setup(
name='django-elastic-transcoder',
version=__version__,
description="django-elastic-transcoder",
author='tzangms',
author_email='[email protected]',
url='http://github.com/StreetVoice/django-elastic-transcoder',
license='MIT',
test_suite='runtests.runtests',
packages=['dj_elastictranscoder',],
include_package_data=True,
zip_safe=False,
install_requires = [
"django >= 1.4",
"boto >= 2.5",
"South >= 0.8",
],
classifiers=[
"Programming Language :: Python",
"Topic :: Software Development :: Libraries :: Python Modules",
"Framework :: Django",
"Environment :: Web Environment",
],
keywords='django,aws,elastic,transcoder',
)

0 comments on commit 21016b7

Please sign in to comment.