зеркало из https://github.com/mozilla/FlightDeck.git
210 строки
7.4 KiB
Python
210 строки
7.4 KiB
Python
"""
|
|
repackage.views
|
|
---------------
|
|
"""
|
|
import commonware
|
|
import simplejson
|
|
|
|
from django.conf import settings
|
|
from django.http import (HttpResponse, HttpResponseBadRequest,
|
|
HttpResponseForbidden)
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.views.decorators.http import require_POST
|
|
from django.shortcuts import get_object_or_404
|
|
|
|
from jetpack.models import SDK
|
|
from utils.helpers import get_random_string
|
|
from utils import validator, exceptions
|
|
|
|
from repackage import tasks
|
|
|
|
log = commonware.log.getLogger('f.repackage')
|
|
|
|
|
|
class BadManifestFieldException(exceptions.SimpleException):
|
|
"""Wrong value in one of the Manifest fields
|
|
"""
|
|
|
|
|
|
def _get_package_overrides(container, sdk_version=None):
|
|
"""
|
|
Prepare package overrides (from POST)
|
|
sdk_version is used to override the version if {sdk_version} provided in
|
|
optional container['version']
|
|
|
|
:attr: container (dict) list of overrides
|
|
:attr: sdk_version (string)
|
|
"""
|
|
version = container.get('version', None)
|
|
if version and sdk_version:
|
|
version = version.format(sdk_version=sdk_version)
|
|
|
|
package_overrides = {
|
|
'version': version,
|
|
'type': container.get('type', None),
|
|
'fullName': container.get('fullName', None),
|
|
'url': container.get('url', None),
|
|
'description': container.get('description', None),
|
|
'author': container.get('author', None),
|
|
'license': container.get('license', None),
|
|
'lib': container.get('lib', None),
|
|
'data': container.get('data', None),
|
|
'tests': container.get('tests', None),
|
|
'main': container.get('main', None)
|
|
}
|
|
if version and not validator.is_valid('alphanum_plus', version):
|
|
log.error("Wrong version format provided (%s)" % version)
|
|
raise BadManifestFieldException("Wrong version format")
|
|
return package_overrides
|
|
|
|
|
|
def _get_latest_sdk_source_dir():
|
|
# get latest SDK
|
|
sdk = SDK.objects.latest('pk')
|
|
# if (when?) choosing POST['sdk_dir'] will be possible
|
|
# sdk = SDK.objects.get(dir=sdk_dir) if sdk_dir else SDK.objects.all()[0]
|
|
return sdk.get_source_dir()
|
|
|
|
|
|
@csrf_exempt
|
|
@require_POST
|
|
def rebuild(request):
|
|
"""Rebuild ``XPI`` file. It can be provided as POST['location']
|
|
|
|
:returns: (JSON) contains one field - hashtag it is later used to download
|
|
the xpi using :meth:`xpi.views.check_download` and
|
|
:meth:`xpi.views.get_download`
|
|
"""
|
|
# validate entries
|
|
secret = request.POST.get('secret', None)
|
|
if not secret or secret != settings.AMO_SECRET_KEY:
|
|
log.error("Rebuild requested with an invalid key. Rejecting.")
|
|
return HttpResponseForbidden('Access denied')
|
|
|
|
options = request.POST.get('options', None)
|
|
|
|
location = request.POST.get('location', None)
|
|
addons = request.POST.get('addons', None)
|
|
upload = request.FILES.get('upload', None)
|
|
|
|
if not location and not upload and not addons:
|
|
log.error("Rebuild requested but files weren't specified. Rejecting.")
|
|
return HttpResponseBadRequest('Please provide XPI files to rebuild')
|
|
if location and upload:
|
|
log.error("Rebuild requested but location and upload provided."
|
|
"Rejecting")
|
|
return HttpResponseBadRequest('Please provide XPI files to rebuild')
|
|
|
|
# locate SDK source directory
|
|
sdk_version = request.POST.get('sdk_version', None)
|
|
if sdk_version:
|
|
sdk = get_object_or_404(SDK, version=sdk_version)
|
|
sdk_source_dir = sdk.get_source_dir()
|
|
else:
|
|
sdk_source_dir = (settings.REPACKAGE_SDK_SOURCE
|
|
or _get_latest_sdk_source_dir())
|
|
|
|
sdk_manifest = '%s/packages/%s/package.json' % (sdk_source_dir, 'addon-kit')
|
|
try:
|
|
handle = open(sdk_manifest)
|
|
except Exception, err:
|
|
log.critical("Problems loading SDK manifest\n%s" % str(err))
|
|
raise
|
|
else:
|
|
sdk_version = simplejson.loads(handle.read())['version']
|
|
handle.close()
|
|
pingback = request.POST.get('pingback', None)
|
|
priority = request.POST.get('priority', None)
|
|
post = request.POST.urlencode()
|
|
if priority and priority == 'high':
|
|
rebuild_task = tasks.high_rebuild
|
|
else:
|
|
rebuild_task = tasks.low_rebuild
|
|
response = {'status': 'success'}
|
|
errors = []
|
|
counter = 0
|
|
|
|
if location or upload:
|
|
hashtag = get_random_string(10)
|
|
if location:
|
|
log.debug('[%s] Single rebuild started for location (%s)' %
|
|
(hashtag, location))
|
|
else:
|
|
log.debug('[%s] Single rebuild started from upload' % hashtag)
|
|
|
|
filename = request.POST.get('filename', None)
|
|
|
|
try:
|
|
package_overrides = _get_package_overrides(request.POST,
|
|
sdk_version)
|
|
except BadManifestFieldException, err:
|
|
errors.append('[%s] %s' % (hashtag, str(err)))
|
|
else:
|
|
rebuild_task.delay(
|
|
location, upload, sdk_source_dir, hashtag,
|
|
package_overrides=package_overrides,
|
|
filename=filename, pingback=pingback,
|
|
post=post, options=options)
|
|
counter = counter + 1
|
|
|
|
if addons:
|
|
try:
|
|
addons = simplejson.loads(addons)
|
|
except Exception, err:
|
|
errors.append('[%s] %s' % (hashtag, str(err)))
|
|
else:
|
|
for addon in addons:
|
|
error = False
|
|
filename = addon.get('filename', None)
|
|
hashtag = get_random_string(10)
|
|
location = addon.get('location', None)
|
|
upload_name = addon.get('upload', None)
|
|
upload = None
|
|
if upload_name:
|
|
upload = request.FILES.get(upload_name, None)
|
|
if not (location or upload):
|
|
errors.append("[%s] Files not specified." % hashtag)
|
|
error = True
|
|
if location and upload:
|
|
errors.append(("[%s] Location and upload provided. "
|
|
"Rejecting") % hashtag)
|
|
error = True
|
|
try:
|
|
package_overrides = _get_package_overrides(addon,
|
|
sdk_version)
|
|
except Exception, err:
|
|
errors.append('[%s] %s' % (hashtag, str(err)))
|
|
error = True
|
|
if not error:
|
|
rebuild_task.delay(
|
|
location, upload, sdk_source_dir, hashtag,
|
|
package_overrides=package_overrides,
|
|
filename=filename, pingback=pingback,
|
|
post=post)
|
|
counter = counter + 1
|
|
|
|
if errors:
|
|
log.error("Errors reported when rebuilding")
|
|
response['status'] = 'some failures'
|
|
response['errors'] = ''
|
|
for e in errors:
|
|
response['errors'] = "%s%s\n" % (response['errors'], e)
|
|
log.error(" Error: %s" % e)
|
|
|
|
response['addons'] = counter
|
|
uuid = request.POST.get('uuid', 'no uuid')
|
|
|
|
log.info("%d addon(s) will be created, %d syntax errors, uuid: %s" %
|
|
(counter, len(errors), uuid))
|
|
|
|
return HttpResponse(simplejson.dumps(response),
|
|
mimetype='application/json')
|
|
|
|
|
|
def sdk_versions(r):
|
|
versions = SDK.objects.all().order_by('id')
|
|
response = [sdk.version for sdk in versions]
|
|
|
|
return HttpResponse(simplejson.dumps(response),
|
|
mimetype='application/json')
|