# # # DEPENDENCIES import os from flask import Flask, url_for, render_template, flash, request, redirect from werkzeug.utils import secure_filename import json import mariadb import sys from PIL import Image # # # GLOBAL VARIABLES UPLOAD_FOLDER = os.path.join(os.getcwd(), 'static/uploads/annotation-compass/') ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} # # # FUNCTIONS def connection(): ''' Open a connection to the mariaDB database ''' try: conn = mariadb.connect( user="guardian_of_the_labels", password="soup_of_the_labels", host="localhost", port=3306, database='collecting_labels', autocommit=True ) except mariadb.Error as e: print(f'Error connecting to MariaDB Platflorm: {e}') sys.exit(1) return conn def make_link_list(names, base_url): ''' Generate a list of link from the files in a folder ''' link_list = '' for name in names: if allowed_file(name, ALLOWED_EXTENSIONS): link = f'{name}
' link_list = link_list + link return link_list def allowed_file(filename, extensions): ''' Check if the file extension is in the allowed extensions array ''' return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in extensions def temp_fix_date(timestamp): ''' JS Date to mySQL Date ''' from datetime import datetime from time import strftime date = datetime.fromtimestamp(timestamp / 1000.0) return date.strftime('%Y-%m-%d %H:%M:%S') def add_label(cursor, label): ''' Insert a new label in the database ''' x = label['position']['x'] y = label['position']['y'] width = label['size']['width'] height = label['size']['height'] text = label['text'] timestamp = temp_fix_date(label['timestamp']) user_id = str(label['userID']) image = label['image'] try: cursor.execute(f'INSERT INTO labels (x,y,width,height,text,timestamp,userID,image) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', (x, y, width, height, text, timestamp, user_id, image )) print(f'Insert label#{cursor.lastrowid} from user {user_id} on {image} at {timestamp}.') except mariadb.Error as e: print(f"Error error error in MariaDB Platform: {e}") return {"message":"oh no", "error":e} def get_labels(cursor, filename): ''' List the labels for a specific image from the database ''' try: cursor.execute(f"SELECT * FROM labels WHERE image = '{filename}'") db_labels = cursor.fetchall() labels = [] for (index, x, y, width, height, text, timestamp, user_id, image) in db_labels: label = { 'position': { 'x': x, 'y': y }, 'size': { 'width': width, 'height': height }, 'text': text, 'timestamp': timestamp, 'userID': user_id, 'image': image } labels.append(label) return labels except mariadb.Error as e: print(f"Error error error in MariaDB Platform: {e}") return {"message":"oh no", "error":e} def add_image_description(filename, description): ''' Set description for an image during upload ''' image_description_output = {} with open(os.path.join(os.getcwd(), "projects/annotation-compass/descriptions.json"), "r") as f: image_description_input = json.loads(f.read()) image_description_output = image_description_input image_description_output[filename] = { 'description': description } with open(os.path.join(os.getcwd(), "projects/annotation-compass/descriptions.json"), "w") as f: f.write(json.dumps(image_description_output)) def get_image_description(filename): ''' Get the description of an uploaded image ''' with open(os.path.join(os.getcwd(), "projects/annotation-compass/descriptions.json"), "r") as f: descriptions = json.loads(f.read()) return descriptions[filename]['description'] def thumbnail(image): try: img = Image.open(image) img.thumbnail((128,128)) name = image.rsplit('.', 1)[0] ext = image.rsplit('.', 1)[1] img.save(f'{name}_thumb.{ext}') except IOError: pass # TODO: clean up this dai # /generic-labels/ → /si16/annotation-compass/ (GET, POST) def upload_file(request): ''' Upload a new image in the Annotation Compass ''' # check if the post request has the file part if 'file' not in request.files: flash('No file part') return redirect(request.url) file = request.files['file'] # If the user does not select a file, the browser submits an # empty file without a filename. if file.filename == '': flash('No selected file') return redirect(request.url) if file and allowed_file(file.filename, ALLOWED_EXTENSIONS): filename = secure_filename(file.filename) file.save(os.path.join(UPLOAD_FOLDER, filename)) thumbnail(os.path.join(UPLOAD_FOLDER, filename)) description = request.form['description'] add_image_description(filename, description) def list_images(): ''' List the images in the Annotation Compass. ''' files = os.listdir(UPLOAD_FOLDER) files.sort() not_thumbs = filter(lambda file: '_thumb.' not in file, files) images = [] for image in not_thumbs: if allowed_file(image, ALLOWED_EXTENSIONS): name = image.rsplit('.', 1)[0] ext = image.rsplit('.', 1)[1] img = image thumb = f'{name}_thumb.{ext}' images.append((img, thumb)) return images # links = make_link_list(images, 'annotate/' ) # TODO: transform this in a template # return f''' # # Collecting Labels # {links} #

Upload new File

#
# # # #
# ''' # /generic-labels/annotate// → /si16/annotation-compass/annotate// # def annotate_image(image=None): # ''' Open the Annotation Compass on a specific image ''' # description = '' # try: # description = get_image_description(image) # except: # print("There is no description") # return render_template('annotate_image.html', image=image, description=description) # /generic-labels/add-label/ → /si16/annotation-compass/add-label # in the URL there is no reference to the image because the info is in the json body of the label itself def insert_label(request): ''' Insert a new label in the database ''' connect = connection() cursor = connect.cursor() add_label(cursor, request.json) connect.close() return {"response": "ok"} # /generic-labels/get-labels/ → /si16/annotation-compass/get-labels// # TODO: adapt the old url with the query # OLD: /get-labels/?image= # NEW: /get-labels// def get_labels_list(image = None): connect = connection() cursor = connect.cursor() labels = get_labels(cursor, image) connect.close() return {"response": "ok", "labels": labels }