implement dynamic file upload
This commit is contained in:
parent
2d72055070
commit
a1c024bfe2
35
htdocs/lib/settings/ImageUpload.js
Normal file
35
htdocs/lib/settings/ImageUpload.js
Normal file
@ -0,0 +1,35 @@
|
||||
$.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';
|
||||
|
||||
input.onchange = function(e) {
|
||||
var reader = new FileReader()
|
||||
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;
|
||||
});
|
||||
}
|
@ -22,4 +22,5 @@ $(function(){
|
||||
});
|
||||
|
||||
$(".sdrdevice").sdrdevice();
|
||||
$(".imageupload").imageUpload();
|
||||
});
|
@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GzipMixin(object):
|
||||
def send_response(self, content, headers=None, content_type="text/html", *args, **kwargs):
|
||||
def send_response(self, content, code=200, headers=None, content_type="text/html", *args, **kwargs):
|
||||
if self.zipable(content_type) and "accept-encoding" in self.request.headers:
|
||||
accepted = [s.strip().lower() for s in self.request.headers["accept-encoding"].split(",")]
|
||||
if "gzip" in accepted:
|
||||
@ -23,7 +23,7 @@ class GzipMixin(object):
|
||||
if headers is None:
|
||||
headers = {}
|
||||
headers["Content-Encoding"] = "gzip"
|
||||
super().send_response(content, headers=headers, content_type=content_type, *args, **kwargs)
|
||||
super().send_response(content, code, headers=headers, content_type=content_type, *args, **kwargs)
|
||||
|
||||
def zipable(self, content_type):
|
||||
types = ["application/javascript", "text/css", "text/html"]
|
||||
@ -78,7 +78,7 @@ class AssetsController(GzipMixin, ModificationAwareController, metaclass=ABCMeta
|
||||
f.close()
|
||||
|
||||
if content_type is None:
|
||||
(content_type, encoding) = mimetypes.MimeTypes().guess_type(file)
|
||||
(content_type, encoding) = mimetypes.MimeTypes().guess_type(self.getFilePath(file))
|
||||
self.send_response(data, content_type=content_type, last_modified=modified, max_age=3600)
|
||||
except FileNotFoundError:
|
||||
self.send_response("file not found", code=404)
|
||||
@ -137,6 +137,7 @@ class CompiledAssetsController(GzipMixin, ModificationAwareController):
|
||||
"lib/Header.js",
|
||||
"lib/settings/Input.js",
|
||||
"lib/settings/SdrDevice.js",
|
||||
"lib/settings/ImageUpload.js",
|
||||
"settings.js",
|
||||
],
|
||||
}
|
||||
|
32
owrx/controllers/imageupload.py
Normal file
32
owrx/controllers/imageupload.py
Normal file
@ -0,0 +1,32 @@
|
||||
from owrx.controllers.assets import AssetsController
|
||||
from owrx.config import CoreConfig
|
||||
import uuid
|
||||
import json
|
||||
|
||||
|
||||
class ImageUploadController(AssetsController):
|
||||
def __init__(self, handler, request, options):
|
||||
super().__init__(handler, request, options)
|
||||
self.uuid = request.query["uuid"][0] if "uuid" in request.query else None
|
||||
self.id = request.query["id"][0] if "id" in request.query else None
|
||||
|
||||
def getFilePath(self, file=None):
|
||||
if self.uuid is None:
|
||||
raise FileNotFoundError("missing uuid")
|
||||
if self.id is None:
|
||||
raise FileNotFoundError("missing id")
|
||||
return "{tmp}/{file}-{uuid}".format(
|
||||
tmp=CoreConfig().get_temporary_directory(),
|
||||
file=self.id,
|
||||
uuid=self.uuid,
|
||||
)
|
||||
|
||||
def indexAction(self):
|
||||
self.serve_file(None)
|
||||
|
||||
def processImage(self):
|
||||
self.uuid = uuid.uuid4().hex
|
||||
contents = self.get_body()
|
||||
with open(self.getFilePath(), 'wb') as f:
|
||||
f.write(contents)
|
||||
self.send_response(json.dumps({"uuid": self.uuid}), content_type="application/json")
|
@ -19,6 +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 urllib.parse import quote
|
||||
from owrx.wsjt import Fst4Profile, Fst4wProfile
|
||||
import json
|
||||
@ -107,6 +108,13 @@ class GeneralSettingsController(AdminController):
|
||||
TextInput("photo_title", "Photo title"),
|
||||
TextAreaInput("photo_desc", "Photo description"),
|
||||
),
|
||||
Section(
|
||||
"Receiver images",
|
||||
AvatarInput(
|
||||
"receiver_avatar",
|
||||
"Receiver Avatar",
|
||||
),
|
||||
),
|
||||
Section(
|
||||
"Receiver listings",
|
||||
TextAreaInput(
|
||||
|
@ -2,6 +2,16 @@ from owrx.form import Input
|
||||
|
||||
|
||||
class AvatarInput(Input):
|
||||
def render_input(self, value):
|
||||
pass
|
||||
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"/>
|
||||
<button class="btn btn-primary">Upload new image...</button>
|
||||
</div>
|
||||
""".format(
|
||||
id=self.id
|
||||
)
|
||||
|
@ -7,6 +7,7 @@ from owrx.controllers.metrics import MetricsController
|
||||
from owrx.controllers.settings import SettingsController, GeneralSettingsController, SdrSettingsController
|
||||
from owrx.controllers.session import SessionController
|
||||
from owrx.controllers.profile import ProfileController
|
||||
from owrx.controllers.imageupload import ImageUploadController
|
||||
from http.server import BaseHTTPRequestHandler
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
import re
|
||||
@ -112,6 +113,8 @@ class Router(object):
|
||||
StaticRoute("/logout", SessionController, options={"action": "logoutAction"}),
|
||||
StaticRoute("/pwchange", ProfileController),
|
||||
StaticRoute("/pwchange", ProfileController, method="POST", options={"action": "processPwChange"}),
|
||||
StaticRoute("/imageupload", ImageUploadController),
|
||||
StaticRoute("/imageupload", ImageUploadController, method="POST", options={"action": "processImage"}),
|
||||
]
|
||||
|
||||
def find_route(self, request):
|
||||
|
Loading…
Reference in New Issue
Block a user