from flask import request, jsonify from flask_classful import FlaskView, route from flask_jwt_extended import jwt_required from werkzeug.datastructures import MultiDict from werkzeug.utils import secure_filename import os import numpy as np from PIL import Image from app.settings import app_cfg from app.sql.common import db, Session from app.sql.models.upload import Upload from app.utils.file_utils import sha256_stream, sha256_tree, VALID_IMAGE_EXTS from app.server.decorators import APIError class UploadView(FlaskView): @jwt_required() def index(self): """ List all uploaded files. * Query string params: offset, limit, sort (id, date), order (asc, desc) """ session = Session() uploads = session.query(Upload).all() response = { 'status': 'ok', 'res': [ upload.toJSON() for upload in uploads ], } session.close() return jsonify(response) @jwt_required() def get(self, id): """ Fetch a single upload. """ session = Session() upload = session.query(Upload).get(id) response = { 'status': 'ok', 'res': upload.toJSON(), } session.close() return jsonify(response) @jwt_required() def post(self): """ Upload a new file. * JSON params: username """ try: username = request.form.get('username') # print(username) except: raise APIError('No username specified') try: tag = request.form.get('tag') # print(tag) except: raise APIError('No tag specified') if 'image' in request.files: file = request.files['image'] # print(fn) elif 'file' in request.files: file = request.files['file'] # print(request.form.get('__image_filename')) # print(fn) else: raise APIError('No file uploaded') # get sha256 sha256 = sha256_stream(file) _, ext = os.path.splitext(file.filename) if ext == '.jpeg': ext = '.jpg' ext = ext[1:] file.seek(0) uploaded_im_fn = secure_filename(file.filename) uploaded_im_abspath = os.path.join(app_cfg.DIR_UPLOADS, tag) uploaded_im_fullpath = os.path.join(uploaded_im_abspath, uploaded_im_fn) session = Session() upload = session.query(Upload).filter_by(sha256=sha256).first() if upload is not None: print("Already uploaded file") if not os.path.exists(uploaded_im_fullpath): # if we got in some weird state where the record wasnt deleted.... os.makedirs(uploaded_im_abspath, exist_ok=True) file.save(uploaded_im_fullpath) response = { 'status': 'ok', 'notes': 'File already uploaded', 'res': upload.toJSON(), } session.close() return jsonify(response) os.makedirs(uploaded_im_abspath, exist_ok=True) file.save(uploaded_im_fullpath) upload = Upload(username=username, tag=tag, fn=uploaded_im_fn, sha256=sha256, ext=ext) session.add(upload) session.commit() response = { 'status': 'ok', 'res': upload.toJSON(), } session.close() return jsonify(response) @jwt_required() def delete(self, id): """ Delete an uploaded file. """ session = Session() upload = session.query(Upload).get(id) if not upload: session.close() return jsonify({ 'status': 'error', 'error': 'not found', }) sha256 = upload.sha256 fn = upload.fn tag = upload.tag # uploaded_im_fn = secure_filename(fn) uploaded_im_abspath = os.path.join(app_cfg.DIR_UPLOADS, tag) uploaded_im_fullpath = os.path.join(uploaded_im_abspath, fn) # uploaded_im_fullpath = os.path.join(uploaded_im_abspath, fn) if os.path.exists(uploaded_im_fullpath): print("Removing " + uploaded_im_fullpath) os.remove(uploaded_im_fullpath) session.delete(upload) session.commit() response = { 'status': 'ok', 'id': id, } session.close() return jsonify(response)