From: PASCALE NOYRET Date: Fri, 22 Mar 2024 13:23:00 +0000 (+0100) Subject: pour se mettre d accord pour le changement d API X-Git-Tag: V_demo_28_mars_2024~21 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=05c7b100094ffa46415267b0772c1cda03f24c55;p=tools%2Feficas.git pour se mettre d accord pour le changement d API --- diff --git a/Accas/extensions/codeErreur.py b/Accas/extensions/codeErreur.py index 829f74cc..11d6ab24 100755 --- a/Accas/extensions/codeErreur.py +++ b/Accas/extensions/codeErreur.py @@ -1,6 +1,6 @@ dictErreurs = { # Categories - 1000 : 'Parametre obligatoire : {}', + 1000 : 'Parametre obligatoire : {}, ', 2000 : 'Erreur d enrolement', 3000 : 'Erreur de Catalogue : ', 4000 : 'Erreur de fichier Dataset : ', @@ -12,5 +12,15 @@ dictErreurs = { 10 : 'fichier {} non trouve', 20 : 'erreur ecriture', 30 : 'erreur a l execution', + 40 : 'mauvaise valeur', + +# Messages specifiques + 100 : 'Numero de Session deja allouée pour autre chose que de Web', +} + +dictGravite = { + 0 : "alert-success", + 1 : "alert-info", + 2 : "alert-warning", + 3 : "alert-danger" } -# 2000 Pas de catalogue connu editor_manager.py diff --git a/Editeur/editor.py b/Editeur/editor.py index 938c7086..13733f99 100755 --- a/Editeur/editor.py +++ b/Editeur/editor.py @@ -113,7 +113,7 @@ class Editor: def construitJdC(self,jdc): #------------------------- # construction du jdc - # Est-il encore necessaire de passer un jdc a l init ? + # Est-il encore necessaire de passer en paramtre un jdc a l init ? # je ne vois plus quel est le cas d usage # je garde . 11 mars 2024 if jdc : @@ -194,9 +194,11 @@ class Editor: fn = str(fn) jdcName = os.path.basename(fn) - print ('-------------------------------------------') - print (fn) - print ('-------------------------------------------') + debug = 0 + if debug : + print ('-------------------------------------------') + print (fn) + print ('-------------------------------------------') # Il faut convertir le contenu du dataSetFile en fonction du format formatIn = self.appliEficas.formatFichierIn @@ -721,7 +723,10 @@ class Editor: @return tuple of two values (boolean, string) giving a success indicator and the name of the saved file """ + #TODO PN : s occuper des suffixes + if fichier != self.dataSetFile : + return (1, 'utiliser saveFileAs pour changer le nom du fichier') self.fichierOut = fichier if not (self.writeFile(fichier, formatLigne=formatLigne)): return (0, None) @@ -729,13 +734,19 @@ class Editor: if self.myWriter != self.XMLWriter: self.XMLWriter.gener(self.jdc) self.XMLWriter.writeDefault(fichier) - return (1, self.dataSetFile) + return (0, self.dataSetFile) if self.jdc.isValid() and hasattr(self.myWriter, "writeDefault"): self.myWriter.writeDefault(fichier) elif self.code == "TELEMAC" and hasattr(self.myWriter, "writeDefault"): self.myWriter.writeDefault(fichier) self.modified = 0 - return (1, self.dataSetFile) + return (0, self.dataSetFile) + + # --------------------------------------------------# + def saveFileAs(self, fichier, formatLigne="beautifie"): + # --------------------------------------------------# + self.dataSetFile = fichier + return self.saveFile(fichier, formatLigne) # -----------------------# def sauveLigneFile(self): @@ -1268,6 +1279,11 @@ class Editor: texteStringDataBase = self.readercata.cata.JdC.dumpStringDataBase(nomDataBaseACreer) return texteStringDataBase + # -----------------------------# + def getEtapesByName(self, name): + # -----------------------------# + if not self.jdc : return (1, 'pas de jdc') + return self.jdc.getEtapesByName(name) if __name__ == "__main__": print("a faire") diff --git a/Editeur/editor_manager.py b/Editeur/editor_manager.py index 4d5db6dc..6442f359 100644 --- a/Editeur/editor_manager.py +++ b/Editeur/editor_manager.py @@ -23,7 +23,7 @@ from uuid import uuid1 from multiprocessing import Lock from Accas.extensions.codeErreur import dictErreurs -debug = 1 +debug = 0 # -------------------------- class EditorManager(object): # -------------------------- @@ -110,11 +110,12 @@ class EditorManager(object): if dataSetFile == None : self.appliEficas.afficheMessage(dictErreurs[1000] , 'nom de dataSet obligatoire pour obtenir un editor') return (None, 1000 , dictErreurs[1000] + ' : nom de dataset obligatoire pour obtenir un editor', None) - if not os.path.isfile(cataFile): + if not os.path.isfile(dataSetFile): self.appliEficas.afficheMessage(dictErreurs[4000] + dictErreurs[10], 'fichier dataSet {} non trouve'.format(cataFile)) return (None, 4000 + 10 , dictErreurs[4000] + dictErreurs[10].format(cataFile), None) + if debug : print ('dictEditors', self.dictEditors) + messageInfo = "" with self.lock : - messageInfo = None for editor in self.dictEditors.values(): if self.samePath(dataSetFile, editor.getDataSetFileName()) and self.samePath(cataFile, editor.getCataFileName()): break @@ -123,7 +124,10 @@ class EditorManager(object): editor = WebEditor(self.appliEficas, cataFile, dataSetFile) if not editor.readercata : - return (None, 3000 + 30 , 'impossible d allouer l editor : {}'.format(editor.pbLectureCata), None) + codeError = 3000 + 30 + message = dict[3000] + ' '+dict[30] + ' ' + message += 'impossible d allouer l editor : {}'.format(editor.pbLectureCata) + return (None, codeError , message, messageInfo) if editor.jdc: # le fichier est bien un jdc self.dictEditors[editor.editorId]=editor @@ -134,19 +138,13 @@ class EditorManager(object): self.appliEficas.dictEditorIdChannelId[editor.editorId]=[cId,] else: # PN : cabler avec le message d info - return (None, 4000 + 30, 'impossible de creer le dataset ; {} '.format(editor.pbLectureDataSet), None) + codeError = 4000 + 30 + message = dict[4000] + ' '+dict[30] + ' ' + message += 'impossible de creer le dataset ; {} '.format(editor.pbLectureDataSet) + return (None, 4000 + 30, 'impossible de creer le dataset ; {} '.format(editor.pbLectureDataSet), messageInfo) return (editor, 0, '', messageInfo) - # -------------------------- - def getEditorById(self, eId): - # --------------------------- - debug = 1 - if eId in self.dictEditors: - return (self.dictEditors[eId], 0, "") - if debug : print ("getEditorById : {} non trouve ".format(eId)) - return (None, 1, "getEditorById : {} non trouve ".format(eId)) - # ------------------------- def samePath(self, f1, f2): @@ -155,7 +153,7 @@ class EditorManager(object): compare two paths. """ if f1 is None or f2 is None: return 0 - if os.path.normcase(os.path.normpath(f1)) == os.path.normcase( os.path.normpath(f2)): + if os.path.realpath(os.path.normcase(os.path.normpath(f1))) == os.path.realpath(os.path.normcase( os.path.normpath(f2))): return 1 return 0 diff --git a/Editeur/eficas_appli.py b/Editeur/eficas_appli.py index 421a51c4..5cf3ece6 100755 --- a/Editeur/eficas_appli.py +++ b/Editeur/eficas_appli.py @@ -169,48 +169,68 @@ class EficasAppli: return self.editor #------------------------------------------------------------------------------------------------------------------- - def getWebEditor(self, sId, cataFile = None, datasetFile=None, jdc=None, include=0, formatIn='python', formatOut='python'): + def getWebEditor(self, cId, cataFile = None, datasetFile=None, jdc=None, include=0, formatIn='python', formatOut='python'): #------------------------------------------------------------------------------------------------------------------- - # en Web sId est le canal Id - debug = 1 - if sId in self.dictChannelType.keys() and self.dictChannelType[sId] != 'Web' : - message = 'Numero de Session deja allouée pour autre chose que de Web' - CR = 1000 - return (sId, None, CR, message, None) - if not sId in self.dictChannelType.keys() : - self.dictChannelType[sId] = 'Web' + debug = 0 + if debug : + print ('______________________________ Eficas_appli getWebEditor ________________________') + print ('self', self) + print (cId, cataFile, datasetFile, jdc, include, formatIn, formatOut) + #PN TODO initialiser info - info = None - (editor, CR, message, info) = self.editorManager.getWebEditor(sId, cataFile,datasetFile, jdc, include) - if not editor : + info = '' + if cId == None : + CR = 1000 + 40 + message = dictErreurs[1000].format('cId') + dictErreurs[40] + return (None, CR, message, info) + + if formatIn not in ('python', 'xml') : + CR = 1000 + 40 + message = dictErreurs[1000].format('formatIn') + dictErreurs[40] + return (None, CR, message, info) + + if formatOut not in ('python', 'xml') : + CR = 1000 + 40 + message = dictErreurs[1000].format('formatIn') + dictErreurs[40] return (None, CR, message, info) + if cId in self.dictChannelType.keys() and self.dictChannelType[cId] != 'Web' : + CR = 100 + return (cId, None, CR, dictErreurs[100], info) + if not cId in self.dictChannelType.keys() : self.dictChannelType[cId] = 'Web' + + (editor, CR, message, info) = self.editorManager.getWebEditor(cId, cataFile,datasetFile, jdc, include) + if not editor : return (None, CR, message, info) + + # on pose une lock egalement pour la mise a jour des dico with lock : - externalEditorId = uuid1().hex + externalEditorId = uuid1().hex + if editor.editorId not in self.dictEditorIdChannelIdExternEid.keys() : + self.dictEditorIdChannelIdExternEid[editor.editorId] = {} + if cId not in self.dictEditorIdChannelIdExternEid[editor.editorId] : + self.dictEditorIdChannelIdExternEid[editor.editorId][cId] = [externalEditorId,] + else : + self.dictEditorIdChannelIdExternEid[editor.editorId][cId].append(externalEditorId) + self.dictExternalEidEditor[externalEditorId] = editor - if editor.editorId not in self.dictEditorIdChannelIdExternEid.keys() : - self.dictEditorIdChannelIdExternEid[editor.editorId] = {} - if sId not in self.dictEditorIdChannelIdExternEid[editor.editorId] : - self.dictEditorIdChannelIdExternEid[editor.editorId][sId] = [externalEditorId,] - else : - self.dictEditorIdChannelIdExternEid[editor.editorId][sId].append(externalEditorId) if debug : - if editor : print ('getWebEditor id de sesssion :', sId, ' editor : ', editor.editorId, 'externe ', externalEditorId) - print (externalEditorId, CR, message, info) + if editor : print ('getWebEditor id de sesssion :', cId, ' editor : ', editor.editorId, 'externe ', externalEditorId) + print ('dictionnaire ' , self.dictEditorIdChannelIdExternEid) + print ('______________________________ fin getWebEditor ________________________') return (externalEditorId, CR, message, info) #-------------------------------------- - def getWebEditorById(self, sId, eId): + def getWebEditorById(self, cId, eId): #-------------------------------------- - if sId == None : - return ( None, 1000, dict[1000].format ('session Id')) + if cId == None : + return ( None, 1000, dict[1000].format ('session Id'), "") editor = self.dictExternalEidEditor[eId] - if sId not in self.dictEditorIdChannelIdExternEid[editor.editorId] : - return ( None, 1000, 'la session ne possede pas cet Editeur') - if eId not in self.dictEditorIdChannelIdExternEid[editor.editorId][sId] : - return ( None, 1000, 'incoherence entre Editeur et session') - return (editor, 0, "") + if cId not in self.dictEditorIdChannelIdExternEid[editor.editorId] : + return ( None, 1000, 'la session ne possede pas cet Editeur', "") + if eId not in self.dictEditorIdChannelIdExternEid[editor.editorId][cId] : + return ( None, 1000, 'incoherence entre Editeur et session', "") + return (editor, 0, "", "") #-------------------------------------------------------------------------------------------------------------------------------- @@ -410,8 +430,9 @@ class EficasAppli: #------------------------------------------------------------------------------------------------- def propageChange (self, editorId, emitChannelId , emitEditorId, toAll , fction, *args, **kwargs): #-------------------------------------------------------------------------------------------------- - if fction == 'appendChildren' : debug = 1 - else : debug = 0 + #if fction == 'appendChildren' : debug = 1 + #else : debug = 0 + debug = 1 if debug : print ("------------------------------------------ Eficas") print ('propageChange avec les arguments ') diff --git a/Web/mdm5.py b/Web/mdm5.py new file mode 100644 index 00000000..e2751761 --- /dev/null +++ b/Web/mdm5.py @@ -0,0 +1,689 @@ +# coding: utf-8 +#!/usr/bin/env python3 +import sys, os + +_no = 1 + +code='Essai' +#code=None + +from flask import Flask, request, render_template, url_for, jsonify, make_response, session, g, Response + + +# 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 #Essais WtForms +from collections import OrderedDict +from markupsafe import escape + +# Flask management of Server Side Event +# Necessite redis +from flask_sse import sse +# from flask_uploads import UploadSet, configure_uploads, IMAGES + +app = Flask(__name__) + +# 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'] = os.urandom(24) +app.config['UPLOAD_FOLDER'] = 'data/' +app.config['THUMBNAIL_FOLDER'] = 'data/thumbnail/' +app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 +#PNPN +#app.config['SESSION_REFRESH_EACH_REQUEST'] = False +ALLOWED_EXTENSIONS = set(['py','comm','txt', 'gif', 'png', 'jpg', 'jpeg', 'bmp', 'rar', 'zip', '7zip', 'doc', 'docx']) +IGNORED_FILES = set(['.gitignore']) + + +### 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 createWebAppli(app): + import os + print('Create Appli'); + sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)),'..')) + from Editeur.eficas_go import getEficas + eficasAppli=getEficas(code, langue='ang',appWeb=app) + return eficasAppli + + +eficasAppli=createWebAppli(app) +debug=0 +if debug : print ('eficasAppli = ', eficasAppli) + +def fromConnecteur(maFonction, sessionId, externEditorId, *args,**kwargs): + if debug : + print ('________________________________________________________________________') + print ('fromConnecteur : ', maFonction, sessionId, externEditorId, *args,**kwargs) + print ('________________________________________________________________________') + fnct=globals()[maFonction] + fnct(sessionId, externEditorId, *args,**kwargs) + +#TODO : Rattacher à une session +# gérer un appel register callback +app.fromConnecteur=fromConnecteur + +## ServerSideEvent from Eficas signals : +# - Validite +# - Ajouter un noeud (et ses enfants) +# - Supprimer un noeud (et ses enfants), +# - ReAffichage d'un noeud (et ses enfants) +# - Changement d'un nom de mot-cle reference + +def propageValide(cId, eId, id, valid): #TODO: RENAME TO ... propagateValidation + if debug : print ('Flask/propageValide: ', id, valid) + sse.publish( {'eId' : eId, 'id':id, 'valid':valid, 'message': "Hello from propageValide!"}, type='propageValide', channel = str(cId)) + +def updateNodeInfo(cId, eId, id, info): + debug=1 + if debug : print ('Flask/updateNodeInfo', cId, eId, id, info) + sse.publish( {'eId' : eId, 'id':id, 'info':info, 'message': "Hello from updateNodeInfo!"}, type='updateNodeInfo', channel = str(cId)) + +def appendChildren(cId, eId, id, fcyTreeJson, pos): + debug = 0 + if debug : print ('Flask/appendChildren: ', id, fcyTreeJson, pos) + sse.publish( {'eId' : eId, 'id':id, 'fcyTreeSrc':fcyTreeJson, 'pos':pos, 'message': "Hello from appendChildren!"}, type='appendChildren', channel = str(cId)) + +def deleteChildren(cId, eId, idList): + if debug : print ('Flask/deleteChildren: ', idList) + sse.publish( {'eId' : eId, 'idList':idList,'message': "Hello from deleteChildren!"}, type='deleteChildren', channel = str(cId)) + +#TODO: Câbler la sélection du catalogue avant d'activer les appels suivants +# car si la page Web n'est pas rendue et que le connecteur génère une erreur... boom ! +def afficheMessage(sId, txt, couleur): #TODO: RENAME TO ... displayWarning + if sId != session['eficasSession'] : return + print ('Flask/afficheMessage: ', txt, couleur) + # sse.publish( {'txt':txt, 'color':couleur, 'messageClass':"alert-warning" ,'message': "Hello from afficheMessage!"}, + # type='displayMessage') + +def afficheAlerte(sId, titre, message): #TODO: RENAME TO ... displayDanger + if sId != session['eficasSession'] : return + print ('Flask/afficheAlerte: ', titre, message) #TODO: titre & message VS txt ? + # sse.publish( {'txt':titre, 'color':couleur, 'messageClass':"alert-danger", 'message': "Hello from afficheAlerte!"}, + # type='displayMessage') + +#Messages Globaux ? +def afficheMessage2(cId, eId, txt, couleur): #TODO: RENAME TO ... displayWarning + if debug : print ('Flask/afficheMessage: ', txt, couleur) + sse.publish( {'txt':txt, 'color':couleur, 'messageClass':"alert-warning" ,'message': txt}, + type='message', channel = str(cId)) + +def afficheAlerte2(cId, eId, titre, message, couleur): #TODO: RENAME TO ... displayDanger + if debug : print ('Flask/afficheAlerte: ', titre, message) #TODO: titre & message VS txt ? + sse.publish( {'txt':titre, 'color':couleur, 'messageClass':"alert-danger", 'message': "Hello from afficheAlerte!"}, + type='error', channel = str(cId)) + + + +## WebApp -> Eficas : +# Pour SIMP : Ajoute, Supprime (MC facultatif), Change la valeur +# Pour FACT : Ajoute, Supprime +# Pour PROC : Ajoute, Supprime +# Pour OPER : Ajoute, Supprime, Nomme, Renomme +# @app.route('/post/') + +@app.route("/updateSimp", methods=['POST']) +def updateSimp(): + # Validate the request body contains JSON + if request.is_json: + # Parse the JSON into a Python dictionary + req = request.get_json() + # Print the dictionary + if debug : print("Flask/updateSimp request : ", req) + if debug : print("Flask/updateSimp request['id'] : ",req['id']) + eId = req['eId'];id=req['id'];value=req['value'] + # id, value = req.values() # Dangereux correspondance implicite + value = str(value) # L'utilisateur peut écrire la valeur Pi + + (eficasEditor, errorCode, errorMsg, infoMsg) = eficasAppli.getWebEditorById(session['canalId'],eId) + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + return make_response(json.dumps( {'errorCode' : errorCode, 'message': message,'msgLevel':msgLevel} )) + + #(rId, errorCode, errorMsg, infoMsg) = eficasEditor.changeValue(session['canalId'], eId, id,value); + #assert(rId==id) + + #changeDone = True + # if debug : print ("Flask/updateSimp changeDone : ",changeDone) + # Ne pas recuperer et ne pas renvoyer le noeud dans le cas du SIMP + # (le changeDone et l''ancienne valeur ds la WebApp suffit + #(node, errorCode, errorMsg, errorLevel) = eficasEditor.getDicoForFancy(eficasEditor.getNodeById(id)) + if debug : print("Flask/updateSimp node : ",node) + # return jsonify([myTreeDico]) + + (node, errorCode, errorMsg, infoMsg) = eficasEditor.changeValue(session['canalId'], eId, id,value); + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + return make_response(json.dumps( {'errorCode' : errorCode, 'message': message,'msgLevel':msgLevel} )) + if infoMessage != "" : msgLevel = 'alert-success' + else : msgLevel = "alert-info" + return make_response(json.dumps( {'source':node, 'errorCode' : errorCode, 'message': infoMessage,'msgLevel':msgLevel} )) + + # Return a string along with an HTTP status code + # return "JSON received!", 200 + else: + # 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) + +@app.route("/updateSDName", methods=['POST']) +def updateSDName(): + # Validate the request body contains JSON + if request.is_json: + # Parse the JSON into a Python dictionary + req = request.get_json() + # Print the dictionary + #print(req) + #print(req['id']) + eId=req['eId'];id=req['id'];sdnom=req['sdnom'] + sdnom = str(sdnom) #On peut écrire Pi + # On attendant que l externalEditorId soit dans le tree + (eficasEditor, errorCode, errorMsg, infoMsg) = eficasAppli.getWebEditorById(session['canalId'],eId) + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + return make_response(json.dumps( {'changeIsAccepted' : changeDone, 'message': message} )) + + (errorCode, errorMsg, infoMsg) = eficasEditor.updateSDName(session['canalId'],eId,id,sdnom); + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + else : + messageLevel = "alert-success" + return make_response(json.dumps( {'errorCode' : errorCode, 'message': message,'msgLevel':msgLevel} )) + else: + # 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) + + +@app.route("/removeNode", methods=['POST']) +def removeNode(): + # Validate the request body contains JSON + if request.is_json: + # Parse the JSON into a Python dictionary + req = request.get_json() + # Print the dictionary + if debug : print("Flask/removeNode ",req);print("/removeNode ",req['eId'],req['id']); + eId = req['eId']; + id = req['id']; + (eficasEditor, errorCode, errorMsg, infoMsg) = eficasAppli.getWebEditorById(session['canalId'],eId) + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + return make_response(json.dumps( {'errorCode' : errorCode, 'message': message,'msgLevel':msgLevel} )) + + (errorCode, errorMsg, infoMsg) = eficasEditor.removeNode(session['canalId'],session['externEditorId'],id); + if debug : print ("Flask/removeNode : ret : ",ret," message : ",message) + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + else : + messageLevel = "alert-success" + + return make_response(json.dumps( {'errorCode' : errorCode, 'message': message,'msgLevel':msgLevel} )) + else: + # 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) + +@app.route("/appendChild", methods=['POST']) +def appendChild(): + # Validate the request body contains JSON + # print ('__________________________________________') + # print ( 'in appendChild') + # print ('__________________________________________') + if request.is_json: + # Parse the JSON into a Python dictionary + req = request.get_json() + # Print the dictionary + if debug : print(__file__+"Flask/appendChild : ",req); + eId = req['eId'];id=req['id'];name=req['name'];pos=req['pos']; + # id, value = req.values() # Dangereux correspondance implicite + #rId,message,changeDone = eficasEditor.appendChild(id,name,pos); + (eficasEditor, errorCode, message) = eficasAppli.getWebEditorById(session['canalId'],eId) + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + return make_response(json.dumps( {'errorCode' : errorCode, 'message': message,'msgLevel':msgLevel} )) + (newId, errorCode, message) = eficasEditor.appendChild(session['canalId'],eId,id,name,pos); + if debug : print (__file__+"Flask/appendChild : newId : ",newId); + if errorCode : + messageLevel = "alert-danger" + message = errorMsg + infoMsg + else : + messageLevel = "alert-success" + return make_response(json.dumps( {'id':newId, 'errorCode' : errorCode, 'message': message,'msgLevel':msgLevel} )) #TODO: Code Erreur + # 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: + # 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) + +@app.route("/newDataset", methods=['POST']) +def newDataset(): + + # Validate the request body contains JSON + if request.is_json: + # Parse the JSON into a Python dictionary + req = request.get_json() + # Print the dictionary + print(__file__+"/newDataset : ",req); + #cataFile =os.path.abspath("../Codes/WebTest/"+req['catalogName']); + cataFile =os.path.abspath("./data/"+req['catalogName']); + dataSetFile =os.path.abspath("./data/"+req['datasetName']); + #cataFile = os.path.abspath('../Codes/WebTest/cata_essai.py') + #dataSetFile = os.path.abspath('../Codes/WebTest/web_tres_simple_avec_2Fact.comm') + else: + # 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) + + cId=session['canalId']; + (editorId, errorCode, errorMessage, messageInfo) = eficasAppli.getWebEditor(cId, cataFile, dataSetFile) + debug = 1 + if debug : + print ('apres getWebEditor : canalId, : ', cId, ' editorId, : ', editorId, + ' code Erreur : ', errorCode,'message : ', errorMessage, 'messageInfo ', messageInfo) + if errorCode : + # TODO ERIC + afficheMessage2(cId, editorId, errorMessage,'macouleur'); + return make_response(jsonify({"message": errorMessage, "code": errorCode}), 400) + + session['externEditorId'] = editorId; + + if debug : print ('idEditor = ', session['externEditorId']) + (eficasEditor, errorCode, errorMessage,messageInfo) = eficasAppli.getWebEditorById(session['canalId'],editorId) + if errorCode: + return make_response(jsonify({"message": errorMessage, "code": errorCode}), 400) + + + fancyTreeDict=eficasEditor.getDicoForFancy(eficasEditor.tree.racine) #TODO: changer le nom Dico en Dict + #fancyTreeJS=json.dumps([fancyTreeDict],indent=4) #TODO : remove indent if not DEBUG + fancyTreeDict['eId']=editorId; + #print("---- myFancyTreeDico ----") + pprint(fancyTreeDict) + #print("---- myFancyTreeJS ----") + #pprint( myFancyTreeJS) + commands = eficasEditor.getListeCommandes(); #TODO: Renommer la fonction + + title = os.path.basename(cataFile)+'/'+os.path.basename(dataSetFile) + if debug : print('liste des commandes', eficasEditor.getListeCommandes()) + return make_response(json.dumps( {'source': [fancyTreeDict], 'commands':commands, 'title':title,} )) + + +@app.route('/') +def index(): + + # Example : + # tree4Fancy = """ [ + # {"title": "Node 1", "key": "1"}, + # {"title": "Folder 2", "key": "2", "folder": true, "children": [ + # {"title": "Node 2.1", "key": "3"}, + # {"title": "Node 2.2", "key": "4"} + # ]} + # ] + # """.replace('\n','') + + #print ('_______________________________________________') + #cataFile = os.path.abspath('../Codes/WebTest/cata_essai.py') + #dataSetFile = os.path.abspath('../Codes/WebTest/web_tres_simple_avec_2Fact.comm') + + # En attendant la génération d'un n° de canal unique + # notion de plage + if not 'canalId' in session : + global _no + _no = _no + 1 + canalId = _no + session['canalId'] = canalId + else : + canalId = session['canalId'] + #if _no == 3: + # dataSetFile = os.path.abspath('../Codes/WebTest/web_tres_simple_incomplet.comm') + + #(canalId, eficasEditor, errorCode, message) = eficasAppli.getWebEditor(cataFile, dataSetFile) + #(externEditorId, errorCode, errorMsg, messageInfo) = eficasAppli.getWebEditor(canalId, cataFile, dataSetFile) + #debug = 0 + #if debug : print ('apres getWebEditor : canalId, : ', canalId, ' externEditorId, : ', externEditorId, ' code Erreur : ', errorCode,'message : ', errorMsg, 'messageInfo ', messageInfo) + #if not errorCode : + # if debug : + # print ('_______________________________________________') + # print ('canalId', canalId) + # print ('externEditorId', externEditorId) + # print ('_______________________________________________') + # session['externEditorId'] = externEditorId + #else : + # # Il faudrait gerer les erreurs + # return render_template('commandes_2.html', + # titre= errorMsg, + # listeCommandes = [], + # tree= None + # ) + + #if debug : print ('idEditor = ', session['externEditorId']) + #(eficasEditor, errorCode, message) = eficasAppli.getWebEditorById(canalId,externEditorId) + #if errorCode: + # return render_template('commandes_2.html', + # titre= errorMsg, + # listeCommandes = [], + # tree= None + # ) + + + #myFancyTreeDico=eficasEditor.getDicoForFancy(eficasEditor.tree.racine) + #if debug : pprint (myFancyTreeDico) + #myFancyTreeJS=json.dumps([myFancyTreeDico],indent=4) #TODO : remove indent if not DEBUG + + #print("---- myFancyTreeDico ----") + #pprint(myFancyTreeDico) + #print("---- myFancyTreeJS ----") + #pprint( myFancyTreeJS) + + #if debug : print ( 'liste des commandes', eficasEditor.getListeCommandes()) + #return render_template('commandes_2.html', + # titre=code, + # efi_update_channel = str(canalId), + # listeCommandes = eficasEditor.getListeCommandes(), + # tree=myFancyTreeJS, + # tree=tree4Fancy, + #) + myFancyTreeJS=json.dumps([{}],indent=4) #TODO : remove indent if not DEBUG + return render_template('commandes_2.html', + titre=code, + efi_update_channel = str(canalId), + listeCommandes = [], + tree=myFancyTreeJS, + ) + # etape = str(escape(request.args.get("etape", ""))) + + + +# @app.route("/forward/", methods=['POST']) +# def move_forward(): +# #Moving forward code +# forward_message = "Moving Forward..." +# return render_template('mdm.html', message=forward_message) + + + +# @app.route('/form', methods=['GET', 'POST']) +# def basicform(): +# form = BasicForm(request.form) +# if request.method == 'POST' and form.validate(): +# with open('/tmp/test.txt', 'w') as f: +# for k in request.form: +# f.write('{0}: {1}\n'.format(k, request.form[k])) +# return render_template('basic.html', form=form) + +# @app.route("/json", methods=["POST"]) +# def json_example(): + +# if request.is_json: + +# req = request.get_json() + +# response_body = { +# "message": "JSON received!", +# "sender": req.get("name") +# } + +# res = make_response(jsonify(response_body), 200) + +# return res + +# else: + +# return make_response(jsonify({"message": "Request body must be JSON"}), 400) + +#TODO: +#from fileManagement import * + +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 + + +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)) + + return True + + except: + print(traceback.format_exc()) + return False + + +@app.route("/upload", methods=['GET', 'POST']) +def upload(): + 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 +# from werkzeug.datastructures import ImmutableOrderedMultiDict +# class MyRequest(Request): +# """Request subclass to override request parameter storage""" +# parameter_storage_class = ImmutableOrderedMultiDict +# class MyFlask(Flask): +# """Flask subclass using the custom request class""" +# request_class = MyReq + +def create_app(test_config=None): + # create and configure the app + app = Flask(__name__, instance_relative_config=True) + app.config.from_mapping( + SECRET_KEY='dev', + DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'), + ) + + if test_config is None: + # load the instance config, if it exists, when not testing + app.config.from_pyfile('config.py', silent=True) + else: + # load the test config if passed in + app.config.from_mapping(test_config) + + # ensure the instance folder exists + try: + os.makedirs(app.instance_path) + except OSError: + pass + + return app + +if __name__ == "__main__": + app.run(host="localhost", port=8321, debug=True) + + + + +#$("#386bc28a2ff811ec853cac220bca9aa6").html('Essai') + +# $("#550f63502b6611ecab61ac220bca9aa6").hover(function(){ +# alert("The text has been changed."); +# }); + +# $("#1f3ca24a2cf911ecab61ac220bca9aa6").hover(function(){ +# $.post("{{ url_for('static', filename='demo_test.txt') }}", +# { +# id: $(this).attr("id"), +# }, +# function(data, status){ +# alert("Data: " + data + "\nStatus: " + status); +# }); +# }); + +# $("#e0a1f2862cfa11ecab61ac220bca9aa6").hover(function(){ +# $.post("http://127.0.0.1:8123/test1", +# { +# id: $(this).attr("id"), +# }, +# function(data, status){ +# alert("Data: " + data + "\nStatus: " + status); +# }); +# }); + +# $(".MCSIMPValide").hover(function(){ +# alert("-5-- :"+ $(this).text() + $("#e0a1f2862cfa11ecab61ac220bca9aa6").text() + $(this).attr("class") + $(this).attr("id")); +# $.post("http://127.0.0.1:8123/test1", +# { +# id: $(this).attr("id"), +# }, +# function(data, status){ +# alert("Data: " + data + "\nStatus: " + status +"\nId :", $(this).attr("id") ); +# }); +# }); + + +# # # $("#550f63502b6611ecab61ac220bca9aa6")[0].id +# $("#e0a1f2862cfa11ecab61ac220bca9aa6").hover(function(){ +# alert("-4-- :"+ $(this).text() + $("#e0a1f2862cfa11ecab61ac220bca9aa6").text() + $(this).attr("class") + $(this).attr("id")); +# }); + +# $("#550f63502b6611ecab61ac220bca9aa6")[0].id + +#$("#ec7abddd2dca11ecab61ac220bca9aa6").parents()[0] +# Pour obtenir le nodeid treeview a partir de l'eficasID +#$("#ec7abddd2dca11ecab61ac220bca9aa6").parent()[0].attributes['data-nodeid'].value