Merge branch 'develop' into release-1.0

This commit is contained in:
Jakob Ketterl 2021-05-07 17:53:51 +02:00
commit 3daf005c81
4 changed files with 42 additions and 16 deletions

View File

@ -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();
}); });
} }
}; };

View File

@ -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

View 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

View File

@ -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)