2021-04-29 16:18:18 +00:00
|
|
|
from owrx.controllers import BodySizeError
|
2021-02-08 22:29:24 +00:00
|
|
|
from owrx.controllers.assets import AssetsController
|
2021-02-10 19:32:07 +00:00
|
|
|
from owrx.controllers.admin import AuthorizationMixin
|
2021-02-11 18:31:44 +00:00
|
|
|
from owrx.config.core import CoreConfig
|
2021-04-29 16:18:18 +00:00
|
|
|
from owrx.form.input.gfx import AvatarInput, TopPhotoInput
|
2021-02-08 22:29:24 +00:00
|
|
|
import uuid
|
|
|
|
import json
|
|
|
|
|
|
|
|
|
2021-02-10 19:32:07 +00:00
|
|
|
class ImageUploadController(AuthorizationMixin, AssetsController):
|
2021-04-29 16:18:18 +00:00
|
|
|
# max upload filesizes
|
|
|
|
max_sizes = {
|
|
|
|
# not the best idea to instantiate inputs, but i didn't want to duplicate the sizes here
|
|
|
|
"receiver_avatar": AvatarInput("id", "label").getMaxSize(),
|
|
|
|
"receiver_top_photo": TopPhotoInput("id", "label").getMaxSize(),
|
|
|
|
}
|
|
|
|
|
2021-02-08 22:29:24 +00:00
|
|
|
def __init__(self, handler, request, options):
|
|
|
|
super().__init__(handler, request, options)
|
2021-02-10 23:20:17 +00:00
|
|
|
self.file = request.query["file"][0] if "file" in request.query else None
|
2021-02-08 22:29:24 +00:00
|
|
|
|
|
|
|
def getFilePath(self, file=None):
|
2021-02-10 23:20:17 +00:00
|
|
|
if self.file is None:
|
|
|
|
raise FileNotFoundError("missing filename")
|
|
|
|
return "{tmp}/{file}".format(
|
2021-02-08 22:29:24 +00:00
|
|
|
tmp=CoreConfig().get_temporary_directory(),
|
2021-02-10 23:20:17 +00:00
|
|
|
file=self.file
|
2021-02-08 22:29:24 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
def indexAction(self):
|
|
|
|
self.serve_file(None)
|
|
|
|
|
2021-02-10 23:20:17 +00:00
|
|
|
def _is_png(self, contents):
|
|
|
|
return contents[0:8] == bytes([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])
|
|
|
|
|
|
|
|
def _is_jpg(self, contents):
|
|
|
|
return contents[0:3] == bytes([0xFF, 0xD8, 0xFF])
|
|
|
|
|
2021-05-07 14:57:54 +00:00
|
|
|
def _is_webp(self, contents):
|
|
|
|
return contents[0:4] == bytes([0x52, 0x49, 0x46, 0x46]) and contents[8:12] == bytes([0x57, 0x45, 0x42, 0x50])
|
|
|
|
|
2021-02-08 22:29:24 +00:00
|
|
|
def processImage(self):
|
2021-02-10 23:20:17 +00:00
|
|
|
if "id" not in self.request.query:
|
2021-04-29 16:18:18 +00:00
|
|
|
self.send_json_response({"error": "missing id"}, code=400)
|
|
|
|
return
|
|
|
|
file_id = self.request.query["id"][0]
|
|
|
|
|
|
|
|
if file_id not in ImageUploadController.max_sizes:
|
|
|
|
self.send_json_response({"error": "unexpected image id"}, code=400)
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
contents = self.get_body(ImageUploadController.max_sizes[file_id])
|
|
|
|
except BodySizeError:
|
|
|
|
self.send_json_response({"error": "file size too large"}, code=400)
|
|
|
|
return
|
|
|
|
|
2021-02-10 23:20:17 +00:00
|
|
|
filetype = None
|
|
|
|
if self._is_png(contents):
|
|
|
|
filetype = "png"
|
2021-05-07 14:57:54 +00:00
|
|
|
elif self._is_jpg(contents):
|
2021-02-10 23:20:17 +00:00
|
|
|
filetype = "jpg"
|
2021-05-07 14:57:54 +00:00
|
|
|
elif self._is_webp(contents):
|
|
|
|
filetype = "webp"
|
2021-02-10 23:20:17 +00:00
|
|
|
if filetype is None:
|
2021-04-29 16:18:18 +00:00
|
|
|
self.send_json_response({"error": "unsupported file type"}, code=400)
|
|
|
|
return
|
|
|
|
|
|
|
|
self.file = "{id}-{uuid}.{ext}".format(
|
|
|
|
id=file_id,
|
|
|
|
uuid=uuid.uuid4().hex,
|
|
|
|
ext=filetype,
|
|
|
|
)
|
|
|
|
with open(self.getFilePath(), "wb") as f:
|
|
|
|
f.write(contents)
|
|
|
|
self.send_json_response({"file": self.file}, code=200)
|
|
|
|
|
|
|
|
def send_json_response(self, obj, code):
|
|
|
|
self.send_response(json.dumps(obj), code=code, content_type="application/json")
|