update 17/02/2022
parent
6c6f895d11
commit
8b0a7d2154
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (venv) (2)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
|
||||||
<component name="PyCharmProfessionalAdvertiser">
|
<component name="PyCharmProfessionalAdvertiser">
|
||||||
<option name="shown" value="true" />
|
<option name="shown" value="true" />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.10 (venv) (2)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
|
@ -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: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: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: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 -
|
||||||
|
|
36
main.py
36
main.py
|
@ -16,16 +16,23 @@ import ela_index_bdd_classes as ela_index_class
|
||||||
import class_mgt as cm
|
import class_mgt as cm
|
||||||
import Dev_api_functions as dev_function
|
import Dev_api_functions as dev_function
|
||||||
from flask_cors import CORS, cross_origin
|
from flask_cors import CORS, cross_origin
|
||||||
|
import time
|
||||||
|
|
||||||
DEBUG_LEVEL = logging.DEBUG
|
DEBUG_LEVEL = logging.DEBUG
|
||||||
LOG_FILE_NAME = "./Log/log_file.log"
|
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)
|
logging.basicConfig( level=DEBUG_LEVEL, filename=LOG_FILE_NAME)
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
cors = CORS(app, resources={r"/foo": {"origins": "*"}})
|
cors = CORS(app, resources={r"/foo": {"origins": "*"}})
|
||||||
app.config['CORS_HEADERS'] = 'Content-Type'
|
app.config['CORS_HEADERS'] = 'Content-Type'
|
||||||
|
app.config['UPLOAD_FOLDER'] = upload_folder
|
||||||
|
|
||||||
|
|
||||||
def crossdomain(origin=None, methods=None, headers=None, max_age=21600,
|
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)
|
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__':
|
if __name__ == '__main__':
|
||||||
print(" debut api")
|
print(" debut api")
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,11 @@ from datetime import datetime
|
||||||
import logging
|
import logging
|
||||||
import secrets
|
import secrets
|
||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
|
import inspect
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import csv
|
||||||
|
|
||||||
TOKEN_SIZE = 25
|
TOKEN_SIZE = 25
|
||||||
CONNECTION_STRING = "mongodb://localhost/cherifdb"
|
CONNECTION_STRING = "mongodb://localhost/cherifdb"
|
||||||
|
@ -24,6 +29,53 @@ def create_user_recid():
|
||||||
return secrets.token_hex(TOKEN_SIZE)
|
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
|
Cette fonction prend un email et un token
|
||||||
puis verifie si la validité du trile (email, token, statut)
|
puis verifie si la validité du trile (email, token, statut)
|
||||||
|
|
33
wrapper.py
33
wrapper.py
|
@ -15,6 +15,8 @@ import prj_common as mycommon
|
||||||
import secrets
|
import secrets
|
||||||
from pymongo import ReturnDocument
|
from pymongo import ReturnDocument
|
||||||
import inspect
|
import inspect
|
||||||
|
import os
|
||||||
|
import csv
|
||||||
|
|
||||||
class JSONEncoder(json.JSONEncoder):
|
class JSONEncoder(json.JSONEncoder):
|
||||||
def default(self, o):
|
def default(self, o):
|
||||||
|
@ -845,3 +847,34 @@ def get_stored_recherche(diction):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
mycommon.myprint(str(inspect.stack()[0][3])+" - "+str(e))
|
mycommon.myprint(str(inspect.stack()[0][3])+" - "+str(e))
|
||||||
return False, "Impossible de recuperer les recherches du user "
|
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 "
|
||||||
|
|
Loading…
Reference in New Issue