From a1ec9130592f0b8dcbb7658eb435d2ba021ae9ce Mon Sep 17 00:00:00 2001 From: Jayjay Montalbo Date: Wed, 4 Mar 2015 11:39:00 +0800 Subject: [PATCH 01/19] update urls.py to support versions of django older than 1.4 --- dj_elastictranscoder/urls.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dj_elastictranscoder/urls.py b/dj_elastictranscoder/urls.py index 7e634f7..3b6d4a3 100644 --- a/dj_elastictranscoder/urls.py +++ b/dj_elastictranscoder/urls.py @@ -1,4 +1,7 @@ -from django.conf.urls import url, patterns +try: + from django.conf.urls import url, patterns +except ImportError: + from django.conf.urls.defaults import url, patterns # Support for Django < 1.4 urlpatterns = patterns('dj_elastictranscoder.views', url(https://github.com/r'%5Eendpoint/'),%20'endpoint'), From a0cf26d34c2b0878db7dcf4bc4da025155ab0e16 Mon Sep 17 00:00:00 2001 From: Jayjay Montalbo Date: Wed, 4 Mar 2015 11:39:14 +0800 Subject: [PATCH 02/19] reduce django requirement to django >= 1.3 from >= 1.4 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e2217e3..effc003 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ include_package_data=True, zip_safe=False, install_requires = [ - "django >= 1.4", + "django >= 1.3", "boto >= 2.5", "South >= 0.8", ], From 4dfc0170b6db0e01888ba829488ad5cfa1fbb592 Mon Sep 17 00:00:00 2001 From: Trent Holliday Date: Thu, 21 Jan 2016 16:29:05 -0500 Subject: [PATCH 03/19] Fixed django warning --- dj_elastictranscoder/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dj_elastictranscoder/models.py b/dj_elastictranscoder/models.py index 8920e04..8422e07 100644 --- a/dj_elastictranscoder/models.py +++ b/dj_elastictranscoder/models.py @@ -1,7 +1,7 @@ from django.db import models from django.contrib.contenttypes.models import ContentType import django -if django.get_version() > '1.8': +if django.get_version() >= '1.8': from django.contrib.contenttypes.fields import GenericForeignKey else: from django.contrib.contenttypes.generic import GenericForeignKey From 4a538bccc5b21e834967110031b0248cd7a12fa1 Mon Sep 17 00:00:00 2001 From: tzangms Date: Sun, 20 Mar 2016 22:46:11 +0800 Subject: [PATCH 04/19] Bump to version 0.9.6 --- .gitignore | 2 ++ dj_elastictranscoder/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7812acb..7398e2d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ *.swp *.pyc *.egg-info +.coverage +.tox diff --git a/dj_elastictranscoder/__init__.py b/dj_elastictranscoder/__init__.py index 4033697..fac5bf4 100644 --- a/dj_elastictranscoder/__init__.py +++ b/dj_elastictranscoder/__init__.py @@ -1 +1 @@ -__version__ = '0.9.4' +__version__ = '0.9.6' From bfbef03e18950474a0fa5971d9c8bfa6c5d8f33b Mon Sep 17 00:00:00 2001 From: tzangms Date: Sun, 20 Mar 2016 22:53:12 +0800 Subject: [PATCH 05/19] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 37fdea5..745a094 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ What is provided in this package? Workflow ----------- -.. image:: docs/images/workflow.jpg +.. image:: https://github.com/StreetVoice/django-elastic-transcoder/blob/master/docs/images/workflow.jpg Install From 98450c20c683e8bfb05a3f5a574ed694ea84fc9d Mon Sep 17 00:00:00 2001 From: tzangms Date: Sun, 20 Mar 2016 23:07:07 +0800 Subject: [PATCH 06/19] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7398e2d..b424fd3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ *.egg-info .coverage .tox +.eggs +.cache From c1c9d7f40d1ce19fe7bd484af08aa5979df1c0fb Mon Sep 17 00:00:00 2001 From: Vinta Date: Thu, 8 Jun 2017 18:59:59 +0800 Subject: [PATCH 07/19] support both Amazon Elastic Transcoder and Qiniu AVthumb --- dj_elastictranscoder/__init__.py | 2 +- dj_elastictranscoder/admin.py | 3 + dj_elastictranscoder/models.py | 1 + dj_elastictranscoder/signals.py | 7 +- dj_elastictranscoder/transcoder.py | 116 +++++++++++++++++++++-------- dj_elastictranscoder/urls.py | 7 +- dj_elastictranscoder/utils.py | 10 +++ dj_elastictranscoder/views.py | 78 +++++++++++++------ setup.py | 7 +- 9 files changed, 169 insertions(+), 62 deletions(-) create mode 100644 dj_elastictranscoder/utils.py diff --git a/dj_elastictranscoder/__init__.py b/dj_elastictranscoder/__init__.py index fac5bf4..1f356cc 100644 --- a/dj_elastictranscoder/__init__.py +++ b/dj_elastictranscoder/__init__.py @@ -1 +1 @@ -__version__ = '0.9.6' +__version__ = '1.0.0' diff --git a/dj_elastictranscoder/admin.py b/dj_elastictranscoder/admin.py index c7ad991..e5881bb 100644 --- a/dj_elastictranscoder/admin.py +++ b/dj_elastictranscoder/admin.py @@ -1,7 +1,10 @@ from django.contrib import admin + from .models import EncodeJob + class EncodeJobAdmin(admin.ModelAdmin): list_display = ('id', 'state', 'message') list_filters = ('state',) + admin.site.register(EncodeJob, EncodeJobAdmin) diff --git a/dj_elastictranscoder/models.py b/dj_elastictranscoder/models.py index 8422e07..c478d6f 100644 --- a/dj_elastictranscoder/models.py +++ b/dj_elastictranscoder/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.contenttypes.models import ContentType + import django if django.get_version() >= '1.8': from django.contrib.contenttypes.fields import GenericForeignKey diff --git a/dj_elastictranscoder/signals.py b/dj_elastictranscoder/signals.py index f5c52c8..75cbb64 100644 --- a/dj_elastictranscoder/signals.py +++ b/dj_elastictranscoder/signals.py @@ -1,5 +1,6 @@ from django.dispatch import Signal -transcode_onprogress = Signal(providing_args=["job", "message"]) -transcode_onerror = Signal(providing_args=["job", "message"]) -transcode_oncomplete = Signal(providing_args=["job", "message"]) + +transcode_onprogress = Signal(providing_args=['job', 'job_response']) +transcode_oncomplete = Signal(providing_args=['job', 'job_response']) +transcode_onerror = Signal(providing_args=['job', 'job_response']) diff --git a/dj_elastictranscoder/transcoder.py b/dj_elastictranscoder/transcoder.py index 6d77f75..b239400 100644 --- a/dj_elastictranscoder/transcoder.py +++ b/dj_elastictranscoder/transcoder.py @@ -1,57 +1,113 @@ -from boto3.session import Session - -from django.conf import settings from django.contrib.contenttypes.models import ContentType from .models import EncodeJob +from .utils import get_setting_or_raise class Transcoder(object): - def __init__(self, pipeline_id, region=None, access_key_id=None, secret_access_key=None): - self.pipeline_id = pipeline_id + def start_job(self, obj, transcode_kwargs, message=''): + raise NotImplementedError() - if not region: - region = getattr(settings, 'AWS_REGION', None) - self.aws_region = region +class AWSTranscoder(Transcoder): + + def __init__(self, access_key_id=None, secret_access_key=None, pipeline_id=None, region=None): if not access_key_id: - access_key_id = getattr(settings, 'AWS_ACCESS_KEY_ID', None) - self.aws_access_key_id = access_key_id + access_key_id = get_setting_or_raise('AWS_ACCESS_KEY_ID') + self.access_key_id = access_key_id if not secret_access_key: - secret_access_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None) - self.aws_secret_access_key = secret_access_key + secret_access_key = get_setting_or_raise('AWS_SECRET_ACCESS_KEY') + self.secret_access_key = secret_access_key - if self.aws_access_key_id is None: - assert False, 'Please provide AWS_ACCESS_KEY_ID' + if not pipeline_id: + pipeline_id = get_setting_or_raise('AWS_TRANSCODER_PIPELINE_ID') + self.pipeline_id = pipeline_id - if self.aws_secret_access_key is None: - assert False, 'Please provide AWS_SECRET_ACCESS_KEY' + if not region: + region = get_setting_or_raise('AWS_REGION') + self.region = region - if self.aws_region is None: - assert False, 'Please provide AWS_REGION' + from boto3.session import Session boto_session = Session( - aws_access_key_id=self.aws_access_key_id, - aws_secret_access_key=self.aws_secret_access_key, - region_name=self.aws_region, + aws_access_key_id=self.access_key_id, + aws_secret_access_key=self.secret_access_key, + region_name=self.region, ) self.client = boto_session.client('elastictranscoder') - def encode(self, input_name, outputs, **kwargs): - self.message = self.client.create_job( - PipelineId=self.pipeline_id, - Input=input_name, - Outputs=outputs, - **kwargs - ) + def start_job(self, obj, transcode_kwargs, message=''): + """ + https://boto3.readthedocs.io/en/latest/reference/services/elastictranscoder.html#ElasticTranscoder.Client.create_job + """ + + if 'PipelineId' not in transcode_kwargs: + transcode_kwargs['PipelineId'] = self.pipeline_id + + ret = self.client.create_job(**transcode_kwargs) - def create_job_for_object(self, obj): content_type = ContentType.objects.get_for_model(obj) + job = EncodeJob() + job.id = ret['Job']['Id'] + job.content_type = content_type + job.object_id = obj.pk + job.message = message + job.save() + +class QiniuTranscoder(Transcoder): + + def __init__( + self, + access_key=None, + secret_key=None, + pipeline_id=None, + bucket_name=None, + notify_url=None, + ): + if not access_key: + access_key = get_setting_or_raise('QINIU_ACCESS_KEY') + self.access_key = access_key + + if not secret_key: + secret_key = get_setting_or_raise('QINIU_SECRET_KEY') + self.secret_key = secret_key + + if not pipeline_id: + pipeline_id = get_setting_or_raise('QINIU_TRANSCODE_PIPELINE_ID') + self.pipeline_id = pipeline_id + + if not bucket_name: + bucket_name = get_setting_or_raise('QINIU_TRANSCODE_BUCKET_NAME') + self.bucket_name = bucket_name + + if not notify_url: + notify_url = get_setting_or_raise('QINIU_TRANSCODE_NOTIFY_URL') + self.notify_url = notify_url + + from qiniu import Auth + + self.client = Auth(self.access_key, self.secret_key) + + def start_job(self, obj, transcode_kwargs, message=''): + """ + https://developer.qiniu.com/dora/manual/1248/audio-and-video-transcoding-avthumb + """ + + from qiniu import PersistentFop + + if 'force' not in transcode_kwargs: + transcode_kwargs['force'] = 1 + + pfop = PersistentFop(self.client, self.bucket_name, self.pipeline_id, self.notify_url) + ret, info = pfop.execute(**transcode_kwargs) + + content_type = ContentType.objects.get_for_model(obj) job = EncodeJob() - job.id = self.message['Job']['Id'] + job.id = ret['persistentId'] job.content_type = content_type job.object_id = obj.pk + job.message = message job.save() diff --git a/dj_elastictranscoder/urls.py b/dj_elastictranscoder/urls.py index 3b6d4a3..37a3698 100644 --- a/dj_elastictranscoder/urls.py +++ b/dj_elastictranscoder/urls.py @@ -3,6 +3,9 @@ except ImportError: from django.conf.urls.defaults import url, patterns # Support for Django < 1.4 -urlpatterns = patterns('dj_elastictranscoder.views', - url(https://github.com/r'%5Eendpoint/'),%20'endpoint'), +urlpatterns = patterns( + 'dj_elastictranscoder.views', + url(https://github.com/r'%5Eendpoint/'),%20'aws_endpoint'), + url(https://github.com/r'%5Eaws_endpoint/'),%20'aws_endpoint',%20name='aws_endpoint'), + url(https://github.com/r'%5Eqiniu_endpoint/'),%20'qiniu_endpoint',%20name='qiniu_endpoint'), ) diff --git a/dj_elastictranscoder/utils.py b/dj_elastictranscoder/utils.py new file mode 100644 index 0000000..c31e5e9 --- /dev/null +++ b/dj_elastictranscoder/utils.py @@ -0,0 +1,10 @@ +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured + + +def get_setting_or_raise(setting_name): + try: + value = getattr(settings, setting_name) + except AttributeError: + raise ImproperlyConfigured('Please provide {0}'.format(setting_name)) + return value diff --git a/dj_elastictranscoder/views.py b/dj_elastictranscoder/views.py index 9ff0f51..aa909c2 100644 --- a/dj_elastictranscoder/views.py +++ b/dj_elastictranscoder/views.py @@ -1,8 +1,9 @@ import json +from django.core.mail import mail_admins from django.http import HttpResponse, HttpResponseBadRequest from django.views.decorators.csrf import csrf_exempt -from django.core.mail import mail_admins +from django.views.decorators.http import require_http_methods from .models import EncodeJob from .signals import ( @@ -11,8 +12,9 @@ transcode_oncomplete ) + @csrf_exempt -def endpoint(request): +def aws_endpoint(request): """ Receive SNS notification """ @@ -22,7 +24,6 @@ def endpoint(request): except ValueError: return HttpResponseBadRequest('Invalid JSON') - # handle SNS subscription if data['Type'] == 'SubscriptionConfirmation': subscribe_url = data['SubscribeURL'] @@ -34,34 +35,65 @@ def endpoint(request): mail_admins('Please confirm SNS subscription', subscribe_body) return HttpResponse('OK') - - # - try: - message = json.loads(data['Message']) - except ValueError: - assert False, data['Message'] + # handle job response + message = json.loads(data['Message']) + state = message['state'] + + job = EncodeJob.objects.get(pk=message['jobId']) - # - if message['state'] == 'PROGRESSING': - job = EncodeJob.objects.get(pk=message['jobId']) - job.message = 'Progress' + # https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/notifications.html + if state == 'PROGRESSING': job.state = 1 job.save() - - transcode_onprogress.send(sender=None, job=job, message=message) - elif message['state'] == 'COMPLETED': - job = EncodeJob.objects.get(pk=message['jobId']) - job.message = 'Success' + transcode_onprogress.send(sender=None, job=job, job_response=data) + elif state == 'COMPLETED': job.state = 4 job.save() - - transcode_oncomplete.send(sender=None, job=job, message=message) - elif message['state'] == 'ERROR': - job = EncodeJob.objects.get(pk=message['jobId']) + transcode_oncomplete.send(sender=None, job=job, job_response=data) + elif state == 'ERROR': job.message = message['messageDetails'] job.state = 2 job.save() + transcode_onerror.send(sender=None, job=job, job_response=data) + else: + raise RuntimeError('Invalid state') + + return HttpResponse('Done') + + +@csrf_exempt +@require_http_methods(['POST', ]) +def qiniu_endpoint(request): + """ + Receive Qiniu notification + """ + + try: + data = json.loads(request.body) + except ValueError: + return HttpResponseBadRequest('Invalid JSON') + + code = data['code'] + desc = data['desc'] + job_id = data['id'] - transcode_onerror.send(sender=None, job=job, message=message) + job = EncodeJob.objects.get(pk=job_id) + + # https://developer.qiniu.com/dora/manual/1294/persistent-processing-status-query-prefop + if code in (1, 2): # Progressing + job.state = 1 + job.save() + transcode_onprogress.send(sender=None, job=job, job_response=data) + elif code == 0: # Complete + job.state = 4 + job.save() + transcode_oncomplete.send(sender=None, job=job, job_response=data) + elif code == 3 or code == 4: # Error + job.message = desc + job.state = 2 + job.save() + transcode_onerror.send(sender=None, job=job, job_response=data) + else: + raise RuntimeError('Invalid code') return HttpResponse('Done') diff --git a/setup.py b/setup.py index 13ecc92..9df5837 100644 --- a/setup.py +++ b/setup.py @@ -15,9 +15,10 @@ include_package_data=True, zip_safe=False, install_requires=[ - "django >= 1.3, < 1.9", "boto3 >= 1.1", - "South >= 0.8", + "django >= 1.3, < 1.9", + "qiniu >= 7.0.8", + "south >= 0.8", ], classifiers=[ "Intended Audience :: Developers", @@ -31,5 +32,5 @@ "Environment :: Web Environment", "Framework :: Django", ], - keywords='django,aws,elastic,transcoder', + keywords='django,aws,elastic,transcoder,qiniu,audio', ) From f8d5567487481ff37a28a19301918fd6b93bcf43 Mon Sep 17 00:00:00 2001 From: Vinta Date: Thu, 8 Jun 2017 19:24:46 +0800 Subject: [PATCH 08/19] improve setup.py --- setup.cfg | 2 ++ setup.py | 29 +++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..2a9acf1 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1 diff --git a/setup.py b/setup.py index 9df5837..eb53a56 100644 --- a/setup.py +++ b/setup.py @@ -1,17 +1,38 @@ +import os +import sys + from setuptools import setup, find_packages -from dj_elastictranscoder import __version__ +def get_version(): + code = None + path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'dj_elastictranscoder', + '__init__.py', + ) + with open(path) as f: + for line in f: + if line.startswith('__version__'): + code = line[len('__version__ = '):] + break + return eval(code) + + +if sys.argv[-1] == 'wheel': + os.system('pip wheel .') + sys.exit() + setup( name='django-elastic-transcoder', - version=__version__, + version=get_version(), description="Django with AWS elastic transcoder", - long_description=open("README.rst").read(), + long_description=open('README.rst').read(), author='tzangms', author_email='tzangms@streetvoice.com', url='http://github.com/StreetVoice/django-elastic-transcoder', license='MIT', - packages=find_packages(), + packages=find_packages(exclude=('testsapp', )), include_package_data=True, zip_safe=False, install_requires=[ From e4076b79a8ce2019050c3de670b68c1daec5dba7 Mon Sep 17 00:00:00 2001 From: Vinta Date: Fri, 9 Jun 2017 13:41:04 +0800 Subject: [PATCH 09/19] ignore wheelhouse --- .gitignore | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index b424fd3..f1c6f94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ -.DS_Store -/dist -*.swp -*.pyc *.egg-info +*.pyc +*.swp +.cache .coverage -.tox +.DS_Store .eggs -.cache +.tox +/dist +/wheelhouse From 4de0aca197f1703ec29d235ff0e0cfd82b0a06b1 Mon Sep 17 00:00:00 2001 From: Vinta Date: Fri, 9 Jun 2017 13:41:28 +0800 Subject: [PATCH 10/19] store wheels in the wheelhouse --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index eb53a56..bed92f2 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ def get_version(): if sys.argv[-1] == 'wheel': - os.system('pip wheel .') + os.system('pip wheel --wheel-dir=wheelhouse .') sys.exit() setup( From ec55876b7b49e1ebdbe338dc58052003f1da7c73 Mon Sep 17 00:00:00 2001 From: Vinta Date: Fri, 9 Jun 2017 17:30:21 +0800 Subject: [PATCH 11/19] version 1.0.1 --- dj_elastictranscoder/__init__.py | 2 +- dj_elastictranscoder/views.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dj_elastictranscoder/__init__.py b/dj_elastictranscoder/__init__.py index 1f356cc..cd7ca49 100644 --- a/dj_elastictranscoder/__init__.py +++ b/dj_elastictranscoder/__init__.py @@ -1 +1 @@ -__version__ = '1.0.0' +__version__ = '1.0.1' diff --git a/dj_elastictranscoder/views.py b/dj_elastictranscoder/views.py index aa909c2..e81a5b9 100644 --- a/dj_elastictranscoder/views.py +++ b/dj_elastictranscoder/views.py @@ -20,7 +20,8 @@ def aws_endpoint(request): """ try: - data = json.loads(request.read().decode('utf-8')) + webhook = request.read().decode('utf-8') + data = json.loads(webhook) except ValueError: return HttpResponseBadRequest('Invalid JSON') @@ -43,15 +44,17 @@ def aws_endpoint(request): # https://docs.aws.amazon.com/elastictranscoder/latest/developerguide/notifications.html if state == 'PROGRESSING': + job.message = webhook job.state = 1 job.save() transcode_onprogress.send(sender=None, job=job, job_response=data) elif state == 'COMPLETED': + job.message = webhook job.state = 4 job.save() transcode_oncomplete.send(sender=None, job=job, job_response=data) elif state == 'ERROR': - job.message = message['messageDetails'] + job.message = webhook job.state = 2 job.save() transcode_onerror.send(sender=None, job=job, job_response=data) @@ -69,27 +72,29 @@ def qiniu_endpoint(request): """ try: - data = json.loads(request.body) + webhook = request.read().decode('utf-8') + data = json.loads(webhook) except ValueError: return HttpResponseBadRequest('Invalid JSON') code = data['code'] - desc = data['desc'] job_id = data['id'] job = EncodeJob.objects.get(pk=job_id) # https://developer.qiniu.com/dora/manual/1294/persistent-processing-status-query-prefop if code in (1, 2): # Progressing + job.message = webhook job.state = 1 job.save() transcode_onprogress.send(sender=None, job=job, job_response=data) elif code == 0: # Complete + job.message = webhook job.state = 4 job.save() transcode_oncomplete.send(sender=None, job=job, job_response=data) elif code == 3 or code == 4: # Error - job.message = desc + job.message = webhook job.state = 2 job.save() transcode_onerror.send(sender=None, job=job, job_response=data) From 453404c84b2e7ad0e5213a043a41f94cc4c6d43a Mon Sep 17 00:00:00 2001 From: sean Date: Fri, 5 Jan 2018 18:15:32 +0800 Subject: [PATCH 12/19] add support aliyun transcoder --- dj_elastictranscoder/transcoder.py | 60 ++++++++++++++++++++++++++++++ dj_elastictranscoder/urls.py | 1 + dj_elastictranscoder/views.py | 36 ++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/dj_elastictranscoder/transcoder.py b/dj_elastictranscoder/transcoder.py index b239400..571271b 100644 --- a/dj_elastictranscoder/transcoder.py +++ b/dj_elastictranscoder/transcoder.py @@ -111,3 +111,63 @@ def start_job(self, obj, transcode_kwargs, message=''): job.object_id = obj.pk job.message = message job.save() + + +class AliyunTranscoder(Transcoder): + + def __init__( + self, + access_key_id=None, + access_key_secret=None, + pipeline_id=None, + region=None, + notify_url=None + ): + if not access_key_id: + access_key_id = get_setting_or_raise('ALIYUN_TRANSCODE_ACCESS_KEY_ID') + self.access_key_id = access_key_id + + if not access_key_secret: + access_key_secret = get_setting_or_raise('ALIYUN_TRANSCODE_ACCESS_KEY_SECRET') + self.access_key_secret = access_key_secret + + if not pipeline_id: + pipeline_id = get_setting_or_raise('ALIYUN_TRANSCODE_PIPELINE_ID') + self.pipeline_id = pipeline_id + + if not region: + region = get_setting_or_raise('ALIYUN_TRANSCODE_REGION') + self.region = region + + if not notify_url: + notify_url = get_setting_or_raise('ALIYUN_TRANSCODE_NOTIFY_URL') + self.notify_url = notify_url + + from aliyunsdkcore import client + + self.client = client.AcsClient(self.access_key_id, self.access_key_secret, self.region) + + def start_job(self, obj, transcode_kwargs, message=''): + """ + https://help.aliyun.com/document_detail/57347.html?spm=5176.doc56767.6.724.AJ8z3E + """ + + import json + from aliyunsdkmts.request.v20140618 import SubmitJobsRequest + + request = SubmitJobsRequest.SubmitJobsRequest() + request.set_accept_format('json') + request.set_Input(json.dumps(transcode_kwargs.get('input_file'))) + request.set_OutputBucket(transcode_kwargs.get('bucket')) + request.set_OutputLocation(transcode_kwargs.get('oss_location')) + request.set_Outputs(json.dumps(transcode_kwargs.get('outputs'))) + request.set_PipelineId(self.pipeline_id) + response = json.loads(self.client.do_action_with_exception(request).decode('utf-8')) + + content_type = ContentType.objects.get_for_model(obj) + job = EncodeJob() + job.id = response['JobResultList']['JobResult'][0]['Job']['JobId'] + job.content_type = content_type + job.object_id = obj.pk + job.message = message + job.save() diff --git a/dj_elastictranscoder/urls.py b/dj_elastictranscoder/urls.py index 37a3698..23555e4 100644 --- a/dj_elastictranscoder/urls.py +++ b/dj_elastictranscoder/urls.py @@ -8,4 +8,5 @@ url(https://github.com/r'%5Eendpoint/'),%20'aws_endpoint'), url(https://github.com/r'%5Eaws_endpoint/'),%20'aws_endpoint',%20name='aws_endpoint'), url(https://github.com/r'%5Eqiniu_endpoint/'),%20'qiniu_endpoint',%20name='qiniu_endpoint'), + url(https://github.com/r'%5Ealiyun_endpoint',%20'aliyun_endpoint',%20name='aliyun_endpoint'), ) diff --git a/dj_elastictranscoder/views.py b/dj_elastictranscoder/views.py index e81a5b9..5de9185 100644 --- a/dj_elastictranscoder/views.py +++ b/dj_elastictranscoder/views.py @@ -102,3 +102,39 @@ def qiniu_endpoint(request): raise RuntimeError('Invalid code') return HttpResponse('Done') + + +@csrf_exempt +@require_http_methods(['POST', ]) +def aliyun_endpoint(request): + """ + Receive Aliyun notification + """ + + try: + webhook = request.read().decode('utf-8') + data = json.loads(webhook) + except ValueError: + return HttpResponseBadRequest('Invalid JSON') + + message = json.loads(data['Message']) + if message['Type'] == 'Transcode': + state = message['state'] + job_id = message['jobId'] + + job = EncodeJob.objects.get(pk=job_id) + + # https://help.aliyun.com/document_detail/57347.html?spm=5176.doc29208.6.724.4zQQQ4 + if state == 'Success': # Complate + job.message = webhook + job.state = 4 + job.save() + transcode_oncomplete.send(sender=None, job=job, job_response=job_id) + elif state == 'Fail': # Error + job.message = webhook + job.state = 2 + job.save() + transcode_onerror.send(sender=None, job=job, job_response=data) + else: + raise RuntimeError('Invalid code') + return HttpResponse('Done') From 81ec8305e95167f3cdb3288cea36e5cf320d232e Mon Sep 17 00:00:00 2001 From: sean Date: Fri, 27 Apr 2018 11:45:49 +0800 Subject: [PATCH 13/19] improve version --- dj_elastictranscoder/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dj_elastictranscoder/__init__.py b/dj_elastictranscoder/__init__.py index cd7ca49..a6221b3 100644 --- a/dj_elastictranscoder/__init__.py +++ b/dj_elastictranscoder/__init__.py @@ -1 +1 @@ -__version__ = '1.0.1' +__version__ = '1.0.2' From 63dbaed328d776c796ba6c3f2229308459673d80 Mon Sep 17 00:00:00 2001 From: sean Date: Tue, 12 Jun 2018 11:41:42 +0800 Subject: [PATCH 14/19] Handle one pipeline multiple projects --- dj_elastictranscoder/__init__.py | 2 +- dj_elastictranscoder/views.py | 7 +++++-- setup.py | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dj_elastictranscoder/__init__.py b/dj_elastictranscoder/__init__.py index a6221b3..3f6fab6 100644 --- a/dj_elastictranscoder/__init__.py +++ b/dj_elastictranscoder/__init__.py @@ -1 +1 @@ -__version__ = '1.0.2' +__version__ = '1.0.3' diff --git a/dj_elastictranscoder/views.py b/dj_elastictranscoder/views.py index 5de9185..a292f08 100644 --- a/dj_elastictranscoder/views.py +++ b/dj_elastictranscoder/views.py @@ -1,7 +1,7 @@ import json from django.core.mail import mail_admins -from django.http import HttpResponse, HttpResponseBadRequest +from django.http import Http404, HttpResponse, HttpResponseBadRequest from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods @@ -122,7 +122,10 @@ def aliyun_endpoint(request): state = message['state'] job_id = message['jobId'] - job = EncodeJob.objects.get(pk=job_id) + try: + job = EncodeJob.objects.get(pk=job_id) + except EncodeJob.DoesNotExist: + raise Http404 # https://help.aliyun.com/document_detail/57347.html?spm=5176.doc29208.6.724.4zQQQ4 if state == 'Success': # Complate diff --git a/setup.py b/setup.py index bed92f2..aa52bbe 100644 --- a/setup.py +++ b/setup.py @@ -53,5 +53,5 @@ def get_version(): "Environment :: Web Environment", "Framework :: Django", ], - keywords='django,aws,elastic,transcoder,qiniu,audio', + keywords='django,aws,elastic,transcoder,qiniu,audio,aliyun', ) From bd9f28f4ccbe4ceebb2d3a4ee537e10d6ad789d3 Mon Sep 17 00:00:00 2001 From: RobertHWChiangSV Date: Mon, 6 Aug 2018 11:26:48 +0800 Subject: [PATCH 15/19] Aliyun Transcoder without installing South --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index aa52bbe..178e608 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,6 @@ def get_version(): "boto3 >= 1.1", "django >= 1.3, < 1.9", "qiniu >= 7.0.8", - "south >= 0.8", ], classifiers=[ "Intended Audience :: Developers", From 709ddf70da2ee17b8d12aa239f6d08df2b0ab247 Mon Sep 17 00:00:00 2001 From: Artin Date: Mon, 1 Oct 2018 14:38:24 +0800 Subject: [PATCH 16/19] url patterns warning in django 1.9 --- dj_elastictranscoder/urls.py | 39 +++++++++++++++++++++++++----------- setup.py | 2 +- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/dj_elastictranscoder/urls.py b/dj_elastictranscoder/urls.py index 23555e4..81c4ac5 100644 --- a/dj_elastictranscoder/urls.py +++ b/dj_elastictranscoder/urls.py @@ -1,12 +1,27 @@ -try: - from django.conf.urls import url, patterns -except ImportError: - from django.conf.urls.defaults import url, patterns # Support for Django < 1.4 - -urlpatterns = patterns( - 'dj_elastictranscoder.views', - url(https://github.com/r'%5Eendpoint/'),%20'aws_endpoint'), - url(https://github.com/r'%5Eaws_endpoint/'),%20'aws_endpoint',%20name='aws_endpoint'), - url(https://github.com/r'%5Eqiniu_endpoint/'),%20'qiniu_endpoint',%20name='qiniu_endpoint'), - url(https://github.com/r'%5Ealiyun_endpoint',%20'aliyun_endpoint',%20name='aliyun_endpoint'), -) +import django + + +if django.get_version() >= '1.9': + from django.conf.urls import url + from dj_elastictranscoder import views + + urlpatterns = [ + url(https://github.com/r'%5Eendpoint/),%20views.aws_endpoint), + url(https://github.com/r'%5Eaws_endpoint/'),%20views.aws_endpoint,%20name='aws_endpoint'), + url(https://github.com/r'%5Eqiniu_endpoint/'),%20views.qiniu_endpoint,%20name='qiniu_endpoint'), + url(https://github.com/r'%5Ealiyun_endpoint',%20views.aliyun_endpoint,%20name='aliyun_endpoint'), + ] + +else: + try: + from django.conf.urls import url, patterns + except ImportError: + from django.conf.urls.defaults import url, patterns # Support for Django < 1.4 + + urlpatterns = patterns( + 'dj_elastictranscoder.views', + url(https://github.com/r'%5Eendpoint/'),%20'aws_endpoint'), + url(https://github.com/r'%5Eaws_endpoint/'),%20'aws_endpoint',%20name='aws_endpoint'), + url(https://github.com/r'%5Eqiniu_endpoint/'),%20'qiniu_endpoint',%20name='qiniu_endpoint'), + url(https://github.com/r'%5Ealiyun_endpoint',%20'aliyun_endpoint',%20name='aliyun_endpoint'), + ) diff --git a/setup.py b/setup.py index 178e608..78a2d78 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,7 @@ def get_version(): zip_safe=False, install_requires=[ "boto3 >= 1.1", - "django >= 1.3, < 1.9", + "django >= 1.3, < 1.10", "qiniu >= 7.0.8", ], classifiers=[ From 1521201ed5ec874dc8926b351818e2d9f19b7339 Mon Sep 17 00:00:00 2001 From: Artin Date: Mon, 1 Oct 2018 14:44:03 +0800 Subject: [PATCH 17/19] update version --- dj_elastictranscoder/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dj_elastictranscoder/__init__.py b/dj_elastictranscoder/__init__.py index 3f6fab6..8a81504 100644 --- a/dj_elastictranscoder/__init__.py +++ b/dj_elastictranscoder/__init__.py @@ -1 +1 @@ -__version__ = '1.0.3' +__version__ = '1.0.4' From 7e030ae3609905c4bb6f51272f2f797a167311a7 Mon Sep 17 00:00:00 2001 From: RobertHWChiangSV Date: Wed, 19 Dec 2018 09:40:05 +0800 Subject: [PATCH 18/19] Get Django version from django.VERSION --- dj_elastictranscoder/models.py | 2 +- dj_elastictranscoder/urls.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dj_elastictranscoder/models.py b/dj_elastictranscoder/models.py index c478d6f..e226543 100644 --- a/dj_elastictranscoder/models.py +++ b/dj_elastictranscoder/models.py @@ -2,7 +2,7 @@ from django.contrib.contenttypes.models import ContentType import django -if django.get_version() >= '1.8': +if django.VERSION >= (1, 8): from django.contrib.contenttypes.fields import GenericForeignKey else: from django.contrib.contenttypes.generic import GenericForeignKey diff --git a/dj_elastictranscoder/urls.py b/dj_elastictranscoder/urls.py index 81c4ac5..7ae4e8c 100644 --- a/dj_elastictranscoder/urls.py +++ b/dj_elastictranscoder/urls.py @@ -1,7 +1,7 @@ import django -if django.get_version() >= '1.9': +if django.VERSION >= (1, 9): from django.conf.urls import url from dj_elastictranscoder import views From b26a6c9e6a482777ebaddc03d8cae96e7012bd07 Mon Sep 17 00:00:00 2001 From: Robert-Chiang Date: Tue, 1 Dec 2020 08:24:31 +0800 Subject: [PATCH 19/19] Modify required Django version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 78a2d78..6268e86 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,7 @@ def get_version(): zip_safe=False, install_requires=[ "boto3 >= 1.1", - "django >= 1.3, < 1.10", + "django >= 1.3, < 2.0", "qiniu >= 7.0.8", ], classifiers=[