#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import os sys.path.append('./') import json from io import BytesIO import zipfile import re from datetime import datetime import importlib import sqlite3 import rrc_evaluation_funcs from config.config import * try: from bottle import route, run, request, static_file, url, template, TEMPLATE_PATH,HTTPResponse,redirect except ImportError: print("""Required module not found: Bottle. Installation: pip install --user bottle""") sys.exit(-1) try: from PIL import Image except ImportError: print("""Required module not found: Pillow. Installation: pip install --user Pillow""") sys.exit(-1) TEMPLATE_PATH.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "views"))) def image_name_to_id(name): # m = re.match(image_name_to_id_str,name) # if m == None: # return False # id = m.group(1) id = name.replace('.jpg', '').replace('.png', '').replace('.gif', '').replace('.bmp', '') return id def get_sample_id_from_num(num): imagesFilePath = os.path.dirname(os.path.abspath(__file__)) + "/gt/images.zip" archive = zipfile.ZipFile(imagesFilePath,'r') current = 0 for image in archive.namelist(): if image_name_to_id(image) != False: current += 1 if (current == num): return image_name_to_id(image) return False def get_sample_from_num(num): imagesFilePath = os.path.dirname(os.path.abspath(__file__)) + "/gt/images.zip" archive = zipfile.ZipFile(imagesFilePath,'r') current = 0 for image in archive.namelist(): if image_name_to_id(image) != False: current += 1 if (current == num): return image,archive.read(image) return False def get_samples(): imagesFilePath = os.path.dirname(os.path.abspath(__file__)) + "/gt/images.zip" archive = zipfile.ZipFile(imagesFilePath,'r') num_samples = 0 samples_list = [] for image in archive.namelist(): if image_name_to_id(image) != False: num_samples += 1 samples_list.append(image) return num_samples,samples_list @route('/static/:path#.+#', name='static') def static(path): return static_file(path, root=os.path.abspath(os.path.join(os.path.dirname(__file__), "static"))) @route('/static_custom/:path#.+#', name='static_custom') def static_custom(path): return static_file(path, root=os.path.abspath(os.path.join(os.path.dirname(__file__), "static_custom"))) @route('/gt/:path#.+#', name='static_gt') def static_gt(path): return static_file(path, root=os.path.abspath(os.path.join(os.path.dirname(__file__), "gt"))) @route('/favicon.ico') def favicon(): return static_file("cvc-ico.png", root=os.path.abspath(os.path.join(os.path.dirname(__file__), "static"))) @route('/') def index(): _,images_list = get_samples() page = 1 if 'p' in request.query: page = int(request.query['p']) subm_data = get_all_submissions() vars = { 'url':url, 'acronym':acronym, 'title':title, 'images':images_list, 'method_params':method_params, 'page':page, 'subm_data':subm_data, 'submit_params':submit_params, 'instructions':instructions, 'extension':gt_ext } return template('index',vars) @route('/exit') def exit(): sys.stderr.close() @route('/method/', methods=['GET']) def method(): _,images_list = get_samples() results = None page = 1 subm_data = {} if 'm' in request.query: id = request.query['m'] submFilePath = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + id + ".zip" if os.path.isfile(submFilePath): results = zipfile.ZipFile(submFilePath,'r') if 'p' in request.query: page = int(request.query['p']) subm_data = get_submission(id) if results is None or subm_data is None: redirect('/') else: redirect('/') vars = { 'url':url, 'acronym':acronym, 'title':title, 'images':images_list, 'method_params':method_params, 'sample_params':sample_params, 'results':results, 'page':page, 'subm_data':subm_data } return template('method',vars) @route('/sample/') def sample(): num_samples,images_list = get_samples() sample = int(request.query['sample']) methodId = request.query['m'] subm_data = get_submission(methodId) samplesValues = [] id = get_sample_id_from_num(int(sample)) sampleId = id + ".json" subms = get_all_submissions() for methodId,methodTitle,_,_ in subms: zipFolderPath = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + str(methodId) sampleFilePath = zipFolderPath + "/" + sampleId if os.path.isfile(sampleFilePath) == False: submFilePath = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + str(methodId) + ".zip" archive = zipfile.ZipFile(submFilePath,'r') if os.path.exists(zipFolderPath) == False: os.makedirs(zipFolderPath) archive.extract(sampleId, zipFolderPath) file = open(sampleFilePath,"r") results = json.loads(file.read()) file.close() #results = json.loads(archive.read(id + ".json")) sampleResults = {"id":methodId, "title":methodTitle} for k,v in sample_params.items(): sampleResults[k] = results[k] samplesValues.append( sampleResults ) vars = { 'url':url, 'acronym':acronym, 'title':title + ' - Sample ' + str(sample) + ' : ' + images_list[sample-1], 'sample':sample, 'num_samples':num_samples, 'subm_data':subm_data, 'samplesValues':samplesValues, 'sample_params':sample_params, 'customJS':customJS, 'customCSS':customCSS } return template('sample',vars) @route('/sampleInfo/', methods=['GET']) def get_sample_info(): methodId = request.query['m'] submFilePath = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + methodId + ".zip" archive = zipfile.ZipFile(submFilePath,'r') id = get_sample_id_from_num(int(request.query['sample'])) results = json.loads(archive.read(id + ".json")) return json.dumps(results) @route('/image_thumb/', methods=['GET']) def image_thumb(): sample = int(request.query['sample']) fileName,data = get_sample_from_num(sample) ext = fileName.split('.')[-1] f = BytesIO(data) image = Image.open(f) maxsize = (205, 130) image.thumbnail(maxsize) output = BytesIO() if ext=="jpg": im_format = "JPEG" header = "image/jpeg" image.save(output,im_format, quality=80, optimize=True, progressive=True) elif ext == "gif": im_format = "GIF" header = "image/gif" image.save(output,im_format) elif ext == "png": im_format = "PNG" header = "image/png" image.save(output,im_format, optimize=True) contents = output.getvalue() output.close() body = contents headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/image/', methods=['GET']) def image(): sample = int(request.query['sample']) fileName,data = get_sample_from_num(sample) ext = fileName.split('.')[-1] if ext=="jpg": header = "image/jpeg" elif ext == "gif": header = "image/gif" elif ext == "png": header = "image/png" body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/gt_image/', methods=['GET']) def gt_image(): imagesFilePath = os.path.dirname(os.path.abspath(__file__)) + "/gt/gt.zip" archive = zipfile.ZipFile(imagesFilePath,'r') fileName = request.query['sample'] ext = fileName.split('.')[-1] if ext=="jpg": header = "image/jpeg" elif ext == "gif": header = "image/gif" elif ext == "png": header = "image/png" data = archive.read(fileName) body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/gt_file/', methods=['GET']) def gt_file(): imagesFilePath = os.path.dirname(os.path.abspath(__file__)) + "/gt/gt.zip" archive = zipfile.ZipFile(imagesFilePath,'r') fileName = request.query['sample'] ext = fileName.split('.')[-1] if ext=="xml": header = "text/xml" data = archive.read(fileName) body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/gt_video/', methods=['GET']) def gt_video(): imagesFilePath = os.path.dirname(os.path.abspath(__file__)) + "/gt/images.zip" archive = zipfile.ZipFile(imagesFilePath,'r') fileName = request.query['sample'] ext = fileName.split('.')[-1] header = "video/mp4" data = archive.read(fileName) body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/subm_image/', methods=['GET']) def subm_image(): submFilePath = os.path.dirname(os.path.abspath(__file__)) + "/output/subm_" + str(request.query['m']) + ".zip" archive = zipfile.ZipFile(submFilePath,'r') fileName = request.query['sample'] ext = fileName.split('.')[-1] if ext=="jpg": header = "image/jpeg" elif ext == "gif": header = "image/gif" elif ext == "png": header = "image/png" data = archive.read(fileName) body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/subm_xml/', methods=['GET']) def subm_xml(): submFilePath = os.path.dirname(os.path.abspath(__file__)) + "/output/subm_" + str(request.query['m']) + ".zip" archive = zipfile.ZipFile(submFilePath,'r') fileName = request.query['sample'] header = "text/xml" data = archive.read(fileName) body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/result_image/', methods=['GET']) def result_image(): submFilePath = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + str(request.query['m']) + ".zip" archive = zipfile.ZipFile(submFilePath,'r') fileName = request.query['name'] ext = fileName.split('.')[-1] if ext=="jpg": header = "image/jpeg" elif ext == "gif": header = "image/gif" elif ext == "png": header = "image/png" data = archive.read(fileName) body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/result_xml/', methods=['GET']) def result_xml(): submFilePath = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + str(request.query['m']) + ".zip" archive = zipfile.ZipFile(submFilePath,'r') fileName = request.query['name'] header = "text/xml" data = archive.read(fileName) body = data headers = dict() headers['Content-Type'] = header if 'c' in request.query: headers['Cache-Control'] = "public, max-age=3600" return HTTPResponse(body, **headers) @route('/evaluate', method=['POST','GET']) def evaluate(): id=0 submFile = request.files.get('submissionFile') if submFile is None: resDict = {"calculated":False,"Message":"No file selected"} if request.query['json']=="1": return json.dumps(resDict) else: vars = {'url':url, 'title':'Method Upload ' + title,'resDict':resDict} return template('upload',vars) else: name, ext = os.path.splitext(submFile.filename) if ext not in ('.' + gt_ext): resDict = {"calculated":False,"Message":"File not valid. A " + gt_ext.upper() + " file is required."} if request.query['json']=="1": return json.dumps(resDict) else: vars = {'url':url, 'title':'Method Upload ' + title,'resDict':resDict} return template('upload',vars) p = { 'g': os.path.dirname(os.path.abspath(__file__)) + "/gt/gt." + gt_ext, 's': os.path.dirname(os.path.abspath(__file__)) + "/output/subm." + gt_ext, 'o': os.path.dirname(os.path.abspath(__file__)) + "/output" } for k,_ in submit_params.items(): p['p'][k] = request.forms.get(k) if os.path.isfile(p['s']): os.remove(p['s']) submFile.save(p['s']) module = importlib.import_module(evaluation_script ) resDict = rrc_evaluation_funcs.main_evaluation(p,module.default_evaluation_params,module.validate_data,module.evaluate_method) if resDict['calculated']==True: dbPath = os.path.dirname(os.path.abspath(__file__)) + "/output/submits" conn = sqlite3.connect(dbPath) cursor = conn.cursor() submTitle = request.forms.get('title') if submTitle=="": submTitle = "unnamed" cursor.execute('INSERT INTO submission(title,sumbit_date,results) VALUES(?,?,?)',(submTitle ,datetime.now().strftime("%Y-%m-%d %H:%M"),json.dumps(resDict['method']))) conn.commit() id = cursor.lastrowid os.rename(p['s'], p['s'].replace("subm." + gt_ext,"subm_" + str(id) + "." + gt_ext) ) os.rename(p['o'] + "/results.zip", p['o'] + "/results_" + str(id) + ".zip" ) conn.close() if request.query['json']=="1": return json.dumps( {"calculated": resDict['calculated'],"Message": resDict['Message'],'id':id} ) else: vars = {'url':url, 'title':'Method Upload ' + title,'resDict':resDict,'id':id} return template('upload',vars) @route('/delete_all', method='POST') def delete_all(): output_folder = os.path.dirname(os.path.abspath(__file__)) + "/output" try: for root, dirs, files in os.walk(output_folder, topdown=False): for f in files: os.remove(os.path.join(root, f)) for d in dirs: os.rmdir(os.path.join(root, d)) except: print("Unexpected error:", sys.exc_info()[0]) @route('/delete_method', method='POST') def delete_method(): id = request.forms.get('id') try: output_folder = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + id if os.path.isdir(output_folder): for root, dirs, files in os.walk(output_folder, topdown=False): for f in files: os.remove(os.path.join(root, f)) for d in dirs: os.rmdir(os.path.join(root, d)) os.rmdir(output_folder) subm_file = os.path.dirname(os.path.abspath(__file__)) + "/output/results_" + id + "." + gt_ext results_file = os.path.dirname(os.path.abspath(__file__)) + "/output/subm_" + id + ".zip" os.remove(subm_file) os.remove(results_file) except: print("Unexpected error:", sys.exc_info()[0]) dbPath = os.path.dirname(os.path.abspath(__file__)) + "/output/submits" conn = sqlite3.connect(dbPath) cursor = conn.cursor() cursor.execute('DELETE FROM submission WHERE id=?',(id)) conn.commit() conn.close() @route('/edit_method', method='POST') def edit_method(): id = request.forms.get('id') name = request.forms.get('name') dbPath = os.path.dirname(os.path.abspath(__file__)) + "/output/submits" conn = sqlite3.connect(dbPath) cursor = conn.cursor() cursor.execute('UPDATE submission SET title=? WHERE id=?',(name,id)) conn.commit() conn.close() def get_all_submissions(): dbPath = os.path.dirname(os.path.abspath(__file__)) + "/output/submits" conn = sqlite3.connect(dbPath) cursor = conn.cursor() cursor.execute("""CREATE TABLE IF NOT EXISTS submission(id integer primary key autoincrement, title varchar(50), sumbit_date varchar(12),results TEXT)""") conn.commit() cursor.execute('SELECT id,title,sumbit_date,results FROM submission') sumbData = cursor.fetchall() conn.close() return sumbData def get_submission(id): dbPath = os.path.dirname(os.path.abspath(__file__)) + "/output/submits" conn = sqlite3.connect(dbPath) cursor = conn.cursor() cursor.execute("""CREATE TABLE IF NOT EXISTS submission(id integer primary key autoincrement, title varchar(50), sumbit_date varchar(12),results TEXT)""") conn.commit() cursor.execute('SELECT id,title,sumbit_date,results FROM submission WHERE id=?',(id,)) sumbData = cursor.fetchone() conn.close() return sumbData if __name__=='__main__': evalModule = importlib.import_module(evaluation_script) try: for module,alias in evalModule.evaluation_imports().items(): importlib.import_module(module) except ImportError: print("Script " + evaluation_script + ". Required module (" + module + ") not found.") if module=="Polygon": print("Install it with: pip3 install Polygon3") else: print("Install it with: pip install """ + module) sys.exit(101) print("***********************************************") print("RRC Standalone Task") print("-----------------------------------------------") print('Command line client:\ncurl -F "submissionFile=submit.zip" http://127.0.0.1:8080/evaluate') print("\nGUI client:firefox http://127.0.0.1:8080") print("-----------------------------------------------") run(host='0.0.0.0', port=8080, debug=True)