diff --git a/.idea/misc.xml b/.idea/misc.xml index faee0d9..f6104af 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/myclass_api.iml b/.idea/myclass_api.iml index a5dba15..7eb1baf 100644 --- a/.idea/myclass_api.iml +++ b/.idea/myclass_api.iml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/Log/log_file.log b/Log/log_file.log index baae1a9..f239e00 100644 --- a/Log/log_file.log +++ b/Log/log_file.log @@ -141846,3 +141846,52 @@ INFO:root:2022-02-13 14:06:49.249882 : {'_id': ObjectId('61f10781c689ebcc85ffe37 INFO:werkzeug:127.0.0.1 - - [13/Feb/2022 14:06:49] "POST /myclass/api/get_class/ HTTP/1.1" 200 - INFO:root:2022-02-13 14:13:28.470564 : {'_id': ObjectId('61f10781c689ebcc85ffe370'), 'external_code': 'VP11519', 'title': 'After Effects et la typographie animée', 'trainer': 'PYRAMYD', 'type': 'mixte', 'support': 'video', 'presentiel': {'presentiel': '1', 'distantiel': '1'}, 'location': {'rue': '2, avenue de la republique', 'ville': 'Paris', 'cp': '75009', 'pays': 'France'}, 'institut_formation': 'PYRAMYD', 'price': '1340', 'url': 'https://pyramyd-formation.com/formation/after-effects-et-la-typographie-animee', 'duree_formation': '2', 'lang': 'fr', 'certif': 'oui', 'indexed': '1', 'indexed_desc': '1', 'indexed_obj': '0', 'description': 'Maîtriser les fondamentaux de l’animation typographique', 'indexed_title': '1', 'valide': '1', 'locked': '0'} INFO:werkzeug:127.0.0.1 - - [13/Feb/2022 14:13:28] "POST /myclass/api/get_class/ HTTP/1.1" 200 - +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\wrapper.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\wrapper.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\main.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\main.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\main.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\prj_common.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\prj_common.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Detected change in 'C:\\Perso\\myclass.com\\Ela_back\\MySy_Back_Office\\prj_common.py', reloading +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug: * Restarting with stat +WARNING:werkzeug: * Debugger is active! +INFO:werkzeug: * Debugger PIN: 797-962-469 +INFO:werkzeug: * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +INFO:werkzeug:127.0.0.1 - - [17/Feb/2022 12:34:11] "POST /myclass/api/add_class_mass/ HTTP/1.1" 200 - diff --git a/main.py b/main.py index fe3960e..a41d393 100644 --- a/main.py +++ b/main.py @@ -16,16 +16,23 @@ import ela_index_bdd_classes as ela_index_class import class_mgt as cm import Dev_api_functions as dev_function from flask_cors import CORS, cross_origin +import time DEBUG_LEVEL = logging.DEBUG LOG_FILE_NAME = "./Log/log_file.log" + +upload_folder = "./Data/" +ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'} + + logging.basicConfig( level=DEBUG_LEVEL, filename=LOG_FILE_NAME) app = Flask(__name__) cors = CORS(app, resources={r"/foo": {"origins": "*"}}) app.config['CORS_HEADERS'] = 'Content-Type' +app.config['UPLOAD_FOLDER'] = upload_folder def crossdomain(origin=None, methods=None, headers=None, max_age=21600, @@ -690,6 +697,35 @@ def add_user_message(): return jsonify(status=status, message=retval) + +''' +Cette API ajoute des formation en masse +par exemple avec un fichier CSV +''' + +def allowed_file(filename): + return '.' in filename and \ + filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + + +@app.route('/myclass/api/add_class_mass/', methods=['POST','GET']) +@crossdomain(origin='*') +def add_class_mass(): + # On recupere le corps (payload) de la requete + payload = request.form.to_dict() + print(" ### payload = ",payload) + print(request.files) + + if request.method == 'POST': + # Create variable for uploaded file + f = request.files['Filee'] + + status, retval = wp.add_class_mass(f, app.config['UPLOAD_FOLDER']) + + return jsonify(status=status, message=retval) + + + if __name__ == '__main__': print(" debut api") diff --git a/prj_common.py b/prj_common.py index 79ee0e9..e6afd6b 100644 --- a/prj_common.py +++ b/prj_common.py @@ -5,6 +5,11 @@ from datetime import datetime import logging import secrets from pymongo import MongoClient +import inspect +from werkzeug.utils import secure_filename +import time +import os +import csv TOKEN_SIZE = 25 CONNECTION_STRING = "mongodb://localhost/cherifdb" @@ -24,6 +29,53 @@ def create_user_recid(): return secrets.token_hex(TOKEN_SIZE) +''' +Cette fonction recupere et enregistrer un +fichier dans le Dossier "./Data/". + +La fonction retourne le nom du fichier +''' +def Upload_Save_CSV_File(file=None, Folder=None): + try: + basename = os.path.basename(file.filename) + basename2 = basename.split(".") + + ''' + Verification qu'il s'agit bien d'un fichier csv, dont le nom ne comporte pas de "." + ''' + if(len(basename2) != 2 ): + myprint(str(inspect.stack()[0][3]) + " - : Le nom du fichier est incorret") + return False, None + + if( str(basename2[1]).lower() != "csv" ): + myprint(str(inspect.stack()[0][3]) + " - : Ce n'est pas un fichier csv") + return False, None + + + + timestr = time.strftime("%Y%m%d%H%M%S") + new_file_name = str(basename2[0]) + "_" + str(timestr) + "." + str(basename2[1]) + file.filename = new_file_name + file.save(os.path.join(str(Folder), secure_filename(file.filename))) # t + + Global_file_name = "./Data/"+file.filename + + + with open(Global_file_name, newline='') as csvfile: + spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|') + for row in spamreader: + print(', '.join(row)) + + + return True, Global_file_name + + except Exception as e : + myprint(str(inspect.stack()[0][3]) + " - " + str(e)) + return False, None + + + + ''' Cette fonction prend un email et un token puis verifie si la validité du trile (email, token, statut) diff --git a/wrapper.py b/wrapper.py index 73616f4..4c7660b 100644 --- a/wrapper.py +++ b/wrapper.py @@ -15,6 +15,8 @@ import prj_common as mycommon import secrets from pymongo import ReturnDocument import inspect +import os +import csv class JSONEncoder(json.JSONEncoder): def default(self, o): @@ -845,3 +847,34 @@ def get_stored_recherche(diction): except Exception as e: mycommon.myprint(str(inspect.stack()[0][3])+" - "+str(e)) return False, "Impossible de recuperer les recherches du user " + + + +''' +Cette fontion import un fichier excel de formation +''' + +def add_class_mass(file=None, Folder=None): + try: + + status, saved_file = mycommon.Upload_Save_CSV_File(file, Folder) + if (status == False): + return False, "Impossible d'inserer les formation en masse " + + " Lecture du fichier " + print(" Lecture du fichier ") + nb_line = 0 + with open(saved_file, newline='') as csvfile: + spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|') + for row in spamreader: + print(', '.join(row)) + nb_line = nb_line +1 + + + print(str(nb_line)+" formations ont été inserées") + + return True, str(nb_line)+" formations ont été inserées" + + except Exception as e: + mycommon.myprint(str(inspect.stack()[0][3]) + " - " + str(e)) + return False, "Impossible d'inserer les formation en masse "