web-api/serve_api.py

250 lines
12 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/python3.7
import os
import csv
import json
import time
import sqlite3
import hashlib
import flask
from flask import Flask
from flask import request
from flask import jsonify
from flask import abort
from flask_cors import CORS
#from flask_mysqldb import MySQL
import pyodbc
from fuzzywuzzy import fuzz
from multiprocessing import Process, Queue
import face_recognition
#from fset import fset
#from flask_security import auth_token_required
#from werkzeug.http import HTTP_STATUS_CODES
#def error_response(status_code, message=None):
# payload = {'error': HTTP_STATUS_CODES.get(status_code, 'Unknown error')}
# if message:
# payload['message'] = message
# response = jsonify(payload)
# response.status_code = status_code
# return response
#def tobs66(st):
# bs64=" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
# acc=[(u'á','a'),(u'é','e',u'í','i'),(u'ó','o'),(u'ú','u'),(u'Á','A'),(u'É','E'),(u'Í','I'),(u'Ó','O'),(u'Ú','U'),('.',' '),(',',' '),(':',' '),(';',' '),('\n',' '),('\t',' '),('-',' '),('"',' '),("'",' ')]
# for r in acc: st=st.replace(r[0],r[1])
# return "".join(c for c in st if c in bs64 or c in [u'ñ',u'Ñ'])
#db_connector = sqlite3.connect("/var/lib/exp/praxis/lists.db")
#db_cursor = db_connector.cursor()
#db_sentence = "SELECT id,nombre,alias FROM lst ;"
#db_cursor.execute(db_sentence)
#names = fset((row[1] for row in db_cursor.fetchall()))
#names = [row for row in db_cursor.fetchall()]
#phph = lambda nnmm:nnmm.replace('LL',u'Ж').replace('RR',u'Р').replace('CH',u'Ч')
#names_ph = {nm[1]:phph(nm[1]) for nm in names}
#db_cursor.close(); db_connector.close()
app = Flask(__name__)
CORS(app)
#app.config['MYSQL_HOST'] = '45.63.49.123'
#app.config['MYSQL_USER'] = 'root'
#app.config['MYSQL_PASSWORD'] = ')(C0nd0R10101'
#app.config['MYSQL_DB'] = 'globalists'
#app.config['MYSQL_CURSORCLASS'] = 'DictCursor' #highly important, this creates a tuple of dictionaries
#mysql = MySQL(app)
connection_string_mysql = "DRIVER={/usr/local/lib/mariadb/libmaodbc.so};SERVER=localhost;PORT=3306;DATABASE=globalists;UID=root;PWD=)(C0nd0R10101"
contador_resultados = 0
#app.config['SECURITY_TOKEN_AUTHENTICATION_KEY'] = '7bvij07Js7Da0ij5VzWTib6AOAv7J9kShu3HM3BTU3iT'
#print(app.config['SECURITY_TOKEN_AUTHENTICATION_HEADER'])
#print(app.config['SECURITY_TOKEN_AUTHENTICATION_KEY'])
#app.config["SERVER_NAME"] = "localhost:2443"
#@app.route("/",subdomain="mneural")
#@app.route("/<path:wp>",subdomain="mneural")
#def webapp2(wp="index.html"): return app.send_static_file("mneural/"+wp+"index.html" if wp.endswith('/') else "mneural/"+wp)
def myFunc(e):
return e['name_similarity']
response_queue = Queue()
@app.route("/match", methods=['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS'])
#@auth_token_required
def match():
fields = {"name":"nombre","nationality":"pais","rfc":"rfc","status":"estatus"}
data = {field:request.args.get(field) for field in list(fields)+["similarity"]}
db_connector = pyodbc.connect(connection_string_mysql)
cur = db_connector.cursor()
cur.execute('SELECT Token FROM Token WHERE Activo = 1')
tokens_si = cur.fetchall()
lista_token = []
for t in tokens_si:
lista_token.append(t[0])
if not (request.args.get("token") and (request.args.get("name") or request.args.get("rfc"))): return {"success":False,"error":"400 Bad Request"},400
if(request.method != 'GET'):
cur.close()
db_connector.close()
return {"success":False,"error":"405 Method Not Allowed"},405
#if request.args.get("token") not in ["7bvij07Js7Da0ij5VzWTib6AOAv7J9kShu3HM3BTU3iT","j6KbS9IVIdWReQkag3Own9XS1YGBCt4L2j070YonBV4T"]:
#if request.args.get("token") not in ["j6KbS9IVIdWReQkag3Own9XS1YGBCt4L2j070YonBV4T","CAQ37QdFa2WtSMPDjq7qPn6ovyewGhUzbB2j6se6vcC4", "Pjvu03ocfsZSY7oQRXMHl5wagGltRhMkhUj0X0SI6CHo"]:
cur2 = db_connector.cursor()
cur2.execute("SELECT ID FROM Cuenta WHERE Fecha_fin >= now() AND Token = '{}' LIMIT 1".format(request.args.get("token")))
cuenta = cur2.fetchall()
if request.args.get("token") not in lista_token:
cur.close()
cur2.close()
db_connector.close()
return {"success":False,"error":"403 Not authorized"},403
if not cuenta:
cur.close()
cur2.close()
db_connector.close()
return {"success":False,"error":"403 expired"},403
print(data)
if not (request.args.get("site")):
cur2.execute("SELECT ID FROM Cuenta WHERE Fecha_fin > (date(now()) + interval 1 day) AND Token = '{}' and Total_Consultas > 0 LIMIT 1".format(request.args.get("token")))
valido = cur2.fetchall()
if(valido):
cur2.execute("update Cuenta set Total_consultas = Total_consultas-1 where Token = '{}'".format(request.args.get("token")))
else:
cur.close()
db_connector.close()
return {"success":False,"error":"Limite de consultas alcanzado, contacta a soporte en helpdesk@condorbs.net"},403
db_connector.commit()
if not (request.args.get("id")):
idUsuario = 0
else:
idUsuario = request.args.get("id")
if not (request.args.get("status")):
lestatus = "null"
else:
lestatus = request.args.get("status")
if not (request.args.get("similarity")):
lesim = 0.8
else:
lesim = request.args.get("similarity")
#print("pasamos la validacion")
#print("insert into LogBuscaApi (FechaConsulta, IdCompañia, IdUsuario, Nombre, RFC, Similitud, Status) values (now(), (SELECT ID FROM Cuenta WHERE TOKEN = '{}' LIMIT 1), {}, '{}', '{}', {}, {})".format(request.args.get("token"), idUsuario, request.args.get("name"), request.args.get("rfc"), request.args.get("similarity"), lestatus))
def __match(data):
prohibidos = ["EL","LA", "LOS", "LAS", "UN", "UNO", "UNA", "UNOS", "UNAS", "SA", "S", "DE", "RL", "CV", "UC"];
#prohibidos = [];
matched_names = []; matched_aliases = []
for sname in sorted(data['name'].replace(".","").upper().split(' '),key=len):
#print(sname);
sname2 = sname.replace("'","")
sname3 = sname.replace("'",".")
tmp_f = f"tmp-{sname2}-{int(time.time())}"
if(sname not in prohibidos):
print(sname);
#os.system("agrep -1 -e '%s' names > %s-n"%(sname,tmp_f))
#os.system("agrep -1 -e '%s' aliases > %s-a"%(sname,tmp_f))
#os.system("parallel agrep -1 -e '%s' ::: names.aa names.ab names.ac names.ad names.ae names.af names.ag names.ah > %s-n"%(sname,tmp_f))
#os.system("parallel agrep -1 -e '%s' ::: aliases > %s-a"%(sname,tmp_f))
os.system('cat names | parallel --pipe agrep -1 -e "%s" >> %s-n'%(sname3,tmp_f))
if(len(sname) > 3):
os.system('cat aliases | parallel --pipe agrep -3 -e "%s" >> %s-a'%(sname3,tmp_f))
else:
os.system('cat aliases | parallel --pipe agrep -1 -e "%s" >> %s-a'%(sname3,tmp_f))
# else:
# os.system("cat names | grep '%s' >> %s-n"%(sname,tmp_f))
# os.system("cat aliases | grep '%s' > %s-a"%(sname,tmp_f))
with open(f"{tmp_f}-n",'r') as tmp_ff:
for row in tmp_ff: matched_names.append(row[:-1].replace("'","''"))
with open(f"{tmp_f}-a",'r') as tmp_ff:
for row in tmp_ff: matched_aliases.append(row[:-1].replace("'","''"))
#print(matched_names)
os.system("rm tmp*")
db_connector = sqlite3.connect("/var/globalists/lists.db")
db_cursor = db_connector.cursor()
#db_sentence = "select distinct nombre from lst;"
#db_cursor.execute(db_sentence)
#nombres_base = db_cursor.fetchall()
#for sname in sorted(data['name'].upper().split(' '),key=len)[-2:]:
#for nombre in nombres_base:
#print(os.system("echo '%s' | parallel --pipe --block 3M agrep -1 -e '%s'"%(nombre[0],sname)))
db_sentence = "SELECT REPLACE(substr(id,0,5), '-', '') as list,nombre as name,alias,ubicacion as location,fechanac as birth_date,pais as nationality,rfc,programa as program,cargo as position,dependencia as department,fechapub as publication_date,estatus as status FROM lst WHERE "
#nms = [nm for nm in matched_names if fuzz.token_set_ratio(data["name"].upper(),nm)>80]
#als = [nm for nm in matched_aliases if fuzz.token_set_ratio(data["name"].upper(),nm)>80]
nms = {nm:fuzz.token_set_ratio(data["name"],nm.replace("''","'")) for nm in matched_names}
als = {nm:fuzz.token_set_ratio(data["name"],nm.replace("''","'")) for nm in matched_aliases}
nms = {nm:nmp for nm,nmp in nms.items() if nmp>=100*float(data["similarity"] or 0.8)}
als = {nm:nmp for nm,nmp in als.items() if nmp>=100*float(data["similarity"] or 0.8)}
#print(nms)
db_sentence+="( nombre IN ("+",".join([f"'{nm}'" for nm in nms])+")"
db_sentence+=" OR alias IN ("+",".join([f"'{nm}'" for nm in als])+") )"
db_sent_2 =" AND ".join([f"{fields[field]} LIKE '%{data[field]}%'" for field in fields if (data[field] and field!="name")])
db_sentence+=" AND "+db_sent_2+";" if db_sent_2 else ";"
#print(db_sentence)
db_cursor.execute(db_sentence)
table = [{db_cursor.description[k][0]:row[k] for k in range(len(row))} for row in db_cursor.fetchall()]
db_cursor.close(); db_connector.close()
#if(request.args.get("name").casefold() == 'ENRIQUE FRANCISCO GALINDO CEBALLOS'.casefold()):
#db_sentence = "SELECT REPLACE(substr(id,0,5), '-', '') as list,nombre as name,alias,ubicacion as location,fechanac as birth_date,pais as nationality,rfc,programa as program,cargo as position,dependencia as department,fechapub as publication_date,estatus as status FROM lst WHERE nombre = 'ENRIQUE FRANCISCO GALINDO CEBALLOS';"
#db_cursor.execute(db_sentence)
#table2 = [{db_cursor.description[k][0]:row[k] for k in range(len(row))} for row in db_cursor.fetchall()]
#print([db_cursor.description[k][0]:row[k] for k in range(len(row))] for row in db_cursor.fetchall())
#print("aqui empieza la otra tabla, ver que show")
#print(table)
global contador_resultados
for row in table:
if(row['name']):
row['name_similarity'] = nms.get(row['name'].replace("'","''"),0.0)/100.0
else:
row['name_similarity'] = nms.get(row['name'],0.0)/100.0
if(row['alias']):
row['alias_similarity'] = als.get(row['alias'].replace("'","''"),0.0)/100.0
else:
row['alias_similarity'] = als.get(row['alias'],0.0)/100.0
contador_resultados = contador_resultados + 1
#if(request.args.get("name").casefold() == 'ENRIQUE FRANCISCO GALINDO CEBALLOS'.casefold()):
#for row in table2:
#row['name_similarity'] = 1
#row['alias_similarity'] = als.get(row['alias'],0.0)/100.0
#for t in table2:
#table.append(t)
table.sort(reverse=True,key=myFunc);
#print(table)
response_queue.put(table)
thread = Process(target=__match,args=(data,),daemon=True)
thread.run()
#resultados = response_queue.get()
global contador_resultados
cur.execute("insert into LogBuscaApi (FechaConsulta, IdCompañia, IdUsuario, Nombre, RFC, Similitud, Status, Resultados) values (now(), (SELECT ID FROM Cuenta WHERE TOKEN = '{}' LIMIT 1), {}, '{}', '{}', {}, {}, {})".format(request.args.get("token"), idUsuario, request.args.get("name").replace("'","''"), request.args.get("rfc"), lesim, lestatus, contador_resultados))
print(contador_resultados)
contador_resultados = 0
db_connector.commit()
cur.close()
cur2.close
db_connector.close()
return jsonify({"success":True,"payload":response_queue.get()})
#@app.route("/face_match",subdomain="api", methods=['GET','POST','PUT','DELETE','TRACE','HEAD','OPTIONS'])
#def face_match():
# fields = ["token","target","candidate"]
# data = {field:request.args.get(field) for field in fields}
#if not all(request.args.get(field) for field in fields): return {"success":False,"error":"400 Bad Request"},400
# if request.method != 'POST': return {"success":False,"error":"405 Method Not Allowed"},405
# if request.args.get("token") != "7bvij07Js7Da0ij5VzWTib6AOAv7J9kShu3HM3BTU3iT":
# return {"success":False,"error":"403 Not authorized"},403 #abort(403)
# target_f = request.files["target"]
# candidate_f = request.files["candidate"]
# breakpoint() este estaba comentado
# target_f.save("target.jpg");candidate_f.save("target2.jpg")
# target_enc = face_recognition.face_encodings(face_recognition.load_image_file(target_f))
# candidate_enc = face_recognition.face_encodings(face_recognition.load_image_file(candidate_f))
# if len(target_enc)==0 or len(candidate_enc)==0:
# return jsonify({"success":False,"error":"No faces found"})
# results = face_recognition.compare_faces(candidate_enc,target_enc[0])
# return jsonify({"success":True,"payload":results[0]})
#app.run(host="0.0.0.0",port=2443,ssl_context=("/etc/letsencrypt/live/condorgl.net/fullchain.pem","/etc/letsencrypt/live/condorgl.net/privkey.pem"),debug=True)
if __name__ == '__main__':
app.run(host="0.0.0.0",port=2443,debug=True)
#import wsgiserver
#server = wsgiserver.WSGIServer(app,host="0.0.0.0",port=5000,certfile='./fullchain.pem',keyfile='./privkey.pem')
#server.start()