]> SALOME platform Git repositories - tools/eficas.git/commitdiff
Salome HOME
Un peu de ménage
authorEric Fayolle <eric.fayolle@edf.fr>
Tue, 5 Apr 2022 13:08:23 +0000 (15:08 +0200)
committerEric Fayolle <eric.fayolle@edf.fr>
Tue, 5 Apr 2022 13:08:23 +0000 (15:08 +0200)
WebTest/cata_Vallee.py [new file with mode: 0644]
testFlask/cata_Vallee.py [changed from file to symlink]
testFlask/mdm.py
testFlask/prefs_Morgane.py [new file with mode: 0644]
testFlask/templates/base.html
testFlask/templates/commandes_2.html

diff --git a/WebTest/cata_Vallee.py b/WebTest/cata_Vallee.py
new file mode 100644 (file)
index 0000000..988822d
--- /dev/null
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-\r
+# Copyright (C) 2008-2018 EDF R&D\r
+#\r
+# This file is part of SALOME ADAO module\r
+#\r
+# This library is free software; you can redistribute it and/or\r
+# modify it under the terms of the GNU Lesser General Public\r
+# License as published by the Free Software Foundation; either\r
+# version 2.1 of the License.\r
+#\r
+# This library is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+# Lesser General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU Lesser General Public\r
+# License along with this library; if not, write to the Free Software\r
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
+#\r
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+import os\r
+from Accas import OPER, BLOC, FACT, SIMP, ASSD, JDC_CATA, VerifTypeTuple, Matrice, UserASSD\r
+from Extensions.i18n import tr\r
+import types\r
+monFichier = os.path.abspath(__file__)\r
+\r
+JdC = JDC_CATA(\r
+    code='Morgane',\r
+    fr = "Modèle physique d'une vallée",\r
+)\r
+VERSION_CATALOGUE = 'V_0'\r
+\r
+class vallee(ASSD) : pass\r
+class usine(UserASSD) : pass\r
+class reservoir(UserASSD) : pass\r
+\r
+unitesChute=['hm3','m3']\r
+\r
+Vallee=OPER(nom="Vallee", sd_prod=vallee,\r
+      fr="Elément défini pour éventuellement contenir la définition des vallées de manière autonome. Les contraintes sont définies au niveau de l'élément et doivent donc être répétées si le type est utilisé ailleurs",\r
+       Reservoirs=FACT(statut='o', \r
+          Reservoir = FACT ( statut ='o', max='**', \r
+             NomReservoir  = SIMP(statut='o', typ=(reservoir,'createObject'),), \r
+             TypeReservoir = SIMP(statut='o', typ= 'TXM', into = ['Lac', 'Eclusee',]), \r
+             Volume        = SIMP(statut='o', typ= 'R', defaut=0, val_min=0,),\r
+             Surface       = SIMP(statut='o', typ= 'R'),\r
+             CotesVolume   = FACT(statut='f',\r
+                 fr="Si, quelque part dans l'étude (usine ou réservoir), il y a des cotes (ie on travaille en mètres), il faut les cotes volumes car le coeur de calcul travaille en volume",\r
+                CoteVolume = FACT (statut='o', max='**',\r
+                     Cote    = SIMP(statut='o', typ='R', defaut=0, val_min=0),\r
+                     Volume  = SIMP(statut='o', typ='R', defaut=0, val_min=0),\r
+                     Surface = SIMP(statut='o', typ='R', defaut=0, val_min=0),\r
+                ),\r
+            ),\r
+          ),\r
+       ), # Reservoirs\r
+\r
+      Usines = FACT(statut ='o', \r
+          fr="Attention, l'ordre des usines a une importance", \r
+          Usine = FACT ( statut ='o', max='**', \r
+             fr="Les usines sont des turbines, des pompes ou des non énergétiques. Leur description dépend de ce type",\r
+             NomDUsine  = SIMP(statut='o', typ=(usine,'createObject'),), \r
+             TypeDUsine = SIMP(statut='o', typ= 'TXM', into = ['Turbine', 'Pompe', 'NonEnergetique']), \r
+             b_TypeDUsine_Turbine = BLOC( condition = 'TypeDUsine == "Turbine"', \r
+                 CaracteristiquesTurbine=FACT( statut='o', \r
+                     fr="Caractéristiques spécifiques aux turbines", DebitMaxPhysique  = SIMP(typ='I',    statut='o',defaut=100000, val_min=0), \r
+                     TypeDeDeversement = SIMP(typ= 'TXM', into = ['CapaciteFixe', 'NonAutorise', 'DebitMaxGestion']),\r
+                     b_Turbine_CapaciteFixe = BLOC( condition = 'TypeDeDeversement == "CapaciteFixe"', \r
+                        Capacite = SIMP(typ='I', defaut=0, val_min=0),\r
+                     ), \r
+                     HauteurChute    = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
+                     Puissance       = SIMP(typ='R', defaut=0,statut='o', val_min=0),\r
+                     Debit           = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
+                     BandePrimaire   = SIMP(typ='R', defaut=0 , statut='o', val_min=0),\r
+                     BandeSecondaire = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
+                  ),\r
+             ), # fin Turbine\r
+             b_TypeDUsine_Pompe = BLOC( condition = 'TypeDUsine == "Pompe"',\r
+                 fr="Caractéristiques spécifiques aux pompes",\r
+                 CaracteristiquesPompe=FACT( statut='o',\r
+                     DebitMaxPhysique = SIMP(typ='I', statut='o',defaut=-100000, val_max=0),\r
+                     HauteurChute     = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
+                     Puissance        = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
+                     Debit            = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
+                   ),\r
+             ), # fin Pompe\r
+             b_TypeDUsine_NonEnergetique = BLOC( condition = 'TypeDUsine == "NonEnergetique"',\r
+                 CaracteristiquesNonEnergetique=FACT( statut='o',\r
+                     DebitMaxPhysique = SIMP(typ='I', statut='o', defaut=100000, val_min=0),\r
+                 ),\r
+             ),\r
+             b_TypeDUsine = BLOC( condition = 'TypeDUsine != None',\r
+                 DelaiAval         = SIMP(typ='I', statut='o',defaut=0, val_min=0),\r
+                 UniteHauteurChute = SIMP(typ="TXM", statut='o', into=unitesChute, defaut="hm3"),\r
+                 Interpolation     = SIMP(typ="TXM", statut='o', into=["EnVolume", "EnCote"], defaut="EnCote"),\r
+                 ReservoirAmont    = SIMP(typ=reservoir,statut='o'),\r
+                 b_DelaiAval_NonNul = BLOC( condition = "DelaiAval != 0",\r
+                      ReservoirAval    = SIMP(typ=reservoir,statut='o'),\r
+                 ),\r
+              ), # fin bloc commun\r
+          ), # fin Usine\r
+            \r
+       ), # Usines\r
+)\r
deleted file mode 100644 (file)
index 988822de78e092ee53677189a3ffdb9283d29700..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,104 +0,0 @@
-# -*- coding: utf-8 -*-\r
-# Copyright (C) 2008-2018 EDF R&D\r
-#\r
-# This file is part of SALOME ADAO module\r
-#\r
-# This library is free software; you can redistribute it and/or\r
-# modify it under the terms of the GNU Lesser General Public\r
-# License as published by the Free Software Foundation; either\r
-# version 2.1 of the License.\r
-#\r
-# This library is distributed in the hope that it will be useful,\r
-# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-# Lesser General Public License for more details.\r
-#\r
-# You should have received a copy of the GNU Lesser General Public\r
-# License along with this library; if not, write to the Free Software\r
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
-#\r
-# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
-import os\r
-from Accas import OPER, BLOC, FACT, SIMP, ASSD, JDC_CATA, VerifTypeTuple, Matrice, UserASSD\r
-from Extensions.i18n import tr\r
-import types\r
-monFichier = os.path.abspath(__file__)\r
-\r
-JdC = JDC_CATA(\r
-    code='Morgane',\r
-    fr = "Modèle physique d'une vallée",\r
-)\r
-VERSION_CATALOGUE = 'V_0'\r
-\r
-class vallee(ASSD) : pass\r
-class usine(UserASSD) : pass\r
-class reservoir(UserASSD) : pass\r
-\r
-unitesChute=['hm3','m3']\r
-\r
-Vallee=OPER(nom="Vallee", sd_prod=vallee,\r
-      fr="Elément défini pour éventuellement contenir la définition des vallées de manière autonome. Les contraintes sont définies au niveau de l'élément et doivent donc être répétées si le type est utilisé ailleurs",\r
-       Reservoirs=FACT(statut='o', \r
-          Reservoir = FACT ( statut ='o', max='**', \r
-             NomReservoir  = SIMP(statut='o', typ=(reservoir,'createObject'),), \r
-             TypeReservoir = SIMP(statut='o', typ= 'TXM', into = ['Lac', 'Eclusee',]), \r
-             Volume        = SIMP(statut='o', typ= 'R', defaut=0, val_min=0,),\r
-             Surface       = SIMP(statut='o', typ= 'R'),\r
-             CotesVolume   = FACT(statut='f',\r
-                 fr="Si, quelque part dans l'étude (usine ou réservoir), il y a des cotes (ie on travaille en mètres), il faut les cotes volumes car le coeur de calcul travaille en volume",\r
-                CoteVolume = FACT (statut='o', max='**',\r
-                     Cote    = SIMP(statut='o', typ='R', defaut=0, val_min=0),\r
-                     Volume  = SIMP(statut='o', typ='R', defaut=0, val_min=0),\r
-                     Surface = SIMP(statut='o', typ='R', defaut=0, val_min=0),\r
-                ),\r
-            ),\r
-          ),\r
-       ), # Reservoirs\r
-\r
-      Usines = FACT(statut ='o', \r
-          fr="Attention, l'ordre des usines a une importance", \r
-          Usine = FACT ( statut ='o', max='**', \r
-             fr="Les usines sont des turbines, des pompes ou des non énergétiques. Leur description dépend de ce type",\r
-             NomDUsine  = SIMP(statut='o', typ=(usine,'createObject'),), \r
-             TypeDUsine = SIMP(statut='o', typ= 'TXM', into = ['Turbine', 'Pompe', 'NonEnergetique']), \r
-             b_TypeDUsine_Turbine = BLOC( condition = 'TypeDUsine == "Turbine"', \r
-                 CaracteristiquesTurbine=FACT( statut='o', \r
-                     fr="Caractéristiques spécifiques aux turbines", DebitMaxPhysique  = SIMP(typ='I',    statut='o',defaut=100000, val_min=0), \r
-                     TypeDeDeversement = SIMP(typ= 'TXM', into = ['CapaciteFixe', 'NonAutorise', 'DebitMaxGestion']),\r
-                     b_Turbine_CapaciteFixe = BLOC( condition = 'TypeDeDeversement == "CapaciteFixe"', \r
-                        Capacite = SIMP(typ='I', defaut=0, val_min=0),\r
-                     ), \r
-                     HauteurChute    = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
-                     Puissance       = SIMP(typ='R', defaut=0,statut='o', val_min=0),\r
-                     Debit           = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
-                     BandePrimaire   = SIMP(typ='R', defaut=0 , statut='o', val_min=0),\r
-                     BandeSecondaire = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
-                  ),\r
-             ), # fin Turbine\r
-             b_TypeDUsine_Pompe = BLOC( condition = 'TypeDUsine == "Pompe"',\r
-                 fr="Caractéristiques spécifiques aux pompes",\r
-                 CaracteristiquesPompe=FACT( statut='o',\r
-                     DebitMaxPhysique = SIMP(typ='I', statut='o',defaut=-100000, val_max=0),\r
-                     HauteurChute     = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
-                     Puissance        = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
-                     Debit            = SIMP(typ='R', defaut=0, statut='o', val_min=0),\r
-                   ),\r
-             ), # fin Pompe\r
-             b_TypeDUsine_NonEnergetique = BLOC( condition = 'TypeDUsine == "NonEnergetique"',\r
-                 CaracteristiquesNonEnergetique=FACT( statut='o',\r
-                     DebitMaxPhysique = SIMP(typ='I', statut='o', defaut=100000, val_min=0),\r
-                 ),\r
-             ),\r
-             b_TypeDUsine = BLOC( condition = 'TypeDUsine != None',\r
-                 DelaiAval         = SIMP(typ='I', statut='o',defaut=0, val_min=0),\r
-                 UniteHauteurChute = SIMP(typ="TXM", statut='o', into=unitesChute, defaut="hm3"),\r
-                 Interpolation     = SIMP(typ="TXM", statut='o', into=["EnVolume", "EnCote"], defaut="EnCote"),\r
-                 ReservoirAmont    = SIMP(typ=reservoir,statut='o'),\r
-                 b_DelaiAval_NonNul = BLOC( condition = "DelaiAval != 0",\r
-                      ReservoirAval    = SIMP(typ=reservoir,statut='o'),\r
-                 ),\r
-              ), # fin bloc commun\r
-          ), # fin Usine\r
-            \r
-       ), # Usines\r
-)\r
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..f0fc7c6cf70c66be573079e058de0b61353613a0
--- /dev/null
@@ -0,0 +1 @@
+../WebTest/cata_Vallee.py
\ No newline at end of file
index b51926fa92eb9201886a6eea7592988b3e3dd704..73a58e24d51e4e5009ecd8c68dfdffbf58abb684 100755 (executable)
@@ -4,6 +4,7 @@ import sys
 sys.path.append('/home/eric/FLASK/eficas.eecj.git/testFlask') #TODO : supprimer
 from connectEficas import accasConnecteur
 
