Merge branch 'develop' into release-1.0
This commit is contained in:
commit
3daf005c81
@ -20,18 +20,22 @@ $.fn.imageUpload = function() {
|
|||||||
$this.removeClass('is-invalid');
|
$this.removeClass('is-invalid');
|
||||||
};
|
};
|
||||||
$uploadButton.click(function(){
|
$uploadButton.click(function(){
|
||||||
$uploadButton.prop('disabled', true);
|
|
||||||
var input = document.createElement('input');
|
var input = document.createElement('input');
|
||||||
input.type = 'file';
|
input.type = 'file';
|
||||||
input.accept = 'image/jpeg, image/png';
|
input.accept = 'image/jpeg, image/png, image/webp';
|
||||||
|
|
||||||
input.onchange = function(e) {
|
input.onchange = function(e) {
|
||||||
|
$uploadButton.prop('disabled', true);
|
||||||
|
var $spinner = $('<span class="spinner-border spinner-border-sm mr-1" role="status"></span>');
|
||||||
|
$uploadButton.prepend($spinner);
|
||||||
|
|
||||||
var reader = new FileReader()
|
var reader = new FileReader()
|
||||||
reader.readAsArrayBuffer(e.target.files[0]);
|
reader.readAsArrayBuffer(e.target.files[0]);
|
||||||
reader.onprogress = function(e) {
|
reader.onprogress = function(e) {
|
||||||
if (e.loaded > maxSize) {
|
if (e.loaded > maxSize) {
|
||||||
handleError('Maximum file size exceeded');
|
handleError('Maximum file size exceeded');
|
||||||
$uploadButton.prop('disabled', false);
|
$uploadButton.prop('disabled', false);
|
||||||
|
$spinner.remove();
|
||||||
reader.abort();
|
reader.abort();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -39,6 +43,7 @@ $.fn.imageUpload = function() {
|
|||||||
if (e.loaded > maxSize) {
|
if (e.loaded > maxSize) {
|
||||||
handleError('Maximum file size exceeded');
|
handleError('Maximum file size exceeded');
|
||||||
$uploadButton.prop('disabled', false);
|
$uploadButton.prop('disabled', false);
|
||||||
|
$spinner.remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@ -49,6 +54,10 @@ $.fn.imageUpload = function() {
|
|||||||
contentType: 'application/octet-stream',
|
contentType: 'application/octet-stream',
|
||||||
}).done(function(data){
|
}).done(function(data){
|
||||||
$input.val(data.file);
|
$input.val(data.file);
|
||||||
|
$img.one('load', function() {
|
||||||
|
$uploadButton.prop('disabled', false);
|
||||||
|
$spinner.remove();
|
||||||
|
});
|
||||||
$img.prop('src', '../imageupload?file=' + data.file);
|
$img.prop('src', '../imageupload?file=' + data.file);
|
||||||
clearError();
|
clearError();
|
||||||
}).fail(function(xhr, error){
|
}).fail(function(xhr, error){
|
||||||
@ -58,8 +67,8 @@ $.fn.imageUpload = function() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
}
|
}
|
||||||
}).always(function(){
|
|
||||||
$uploadButton.prop('disabled', false);
|
$uploadButton.prop('disabled', false);
|
||||||
|
$spinner.remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -96,7 +96,7 @@ class OwrxAssetsController(AssetsController):
|
|||||||
}
|
}
|
||||||
if file in mappedFiles and ("mapped" not in self.request.query or self.request.query["mapped"][0] != "false"):
|
if file in mappedFiles and ("mapped" not in self.request.query or self.request.query["mapped"][0] != "false"):
|
||||||
config = CoreConfig()
|
config = CoreConfig()
|
||||||
for ext in ["png", "jpg"]:
|
for ext in ["png", "jpg", "webp"]:
|
||||||
user_file = "{}/{}.{}".format(config.get_data_directory(), mappedFiles[file], ext)
|
user_file = "{}/{}.{}".format(config.get_data_directory(), mappedFiles[file], ext)
|
||||||
if os.path.exists(user_file) and os.path.isfile(user_file):
|
if os.path.exists(user_file) and os.path.isfile(user_file):
|
||||||
return user_file
|
return user_file
|
||||||
|
@ -36,6 +36,9 @@ class ImageUploadController(AuthorizationMixin, AssetsController):
|
|||||||
def _is_jpg(self, contents):
|
def _is_jpg(self, contents):
|
||||||
return contents[0:3] == bytes([0xFF, 0xD8, 0xFF])
|
return contents[0:3] == bytes([0xFF, 0xD8, 0xFF])
|
||||||
|
|
||||||
|
def _is_webp(self, contents):
|
||||||
|
return contents[0:4] == bytes([0x52, 0x49, 0x46, 0x46]) and contents[8:12] == bytes([0x57, 0x45, 0x42, 0x50])
|
||||||
|
|
||||||
def processImage(self):
|
def processImage(self):
|
||||||
if "id" not in self.request.query:
|
if "id" not in self.request.query:
|
||||||
self.send_json_response({"error": "missing id"}, code=400)
|
self.send_json_response({"error": "missing id"}, code=400)
|
||||||
@ -55,8 +58,10 @@ class ImageUploadController(AuthorizationMixin, AssetsController):
|
|||||||
filetype = None
|
filetype = None
|
||||||
if self._is_png(contents):
|
if self._is_png(contents):
|
||||||
filetype = "png"
|
filetype = "png"
|
||||||
if self._is_jpg(contents):
|
elif self._is_jpg(contents):
|
||||||
filetype = "jpg"
|
filetype = "jpg"
|
||||||
|
elif self._is_webp(contents):
|
||||||
|
filetype = "webp"
|
||||||
if filetype is None:
|
if filetype is None:
|
||||||
self.send_json_response({"error": "unsupported file type"}, code=400)
|
self.send_json_response({"error": "unsupported file type"}, code=400)
|
||||||
return
|
return
|
||||||
|
@ -19,6 +19,7 @@ from owrx.breadcrumb import Breadcrumb, BreadcrumbItem
|
|||||||
from owrx.controllers.settings import SettingsBreadcrumb
|
from owrx.controllers.settings import SettingsBreadcrumb
|
||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -170,22 +171,33 @@ class GeneralSettingsController(SettingsFormController):
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def handle_image(self, data, image_id):
|
def remove_existing_image(self, image_id):
|
||||||
if image_id in data:
|
|
||||||
config = CoreConfig()
|
config = CoreConfig()
|
||||||
if data[image_id] == "restore":
|
|
||||||
# remove all possible file extensions
|
# remove all possible file extensions
|
||||||
for ext in ["png", "jpg"]:
|
for ext in ["png", "jpg", "webp"]:
|
||||||
try:
|
try:
|
||||||
os.unlink("{}/{}.{}".format(config.get_data_directory(), image_id, ext))
|
os.unlink("{}/{}.{}".format(config.get_data_directory(), image_id, ext))
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def handle_image(self, data, image_id):
|
||||||
|
if image_id in data:
|
||||||
|
config = CoreConfig()
|
||||||
|
if data[image_id] == "restore":
|
||||||
|
self.remove_existing_image(image_id)
|
||||||
elif data[image_id]:
|
elif data[image_id]:
|
||||||
if not data[image_id].startswith(image_id):
|
if not data[image_id].startswith(image_id):
|
||||||
logger.warning("invalid file name: %s", data[image_id])
|
logger.warning("invalid file name: %s", data[image_id])
|
||||||
else:
|
else:
|
||||||
# get file extension (luckily, all options are three characters long)
|
# get file extension (at least 3 characters)
|
||||||
ext = data[image_id][-3:]
|
# should be all lowercase since they are set by the upload script
|
||||||
|
pattern = re.compile(".*\\.([a-z]{3,})$")
|
||||||
|
matches = pattern.match(data[image_id])
|
||||||
|
if matches is None:
|
||||||
|
logger.warning("could not determine file extension for %s", image_id)
|
||||||
|
else:
|
||||||
|
self.remove_existing_image(image_id)
|
||||||
|
ext = matches.group(1)
|
||||||
data_file = "{}/{}.{}".format(config.get_data_directory(), image_id, ext)
|
data_file = "{}/{}.{}".format(config.get_data_directory(), image_id, ext)
|
||||||
temporary_file = "{}/{}".format(config.get_temporary_directory(), data[image_id])
|
temporary_file = "{}/{}".format(config.get_temporary_directory(), data[image_id])
|
||||||
shutil.copy(temporary_file, data_file)
|
shutil.copy(temporary_file, data_file)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user