summaryrefslogtreecommitdiff
path: root/old/server/app/main/views.py
diff options
context:
space:
mode:
Diffstat (limited to 'old/server/app/main/views.py')
-rw-r--r--old/server/app/main/views.py300
1 files changed, 300 insertions, 0 deletions
diff --git a/old/server/app/main/views.py b/old/server/app/main/views.py
new file mode 100644
index 00000000..11a8ca53
--- /dev/null
+++ b/old/server/app/main/views.py
@@ -0,0 +1,300 @@
+import os
+import uuid
+import json
+from flask import render_template, redirect, url_for, send_from_directory
+from flask import request, make_response, jsonify
+from . import main, utils
+from .tasks import task_lookup, make_task_json
+from PIL import Image, ImageOps
+import cv2 as cv
+
+from .paths import get_paths
+
+from flask import current_app as app
+from werkzeug.utils import secure_filename
+import imutils
+
+# ------------------------------------------------------------
+# Temp: run mask rcnn outside celery
+# ------------------------------------------------------------
+
+# init image processors
+import sys
+from .img_proc_config import ImgProcConfig
+sys.path.append('/dulldream/src/')
+from image_processors.mask_rcnn import MaskRCNN
+from utils import imx
+from utils import fiox
+
+img_proc_congif = ImgProcConfig()
+mask_rcnn = MaskRCNN(img_proc_congif.mask_rcnn_class_config,
+ model_path=img_proc_congif.mask_rcnn_model)
+
+# ------------------------------------------------------------
+# Tasks
+# ------------------------------------------------------------
+
+@main.route('/status/<task_name>/<task_id>')
+def task_status(task_name, task_id):
+ """Return celery image processing status"""
+ if task_name in task_lookup:
+ task = task_lookup[task_name]['task'].AsyncResult(task_id)
+ else:
+ return jsonify({
+ 'state': 'error',
+ 'percent': 100,
+ 'message': 'Unknown task'
+ })
+
+ app.logger.info('task state: {}'.format(task.state))
+ if task.state == 'PENDING':
+ response = {
+ 'state': task.state,
+ 'percent': 0,
+ 'message': 'Pending...'
+ }
+ elif task.state != 'FAILURE':
+ response = {
+ 'state': task.state,
+ 'percent': task.info.get('percent', 0),
+ 'uuid': task.info.get('uuid', 0),
+ 'message': task.info.get('message', '')
+ }
+ if 'result' in task.info:
+ response['result'] = task.info['result']
+ else:
+ # something went wrong in the background job
+ response = {
+ 'state': task.state,
+ 'percent': 100,
+ 'message': str(task.info), # this is the exception raised
+ }
+ return jsonify(response)
+
+# ------------------------------------------------------------
+# POST Routes
+# ------------------------------------------------------------
+
+@main.route('/upload/sleep', methods=['GET', 'POST'])
+def sleep_test():
+ async_task = task_lookup['sleep']['task'].apply_async(args=['sleep_test'])
+ task_url = url_for('main.task_status', task_name='sleep', task_id=async_task.id)
+ return jsonify({
+ 'result': True,
+ 'task_url': task_url,
+ })
+
+@main.route('/upload', methods=['POST'])
+def upload():
+
+ style = request.form['style']
+ print('style',style)
+ if style in task_lookup:
+ task = task_lookup[style]['task']
+ print('task',task)
+ else:
+ return jsonify({
+ 'result': False,
+ 'error': 'Unknown task',
+ })
+
+ file = request.files['user_image']
+ agree = bool(request.form['agree'])
+ ext = request.form['ext']
+ if ext is None:
+ ext = request.files['ext']
+
+ uuid_name = str(uuid.uuid4())
+
+ app.logger.info('[+] style: {}'.format(style))
+ app.logger.info('[+] ext: {}'.format(ext))
+ app.logger.info('[+] uuid_name: {}'.format(uuid_name))
+ app.logger.info('[+] agreed: {}'.format(agree))
+
+ # convert PNG to JPG
+ print('[+] Resizing image')
+
+ # LOL MaskRCNN needs to be run outside of the Celery Task
+ im = Image.open(file.stream).convert('RGB')
+ im = ImageOps.fit(im,(512,512))
+ if agree:
+ upload_folder = app.config['UPLOADS']
+ else:
+ upload_folder = app.config['UPLOADS_PRIVATE']
+
+ fpath = os.path.join(upload_folder, uuid_name + '.jpg')
+
+ # Save image to disk
+ print('[+] Save image to {}'.format(fpath))
+ im.save(fpath, 'JPEG', quality=100)
+ im_pil_256 = im.resize((256,256))
+
+ print('[+] ensure_np...')
+ im_np = imx.ensure_np(im_pil_256)
+ #print('[+] resize np...')
+ #im_np = imutils.resize(im_np,width=256)
+
+ upload_dir, render_dir, json_dir, upload_uri, render_uri = get_paths(agree)
+
+ print('[+] Run mrcnn...')
+ try:
+ result = mask_rcnn.create_segmentations(im_np,concat=True)
+ except:
+ print('[-] Error. Could not run mask_rcnn')
+ result = []
+
+ if len(result) > 0:
+ result = result[0]
+
+ # save data, then pass to celery task
+ print('[+] Save masks')
+ seg_mask = result['seg_mask']
+ fpath_seg_mask = os.path.join(render_dir, uuid_name + '_seg_mask.jpg')
+ #cv.imwrite(fpath_seg_mask,cv.cvtColor(seg_mask,cv.COLOR_BGR2RGB))
+ #seg_mask = seg_mask[:,:,::-1]
+ seg_mask_pil = imx.ensure_pil(seg_mask)
+ seg_mask_pil.save(fpath_seg_mask, 'JPEG', quality=100)
+
+ im_mask = result['im_mask']
+ fpath_im_mask = os.path.join(render_dir, uuid_name + '_im_mask.jpg')
+ #im_mask = im_mask[:,:,::-1]
+ im_mask_pil = imx.ensure_pil(im_mask)
+ im_mask_pil.save(fpath_im_mask, 'JPEG',quality=100)
+ #cv.imwrite(fpath_im_mask,cv.cvtColor(im_mask,cv.COLOR_BGR2RGB))
+
+ celery_result = {
+ 'score':str(result['score']),
+ 'name':str(result['name']),
+ 'class_index':str(result['class_index']),
+ 'color':str(result['color']),
+ 'fp_im_mask':fpath_im_mask,
+ 'fp_seg_mask':fpath_seg_mask,
+ 'valid':True
+ }
+ else:
+ print('[-] no reults. process background only')
+ celery_result = {
+ 'score':None,
+ 'name':None,
+ 'class_index':None,
+ 'color':None,
+ 'fp_im_mask':None,
+ 'fp_seg_mask':None,
+ 'valid':False
+ }
+
+ print('[+] Start celery')
+ async_task = task.apply_async(args=[uuid_name, agree, celery_result])
+ task_url = url_for('main.task_status', task_name=style, task_id=async_task.id)
+
+ return jsonify({
+ 'result': True,
+ 'task_url': task_url,
+ 'uuid': uuid_name
+ })
+
+
+
+# ----------------------------------------------------
+# Fileserver, temp solution
+# ----------------------------------------------------
+
+@main.route('/img/<string:imtype>/<string:uuid_name>')
+def get_image(imtype,uuid_name):
+ """Return image files from render or uploads"""
+ if imtype == 'uploads':
+ d = app.config['UPLOADS']
+ suffix = ''
+ elif imtype == 'renders':
+ d = app.config['RENDERS']
+ suffix = ''
+ elif imtype == 'fcn':
+ d = app.config['RENDERS']
+ suffix = '_fcn8'
+
+ fname = uuid_name + suffix + '.jpg'
+ fpath = os.path.join(d, fname)
+
+ if os.path.isfile(fpath):
+ return send_from_directory(d,fname)
+ else:
+ return send_from_directory('static', 'img/404.jpg')
+
+# ----------------------------------------------------
+# Deleting images
+# ----------------------------------------------------
+
+def destroy_data(uuid_name, is_public):
+ uri_base = app.config['URI_BASE']
+ upload_dir, render_dir, json_dir, upload_uri, render_uri = get_paths(is_public)
+
+ json_path = os.path.join(json_dir, uuid_name + '.json')
+ with open(json_path) as json_file:
+ data = json.load(json_file)
+ for f in data['files']:
+ path = os.path.join(uri_base, f['fn'][1:])
+ if os.path.exists(path):
+ os.remove(path)
+ os.remove(json_path)
+
+@main.route('/d/<uuid_name>/destroy', strict_slashes=False) # public
+def route_public_destroy(uuid_name):
+ destroy_data(uuid_name, True)
+ return redirect("/", code=302)
+
+@main.route('/p/<uuid_name>/destroy', strict_slashes=False) # private
+def route_private_destroy(uuid_name):
+ destroy_data(uuid_name, False)
+ return redirect("/", code=302)
+
+# ----------------------------------------------------
+# Static routes
+# ----------------------------------------------------
+
+# Most of the pages are served with the single page app in index.html:
+
+task_json = make_task_json()
+
+@main.route('/', strict_slashes=False)
+def index():
+ return render_template('index.html', task_json=task_json)
+
+@main.route('/about', strict_slashes=False)
+def about():
+ return render_template('index.html', task_json=task_json)
+
+@main.route('/d/<uuid_name>', strict_slashes=False) # public
+def route_public(uuid_name):
+ return render_template('index.html', task_json=task_json)
+
+@main.route('/p/<uuid_name>', strict_slashes=False) # private
+def route_private(uuid_name):
+ return render_template('index.html', task_json=task_json)
+
+@main.route('/privacy', strict_slashes=False)
+def privacy():
+ return render_template('index.html', task_json=task_json)
+
+# Some of the pages have their own static file:
+
+@main.route('/gallery', strict_slashes = False)
+def gallery():
+ app.logger.info('access gallery')
+ uploads, renders, urls = utils.get_recent_uploads(limit=50)
+ uuids = [os.path.splitext(os.path.basename(f))[0] for f in uploads]
+ images = [{'upload':u,'render':r, 'url':url} for u,r,url in zip(uploads,renders,urls)]
+ return render_template('gallery.html',images=images)
+
+@main.route('/zkm', strict_slashes=False)
+def zkm():
+ app.logger.info('access ZkM')
+ return render_template('zkm.html')
+
+@main.route('/celery', strict_slashes=False)
+def celery_route():
+ return render_template('celery.html')
+
+@main.route('/projector', strict_slashes=False)
+def projector():
+ uploads, renders,urls = utils.get_recent_uploads()
+ return render_template('projector.html', uploads=uploads, renders=renders)