+#code='Morgane'
 code='Essai'
 
 from flask import Flask, request, render_template, url_for, jsonify, make_response, session, g, Response
@@ -46,155 +47,6 @@ 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'])
 
-#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/<string:filename>", 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/<string:filename>", methods=['GET'])
-def get_thumbnail(filename):
-    return send_from_directory(app.config['THUMBNAIL_FOLDER'], filename=filename)
-
-
-@app.route("/data/<string:filename>", 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
 
 ### Server Side Event config
 app.config["REDIS_URL"] = "redis://localhost"
@@ -254,119 +106,6 @@ def afficheAlerte(titre, message):
 #     sse.publish({"message": "Hello!"}, type='update')
 #     return "Message sent!"
 
-@app.route('/')
-def index():
-    tree4treeview = """ [
-      {
-        "text": "Parent 1",
-        "nodes": [
-          {
-            "text": "Child 1.1",
-            "nodes": [
-              {
-                "text": "Grandchild 1.1"
-              },
-              {
-                "text": "Grandchild 1.2"
-              }
-            ]
-          },
-          {
-            "text": "Child 1.2",
-            "nodes": [
-              {
-                "text": "Grandchild 1.1"
-              },
-              {
-                "text": "Grandchild 1.2"
-              }
-            ]
-          },
-          {
-            "text": "Child 2"
-          }
-        ]
-      },
-      {
-        "text": "Parent 2"
-      },
-      {
-        "text": "<span class='icon node-icon' id='idtest0'>Parent 3</span>",
-        "nodes":   [{"text":"<span class='icon node-icon' id='idtest1'>3.5</span>"}]
-      },
-      {
-        "txt": "Parent 4"
-      },
-      {
-        "text": "Parent 5"
-      }
-    ]
-    """.replace('\n','')
-
-    treeB = """ [
-      {
-        "nodes": [
-          {
-            "text": "Child 1.1",
-            "nodes": [
-              {
-                "text": "Grandchild 1.1"
-              },
-              {
-                "text": "Grandchild 1.2"
-              }
-            ]
-          }
-        ]
-      }
-    ]
-    """.replace('\n','')
-
-
-    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("treeB : %s"%treeB);
-    
-    dictC={'nodes': [{'text': 'Child 1.1', 'nodes': [{'text': 'Grandchild 1.1'}, {'text': 'Grandchild 1.2'}]}]}
-    treeC=[dictC]
-
-    # print("mytree : %s"%mytree);
-    mcTraite={'MonProc2': {'s1': ('I', 2), 'F2': {'s2': ('I', 3), 'F3': {'s3': ('I', 4)}}}};
-
-    monConnecteur.litFichierComm('../WebTest/web_tres_simple_avec_2Fact.comm')
-    #monConnecteur.litFichierComm('../WebTest/edg_REP1300_FULL_PN.comm')
-    #myTreeDico=monConnecteur.getDicoObjetsCompletsPourTree(monConnecteur.monEditeur.tree.racine)
-    myFancyTreeDico=monConnecteur.getDicoForFancy(monConnecteur.monEditeur.tree.racine)
-    print (myFancyTreeDico)
-    
-    #myTreeJS=json.dumps([myTreeDico])
-    myFancyTreeJS=json.dumps([myFancyTreeDico])
-    myFancyTreeJS=json.dumps([myFancyTreeDico],indent=4)  #TODO : remove indent if not DEBUG
-    
-    print("---- myFancyTreeDico ----")
-    pprint(myFancyTreeDico)
-    print("---- myFancyTreeJS ----")
-    pprint( myFancyTreeJS)
-
-    return render_template('commandes_2.html',
-      titre=code,
-      listeCommandes = monConnecteur.getListeCommandes(),
-      # profondeur=4,
-      mcTraite={'MonProc2': {'s1': ('I', 2), 'F2': {'s2': ('I', 3), 'F3': {'s3': ('I', 4)}}}},
-      mcTraiteJson=json.dumps(mcTraite),
-      tree=myFancyTreeJS,
-      # tree=tree4Fancy,
-      # tree=myTreeJS
-      # tree='['+myTreeJS+']'
-    )
-    # etape  = str(escape(request.args.get("etape", "")))
 
 ## WebApp -> Eficas  :
 # Pour SIMP : Ajoute, Supprime (MC facultatif), Change la valeur
@@ -404,6 +143,32 @@ def updateSimp():
         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'])
+        id=req['id'];value=req['value']
+        # id, value = req.values()       # Dangereux correspondance implicite
+        value             = str(value)   #On peut écrire Pi
+        rId,message,changeDone       = monConnecteur.updateSDName(id,value);
+        assert(rId==id)
+        #changeDone        = True
+        print ("changeDone : ",changeDone)
+        
+        #return make_response(json.dumps( {'id':id , 'changeIsAccepted' : changeDone, 'message': message} ))
+        return make_response(json.dumps( {'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("/removeNode", methods=['POST'])
 def removeNode():
@@ -446,6 +211,41 @@ def appendChild():
         return "Request was not JSON", 400
         #return make_response(jsonify({"message": "Request body must be JSON"}), 400)
 
+@app.route('/')
+def index():
+
+   #  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','')
+
+
+    monConnecteur.litFichierComm('../WebTest/web_tres_simple_avec_2Fact.comm')
+    #monConnecteur.litFichierComm('../WebTest/edg_REP1300_FULL_PN.comm')
+    myFancyTreeDico=monConnecteur.getDicoForFancy(monConnecteur.monEditeur.tree.racine)
+    #print (myFancyTreeDico)
+    
+    #myFancyTreeJS=json.dumps([myFancyTreeDico])
+    myFancyTreeJS=json.dumps([myFancyTreeDico],indent=4)  #TODO : remove indent if not DEBUG
+    
+    print("---- myFancyTreeDico ----")
+    pprint(myFancyTreeDico)
+    print("---- myFancyTreeJS ----")
+    pprint( myFancyTreeJS)
+
+    return render_template('commandes_2.html',
+      titre=code,
+      listeCommandes = monConnecteur.getListeCommandes(),
+      tree=myFancyTreeJS,
+      # tree=tree4Fancy,
+    )
+    # etape  = str(escape(request.args.get("etape", "")))
+
+
 
 @app.route("/forward/", methods=['POST'])
 def move_forward():
@@ -484,6 +284,156 @@ def json_example():
 
         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/<string:filename>", 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/<string:filename>", methods=['GET'])
+def get_thumbnail(filename):
+    return send_from_directory(app.config['THUMBNAIL_FOLDER'], filename=filename)
+
+
+@app.route("/data/<string:filename>", 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
+
 if __name__ == "__main__":
     app.run(host="localhost", port=8321, debug=True)
 
diff --git a/testFlask/prefs_Morgane.py b/testFlask/prefs_Morgane.py
new file mode 100644 (file)
index 0000000..e09c731
--- /dev/null
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+#            maConfiguration MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 2007-2021  EDF R&D                  
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+
+import os,sys
+# repIni sert a localiser le fichier editeur.ini
+# Obligatoire
+repIni=os.path.dirname(os.path.abspath(__file__))
+INSTALLDIR=os.path.join(repIni,'..')
+sys.path[:0]=[INSTALLDIR]
+
+
+# lang indique la langue utilisee pour les chaines d'aide : fr ou ang
+lang='ang'
+
+# Codage des strings qui accepte les accents (en remplacement de 'ascii')
+encoding='iso-8859-1'
+code = 'Morgane'
+
+#
+catalogues=(
+    ('Morgane','Morgane',os.path.join(repIni,'cata_Vallee.py'),'python','python'),
+)
index 95b50ed8ea01960018627afa46f559284adcb033..0b362bbeaabd17319cef58f35ad15ce58c86fd73 100644 (file)
     <script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>
     <!-- (Optional) Latest compiled and minified JavaScript translation files -->
     <script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/i18n/defaults-*.min.js"></script>
+
+
+    <!-- Add the tablenavigator javascript and CSS file  -->
+    <!-- <script src="{{ url_for('static', filename='tablenavigator.jquery.js') }}"></script> -->
+
+    <!-- Add the handsontable javascript and CSS file  -->
+    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.js"></script>
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css" />
+
     
     <meta name="description" content={{description}}>
     <!-- <link rel="shortcut icon" href="../images/favicon-32x32.png"> -->
index 1427f4321f42eeb1629d541f5209f133f8338e52..0a5b86f4e92949499edd5e7e25fd8944a128f4ba 100644 (file)
@@ -2,17 +2,18 @@
 
 {% block content %}
 
-<!--     {%- for key, value in mcTraite.items() recursive %} -->
-<!--   <h3>{{ key }} </h3> -->
-<!--   {%- if value %} -->
-<!--       {% if value is mapping %} -->
-<!--         <ul>{{ loop(value.items())}}</ul> -->
-<!--       {%- else %} -->
-<!--         type {{value[0]}} valeur{{value[1]}} -->
-<!--       {%- endif %} -->
-<!--   {%- endif %} -->
+
+<!--     {#- for key, value in mcTraite.items() recursive #} -->
+<!--   <h3>{#{ key }#} </h3> -->
+<!--   {#- if value #} -->
+<!--       {# if value is mapping #} -->
+<!--         <ul>{#{ loop(value.items())}#}</ul> -->
+<!--       {#- else #} -->
+<!--         type {#{value[0]}#} valeur{#{value[1]}#} -->
+<!--       {#- endif #} -->
+<!--   {#- endif #} -->
 <!--    <\!-- </li> -\-> -->
-<!--     {%- endfor %}                                  -->
+<!--     {#- endfor #}                                  -->
 
 <!-- <div id="tree2"></div> -->
 
   </div>  <!-- col -->
   
 </div> <!-- row -->
+
+    <div id='handsontable_test1'/>
+    
 <script>
+
+const handsontable_data0 = [
+    { id: 1, name: 'Ted Right', address: '',col3: 3, col4: 4, col5: 5, col6: 6 },
+    { id: 2, name: 'Frank Honest', address: '' },
+    { id: 3, name: 'Joan Well', address: '' },
+    { id: 4, name: 'Gail Polite', address: '' },
+    { id: 5, name: 'Michael Fair', address: '' },
+];
+const handsontable_data1 = [
+    { id: 1, name: 'Ted Right', address: '',col3: 3, col4: 4, col5: 5, col6: 6 },
+    { id: 2, name: 'Frank Honest', address: '' },
+    { id: 3, name: 'Joan Well', address: '' },
+    { id: 4, name: 'Gail Polite', address: '' },
+    { id: 5, name: 'Michael Fair', address: '' },
+];
+
+    <!-- const container0= document.getElementById('handsontable_test1'); -->
+    <!-- const hot0 = new Handsontable(container0, { -->
+    <!--       data: handsontable_data0, -->
+    <!--       colHeaders: false, -->
+    <!--       height: 'auto', -->
+    <!--       width: 'auto', -->
+    <!--       minSpareRows: 0, -->
+    <!--       licenseKey: 'non-commercial-and-evaluation' -->
+    <!-- }); -->
+
   //$("#navbar-optionals").affix({offset: {top: $("#row-commands_menu").outerHeight(true)} }); 
   $("#col-optional_tree").affix({offset: {top: $("#row-commands_menu").outerHeight(true)} }).css('right',0); 
 </script>
@@ -138,9 +168,10 @@ $(function () {
       });
  });
 
-//$.ui.fancytree.debugLevel=4; // Set the fancyTree debug level
+// if tree.options.debug is null: use global setting $.ui.fancytree.debugLevel)
+// $.ui.fancytree.debugLevel=4; // Set the fancyTree debug level
 
-//Créer une fonction pour désactiver toutes les classes d'alert pour positionner une seule 
+//Créer une fonction pour désactiver toutes les classes d'alert et pour en positionner une seule 
 let treeMessage=function(msgCssSelStr,messageClass,message) {
     const messageClasses = new Set(["alert-success","alert-info","alert-warning","alert-danger"]);
     if (messageClasses.has(messageClass)) {
@@ -154,6 +185,7 @@ let treeMessage=function(msgCssSelStr,messageClass,message) {
            $.ui.fancytree.info(message);     // debugLevel >= 3
        } else {
             console.debug(message);           // debugLevel >= 4
+           $.ui.fancytree.debug(message);    // debugLevel >= 4
        };
         $(msgCssSelStr).text(message);
     } else {
@@ -331,12 +363,12 @@ source.addEventListener('message', function(event) {
            treeMessage(_msgCssSelStr,"alert-danger",msgerror);
            return;
        };
-        console.log("-------------  message 2a: "+ node.data.title); 
-        console.log("-------------  message 2b: "+ info.title);
+        // console.log("-------------  message 2a: "+ node.data.title); 
+        // console.log("-------------  message 2b: "+ info.title);
        // En fait, il faut que fancytree trie les propriétés qui l'interesse de celles qui vont dans data
        // Object.assign(node.data,info); //merge new options to node.data
        node.fromDict(info);
-        console.log("-------------  message 2c: "+ node.data.title); 
+        // console.log("-------------  message 2c: "+ node.data.title); 
         node.render(true,false);       //force rendering the node (not parents nor descendants)
         //node.renderStatus();         //CSS element updates only          
     }, false);
@@ -420,10 +452,6 @@ function getTree1() {
 }
 
 
-    // function getTree2() {
-    // // Some logic to retrieve, or generate tree structure
-    // return  {{ mcTraiteJson|tojson }};
-    // }
 
     // $("#tree1").fancytree({ source: [ {title: "Node 1", key: "1000"},{title: "Folder 2", key: "2", folder: true, children: [ {title: "Node 2.1", key: "3000"},{title: "Node 2.2", key: "44"} ]}    ], })
 
@@ -460,9 +488,10 @@ function iconRendering(event, data) {
 $(function(){
     $("#tree1").fancytree({
        //focusOnSelect:true,
-       debug:4,
+       debug:4, //if null: use global setting $.ui.fancytree.debugLevel
+       debuLevel:4, //if null: use global setting $.ui.fancytree.debugLevel
        //extensions: ["dnd5", "edit", "glyph", "wide", "table", "gridnav"],
-       extensions: [ "glyph", "table", "ariagrid"],
+       extensions: [ "glyph", "table", "ariagrid"], // https://github.com/mar10/fancytree/wiki/ExtTable
        //extensions: [ "glyph", "table", "gridnav"],
        checkbox: true, // Activate the use of checkboxes next to the nodes
 
@@ -505,7 +534,7 @@ $(function(){
        },
        gridnav: {
            autofocusInput:   true, // Focus first embedded input if node gets activated
-           handleCursorKeys: true  // Allow UP/DOWN in inputs to move to prev/next node
+           handleCursorKeys: false  // Allow UP/DOWN in inputs to move to prev/next node
        },
        ariagrid:       {
             cellFocus: 'allow'
@@ -519,7 +548,7 @@ $(function(){
        //  data.result = {url: "ajax-sub2.json", debugDelay: 1000};
        //}
        // renderStatusColumns: Pour le CSS
-       renderColumns: function(event, data) {
+       renderColumns: function(event, data) { //TODO : use createNode event to avaoid recreating content when rendering
 
             // Pour tester ds la console :
             //var tree=$.ui.fancytree.getTree("#tree1")
@@ -532,12 +561,12 @@ $(function(){
 
             const node          = data.node,
                $tdList          = $(node.tr).find(">td");
-            const classeAccas   = node.data.classeAccas;
+            const classeAccas   = node.data.classeAccas;  //TODO : Utiliser les types fancytree
             const validite      = node.data.validite;
             const wValue         = node.data.wValue;
             const statut         = node.data.statut;
-           const cmdName        = node.data.nomCommande; // undefined if classeAccas != 'MCFACT'
-           const repeatable     = node.data.repetable;          // ?? undefined if classeAccas != 'MCFACT' ??
+           const cmdName        = node.data.nomCommande;  // undefined if classeAccas != 'MCFACT'
+           const repeatable     = node.data.repetable;    // ?? undefined if classeAccas != 'MCFACT' ??
            const infoOptionnels = node.data.infoOptionnels;
             const key           = node.key;
             const name          = node.title;
@@ -573,13 +602,30 @@ $(function(){
                        "<form>"+ 
                            "<div class='form-group'>" +
                            "<input type='input' class='form-control input-sm' id='"+key+"' placeholder='"
-                           + wValue + //TODO:intosugg
-                       "' value='"+wValue+"' required>"+
+                             + wValue + //TODO:intosugg
+                             "' value='"+wValue+"' required>"+
+                           // "<input type='input' class='form-control input-sm' id='"+key+"' placeholder='"
+                           //   + wValue + //TODO:intosugg
+                           //   "' value='"+wValue+"' required>"+
+                           "<div id='handsontable_"+key+"' />"+
                            "</div>"+
-                           "</form>"
+                       "</form>"
                    )
                    .addClass(_attr)
                    .find("input").css('color','black'); //TODO : A placer ds le CSS
+                   // const container = document.getElementById('handsontable_'+key);
+                   // const hot = new Handsontable(container, {
+                   //  data: handsontable_data0,
+                   //  colHeaders: false,
+                   //  height: 'auto',
+                   //  width: 'auto',
+                   //  minSpareRows: 1,
+                   //  licenseKey: 'non-commercial-and-evaluation'
+                   // });
+                   // hot.render();
+                   // hot.addHook('afterCreateRow', (row, amount) => {
+                   //  console.log(`${amount} row(s) were created, starting at index ${row}`);
+                   // });
                                
             }; // Not classeAccas ==  "MCSIMP"
 
@@ -676,7 +722,7 @@ $(function(){
            
            let buildOptionalTreeSrc=function(node) {
                if ( node == null ) return [];
-               let parentList = node.getParentList(false,true); // default : (false,false)==(rootNode exclus, not self)
+               let parentList = node.getParentList(false,hasOpt(node)); // default : (false,false)==(rootNode exclus, not self)
                if ( parentList.length > 0 ) { parentList=parentList.slice(1);}; // The first node is the current dataset name node
                // La construction des optionals en suivant les parents fonctionnent car les SIMP ne portent pas les optionnals
                // [ {title: "Node 1"}, {title: "Folder 2", children: [ {title: "Node 2.1"}, {title: "Node 2.2"} ]} ]
@@ -750,6 +796,7 @@ $(function(){
            
        // },
        defaultGridAction: function( event, data ) { //(used by ext-aria) The user hit enter on the active row or cell.
+           //return true;
             const node = data.node
             // var   rValue,rValidite,rChangeIsAccepted
             const _msgCssSelStr='#tree1-messages'; //TODO: A déplacer
@@ -763,7 +810,6 @@ $(function(){
                // Return false to prevent default
                // data.activeTd contains the currently active <td> element or null
                // data.colIdx   contains the 0-based column index or -1
-               // console.log("event.type, data :"+event.type+" , "+data);
                if( !data.activeTd ) {
                    alert( "Custom default action for row: " + data.node.title );
                    // we don't return false, so default action is applied:
@@ -781,7 +827,7 @@ $(function(){
                    //node.fromDict()
                    //source=JSON.parse(getTree1())
                    if ( changeIsAccepted ) {
-                       // $.ui.fancytree.assert(value == wValue); il faut gérer les représentations des types pour activer cet assert
+                       // $.ui.fancytree.assert(value == wValue); il faut gérer les représentations des types pour activer cet assert (ex: string vs int)
                        node.data.wValue   = wValue
                        node.data.validite = validite
                        treeMessage(_msgCssSelStr,"alert-success","Changing SIMP "+node.title+" value to "+value+" has been accepted.");
@@ -843,6 +889,15 @@ $(function(){
        keydown: function(event, data) {
             console.log("event.type, data :"+event.type+" , "+data);
        },
+       // renderColumns: function(event, data) {
+        //     console.log("event.type, data :"+event.type+" , "+data);
+       // },
+       renderStatusColumns: function(event, data) {
+            console.log("event.type, data :"+event.type+" , "+data);
+       },
+       renderNode: function(event, data) {
+            console.log("event.type, data :"+event.type+" , "+data);
+       },
        
     });
 });
@@ -908,3 +963,7 @@ $(function(){
 // optTree=$optTree.fancytree()
 // #var optTree=$.ui.fancytree.getTree("#bebe")
 // optTree.expandAll()
+
+//TRICKS :
+// Tester si un objet existe :
+// if (typeof myObj !== "undefined" && myObj !== null)