implement uploading of top panorama, too
This commit is contained in:
parent
ad5daaae95
commit
3b670016be
@ -32,4 +32,14 @@ h1 {
|
||||
|
||||
.q65-matrix {
|
||||
grid-template-columns: repeat(5, auto);
|
||||
}
|
||||
}
|
||||
|
||||
.imageupload .image-container {
|
||||
max-width: 100%;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.imageupload img.webrx-top-photo {
|
||||
max-height: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
@ -1,36 +1,37 @@
|
||||
$.fn.imageUpload = function() {
|
||||
var $button = $(this).find('button');
|
||||
var $img = $(this).find('img');
|
||||
var $input = $(this).find('input');
|
||||
var id = $input.prop('id');
|
||||
console.info(id);
|
||||
$button.click(function(){
|
||||
$button.prop('disabled', true);
|
||||
var input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.accept = 'image/jpeg, image/png';
|
||||
$.each(this, function(){
|
||||
var $button = $(this).find('button');
|
||||
var $img = $(this).find('img');
|
||||
var $input = $(this).find('input');
|
||||
var id = $input.prop('id');
|
||||
$button.click(function(){
|
||||
$button.prop('disabled', true);
|
||||
var input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.accept = 'image/jpeg, image/png';
|
||||
|
||||
input.onchange = function(e) {
|
||||
var reader = new FileReader()
|
||||
// TODO: implement file size check
|
||||
reader.readAsArrayBuffer(e.target.files[0]);
|
||||
reader.onload = function(e) {
|
||||
$.ajax({
|
||||
url: '/imageupload?id=' + id,
|
||||
type: 'POST',
|
||||
data: e.target.result,
|
||||
processData: false,
|
||||
contentType: 'application/octet-stream',
|
||||
}).done(function(data){
|
||||
$input.val(data.uuid);
|
||||
$img.prop('src', "/imageupload?id=" + id + "&uuid=" + data.uuid);
|
||||
}).always(function(){
|
||||
$button.prop('disabled', false);
|
||||
});
|
||||
}
|
||||
};
|
||||
input.onchange = function(e) {
|
||||
var reader = new FileReader()
|
||||
// TODO: implement file size check
|
||||
reader.readAsArrayBuffer(e.target.files[0]);
|
||||
reader.onload = function(e) {
|
||||
$.ajax({
|
||||
url: '/imageupload?id=' + id,
|
||||
type: 'POST',
|
||||
data: e.target.result,
|
||||
processData: false,
|
||||
contentType: 'application/octet-stream',
|
||||
}).done(function(data){
|
||||
$input.val(data.uuid);
|
||||
$img.prop('src', "/imageupload?id=" + id + "&uuid=" + data.uuid);
|
||||
}).always(function(){
|
||||
$button.prop('disabled', false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
input.click();
|
||||
return false;
|
||||
input.click();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
@ -90,11 +90,15 @@ class AssetsController(GzipMixin, ModificationAwareController, metaclass=ABCMeta
|
||||
|
||||
class OwrxAssetsController(AssetsController):
|
||||
def getFilePath(self, file):
|
||||
mappedFiles = {
|
||||
"gfx/openwebrx-avatar.png": "receiver_avatar",
|
||||
"gfx/openwebrx-top-photo.jpg": "receiver_top_photo",
|
||||
}
|
||||
config = CoreConfig()
|
||||
if file == "gfx/openwebrx-avatar.png":
|
||||
file = config.get_data_directory() + "/receiver_avatar"
|
||||
if os.path.exists(file) and os.path.isfile(file):
|
||||
return file
|
||||
if file in mappedFiles:
|
||||
user_file = config.get_data_directory() + "/" + mappedFiles[file]
|
||||
if os.path.exists(user_file) and os.path.isfile(user_file):
|
||||
return user_file
|
||||
return pkg_resources.resource_filename("htdocs", file)
|
||||
|
||||
|
||||
|
@ -28,7 +28,9 @@ class ImageUploadController(AssetsController):
|
||||
def processImage(self):
|
||||
self.uuid = uuid.uuid4().hex
|
||||
# TODO: limit file size
|
||||
# TODO: check image mime type, if possible
|
||||
contents = self.get_body()
|
||||
# TODO: clean up files after timeout or on shutdown
|
||||
with open(self.getFilePath(), 'wb') as f:
|
||||
f.write(contents)
|
||||
self.send_response(json.dumps({"uuid": self.uuid}), content_type="application/json")
|
||||
|
@ -19,7 +19,7 @@ from owrx.form.receiverid import ReceiverKeysConverter
|
||||
from owrx.form.aprs import AprsBeaconSymbols, AprsAntennaDirections
|
||||
from owrx.form.wfm import WfmTauValues
|
||||
from owrx.form.wsjt import Q65ModeMatrix
|
||||
from owrx.form.gfx import AvatarInput
|
||||
from owrx.form.gfx import AvatarInput, TopPhotoInput
|
||||
from urllib.parse import quote
|
||||
from owrx.wsjt import Fst4Profile, Fst4wProfile
|
||||
import json
|
||||
@ -115,6 +115,10 @@ class GeneralSettingsController(AdminController):
|
||||
"receiver_avatar",
|
||||
"Receiver Avatar",
|
||||
),
|
||||
TopPhotoInput(
|
||||
"receiver_top_photo",
|
||||
"Receiver Panorama",
|
||||
),
|
||||
),
|
||||
Section(
|
||||
"Receiver listings",
|
||||
@ -303,11 +307,7 @@ class GeneralSettingsController(AdminController):
|
||||
append="dBi",
|
||||
converter=OptionalConverter(),
|
||||
),
|
||||
DropdownInput(
|
||||
"aprs_igate_dir",
|
||||
"Antenna direction",
|
||||
AprsAntennaDirections
|
||||
),
|
||||
DropdownInput("aprs_igate_dir", "Antenna direction", AprsAntennaDirections),
|
||||
),
|
||||
Section(
|
||||
"pskreporter settings",
|
||||
@ -365,14 +365,11 @@ class GeneralSettingsController(AdminController):
|
||||
return variables
|
||||
|
||||
def handle_image(self, data, image_id):
|
||||
if image_id not in data:
|
||||
if image_id not in data or not data[image_id]:
|
||||
return
|
||||
config = CoreConfig()
|
||||
filename = "{}-{}".format(image_id, data[image_id])
|
||||
shutil.copy(
|
||||
config.get_temporary_directory() + "/" + filename,
|
||||
config.get_data_directory() + "/" + image_id
|
||||
)
|
||||
shutil.copy(config.get_temporary_directory() + "/" + filename, config.get_data_directory() + "/" + image_id)
|
||||
del data[image_id]
|
||||
|
||||
def processFormData(self):
|
||||
@ -380,6 +377,7 @@ class GeneralSettingsController(AdminController):
|
||||
data = {k: v for i in GeneralSettingsController.sections for k, v in i.parse(data).items()}
|
||||
# Image handling
|
||||
self.handle_image(data, "receiver_avatar")
|
||||
self.handle_image(data, "receiver_top_photo")
|
||||
config = Config.get()
|
||||
for k, v in data.items():
|
||||
if v is None:
|
||||
|
@ -2,14 +2,28 @@ from owrx.form import Input
|
||||
|
||||
|
||||
class AvatarInput(Input):
|
||||
def __init__(self, id, label, infotext=None):
|
||||
super().__init__(id, label, infotext=infotext)
|
||||
|
||||
def render_input(self, value):
|
||||
return """
|
||||
<div class="imageupload">
|
||||
<input type="hidden" id="{id}" name="{id}">
|
||||
<img class="webrx-rx-avatar" src="static/gfx/openwebrx-avatar.png" alt="Receiver avatar"/>
|
||||
<div class="image-container">
|
||||
<img class="webrx-rx-avatar" src="static/gfx/openwebrx-avatar.png" alt="Receiver avatar"/>
|
||||
</div>
|
||||
<button class="btn btn-primary">Upload new image...</button>
|
||||
</div>
|
||||
""".format(
|
||||
id=self.id
|
||||
)
|
||||
|
||||
|
||||
class TopPhotoInput(Input):
|
||||
def render_input(self, value):
|
||||
return """
|
||||
<div class="imageupload">
|
||||
<input type="hidden" id="{id}" name="{id}">
|
||||
<div class="image-container">
|
||||
<img class="webrx-top-photo" src="static/gfx/openwebrx-top-photo.jpg" alt="Receiver Panorama"/>
|
||||
</div>
|
||||
<button class="btn btn-primary">Upload new image...</button>
|
||||
</div>
|
||||
""".format(
|
||||
|
Loading…
Reference in New Issue
Block a user