From: Eric Fayolle Date: Thu, 3 Feb 2022 14:22:36 +0000 (+0100) Subject: Première version avec gestio des fichiers X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=94f9c9ab7661d013d4fa628f9db8fc77099ae25a;p=tools%2Feficas.git Première version avec gestio des fichiers --- diff --git a/testFlask/lib/__init__.py b/testFlask/lib/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/testFlask/lib/upload_file.py b/testFlask/lib/upload_file.py new file mode 100644 index 00000000..e768b8dc --- /dev/null +++ b/testFlask/lib/upload_file.py @@ -0,0 +1,67 @@ +import os + +class uploadfile(): + def __init__(self, name, type=None, size=None, not_allowed_msg=''): + self.name = name + self.type = type + self.size = size + self.not_allowed_msg = not_allowed_msg + self.url = "data/%s" % name + self.thumbnail_url = "thumbnail/%s" % name + self.delete_url = "delete/%s" % name + self.delete_type = "DELETE" + + + def is_image(self): + fileName, fileExtension = os.path.splitext(self.name.lower()) + + if fileExtension in ['.jpg', '.png', '.jpeg', '.bmp']: + return True + + return False + + + def get_file(self): + if self.type != None: + # POST an image + if self.type.startswith('image'): + return {"name": self.name, + "type": self.type, + "size": self.size, + "url": self.url, + "thumbnailUrl": self.thumbnail_url, + "deleteUrl": self.delete_url, + "deleteType": self.delete_type,} + + # POST an normal file + elif self.not_allowed_msg == '': + return {"name": self.name, + "type": self.type, + "size": self.size, + "url": self.url, + "deleteUrl": self.delete_url, + "deleteType": self.delete_type,} + + # File type is not allowed + else: + return {"error": self.not_allowed_msg, + "name": self.name, + "type": self.type, + "size": self.size,} + + # GET image from disk + elif self.is_image(): + return {"name": self.name, + "size": self.size, + "url": self.url, + "thumbnailUrl": self.thumbnail_url, + "deleteUrl": self.delete_url, + "deleteType": self.delete_type,} + + # GET normal file from disk + else: + return {"name": self.name, + "size": self.size, + "url": self.url, + "deleteUrl": self.delete_url, + "deleteType": self.delete_type,} diff --git a/testFlask/mdm.py b/testFlask/mdm.py index 236ba863..5fd67d99 100755 --- a/testFlask/mdm.py +++ b/testFlask/mdm.py @@ -7,36 +7,181 @@ from connectEficas import accasConnecteur code='Essai' from flask import Flask, request, render_template, url_for, jsonify, make_response, session, g, Response -# from flask import Flask, request, render_template, url_for, json, jsonify + +# File management +from flask import redirect, send_from_directory +from werkzeug.utils import secure_filename +from lib.upload_file import uploadfile +import PIL +from PIL import Image +import simplejson +import traceback + +# from flask import ?? json, jsonify ?? import json import os from pprint import pprint -#from forms import BasicForm +#from forms import BasicForm #Essais WtForms from collections import OrderedDict from markupsafe import escape +# Flask management of Server Side Event from flask_sse import sse -from flask_uploads import UploadSet, configure_uploads, IMAGES +# from flask_uploads import UploadSet, configure_uploads, IMAGES app = Flask(__name__) -CATALOGS_EXT=("py",) -catalogs = UploadSet("catalogs",CATALOGS_EXT) -app.config["UPLOADED_CATALOGS_DEST"] = "data/catalogs" -app.config["SECRET_KEY"] = os.urandom(24) +# CATALOGS_EXT=("py","jpg") #TODO : supprimer jpg pour test +# catalogs = UploadSet("catalogs",CATALOGS_EXT) +# app.config["UPLOADED_CATALOGS_DEST"] = "data/catalogs" +# app.config["SECRET_KEY"] = os.urandom(24) + +# configure_uploads(app, catalogs) + +app.config['SECRET_KEY'] = 'hard to guess string' +app.config['UPLOAD_FOLDER'] = 'data/' +app.config['THUMBNAIL_FOLDER'] = 'data/thumbnail/' +app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 + +ALLOWED_EXTENSIONS = set(['py','comm','txt', 'gif', 'png', 'jpg', 'jpeg', 'bmp', 'rar', 'zip', '7zip', 'doc', 'docx']) +IGNORED_FILES = set(['.gitignore']) + +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + + +def gen_file_name(filename): + """ + If file was exist already, rename it and return a new name + """ + + i = 1 + while os.path.exists(os.path.join(app.config['UPLOAD_FOLDER'], filename)): + name, extension = os.path.splitext(filename) + filename = '%s_%s%s' % (name, str(i), extension) + i += 1 + + return filename -configure_uploads(app, catalogs) +def create_thumbnail(image): + try: + base_width = 80 + img = Image.open(os.path.join(app.config['UPLOAD_FOLDER'], image)) + w_percent = (base_width / float(img.size[0])) + h_size = int((float(img.size[1]) * float(w_percent))) + img = img.resize((base_width, h_size), PIL.Image.ANTIALIAS) + img.save(os.path.join(app.config['THUMBNAIL_FOLDER'], image)) -@app.route("/upload", methods=['POST']) + return True + + except: + print(traceback.format_exc()) + return False + + +@app.route("/upload", methods=['GET', 'POST']) def upload(): - if request.method == 'POST' and 'catalogFile' in request.files: - catalogs.save(request.files['catalogFile']) - # flash("Catalog saved successfully.") - # return render_template('upload.html') - # return render_template('upload.html') - return "upload returns", 200 + if request.method == 'POST': + files = request.files['file'] + + if files: + filename = secure_filename(files.filename) + filename = gen_file_name(filename) + mime_type = files.content_type + + if not allowed_file(files.filename): + result = uploadfile(name=filename, type=mime_type, size=0, not_allowed_msg="File type not allowed") + + else: + # save file to disk + uploaded_file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) + files.save(uploaded_file_path) + + # create thumbnail after saving + if mime_type.startswith('image'): + create_thumbnail(filename) + + # get file size after saving + size = os.path.getsize(uploaded_file_path) + + # return json for js call back + result = uploadfile(name=filename, type=mime_type, size=size) + + return simplejson.dumps({"files": [result.get_file()]}) + + if request.method == 'GET': + # get all file in ./data directory + files = [f for f in os.listdir(app.config['UPLOAD_FOLDER']) if os.path.isfile(os.path.join(app.config['UPLOAD_FOLDER'],f)) and f not in IGNORED_FILES ] + + file_display = [] + + for f in files: + size = os.path.getsize(os.path.join(app.config['UPLOAD_FOLDER'], f)) + file_saved = uploadfile(name=f, size=size) + file_display.append(file_saved.get_file()) + + return simplejson.dumps({"files": file_display}) + + return redirect(url_for('index')) + + + +@app.route("/delete/", methods=['DELETE']) +def delete(filename): + file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) + file_thumb_path = os.path.join(app.config['THUMBNAIL_FOLDER'], filename) + if os.path.exists(file_path): + try: + os.remove(file_path) + + if os.path.exists(file_thumb_path): + os.remove(file_thumb_path) + + return simplejson.dumps({filename: 'True'}) + except: + return simplejson.dumps({filename: 'False'}) + + +# serve static files +@app.route("/thumbnail/", methods=['GET']) +def get_thumbnail(filename): + return send_from_directory(app.config['THUMBNAIL_FOLDER'], filename=filename) + + +@app.route("/data/", methods=['GET']) +def get_file(filename): + return send_from_directory(os.path.join(app.config['UPLOAD_FOLDER']), filename=filename) + + +# @app.route("/_upload", methods=['POST']) +# def _upload(): + +# # Validate the request body contains JSON +# if request.is_json: +# # Parse the JSON into a Python dictionary +# req = request.get_json() +# # Print the dictionary +# uploadRequest=json.dumps([req],indent=4); #TODO : remove indent if not DEBUG +# pprint(uploadRequest); + +# return make_response(json.dumps( {'source':node, 'changeIsAccepted' : changeDone, 'message': message} )) +# # Return a string along with an HTTP status code +# # return "JSON received!", 200 +# else: +# print(request) +# files = request.files['files'] +# if files: +# result=catalogs.save(files) +# return make_response(json.dumps( {"files": ["coucou"]} )) +# # if request.method == 'POST' and 'files' in request.files: + + +# # The request body wasn't JSON so return a 400 HTTP status code +# return "Request was not JSON", 400 +# #return make_response(jsonify({"message": "Request body must be JSON"}), 400) # For example, you may want to override how request parameters are handled to preserve their order: # from flask import Flask, Request @@ -48,6 +193,13 @@ def upload(): # """Flask subclass using the custom request class""" # request_class = MyReq +### Server Side Event config +app.config["REDIS_URL"] = "redis://localhost" +#app.config["REDIS_URL"] = "redis://:password@localhost" +#TODO: personaliser l'url en fonction de la session utilisateur +app.register_blueprint(sse, url_prefix='/stream') + +### Eficas Connector def createConnecteur(app): monConnecteur=accasConnecteur(code, langue='ang',appWeb=app) return monConnecteur @@ -55,12 +207,6 @@ def createConnecteur(app): monConnecteur=createConnecteur(app) print (monConnecteur.getListeCommandes()) -#Server Side Event config -app.config["REDIS_URL"] = "redis://localhost" -#app.config["REDIS_URL"] = "redis://:password@localhost" -#TODO: personaliser l'url en fonction de la session utilisateur -app.register_blueprint(sse, url_prefix='/stream') - def fromConnecteur(maFonction,*args,**kwargs): #print ('dans fromConnecteur: ', maFonction) fnct=globals()[maFonction] diff --git a/testFlask/static/jQuery-File-Upload b/testFlask/static/jQuery-File-Upload new file mode 160000 index 00000000..0e92a4d4 --- /dev/null +++ b/testFlask/static/jQuery-File-Upload @@ -0,0 +1 @@ +Subproject commit 0e92a4d4613d4ed5231ee0d8513519f2e04f99ba diff --git a/testFlask/templates/base.html b/testFlask/templates/base.html index 8e116197..58569be5 100644 --- a/testFlask/templates/base.html +++ b/testFlask/templates/base.html @@ -1,6 +1,7 @@ + {% block head %} {% block title %} MDM {{titre}} {% endblock %} @@ -45,6 +46,12 @@ + + + + + + @@ -87,7 +94,7 @@ - + {% endblock head %} @@ -134,101 +141,30 @@ #row-tree1-messages nav, #tree1-messages { margin-bottom: 0px; } - + + #file_management { + z-index: 8500; + } -
-
- -
+
+ {% block main_menu %} {% endblock %} {% block commands_menu %} {% endblock %} + {% block file_management %} {% endblock %} + {% block content %} {% endblock %}
- + + {% block scripts %} + {#{ super() }#} + {% endblock %} + diff --git a/testFlask/templates/commandes_2.html b/testFlask/templates/commandes_2.html index e6d216d8..258d73a8 100644 --- a/testFlask/templates/commandes_2.html +++ b/testFlask/templates/commandes_2.html @@ -1,8 +1,7 @@ -{% extends 'commands_menu.html' %} +{% extends 'file_management.html' %} {% block content %} - @@ -127,6 +126,18 @@ - {% endblock %} diff --git a/testFlask/templates/commands_menu.html b/testFlask/templates/commands_menu.html index eea5f8fa..06721e99 100644 --- a/testFlask/templates/commands_menu.html +++ b/testFlask/templates/commands_menu.html @@ -1,5 +1,4 @@ -{% extends 'base.html' %} - +{% extends 'main_menu.html' %} {% block commands_menu %} diff --git a/testFlask/templates/file_management.html b/testFlask/templates/file_management.html new file mode 100644 index 00000000..79f92777 --- /dev/null +++ b/testFlask/templates/file_management.html @@ -0,0 +1,193 @@ +{% extends 'commands_menu.html' %} + +{% block file_management %} + + + + + +{% raw %} + + + + +{% endraw %} + +{% endblock file_management %} + +{% block scripts %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% endblock %} + diff --git a/testFlask/templates/file_management_menu.html b/testFlask/templates/file_management_menu.html new file mode 100644 index 00000000..29afa6b5 --- /dev/null +++ b/testFlask/templates/file_management_menu.html @@ -0,0 +1,26 @@ +{% extends commands_menu.html' %} + +{% block file_management %} + + + + +{% endblock file_management %} diff --git a/testFlask/templates/main_menu.html b/testFlask/templates/main_menu.html new file mode 100644 index 00000000..4458abd7 --- /dev/null +++ b/testFlask/templates/main_menu.html @@ -0,0 +1,55 @@ +{% extends 'base.html' %} + +{% block main_menu %} + +
+ +
+ +{% endblock %} +