def put(self): """ This endpoint is used to upload user avatar. All avatars are named after the user's id in such format: user_{id}.{ext}. It will overwrite the existing avatar. """ data = image_schema.load(request.files) filename = f"user_{g.user.id}" folder = "avatars" avatar_path = image_helper.find_image_any_format(filename, folder) if avatar_path: try: os.remove(avatar_path) except: return {"message": gettext("avatar_delete_failed")}, 500 try: ext = image_helper.get_extension(data[0]["image"].filename) avatar = filename + ext # use our naming format + true extension avatar_path = image_helper.save_image( data[0]["image"], folder=folder, name=avatar ) basename = image_helper.get_basename(avatar_path) return {"message": gettext("avatar_uploaded").format(basename)}, 200 except UploadNotAllowed: # forbidden file type extension = image_helper.get_extension(data[0]["image"]) return {"message": gettext("image_illegal_extension").format(extension)}, 400
def get(self, filename: str): """ This endpoint returns the requested image if exists. It will use JWT to retrieve user information and look for the image inside the user's folder. """ user_id = g.user.id folder = f"user_{user_id}" # check if filename is URL secure if not image_helper.is_filename_safe(filename): return {"message": gettext("image_illegal_file_name").format(filename)}, 400 try: # try to send the requested file to the user with status code 200 return send_file(image_helper.get_path(filename, folder=folder)) except FileNotFoundError: return {"message": gettext("image_not_found").format(filename)}, 404
def get(cls, user_id: int): """ This endpoint returns the avatar of the user specified by user_id. """ folder = "avatars" filename = f"user_{user_id}" avatar = image_helper.find_image_any_format(filename, folder) if avatar: return send_file(avatar) return {"message": gettext("avatar_not_found")}, 404
def delete(self, filename: str): """ This endpoint is used to delete the requested image under the user's folder. It uses the JWT to retrieve user information. """ user_id = g.user.id folder = f"user_{user_id}" # check if filename is URL secure if not image_helper.is_filename_safe(filename): return {"message": gettext("image_illegal_file_name").format(filename)}, 400 try: os.remove(image_helper.get_path(filename, folder=folder)) return {"message": gettext("image_deleted").format(filename)}, 200 except FileNotFoundError: return {"message": gettext("image_not_found").format(filename)}, 404 except: traceback.print_exc() return {"message": gettext("image_delete_failed")}, 500
def post(self): """ This endpoint is used to upload an image file. It uses the JWT to retrieve user information and save the image in the user's folder. If a file with the same name exists in the user's folder, name conflicts will be automatically resolved by appending a underscore and a smallest unused integer. (eg. filename.png to filename_1.png). """ data = image_schema.load(request.files) user_id = g.user.id folder = f"user_{user_id}" try: # save(self, storage, folder=None, name=None) image_path = image_helper.save_image(data[0]['image'], folder=folder) # here we only return the basename of the image and hide the internal folder structure from our user basename = image_helper.get_basename(image_path) return {"message": gettext("image_uploaded").format(basename)}, 201 except UploadNotAllowed: # forbidden file type extension = image_helper.get_extension(data["image"]) return {"message": gettext("image_illegal_extension").format(extension)}, 400