Bug 622602 - Unicode blocks screenshot saving
This commit is contained in:
Родитель
1e23cfef7f
Коммит
d9550764eb
|
@ -6,6 +6,7 @@ from django.conf import settings
|
|||
from django.forms.formsets import BaseFormSet, formset_factory
|
||||
|
||||
import happyforms
|
||||
import path
|
||||
from tower import ugettext as _, ungettext as ngettext
|
||||
|
||||
import amo
|
||||
|
@ -217,57 +218,28 @@ def icons():
|
|||
|
||||
|
||||
class AddonFormMedia(AddonFormBase):
|
||||
icon_upload = forms.FileField(required=False)
|
||||
icon_type = forms.CharField(widget=forms.RadioSelect(
|
||||
renderer=IconWidgetRenderer, choices=icons()), required=False)
|
||||
icon_upload_hash = forms.CharField(required=False)
|
||||
|
||||
class Meta:
|
||||
model = Addon
|
||||
fields = ('icon_upload', 'icon_type')
|
||||
fields = ('icon_upload_hash', 'icon_type')
|
||||
|
||||
def save(self, addon, commit=True):
|
||||
if 'icon_upload' in self.request.FILES:
|
||||
icon = self.request.FILES['icon_upload']
|
||||
icon.seek(0)
|
||||
if self.cleaned_data['icon_upload_hash']:
|
||||
upload_hash = self.cleaned_data['icon_upload_hash']
|
||||
upload_path = path.path(settings.TMP_PATH) / 'icon' / upload_hash
|
||||
|
||||
dirname = addon.get_icon_dir()
|
||||
tmp_destination = os.path.join(dirname, '%s-temp' % addon.id)
|
||||
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
|
||||
with open(tmp_destination, 'wb+') as icon_file:
|
||||
for chunk in icon.read():
|
||||
icon_file.write(chunk)
|
||||
|
||||
destination = os.path.join(dirname, '%s' % addon.id)
|
||||
|
||||
remove_icons(destination)
|
||||
tasks.resize_icon.delay(tmp_destination, destination,
|
||||
tasks.resize_icon.delay(upload_path, destination,
|
||||
amo.ADDON_ICON_SIZES)
|
||||
|
||||
return super(AddonFormMedia, self).save(commit)
|
||||
|
||||
def clean_icon_upload(self):
|
||||
icon = self.cleaned_data['icon_upload']
|
||||
|
||||
if not icon:
|
||||
return
|
||||
|
||||
check = ImageCheck(icon)
|
||||
if (not check.is_image() or
|
||||
icon.content_type not in ('image/png', 'image/jpeg', 'image/jpg')):
|
||||
raise forms.ValidationError(_('Icons must be either PNG or JPG.'))
|
||||
|
||||
if check.is_animated():
|
||||
raise forms.ValidationError(_('Icons cannot be animated.'))
|
||||
|
||||
if icon.size > settings.MAX_ICON_UPLOAD_SIZE:
|
||||
raise forms.ValidationError(
|
||||
_('Please use images smaller than %dMB.' %
|
||||
(settings.MAX_ICON_UPLOAD_SIZE / 1024 / 1024 - 1)))
|
||||
|
||||
return icon
|
||||
|
||||
|
||||
class AddonFormDetails(AddonFormBase):
|
||||
default_locale = forms.TypedChoiceField(choices=Addon.LOCALES)
|
||||
|
||||
|
|
|
@ -497,7 +497,7 @@ class PreviewForm(happyforms.ModelForm):
|
|||
if self.cleaned_data['upload_hash']:
|
||||
upload_hash = self.cleaned_data['upload_hash']
|
||||
settings_path = settings.PREVIEWS_PATH
|
||||
upload_path = path.path(settings_path) / 'temp' / upload_hash
|
||||
upload_path = path.path(settings.TMP_PATH) / 'preview' / upload_hash
|
||||
|
||||
tasks.resize_preview.delay(str(upload_path),
|
||||
self.instance.thumbnail_path,
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
<div class="icon_preview" id="icon_preview_32">
|
||||
<img src="{{ addon.icon_url }}">
|
||||
</div>
|
||||
<div class="js-hidden">
|
||||
{{ form.icon_upload_hash|safe }}
|
||||
</div>
|
||||
|
||||
<div class="edit-media-details">
|
||||
{# L10n: The size of the icon #}
|
||||
{{ _('32x32px') }}
|
||||
|
@ -43,14 +47,12 @@
|
|||
</ul>
|
||||
<div class="invisible-upload">
|
||||
<a class="button" href="#">{{ _('Upload a Custom Icon...') }}</a>
|
||||
{{ form.icon_upload|safe }}
|
||||
</div>
|
||||
<div class="edit-media-details">
|
||||
{% trans %}
|
||||
PNG and JPG supported. Icons resized to 64x64 pixels if larger.
|
||||
{% endtrans %}
|
||||
</div>
|
||||
{{ form.icon_upload.errors|safe }}
|
||||
<ul class="errorlist">
|
||||
<li id="edit-icon-error"></li>
|
||||
</ul>
|
||||
|
|
|
@ -51,14 +51,17 @@
|
|||
</ul>
|
||||
<div class="invisible-upload">
|
||||
<a class="button" href="#">{{ _('Upload a Custom Icon...') }}</a>
|
||||
{{ form.icon_upload|safe }}
|
||||
<input type="file" id="id_icon_upload" name="icon_upload"
|
||||
data-upload-url="{{ url('devhub.addons.upload_icon', addon.slug) }}">
|
||||
</div>
|
||||
<div class="js-hidden">
|
||||
{{ form.icon_upload_hash|safe }}
|
||||
</div>
|
||||
<div class="edit-media-details">
|
||||
{% trans %}
|
||||
PNG and JPG supported. Icons resized to 64x64 pixels if larger.
|
||||
{% endtrans %}
|
||||
</div>
|
||||
{{ form.icon_upload.errors|safe }}
|
||||
<ul class="errorlist">
|
||||
<li id="edit-icon-error"></li>
|
||||
</ul>
|
||||
|
|
|
@ -986,6 +986,10 @@ class TestEdit(test_utils.TestCase):
|
|||
self.basic_url = self.get_url('basic', True)
|
||||
ctx = self.client.get(self.basic_url).context['cat_form']
|
||||
self.cat_initial = initial(ctx.initial_forms[0])
|
||||
self.preview_upload = reverse('devhub.addons.upload_preview',
|
||||
args=[self.addon.slug])
|
||||
self.icon_upload = reverse('devhub.addons.upload_icon',
|
||||
args=[self.addon.slug])
|
||||
|
||||
def tearDown(self):
|
||||
reset_redis(self._redis)
|
||||
|
@ -1448,7 +1452,6 @@ class TestEdit(test_utils.TestCase):
|
|||
|
||||
for k in data:
|
||||
eq_(unicode(getattr(addon, k)), data[k])
|
||||
|
||||
def test_edit_media_preuploadedicon(self):
|
||||
data = dict(icon_type='icon/appearance')
|
||||
data_formset = self.formset_media(**data)
|
||||
|
@ -1466,21 +1469,29 @@ class TestEdit(test_utils.TestCase):
|
|||
img = "%s/img/amo2009/tab-mozilla.png" % settings.MEDIA_ROOT
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(upload_image=src_image)
|
||||
|
||||
response = self.client.post(self.icon_upload, data)
|
||||
response_json = json.loads(response.content)
|
||||
addon = self.get_addon()
|
||||
|
||||
# Now, save the form so it gets moved properly.
|
||||
data = dict(icon_type='image/png',
|
||||
icon_upload=src_image)
|
||||
icon_upload_hash=response_json['upload_hash'])
|
||||
data_formset = self.formset_media(**data)
|
||||
|
||||
r = self.client.post(self.get_url('media', True), data_formset)
|
||||
eq_(r.context['form'].errors, {})
|
||||
addon = self.get_addon()
|
||||
|
||||
addon.get_icon_url(64).endswith('%s/%s-64.png' %
|
||||
(settings.ADDON_ICONS_DEFAULT_URL, addon.id))
|
||||
eq_('/'.join(addon.get_icon_url(64).split('/')[-3:-1]),
|
||||
'addon_icon/%s' % addon.id)
|
||||
|
||||
eq_(data['icon_type'], 'image/png')
|
||||
|
||||
# Check that it was actually uploaded
|
||||
dirname = addon.get_icon_dir()
|
||||
dirname = os.path.join(settings.ADDON_ICONS_PATH,
|
||||
'%s' % (addon.id / 1000))
|
||||
dest = os.path.join(dirname, '%s-32.png' % addon.id)
|
||||
|
||||
assert os.path.exists(dest)
|
||||
|
@ -1497,16 +1508,23 @@ class TestEdit(test_utils.TestCase):
|
|||
img = "%s/img/amo2009/notifications/error.png" % settings.MEDIA_ROOT
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(upload_image=src_image)
|
||||
|
||||
response = self.client.post(self.icon_upload, data)
|
||||
response_json = json.loads(response.content)
|
||||
addon = self.get_addon()
|
||||
|
||||
# Now, save the form so it gets moved properly.
|
||||
data = dict(icon_type='image/png',
|
||||
icon_upload=src_image)
|
||||
icon_upload_hash=response_json['upload_hash'])
|
||||
data_formset = self.formset_media(**data)
|
||||
|
||||
r = self.client.post(self.get_url('media', True), data_formset)
|
||||
eq_(r.context['form'].errors, {})
|
||||
addon = self.get_addon()
|
||||
|
||||
addon.get_icon_url(64).endswith('%s/%s-64.png' %
|
||||
(settings.ADDON_ICONS_DEFAULT_URL, addon.id))
|
||||
eq_('/'.join(addon.get_icon_url(64).split('/')[-3:-1]),
|
||||
'addon_icon/%s' % addon.id)
|
||||
|
||||
eq_(data['icon_type'], 'image/png')
|
||||
|
||||
|
@ -1514,6 +1532,7 @@ class TestEdit(test_utils.TestCase):
|
|||
dirname = os.path.join(settings.ADDON_ICONS_PATH,
|
||||
'%s' % (addon.id / 1000))
|
||||
dest = os.path.join(dirname, '%s-64.png' % addon.id)
|
||||
|
||||
assert os.path.exists(dest)
|
||||
|
||||
eq_(Image.open(dest).size, (48, 48))
|
||||
|
@ -1522,13 +1541,12 @@ class TestEdit(test_utils.TestCase):
|
|||
img = "%s/js/zamboni/devhub.js" % settings.MEDIA_ROOT
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(icon_type='image/png',
|
||||
icon_upload=src_image)
|
||||
data_formset = self.formset_media(**data)
|
||||
data = {'upload_image': src_image}
|
||||
|
||||
r = self.client.post(self.get_url('media', True), data_formset)
|
||||
error = 'Icons must be either PNG or JPG.'
|
||||
self.assertFormError(r, 'form', 'icon_upload', error)
|
||||
res = self.client.post(self.preview_upload, data)
|
||||
response_json = json.loads(res.content)
|
||||
|
||||
eq_(response_json['errors'][0], u'Icons must be either PNG or JPG.')
|
||||
|
||||
def setup_image_status(self):
|
||||
addon = self.get_addon()
|
||||
|
@ -1573,19 +1591,21 @@ class TestEdit(test_utils.TestCase):
|
|||
|
||||
def test_icon_animated(self):
|
||||
filehandle = open(get_image_path('animated.png'), 'rb')
|
||||
data = {'icon_type': 'image/png', 'icon_upload': filehandle}
|
||||
data_formset = self.formset_media(**data)
|
||||
res = self.client.post(self.get_url('media', True), data_formset)
|
||||
eq_(res.context['form'].errors['icon_upload'][0],
|
||||
u'Icons cannot be animated.')
|
||||
data = {'upload_image': filehandle}
|
||||
|
||||
res = self.client.post(self.preview_upload, data)
|
||||
response_json = json.loads(res.content)
|
||||
|
||||
eq_(response_json['errors'][0], u'Icons cannot be animated.')
|
||||
|
||||
def preview_add(self, amount=1):
|
||||
img = "%s/img/amo2009/tab-mozilla.png" % settings.MEDIA_ROOT
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(upload_preview=src_image)
|
||||
data = dict(upload_image=src_image)
|
||||
data_formset = self.formset_media(**data)
|
||||
url = reverse('devhub.addons.upload_preview', args=['a3615'])
|
||||
url = self.preview_upload
|
||||
|
||||
r = self.client.post(url, data_formset)
|
||||
|
||||
details = json.loads(r.content)
|
||||
|
@ -2575,7 +2595,6 @@ class TestSubmitStep1(TestSubmitBase):
|
|||
"Looks like link %r to %r is still a placeholder" %
|
||||
(href, ln.text))
|
||||
|
||||
|
||||
class TestSubmitStep2(test_utils.TestCase):
|
||||
# More tests in TestCreateAddon.
|
||||
fixtures = ['base/users']
|
||||
|
@ -2770,6 +2789,10 @@ class TestSubmitStep4(TestSubmitBase):
|
|||
SubmitStep.objects.create(addon_id=3615, step=5)
|
||||
self.url = reverse('devhub.submit.4', args=['a3615'])
|
||||
self.next_step = reverse('devhub.submit.5', args=['a3615'])
|
||||
self.icon_upload = reverse('devhub.addons.upload_icon',
|
||||
args=['a3615'])
|
||||
self.preview_upload = reverse('devhub.addons.upload_preview',
|
||||
args=['a3615'])
|
||||
|
||||
def tearDown(self):
|
||||
settings.ADDON_ICON_URL = self.old_addon_icon_url
|
||||
|
@ -2829,12 +2852,21 @@ class TestSubmitStep4(TestSubmitBase):
|
|||
img = "%s/img/amo2009/tab-mozilla.png" % settings.MEDIA_ROOT
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(upload_image=src_image)
|
||||
|
||||
response = self.client.post(self.icon_upload, data)
|
||||
response_json = json.loads(response.content)
|
||||
addon = self.get_addon()
|
||||
|
||||
# Now, save the form so it gets moved properly.
|
||||
data = dict(icon_type='image/png',
|
||||
icon_upload=src_image)
|
||||
icon_upload_hash=response_json['upload_hash'])
|
||||
data_formset = self.formset_media(**data)
|
||||
self.client.post(self.url, data_formset)
|
||||
|
||||
r = self.client.post(self.url, data_formset)
|
||||
|
||||
addon = self.get_addon()
|
||||
|
||||
eq_('/'.join(addon.get_icon_url(64).split('/')[-3:-1]),
|
||||
'addon_icon/%s' % addon.id)
|
||||
|
||||
|
@ -2853,11 +2885,18 @@ class TestSubmitStep4(TestSubmitBase):
|
|||
img = "%s/img/amo2009/notifications/error.png" % settings.MEDIA_ROOT
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(upload_image=src_image)
|
||||
|
||||
response = self.client.post(self.icon_upload, data)
|
||||
response_json = json.loads(response.content)
|
||||
addon = self.get_addon()
|
||||
|
||||
# Now, save the form so it gets moved properly.
|
||||
data = dict(icon_type='image/png',
|
||||
icon_upload=src_image)
|
||||
icon_upload_hash=response_json['upload_hash'])
|
||||
data_formset = self.formset_media(**data)
|
||||
|
||||
self.client.post(self.url, data_formset)
|
||||
r = self.client.post(self.url, data_formset)
|
||||
addon = self.get_addon()
|
||||
|
||||
eq_('/'.join(addon.get_icon_url(64).split('/')[-3:-1]),
|
||||
|
@ -2876,20 +2915,23 @@ class TestSubmitStep4(TestSubmitBase):
|
|||
|
||||
def test_client_lied(self):
|
||||
filehandle = open(get_image_path('non-animated.gif'), 'rb')
|
||||
data = {'icon_type': 'image/png', 'icon_upload': filehandle}
|
||||
data_formset = self.formset_media(**data)
|
||||
|
||||
res = self.client.post(self.url, data_formset)
|
||||
eq_(res.context['form'].errors['icon_upload'][0],
|
||||
u'Icons must be either PNG or JPG.')
|
||||
|
||||
data = {'upload_image': filehandle}
|
||||
|
||||
res = self.client.post(self.preview_upload, data)
|
||||
response_json = json.loads(res.content)
|
||||
|
||||
eq_(response_json['errors'][0], u'Icons must be either PNG or JPG.')
|
||||
|
||||
def test_icon_animated(self):
|
||||
filehandle = open(get_image_path('animated.png'), 'rb')
|
||||
data = {'icon_type': 'image/png', 'icon_upload': filehandle}
|
||||
data_formset = self.formset_media(**data)
|
||||
res = self.client.post(self.url, data_formset)
|
||||
eq_(res.context['form'].errors['icon_upload'][0],
|
||||
u'Icons cannot be animated.')
|
||||
data = {'upload_image': filehandle}
|
||||
|
||||
res = self.client.post(self.preview_upload, data)
|
||||
response_json = json.loads(res.content)
|
||||
|
||||
eq_(response_json['errors'][0], u'Icons cannot be animated.')
|
||||
|
||||
def test_icon_non_animated(self):
|
||||
filehandle = open(get_image_path('non-animated.png'), 'rb')
|
||||
|
@ -2899,7 +2941,6 @@ class TestSubmitStep4(TestSubmitBase):
|
|||
eq_(res.status_code, 302)
|
||||
eq_(self.get_step().step, 5)
|
||||
|
||||
|
||||
class TestSubmitStep5(TestSubmitBase):
|
||||
"""License submission."""
|
||||
|
||||
|
@ -3117,7 +3158,6 @@ class TestResumeStep(TestSubmitBase):
|
|||
self.assertRedirects(r, reverse('devhub.submit.%s' % i,
|
||||
args=['a3615']))
|
||||
|
||||
|
||||
class TestSubmitSteps(test_utils.TestCase):
|
||||
fixtures = ['base/apps', 'base/users', 'base/addon_3615']
|
||||
|
||||
|
|
|
@ -39,8 +39,10 @@ detail_patterns = patterns('',
|
|||
url('^edit_(?P<section>[^/]+)(?:/(?P<editable>[^/]+))?$',
|
||||
views.addons_section, name='devhub.addons.section'),
|
||||
|
||||
url('^upload_preview$', views.upload_preview,
|
||||
name='devhub.addons.upload_preview'),
|
||||
url('^upload_preview$', views.upload_image, {'upload_type': 'preview'},
|
||||
name='devhub.addons.upload_preview' ),
|
||||
url('^upload_icon$', views.upload_image, {'upload_type': 'icon'},
|
||||
name='devhub.addons.upload_icon'),
|
||||
|
||||
url('^versions/$', views.version_list, name='devhub.versions'),
|
||||
url('^versions/delete$', views.version_delete,
|
||||
|
|
|
@ -622,16 +622,18 @@ def image_status(request, addon_id, addon):
|
|||
'icons': icons,
|
||||
'previews': previews}
|
||||
|
||||
|
||||
@json_view
|
||||
@dev_required
|
||||
def upload_preview(request, addon_id, addon):
|
||||
if 'upload_preview' in request.FILES:
|
||||
upload_preview = request.FILES['upload_preview']
|
||||
def upload_image(request, addon_id, addon, upload_type):
|
||||
errors = []
|
||||
upload_hash = ''
|
||||
|
||||
if 'upload_image' in request.FILES:
|
||||
upload_preview = request.FILES['upload_image']
|
||||
upload_preview.seek(0)
|
||||
|
||||
upload_hash = uuid.uuid4().hex
|
||||
loc = path.path(settings.PREVIEWS_PATH) / 'temp' / upload_hash
|
||||
loc = path.path(settings.TMP_PATH) / upload_type / upload_hash
|
||||
if not loc.dirname().exists():
|
||||
loc.dirname().makedirs()
|
||||
|
||||
|
@ -639,9 +641,27 @@ def upload_preview(request, addon_id, addon):
|
|||
for chunk in upload_preview:
|
||||
fd.write(chunk)
|
||||
|
||||
return {'upload_hash': upload_hash, 'errors': False}
|
||||
check = amo.utils.ImageCheck(upload_preview)
|
||||
if (not check.is_image() or
|
||||
upload_preview.content_type not in
|
||||
('image/png', 'image/jpeg', 'image/jpg')):
|
||||
errors.append(_('Icons must be either PNG or JPG.'))
|
||||
|
||||
if check.is_animated():
|
||||
errors.append(_('Icons cannot be animated.'))
|
||||
|
||||
if (upload_type == 'icon' and
|
||||
upload_preview.size > settings.MAX_ICON_UPLOAD_SIZE):
|
||||
errors.append(_('Please use images smaller than %dMB.') %
|
||||
(settings.MAX_ICON_UPLOAD_SIZE / 1024 / 1024 - 1))
|
||||
else:
|
||||
errors.append(_('There was an error uploading your preview.'))
|
||||
|
||||
if errors:
|
||||
upload_hash = ''
|
||||
|
||||
return {'upload_hash': upload_hash, 'errors': errors}
|
||||
|
||||
return {'errors': [_('There was an error uploading your preview.')]}
|
||||
|
||||
|
||||
@dev_required
|
||||
|
|
|
@ -214,11 +214,18 @@ function addonFormSubmit() {
|
|||
var baseurl = function(){
|
||||
return parent_div.find('#addon-edit-basic').attr('data-baseurl');
|
||||
}
|
||||
$('form', parent_div.not('#edit-addon-media')).submit(function(e){
|
||||
$('form', parent_div).submit(function(e){
|
||||
e.preventDefault();
|
||||
var old_baseurl = baseurl();
|
||||
parent_div.find(".item").removeClass("loaded").addClass("loading");
|
||||
var scrollBottom = $(document).height() - $(document).scrollTop();
|
||||
|
||||
if(parent_div.is('#edit-addon-media')) {
|
||||
if($('input[name=icon_type]:checked').val().match(/^image\//)) {
|
||||
setTimeout(checkImageStatus, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
$.post(parent_div.find('form').attr('action'),
|
||||
$(this).serialize(), function(d) {
|
||||
parent_div.html(d).each(addonFormSubmit);
|
||||
|
@ -237,6 +244,10 @@ function addonFormSubmit() {
|
|||
setTimeout(function(){ e.remove(); }, 1500);
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
if(parent_div.is('#edit-addon-media')) {
|
||||
hideSameSizedIcons();
|
||||
}
|
||||
});
|
||||
});
|
||||
z.refreshL10n();
|
||||
|
@ -298,70 +309,79 @@ function create_new_preview_field() {
|
|||
return last;
|
||||
}
|
||||
|
||||
function imageUploadFile(f, url, parent_form, upload_success, upload_errors) {
|
||||
var data = f.getAsBinary(),
|
||||
file = {},
|
||||
xhr = new XMLHttpRequest(),
|
||||
output = "",
|
||||
boundary = "BoUnDaRyStRiNg";
|
||||
|
||||
file.name = f.name || f.fileName;
|
||||
file.size = f.size;
|
||||
file.data = '';
|
||||
file.aborted = false;
|
||||
|
||||
xhr.open("POST", url, true);
|
||||
|
||||
xhr.setRequestHeader("Content-Length", file.size);
|
||||
xhr.setRequestHeader('Content-Disposition', 'file; name="upload";');
|
||||
xhr.setRequestHeader("X-File-Name", file.name);
|
||||
xhr.setRequestHeader("X-File-Size", file.size);
|
||||
|
||||
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
|
||||
xhr.setRequestHeader('Content-length', false);
|
||||
xhr.setRequestHeader("Content-Type", "multipart/form-data;" +
|
||||
"boundary=" + boundary);
|
||||
|
||||
output += "--" + boundary + "\r\n";
|
||||
output += "Content-Disposition: form-data; name=\"csrfmiddlewaretoken\";";
|
||||
|
||||
output += "\r\n\r\n";
|
||||
output += parent_form.find('input[name=csrfmiddlewaretoken]').val();
|
||||
output += "\r\n";
|
||||
|
||||
output += "--" + boundary + "\r\n";
|
||||
output += "Content-Disposition: form-data; name=\"upload_image\";";
|
||||
|
||||
output += " filename=\"new-upload\";\r\n";
|
||||
output += "Content-Type: " + f.type;
|
||||
|
||||
output += "\r\n\r\n";
|
||||
output += data;
|
||||
output += "\r\n";
|
||||
output += "--" + boundary + "--";
|
||||
|
||||
xhr.onreadystatechange = function(){
|
||||
if (xhr.readyState == 4 && xhr.responseText &&
|
||||
(xhr.status == 200 || xhr.status == 304)) {
|
||||
try {
|
||||
json = JSON.parse(xhr.responseText);
|
||||
} catch(err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(json.errors.length) {
|
||||
upload_errors(json.errors);
|
||||
} else {
|
||||
upload_success(json.upload_hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.sendAsBinary(output);
|
||||
}
|
||||
|
||||
function initUploadPreview() {
|
||||
$('#edit-addon-media, #submit-media').delegate('#screenshot_upload', 'change', function(e){
|
||||
url = $(this).attr('data-upload-url');
|
||||
|
||||
// TODO(gkoberger): Make sure this works on non-Fx browsers that don't
|
||||
//support multiple files
|
||||
$.each($('#screenshot_upload')[0].files, function(k, f){
|
||||
var form = create_new_preview_field(),
|
||||
upload_success = function(upload_hash){
|
||||
form.find('[name$=upload_hash]').val(upload_hash);
|
||||
},
|
||||
upload_errors = function(){};
|
||||
|
||||
var data = f.getAsBinary(),
|
||||
form = create_new_preview_field(),
|
||||
file = {},
|
||||
xhr = new XMLHttpRequest(),
|
||||
output = "",
|
||||
boundary = "BoUnDaRyStRiNg";
|
||||
|
||||
file.name = f.name || f.fileName;
|
||||
file.size = f.size;
|
||||
file.data = '';
|
||||
file.aborted = false;
|
||||
|
||||
xhr.open("POST", url, true);
|
||||
|
||||
xhr.setRequestHeader("Content-Length", file.size);
|
||||
xhr.setRequestHeader('Content-Disposition', 'file; name="upload";');
|
||||
xhr.setRequestHeader("X-File-Name", file.name);
|
||||
xhr.setRequestHeader("X-File-Size", file.size);
|
||||
|
||||
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
|
||||
xhr.setRequestHeader('Content-length', false);
|
||||
xhr.setRequestHeader("Content-Type", "multipart/form-data;" +
|
||||
"boundary=" + boundary);
|
||||
|
||||
output += "--" + boundary + "\r\n";
|
||||
output += "Content-Disposition: form-data; name=\"csrfmiddlewaretoken\";";
|
||||
|
||||
parent_form = $('#screenshot_upload').closest('form')
|
||||
output += "\r\n\r\n";
|
||||
output += parent_form.find('input[name=csrfmiddlewaretoken]').val();
|
||||
output += "\r\n";
|
||||
|
||||
output += "--" + boundary + "\r\n";
|
||||
output += "Content-Disposition: form-data; name=\"upload_preview\";";
|
||||
|
||||
output += " filename=\"new-upload\";\r\n";
|
||||
output += "Content-Type: " + f.type;
|
||||
|
||||
output += "\r\n\r\n";
|
||||
output += data;
|
||||
output += "\r\n";
|
||||
output += "--" + boundary + "--";
|
||||
|
||||
xhr.onreadystatechange = function(){
|
||||
if (xhr.readyState == 4 && xhr.responseText &&
|
||||
(xhr.status == 200 || xhr.status == 304)) {
|
||||
try {
|
||||
json = JSON.parse(xhr.responseText);
|
||||
} catch(err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
form.find('[name$=upload_hash]').val(json.upload_hash);
|
||||
}
|
||||
}
|
||||
xhr.sendAsBinary(output);
|
||||
imageUploadFile(f, url, $(form).closest('form'), upload_success, upload_errors);
|
||||
});
|
||||
|
||||
$('#screenshot_upload').val("");
|
||||
|
@ -377,26 +397,10 @@ function initUploadPreview() {
|
|||
}
|
||||
|
||||
function initUploadIcon() {
|
||||
$('#edit-addon-media').delegate('form', 'submit', function(e) {
|
||||
e.preventDefault();
|
||||
multipartUpload($(this), function(e, xhr){
|
||||
if (xhr.readyState == 4 && xhr.responseText &&
|
||||
(xhr.status == 200 || xhr.status == 304)) {
|
||||
$('#edit-addon-media').html(xhr.responseText);
|
||||
|
||||
hideSameSizedIcons();
|
||||
}
|
||||
});
|
||||
|
||||
if($('input[name=icon_type]:checked').val().match(/^image\//)) {
|
||||
setTimeout(checkImageStatus, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
$('#edit-addon-media, #submit-media').delegate('#icons_default a', 'click', function(e){
|
||||
e.preventDefault();
|
||||
|
||||
$('#edit-icon-error').hide();
|
||||
$('#edit-icon-error').parent().find('li').hide();
|
||||
|
||||
$parent = $(this).closest('li');
|
||||
$('input', $parent).attr('checked', true);
|
||||
|
@ -411,7 +415,7 @@ function initUploadIcon() {
|
|||
});
|
||||
|
||||
$('#edit-addon, #submit-media').delegate('#id_icon_upload', 'change', function(){
|
||||
$('#edit-icon-error').hide();
|
||||
$('#edit-icon-error').parent().find('li').hide();
|
||||
file = $('#id_icon_upload')[0].files[0];
|
||||
|
||||
if(file.type == 'image/jpeg' || file.type == 'image/png') {
|
||||
|
@ -420,8 +424,20 @@ function initUploadIcon() {
|
|||
$('input[name=icon_type][value='+file.type+']', $('#icons_default'))
|
||||
.attr('checked', true);
|
||||
|
||||
$('#icons_default a.active').removeClass('active');
|
||||
$('#icon_preview img').attr('src', file.getAsDataURL());
|
||||
var upload_errors = function(errors){
|
||||
$.each(errors, function(i, v){
|
||||
$('#icon_preview').parent().find('.errorlist').append("<li>" + v + "</li>");
|
||||
});
|
||||
}
|
||||
|
||||
var upload_success = function(upload_hash){
|
||||
$('#id_icon_upload_hash').val(upload_hash)
|
||||
$('#icons_default a.active').removeClass('active');
|
||||
$('#icon_preview img').attr('src', file.getAsDataURL());
|
||||
}
|
||||
|
||||
imageUploadFile(file, $(this).attr('data-upload-url'), $(this).closest('form'),
|
||||
upload_success, upload_errors);
|
||||
} else {
|
||||
error = gettext('This filetype is not supported.');
|
||||
$('#edit-icon-error').text(error).show();
|
||||
|
|
Загрузка…
Ссылка в новой задаче