from flask import request, jsonify from flask_classful import FlaskView, route from werkzeug.datastructures import MultiDict from werkzeug.utils import secure_filename import os import numpy as np from PIL import Image import json 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): def index(self): """ List all uploads """ session = Session() query = session.query(Upload) graph_id = args.get('graph_id', default=None) if graph_id is not None: query = query.filter(Upload.graph_id == int(graph_id)) items = query.all() res = { 'status': 'ok', 'res': [ item.toJSON() for item in items ], } session.close() return jsonify(res) 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) 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') try: graph_id = request.form.get('graph_id') # print(graph_id) except: raise APIError('No graph_id specified') try: settings = request.form.get('settings') settings = json.loads(settings) # print(graph_id) except: settings = {} 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, str(graph_id), 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, graph_id=graph_id, settings=settings) session.add(upload) session.commit() response = { 'status': 'ok', 'res': upload.toJSON(), } session.close() return jsonify(response) 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 uploaded_im_fn = secure_filename(sha256 + upload.ext) uploaded_im_abspath = os.path.join(app_cfg.DIR_UPLOADS, sha256_tree(sha256)) uploaded_im_fullpath = os.path.join(uploaded_im_abspath, uploaded_im_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)