1118 lines
42 KiB
Python
1118 lines
42 KiB
Python
|
|
from pymongo import MongoClient
|
|
import pymongo
|
|
import json
|
|
from flask import Flask, request, jsonify
|
|
#from flask_mongoengine import MongoEngine
|
|
import json
|
|
from bson import ObjectId
|
|
import re
|
|
import numpy as np
|
|
import ela_index_bdd_classes as ela_index
|
|
import logging
|
|
from datetime import datetime
|
|
import prj_common as mycommon
|
|
import secrets
|
|
from pymongo import ReturnDocument
|
|
import inspect
|
|
import sys, os
|
|
import csv
|
|
import pandas as pd
|
|
from unidecode import unidecode
|
|
import GlobalVariable as MYSY_GV
|
|
|
|
|
|
|
|
class JSONEncoder(json.JSONEncoder):
|
|
def default(self, o):
|
|
if isinstance(o, ObjectId):
|
|
return str(o)
|
|
print(self)
|
|
print(o)
|
|
return json.JSONEncoder.default(self, o)
|
|
|
|
|
|
|
|
def get_recherche_gle_class(sentence):
|
|
try:
|
|
if not sentence:
|
|
return False
|
|
|
|
#mycommon.myprint(" On recehrche la phrase +'"+sentence+"'")
|
|
|
|
tab_training = []
|
|
tab_training = ela_index.ela_recherche_tokens(sentence)
|
|
|
|
'''
|
|
pour analyser la recherche, decommenter les 2 lignes ci-dessous
|
|
'''
|
|
#mycommon.myprint(" pour phrase : #"+sentence+"#, voici la liste des formations")
|
|
#mycommon.myprint(tab_training)
|
|
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
|
|
insertObject = []
|
|
|
|
|
|
|
|
for x in coll_name.find({"external_code": {"$in": tab_training}}, {"_id": 0, "indexed": 0, "indexed_desc": 0, "indexed_obj": 0, "indexed_title": 0, "valide": 0,
|
|
"locked": 0, "partner_owner_recid": 0, }):
|
|
mycommon.myprint(x)
|
|
user = x
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
|
|
# mycommon.myprint(" insertObject = ", insertObject)
|
|
return insertObject
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False
|
|
|
|
|
|
|
|
def get_class_by_list_attr(attribut, list_values):
|
|
try:
|
|
ela_array = []
|
|
ela_array = list_values.split(",")
|
|
mycommon.myprint(" attribut"+ attribut+" ==> list_values = "+ela_array)
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
|
|
insertObject = []
|
|
for x in coll_name.find({attribut:{ "$in":ela_array}},{"_id": 0, "indexed": 0, "indexed_desc": 0, "indexed_obj": 0, "indexed_title": 0,
|
|
"valide": 0, "locked": 0, "partner_owner_recid": 0, }):
|
|
mycommon.myprint(x)
|
|
user = x
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
|
|
#mycommon.myprint(" insertObject = ", insertObject)
|
|
return insertObject
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False
|
|
|
|
|
|
|
|
def update_class_by_attribut(objId, attribut, value):
|
|
try:
|
|
mycommon.myprint("objId = "+objId+" attribut "+attribut+" value = "+value)
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
|
|
insertObject = []
|
|
for x in coll_name.find({attribut: value}, {"_id": 0, "indexed": 0, "indexed_desc": 0, "indexed_obj": 0,
|
|
"indexed_title": 0, "valide": 0, "locked": 0, "partner_owner_recid": 0, }):
|
|
mycommon.myprint(x)
|
|
user = x
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
|
|
mycommon.myprint(" insertObject = "+ insertObject)
|
|
return insertObject
|
|
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False
|
|
|
|
|
|
import random
|
|
def get_all_class(diction):
|
|
try:
|
|
|
|
# Dictionnaire des champs utilisables
|
|
field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
|
|
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif',
|
|
'support', 'type', 'lang', 'price', 'distance', 'duration']
|
|
|
|
incom_keys = diction.keys()
|
|
|
|
'''
|
|
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
|
|
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
|
|
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
|
|
# field_list.
|
|
'''
|
|
for val in incom_keys:
|
|
if str(val).lower() not in str(field_list).lower():
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " Le champ '" + val + "' n'est pas autorisé")
|
|
return False, " Recherche impossible"
|
|
|
|
|
|
# Recuperation des parametres
|
|
mydata = {}
|
|
if ("user_ip" in diction.keys()):
|
|
if diction['user_ip']:
|
|
mydata['user_ip'] = diction['user_ip']
|
|
|
|
if ("user_country_code" in diction.keys()):
|
|
if diction['user_country_code']:
|
|
mydata['user_country_code'] = diction['user_country_code']
|
|
|
|
if ("user_country_name" in diction.keys()):
|
|
if diction['user_country_name']:
|
|
mydata['user_country_name'] = diction['user_country_name']
|
|
|
|
if ("user_city" in diction.keys()):
|
|
if diction['user_city']:
|
|
mydata['user_city'] = diction['user_city']
|
|
|
|
if ("user_postal" in diction.keys()):
|
|
if diction['user_postal']:
|
|
mydata['user_postal'] = diction['user_postal']
|
|
|
|
if ("user_latitude" in diction.keys()):
|
|
if diction['user_latitude']:
|
|
mydata['user_latitude'] = diction['user_latitude']
|
|
|
|
if ("user_longitude" in diction.keys()):
|
|
if diction['user_longitude']:
|
|
mydata['user_longitude'] = diction['user_longitude']
|
|
|
|
if ("user_state" in diction.keys()):
|
|
if diction['user_state']:
|
|
mydata['user_state'] = diction['user_state']
|
|
|
|
#print(" My Data ="+str(mydata))
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
|
|
val_tmp = 1
|
|
insertObject = []
|
|
|
|
|
|
for x in coll_name.find({'valide':'1', 'locked':'0', 'isalaune':'1'}, {"_id": 0, "indexed": 0, "indexed_desc": 0, "indexed_obj": 0, "indexed_title": 0,
|
|
"valide": 0, "locked": 0, "partner_owner_recid": 0, }).\
|
|
limit(MYSY_GV.MAINPAGE_QUERY_LIMIT_ROW).\
|
|
sort(
|
|
[ ("coeur", pymongo.DESCENDING), ("date_update", pymongo.DESCENDING),]):
|
|
|
|
|
|
|
|
#print("AVANT ==> "+str(x['description']))
|
|
val = x['description']
|
|
if( len(x['description']) > MYSY_GV.MAX_CARACT ):
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT]+" ..."
|
|
|
|
else:
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT]
|
|
|
|
#mycommon.myprint("APRES ==> " + str(x['description']))
|
|
|
|
user = x
|
|
user['id'] = str(val_tmp)
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
val_tmp = val_tmp + 1
|
|
|
|
#print(" insertObject = ", str(insertObject))
|
|
return True, insertObject
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False, " Impossible de recuperer les formations"
|
|
|
|
|
|
|
|
'''
|
|
Cette fonction recherche les formations correspondant à un text
|
|
IMPORTANT : Dans la recherche par tips, on fait du && et non du ou.
|
|
exemple :
|
|
pour la recherche "description:"fichier" title:"Niveau 1""
|
|
le système va chercher toutes les formation qui on :
|
|
- "description:"fichier" ET ET ET ET ET
|
|
- title:"Niveau 1"
|
|
|
|
En gros, on fait une intersection entre les 2 listes.
|
|
|
|
'''
|
|
|
|
def recherche_text_simple(diction):
|
|
try:
|
|
'''
|
|
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
|
|
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
|
|
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
|
|
# field_list.
|
|
'''
|
|
field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
|
|
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif',
|
|
'support', 'type', 'lang', 'price', 'distance', 'duration']
|
|
incom_keys = diction.keys()
|
|
for val in incom_keys:
|
|
if val not in field_list:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - : Le champ '" + val + "' n'existe pas, recherche annuléee")
|
|
return False, " Le champ '" + val + "' n'existe pas, recherche annulée"
|
|
|
|
'''
|
|
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
|
|
On controle que les champs obligatoires sont presents dans la liste
|
|
'''
|
|
field_list_obligatoire = ['search_text', 'token']
|
|
|
|
for val in field_list_obligatoire:
|
|
if val not in diction:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - La valeur '" + val + "' n'est pas presente dans liste ")
|
|
return False, " : La valeur '" + val + "' n'est pas presente dans liste "
|
|
|
|
# recuperation des paramettre
|
|
search_text = ""
|
|
user_recid = ""
|
|
token = ""
|
|
critere_date = {}
|
|
critere_string = ""
|
|
new_diction = {}
|
|
new_diction['token'] = ""
|
|
|
|
if ("search_text" in diction.keys()):
|
|
if diction['search_text']:
|
|
search_text = diction['search_text']
|
|
|
|
|
|
if ("token" in diction.keys()):
|
|
if diction['token']:
|
|
token = diction['token']
|
|
new_diction['token'] = diction['token']
|
|
|
|
'''
|
|
/!\ Important : si le token est vide, alors c'est une recherche faite en mode non-connecté.
|
|
on doit l'accepter.
|
|
|
|
le controle de la validé du token est faite que ce dernier n'est pas vide.
|
|
'''
|
|
|
|
user_recid = "None"
|
|
coll_search_result = MYSY_GV.dbname['user_recherche_result']
|
|
|
|
# Verification de la validité du token/mail dans le cas des user en mode connecté
|
|
if ( len(str(token)) > 0 ):
|
|
retval = mycommon.check_token_validity("", token)
|
|
|
|
if retval is False :
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Le token n'est pas valide")
|
|
return False, "Le token n'est pas valide"
|
|
|
|
# Recuperation du recid de l'utilisateur
|
|
user_recid = mycommon.get_user_recid_from_token(token)
|
|
if user_recid is False:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de recuperer le token de l'utilisateur")
|
|
return False, " Impossible de desactiver l'objectif utilisateur"
|
|
|
|
|
|
#mycommon.myprint(" On recehrche la phrase +'" + search_text + "' + user_recid = "+user_recid)
|
|
|
|
# Enregistrerment de la recherche
|
|
retval, message, store_recherche_Id = store_recherche(diction, user_recid)
|
|
if (retval is False):
|
|
return retval, message
|
|
|
|
'''
|
|
Verification si le texte de recherche contient un pattern de tips,
|
|
c'est a dire une chaine de type : title:"titre"
|
|
|
|
Si c'est le cas, nous sommes dans le cadre d'un recherche par type
|
|
|
|
'''
|
|
|
|
cleaned_search_text = mycommon.Parse_Clean_Search_Text(search_text)
|
|
|
|
#print(" NOT CLEANED search_text = " + str(search_text))
|
|
#print(" CLEANED search_text = "+str(cleaned_search_text))
|
|
|
|
|
|
|
|
regexp = r"[\w\.-]+:\"[\w\s]*\""
|
|
tips = re.findall(regexp, str(cleaned_search_text), re.MULTILINE)
|
|
nb_tips = len(tips)
|
|
final_message3 = {}
|
|
|
|
if( nb_tips > 0 ):
|
|
mycommon.myprint(" Une recherche par tips a été identifiée")
|
|
new_diction['token'] = token
|
|
|
|
# Traitement pour chaque recherche par tips
|
|
final_retval = False
|
|
final_message = []
|
|
insertObject = []
|
|
|
|
is_first_tip = True
|
|
for val in tips :
|
|
val2 = val.replace('"', '')
|
|
new_diction['search_text'] = val2
|
|
print(" On va recherche : #####"+str(new_diction['search_text'] ))
|
|
retval, message = recherche_tips_ret_ref(new_diction)
|
|
|
|
print(" pour la recherche de : "+str(new_diction)+" -- Voici le resultat "+str(message))
|
|
if (retval == True ):
|
|
final_retval = True
|
|
#print(" contact de message "+str(message)+ " # final_message "+str(final_message))
|
|
|
|
if( is_first_tip is True) :
|
|
final_message3 = message
|
|
else:
|
|
final_message3 = [x for x in message if x in final_message3]
|
|
|
|
print(" final_message3 = "+str(final_message3))
|
|
final_message.append(message)
|
|
is_first_tip = False
|
|
|
|
final_message = final_message3
|
|
#print(" liste defitive des ref "+str(final_message))
|
|
final_message2 = []
|
|
|
|
for t in final_message:
|
|
if( t is not False):
|
|
#print( " unique = "+str(t))
|
|
final_message2.append(t)
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
|
|
|
|
|
|
'''
|
|
A present mise à jour de la table "user_recherche" avec les resultats trouvés
|
|
'''
|
|
#store_recherche_Id
|
|
find_result = {'find_result':str(final_message2)}
|
|
|
|
tab_user_recherche = MYSY_GV.dbname['user_recherche']
|
|
# seules les formation avec locked = 0 et valide=1 sont modifiables
|
|
#print(str(inspect.stack()[0][3]) + " ENREG DES RESULT :"+str(store_recherche_Id)+" --- "+str(final_message2))
|
|
|
|
|
|
ret_val_user_rech = coll_name.find_one_and_update(
|
|
{'_id': ObjectId(store_recherche_Id)},
|
|
{"$set": find_result},
|
|
return_document=ReturnDocument.AFTER
|
|
)
|
|
|
|
if (ret_val_user_rech is False ):
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
|
|
" d'une recherche de formation. Voir _id = "+ str( store_recherche_Id))
|
|
return False, "La recheche est impossible "
|
|
|
|
'''
|
|
la valeur nb_result permettra de savoir si la requete a donnée un resultat.
|
|
si ce n'est pas le cas, il faudra à la fin enregistrer la requete avec un result a vide'''
|
|
nb_result = 0
|
|
for x in coll_name.find({"external_code": {"$in": final_message2}},
|
|
{"_id": 0, "indexed": 0, "indexed_desc": 0, "indexed_obj": 0,
|
|
"indexed_title": 0, "valide": 0, "locked": 0, "partner_owner_recid": 0, }):
|
|
|
|
nb_result = nb_result +1
|
|
my_recid = {}
|
|
my_recid['user_rec_id'] = str(user_recid)
|
|
mydict_combined = {**diction, **x, **my_recid}
|
|
mydict_combined['date_update'] = str(datetime.now())
|
|
mydict_combined['type_view'] = "summary"
|
|
|
|
if ("_id" in mydict_combined.keys()):
|
|
mydict_combined['class_id'] = mydict_combined.pop('_id')
|
|
|
|
#mycommon.myprint("COMBINED = " + str(mydict_combined))
|
|
|
|
'''
|
|
Statistique : Insertion du recherche - resultat '''
|
|
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
|
|
if (ret_val_tmp is False):
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
|
|
" d'une recherche de formation. Voir _id = ")
|
|
return False, "La recheche est impossible "
|
|
|
|
user = x
|
|
val = x['description']
|
|
if (len(x['description']) > MYSY_GV.MAX_CARACT):
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT] + " ..."
|
|
else:
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT]
|
|
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
|
|
# mycommon.myprint(" insertObject = ", insertObject)
|
|
|
|
''' en cas de resultat vide, enregsitrement de la requete de recherche avec les filtres associé'''
|
|
if( nb_result == 0):
|
|
my_recid = {}
|
|
my_recid['user_rec_id'] = str(user_recid)
|
|
mydict_combined = {**diction, **my_recid}
|
|
mydict_combined['date_update'] = str(datetime.now())
|
|
mydict_combined['type_view'] = "summary"
|
|
|
|
|
|
'''
|
|
Statistique : Insertion du recherche - resultat '''
|
|
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
|
|
if (ret_val_tmp is False):
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
|
|
" d'une recherche de formation. Voir _id = ")
|
|
return False, "La recheche est impossible "
|
|
|
|
return True, insertObject
|
|
# Fin de la recherche par tips.
|
|
|
|
|
|
tab_training = []
|
|
tab_training = ela_index.ela_recherche_tokens(search_text)
|
|
|
|
'''
|
|
pour analyser la recherche, decommenter les 2 lignes ci-dessous
|
|
'''
|
|
#mycommon.myprint(" pour phrase : #" + search_text + "#, voici la liste des formations")
|
|
#mycommon.myprint(tab_training)
|
|
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
'''
|
|
la valeur nb_result permettra de savoir si la requete a donnée un resultat.
|
|
si ce n'est pas le cas, il faudra à la fin enregistrer la requete avec un result a vide'''
|
|
nb_result = 0
|
|
insertObject = []
|
|
|
|
for val in tab_training:
|
|
for x in coll_name.find( {"external_code": str(val) },
|
|
{"_id": 0, "indexed": 0, "indexed_desc": 0,
|
|
"indexed_obj": 0, "indexed_title": 0, "valide": 0,
|
|
"locked": 0, "partner_owner_recid": 0, }):
|
|
|
|
nb_result = nb_result + 1
|
|
my_recid = {}
|
|
my_recid['user_rec_id'] = str(user_recid)
|
|
mydict_combined = {**diction, **x, **my_recid}
|
|
mydict_combined['date_update'] = str(datetime.now())
|
|
mydict_combined['type_view'] = "summary"
|
|
|
|
if ("_id" in mydict_combined.keys()):
|
|
mydict_combined['class_id'] = mydict_combined.pop('_id')
|
|
|
|
|
|
'''
|
|
Statistique : Insertion du recherche - resultat '''
|
|
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
|
|
if (ret_val_tmp is False):
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
|
|
" d'une recherche de formation. Voir _id = ")
|
|
return False, "La recheche est impossible "
|
|
|
|
user = x
|
|
val = x['description']
|
|
if (len(x['description']) > MYSY_GV.MAX_CARACT):
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT] + " ..."
|
|
else:
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT]
|
|
|
|
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
|
|
'''
|
|
/!\ Important : Recuperation des elements de la recherche etendue
|
|
c'est a dire l'utilisation d'API externe
|
|
|
|
/!\ update du 20/05/22 : Cette approche relentie bcp le systeme avec l'appel externe.
|
|
donc on annule
|
|
|
|
# aller chercher la recherche etendue et la rajouter ici.
|
|
ext_status, external_code_prefixe = mycommon.Get_Extended_Result(search_text)
|
|
|
|
|
|
|
|
if(ext_status is True):
|
|
exten_coll = MYSY_GV.YTUBES_dbname['mysyserpapi']
|
|
for x in exten_coll.find({'external_code': {'$regex': re.compile(r".*" + str(external_code_prefixe) + ".*")}},
|
|
{"_id": 0, "valide": 0, }):
|
|
|
|
nb_result = nb_result + 1
|
|
my_recid = {}
|
|
my_recid['user_rec_id'] = str(user_recid)
|
|
user = x
|
|
val = x['description']
|
|
if (len(x['description']) > MYSY_GV.MAX_CARACT):
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT] + " ..."
|
|
else:
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT]
|
|
|
|
x['extented_search'] = "1"
|
|
|
|
|
|
if str(x['url']) not in str(insertObject):
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
else:
|
|
print(str(x['url'])+" existe deja, pas d'ajout à faire ")
|
|
|
|
'''
|
|
#print(insertObject)
|
|
#print(" result ok ")
|
|
''' en cas de resultat vide, enregsitrement de la requete de recherche avec les filtres associé'''
|
|
if (nb_result == 0):
|
|
my_recid = {}
|
|
my_recid['user_rec_id'] = str(user_recid)
|
|
mydict_combined = {**diction, **my_recid}
|
|
mydict_combined['date_update'] = str(datetime.now())
|
|
mydict_combined['type_view'] = "summary"
|
|
|
|
'''
|
|
Statistique : Insertion du recherche - resultat '''
|
|
ret_val_tmp = coll_search_result.insert_one(mydict_combined)
|
|
if (ret_val_tmp is False):
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " - Impossible de mettre à jour la table des resultat"
|
|
" d'une recherche de formation. Voir _id = ")
|
|
return False, "La recheche est impossible "
|
|
|
|
|
|
return True, insertObject
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False, "Impossible de lancer la recherche"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'''
|
|
Cette fonction enregistre les recherches faites par les user
|
|
dans la base de données.
|
|
L'idée principale est de stocker toutes les recherche, que soit en mode connecté ou en mode non connecté.
|
|
le difference se fera au niveau du mail de la personne.
|
|
structure du document dans la BDD (id, uer_mail, text_recherche, critere_recherce(JSON), valide)
|
|
la fontion prend en entrée un dictionnaire :
|
|
- le texte
|
|
- la liste des critères; dont les valeurs exacts sont :
|
|
• type
|
|
• lang
|
|
• level
|
|
• dist (distance)
|
|
• price
|
|
• certif
|
|
• source
|
|
|
|
Dans le cas ou le user a donnée un nom à la recherche, on ajoute le champ "name", ou s'il d'agit d'une mise à jour
|
|
le champ "id"
|
|
• name
|
|
• id
|
|
|
|
'''
|
|
|
|
def store_recherche(diction, user_recid=""):
|
|
try:
|
|
'''
|
|
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
|
|
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
|
|
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
|
|
# field_list.
|
|
'''
|
|
|
|
if ( len(str(user_recid)) <= 0 ):
|
|
user_recid = 'None' # by default
|
|
|
|
|
|
|
|
field_list = ['token', 'user_ip', 'user_country_code', 'user_country_name', 'user_city',
|
|
'user_postal', 'user_latitude', 'user_longitude', 'user_state', 'search_text', 'certif',
|
|
'support', 'type', 'lang', 'price', 'distance', 'duration']
|
|
incom_keys = diction.keys()
|
|
for val in incom_keys:
|
|
if val not in field_list:
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " Le champ '" + val + "' n'existe pas, recherche annulée")
|
|
return False, " Le champ '" + val + "' n'existe pas, recherche annulée", None
|
|
|
|
'''
|
|
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
|
|
On controle que les champs obligatoires sont presents dans la liste
|
|
'''
|
|
field_list_obligatoire = ['search_text', 'token']
|
|
|
|
for val in field_list_obligatoire:
|
|
if val not in diction:
|
|
mycommon.myprint(" : La valeur '" + val + "' n'est pas presente dans liste ")
|
|
return False, " : La valeur '" + val + "' n'est pas presente dans liste ", None
|
|
|
|
|
|
# recuperation des paramettre
|
|
mydata = {}
|
|
mydata_id = ""
|
|
my_token = ""
|
|
|
|
if ("search_text" in diction.keys()):
|
|
if diction['search_text']:
|
|
mydata['search_text'] = diction['search_text']
|
|
|
|
|
|
if ("user_mail" in diction.keys()):
|
|
if diction['user_recid']:
|
|
mydata['user_recid'] = diction['user_recid']
|
|
|
|
if ("token" in diction.keys()):
|
|
if diction['token']:
|
|
my_token = diction['token']
|
|
|
|
'''# Recuperation du recid de l'utilisateur
|
|
user_recid = mycommon.get_user_recid_from_token(my_token)
|
|
if user_recid is False:
|
|
mycommon.myprint(" Impossible d'enregistrer la recherche de utilisateur")
|
|
return False, " Impossible d'enregistrer la recherche de utilisateur"
|
|
'''
|
|
mydata['user_recid'] = user_recid
|
|
mydata['document_recherche'] = "formation"
|
|
|
|
if ("type" in diction.keys()):
|
|
if diction['type']:
|
|
mydata['type'] = diction['type']
|
|
|
|
if ("lang" in diction.keys()):
|
|
if diction['lang']:
|
|
mydata['lang'] = diction['lang']
|
|
|
|
if ("level" in diction.keys()):
|
|
if diction['level']:
|
|
mydata['level'] = diction['level']
|
|
|
|
if ("dist" in diction.keys()):
|
|
if diction['dist']:
|
|
mydata['dist'] = diction['dist']
|
|
|
|
if ("price" in diction.keys()):
|
|
if diction['price']:
|
|
mydata['price'] = diction['price']
|
|
|
|
if ("certif" in diction.keys()):
|
|
if diction['certif']:
|
|
mydata['certif'] = diction['certif']
|
|
|
|
if ("source" in diction.keys()):
|
|
if diction['source']:
|
|
mydata['source'] = diction['source']
|
|
|
|
if ("name" in diction.keys()):
|
|
if diction['name']:
|
|
mydata['name'] = diction['name']
|
|
|
|
|
|
if ("id" in diction.keys()):
|
|
if diction['id']:
|
|
mydata_id = diction['id']
|
|
|
|
mydata['date_update'] = str(datetime.now())
|
|
|
|
mydata['valide'] = "1" # By default
|
|
if ("valide" in diction.keys()):
|
|
if diction['valide']:
|
|
mydata['valide'] = diction['valide']
|
|
|
|
|
|
coll_name = MYSY_GV.dbname['user_recherche']
|
|
|
|
# Si le champ "id" est renseigné, il s'agit d'une mis jour
|
|
#mycommon.myprint(str(inspect.stack()[0][3]) + " on va stocker "+str(mydata)+" id = "+str(mydata_id))
|
|
|
|
if( len(str(mydata_id)) > 0 ):
|
|
ret_val = coll_name.find_one_and_update({'_id': ObjectId(str(mydata_id)), 'valide': '1'},
|
|
{"$set": mydata},
|
|
return_document=ReturnDocument.AFTER
|
|
)
|
|
|
|
if (ret_val and ret_val['_id']):
|
|
nb_doc = str(ret_val['_id'])
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " La recherche a bien été mise à jour . Le Doc Id = "+str(nb_doc))
|
|
return True, "La recherche a bien été mise à jour", ret_val['_id']
|
|
|
|
else:
|
|
return False, "Impossible de mettre à jour a la recherche", None
|
|
|
|
else:
|
|
ret_val = coll_name.insert_one(mydata)
|
|
|
|
if ret_val and ret_val.inserted_id:
|
|
nb_doc = ret_val.inserted_id
|
|
#mycommon.myprint(str(inspect.stack()[0][3]) + " La recherche a été bien enregistrée. Id = '" + str(nb_doc)+"' ")
|
|
return True, "La recherche a bien été mise à jour", nb_doc
|
|
else:
|
|
mycommon.myprint(
|
|
str(inspect.stack()[0][3]) + "Impossible d'enregistrer la recherche")
|
|
return False, "Impossible d'enregistrer la recherche ", None
|
|
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False, "Impossible d'enregistrer la recherche", None
|
|
|
|
|
|
|
|
|
|
'''
|
|
Cette fonction prend une chaine de recherche en mode tips.
|
|
Si la fonction detecte un tips, alors elle retroune un
|
|
1 - Un status = True et
|
|
2 - Un tableau avec qui contient uniquement la reference externe de la formation
|
|
|
|
|
|
Si la fonction ne detecte pas de tips, elle retoure
|
|
1 - Un status = False
|
|
2 - Un tableau = False
|
|
'''
|
|
|
|
def recherche_tips_ret_ref(diction):
|
|
try:
|
|
'''
|
|
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
|
|
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
|
|
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
|
|
# field_list.
|
|
'''
|
|
|
|
#print(" RRRRR "+str(diction))
|
|
field_list = ['search_text', 'token', 'support', 'id',
|
|
'type', 'lang', 'level', 'dist', 'price',
|
|
'certif', 'source', 'name','valide', 'duration', 'distance']
|
|
incom_keys = diction.keys()
|
|
for val in incom_keys:
|
|
if val not in field_list:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Le champ '" + val + "' n'est pas autorisé, recherche annulée")
|
|
return False, " Le champ '" + val + "' n'est pas autorisé, recherche annulée"
|
|
|
|
'''
|
|
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
|
|
On controle que les champs obligatoires sont presents dans la liste
|
|
'''
|
|
field_list_obligatoire = ['search_text', 'token']
|
|
|
|
for val in field_list_obligatoire:
|
|
if val not in diction:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - La valeur '" + val + "' n'est pas presente dans liste ")
|
|
return False, " : La valeur '" + val + "' n'est pas presente dans liste "
|
|
|
|
user_recid = "None"
|
|
# recuperation du recId du user si le token est fourni.
|
|
# si le token est vide, c'est que nous sommes sur une recherche en mode non connecté.
|
|
if (len(str(diction['token'])) > 0):
|
|
user_recid = mycommon.get_user_recid_from_token(str(diction['token']))
|
|
if user_recid is False :
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de recuperer le recid du user")
|
|
return False, "Impossible d'enregistrer la recherche"
|
|
|
|
|
|
print(" ####### recherche tips, voici mon new diction"+str(diction)+ " user_recid = "+user_recid)
|
|
|
|
# Enregistrerment de la recherche
|
|
retval, message, store_recherche_Id = store_recherche(diction, user_recid)
|
|
if( retval is False):
|
|
return retval, message
|
|
|
|
|
|
# recuperation des paramettre
|
|
search_text = ""
|
|
user_mail = ""
|
|
token = ""
|
|
|
|
if ("search_text" in diction.keys()):
|
|
if diction['search_text']:
|
|
search_text = diction['search_text']
|
|
|
|
|
|
if( len(str(search_text)) <= 0 ):
|
|
return False, False
|
|
|
|
if (":" not in search_text):
|
|
print(" La phrase ne contient pas de ':' ")
|
|
return False, False
|
|
|
|
print(" la chaine recu est "+search_text)
|
|
chaine = search_text.split(":")
|
|
|
|
val1 = str(chaine[0]).lower()
|
|
|
|
print(" chaine[0] = "+val1)
|
|
|
|
# Liste des tips acceptés
|
|
tab_tips = ['title', 'description', 'desc', 'objectif', 'obj','trainer']
|
|
|
|
min = 100
|
|
my_tips = ""
|
|
for val in tab_tips:
|
|
retval = mycommon.levenshtein(val1, val)
|
|
#print(" la distance entre '"+val1+"' et le mot "+str(val)+" = "+str(retval))
|
|
if( retval <= min ):
|
|
min = retval
|
|
my_tips = val
|
|
|
|
if (min >= len(str(val1)) or min >= len(str(my_tips)) ):
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - le mot '"+val1+" ne correspond aucun tips, sorry")
|
|
return False, " le mot '"+val1+" ne correspond aucun tips, sorry"
|
|
|
|
if (str(my_tips) == "desc"):
|
|
my_tips = 'description'
|
|
|
|
mycommon.myprint(" Le tips recherché est "+my_tips+". Sa distance de Levenshtein ="+str(min))
|
|
|
|
tab_ret = {}
|
|
tab_ret['tips'] = str(my_tips)
|
|
tab_ret['search_text'] = str(chaine[1]).lower()
|
|
|
|
#return True, " le tips recherché est '"+my_tips+"' "
|
|
|
|
tab_training = []
|
|
tab_training = ela_index.ela_recherche_tokens_source_field(str(chaine[1]).lower(), str(my_tips) )
|
|
|
|
if( tab_training is False):
|
|
return False, tab_training
|
|
|
|
#mycommon.myprint(" pour phrase : #" + str(chaine[1]).lower() + "# , Pour le tips #"+ str(my_tips)+"#, voici la liste des formations")
|
|
#mycommon.myprint(tab_training)
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
|
|
return True, tab_training
|
|
|
|
|
|
# ici lancer la recherche sur le champs title sss
|
|
#return True, str(tab_ret)
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False, "N/A"
|
|
|
|
|
|
|
|
|
|
'''
|
|
Cette fonction prend une chaine de recherche en mode tips.
|
|
Si la fonction detecte un tips, alors elle retroune un
|
|
1 - Un status = True et
|
|
2 - Un tableau avec
|
|
- Tab[0] : le champ sur lequel s'applique la recherche
|
|
- Tab[0] : la chaine à rechercher
|
|
|
|
Si la fonction ne detecte pas de tips, elle retoure
|
|
1 - Un status = False
|
|
2 - Un tableau = False
|
|
'''
|
|
|
|
def recherche_tips(diction):
|
|
try:
|
|
'''
|
|
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
|
|
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
|
|
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
|
|
# field_list.
|
|
'''
|
|
|
|
|
|
field_list = ['search_text', 'token', 'support', 'id',
|
|
'type', 'lang', 'level', 'dist', 'price',
|
|
'certif', 'source', 'name','valide']
|
|
|
|
incom_keys = diction.keys()
|
|
for val in incom_keys:
|
|
if val not in field_list:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Le champ '" + val + "' n'existe pas, recherche annulée")
|
|
return False, " Le champ '" + val + "' n'existe pas, recherche annulée"
|
|
|
|
'''
|
|
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
|
|
On controle que les champs obligatoires sont presents dans la liste
|
|
'''
|
|
field_list_obligatoire = ['search_text', 'token']
|
|
|
|
for val in field_list_obligatoire:
|
|
if val not in diction:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - La valeur '" + val + "' n'est pas presente dans liste ")
|
|
return False, " : La valeur '" + val + "' n'est pas presente dans liste "
|
|
|
|
user_recid = "None"
|
|
# recuperation du recId du user si le token est fourni.
|
|
# si le token est vide, c'est que nous sommes sur une recherche en mode non connecté.
|
|
if (len(str(diction['token'])) > 0):
|
|
user_recid = mycommon.get_user_recid_from_token(str(diction['token']))
|
|
if user_recid is False :
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de recuperer le recid du user")
|
|
return False, "Impossible d'enregistrer la recherche"
|
|
|
|
|
|
print(" ####### recherche tips, voici mon new diction"+str(diction)+" RRRC ID = "+user_recid)
|
|
|
|
# Enregistrerment de la recherche
|
|
retval, message, store_recherche_Id = store_recherche(diction, user_recid)
|
|
if( retval is False):
|
|
return retval, message
|
|
|
|
|
|
# recuperation des paramettre
|
|
search_text = ""
|
|
user_mail = ""
|
|
token = ""
|
|
|
|
if ("search_text" in diction.keys()):
|
|
if diction['search_text']:
|
|
search_text = diction['search_text']
|
|
|
|
|
|
if( len(str(search_text)) <= 0 ):
|
|
return False, False
|
|
|
|
if (":" not in search_text):
|
|
print(" La phrase ne contient pas de ':' ")
|
|
return False, False
|
|
|
|
print(" la chaine recu est "+search_text)
|
|
chaine = search_text.split(":")
|
|
|
|
val1 = str(chaine[0]).lower()
|
|
|
|
print(" chaine[0] = "+val1)
|
|
|
|
# Liste des tips acceptés
|
|
tab_tips = ['title', 'description', 'desc', 'objectif', 'obj','trainer']
|
|
|
|
min = 100
|
|
my_tips = ""
|
|
for val in tab_tips:
|
|
retval = mycommon.levenshtein(val1, val)
|
|
#print(" la distance entre '"+val1+"' et le mot "+str(val)+" = "+str(retval))
|
|
if( retval <= min ):
|
|
min = retval
|
|
my_tips = val
|
|
|
|
if (min >= len(str(val1)) or min >= len(str(my_tips)) ):
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - le mot '"+val1+" ne correspond aucun tips, sorry")
|
|
return False, " le mot '"+val1+" ne correspond aucun tips, sorry"
|
|
|
|
'''
|
|
Remplacement de l'abreviation 'desc' par description '''
|
|
|
|
if( str(my_tips) == "desc"):
|
|
my_tips = 'description'
|
|
|
|
|
|
mycommon.myprint(" Le tips recherché est '"+my_tips+"'. Sa distance de Levenshtein ="+str(min))
|
|
|
|
tab_ret = {}
|
|
tab_ret['tips'] = str(my_tips)
|
|
tab_ret['search_text'] = str(chaine[1]).lower()
|
|
|
|
#return True, " le tips recherché est '"+my_tips+"' "
|
|
|
|
tab_training = []
|
|
tab_training = ela_index.ela_recherche_tokens_source_field(str(chaine[1]).lower(), str(my_tips) )
|
|
|
|
if (tab_training is False):
|
|
return False, tab_training
|
|
|
|
'''
|
|
Pour analyser les recherches, decommenter les 2 lignes ci-dessous
|
|
'''
|
|
#mycommon.myprint(" pour phrase : #" + str(chaine[1]).lower() + "# , Pour le tips #"+ str(my_tips)+"#, voici la liste des formations")
|
|
#mycommon.myprint(tab_training)
|
|
|
|
coll_name = MYSY_GV.dbname['myclass']
|
|
|
|
insertObject = []
|
|
for x in coll_name.find({"external_code": {"$in": tab_training}}, {"_id": 0, "indexed": 0, "indexed_desc": 0, "indexed_obj": 0, "indexed_title": 0,
|
|
"valide": 0, "locked": 0, "partner_owner_recid": 0, }):
|
|
#mycommon.myprint(x)
|
|
user = x
|
|
val = x['description']
|
|
if (len(x['description']) > MYSY_GV.MAX_CARACT):
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT] + " ..."
|
|
else:
|
|
x['description'] = val[:MYSY_GV.MAX_CARACT]
|
|
insertObject.append(JSONEncoder().encode(user))
|
|
|
|
# mycommon.myprint(" insertObject = ", insertObject)
|
|
return True, insertObject
|
|
|
|
|
|
# ici lancer la recherche sur le champs title sss
|
|
#return True, str(tab_ret)
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False, "N/A"
|
|
|
|
|
|
|
|
'''
|
|
Cette fonction retourne les recherche enregistrer d'un user donnée
|
|
'''
|
|
def get_stored_recherche(diction):
|
|
try:
|
|
|
|
'''
|
|
# Verification que les champs reçus dans l'API sont bien dans la liste des champs autorisés
|
|
# Cela evite le cas ou une entité tierce ajouter les valeurs inconnu dans l'API
|
|
# Ici on doit mettre tous les champs possible (obligatoire ou non) de la BDD dans la liste
|
|
# field_list.
|
|
'''
|
|
field_list = ['token']
|
|
incom_keys = diction.keys()
|
|
for val in incom_keys:
|
|
if val not in field_list:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Le champ '" + val + "' n'existe pas, recherche annulée")
|
|
return False, " Le champ '" + val + "' n'existe pas, recherche annulée"
|
|
|
|
'''
|
|
Une fois qu'on a controlé que toutes les clés mise dans l'API sont correcte. etape precedente,
|
|
On controle que les champs obligatoires sont presents dans la liste
|
|
'''
|
|
field_list_obligatoire = [ 'token']
|
|
|
|
for val in field_list_obligatoire:
|
|
if val not in diction:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - La valeur '" + val + "' n'est pas presente dans liste ")
|
|
return False, " : La valeur '" + val + "' n'est pas presente dans liste "
|
|
|
|
# recuperation des paramettre
|
|
search_text = ""
|
|
user_recid = ""
|
|
token = ""
|
|
|
|
if ("search_text" in diction.keys()):
|
|
if diction['search_text']:
|
|
search_text = diction['search_text']
|
|
|
|
if ("token" in diction.keys()):
|
|
if diction['token']:
|
|
token = diction['token']
|
|
|
|
|
|
# Verification de la validité du token/mail dans le cas des user en mode connecté
|
|
if ( len(str(token)) <= 0):
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Le token est vide")
|
|
return False, " Impossible de recuperer historique de recherche"
|
|
|
|
retval = mycommon.check_token_validity("", token)
|
|
|
|
if retval is False:
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Le token n'est pas valide")
|
|
return False, " Impossible de recuperer l'historique de recherche"
|
|
|
|
# Recuperation du recid du user
|
|
user_recid = ""
|
|
user_recid = mycommon.get_user_recid_from_token(token)
|
|
if user_recid is False :
|
|
mycommon.myprint(str(inspect.stack()[0][3])+" - Impossible de recuperer le recid du user")
|
|
return False, " Impossible de recuperer l'historique de recherche"
|
|
|
|
|
|
coll_name = MYSY_GV.dbname['user_recherche']
|
|
|
|
RetObject = []
|
|
for retVal in coll_name.find({'user_recid': user_recid, 'valide':'1'}):
|
|
#mycommon.myprint(str(retVal))
|
|
user = retVal
|
|
RetObject.append(JSONEncoder().encode(user))
|
|
|
|
return True, RetObject
|
|
|
|
except Exception as e:
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
mycommon.myprint(str(inspect.stack()[0][3]) + " -" + str(e) + " - ERRORRRR AT Line : " + str(exc_tb.tb_lineno))
|
|
return False, "Impossible de recuperer les recherches du user "
|
|
|