Functions/busqueda/handler.py

165 lines
4.6 KiB
Python
Raw Normal View History

2022-07-19 14:56:46 +00:00
import unicodedata
import urllib
from collections import namedtuple as nt
from dataclasses import dataclass
from json import loads
import logging
import pygal
import pyrqlite.dbapi2 as dbapi2
import requests
connection = dbapi2.connect(
host="10.61.0.1",
user="root",
port=4001,
password="",
)
def remove_accents(input_str):
nfkd_form = unicodedata.normalize("NFKD", input_str)
return "".join([c for c in nfkd_form if not unicodedata.combining(c)])
def femininidad(nombre):
sql1 = """
SELECT COALESCE(frecuencia,0)
FROM mujeres WHERE nombre=:nombre
"""
sql2 = """
SELECT COALESCE(frecuencia,0)
FROM hombres WHERE nombre=:nombre
"""
with connection.cursor() as cursor:
2022-07-25 13:14:00 +00:00
nombre = nombre.strip().split()[0].strip().upper()
mujeres = cursor.execute(sql1, {"nombre": nombre}).fetchone()
mujeres = 0 if mujeres is None else mujeres[0]
2022-07-25 13:14:00 +00:00
hombres = cursor.execute(sql2, {"nombre": nombre}).fetchone()
hombres = 0 if hombres is None else hombres[0]
if hombres == mujeres == 0:
return 0.5
return mujeres / (hombres + mujeres)
2022-07-19 14:56:46 +00:00
def split_por_genero(nombres):
femeninos = []
masculinos = []
for n in nombres:
fem = femininidad(n[1])
if fem is None:
femeninos.append(n)
masculinos.append(n)
elif fem >= 0.5:
femeninos.append(n)
else:
masculinos.append(n)
return {"f": femeninos, "m": masculinos}
2022-07-19 14:56:46 +00:00
def handle(req):
"""handle a request to the function
Args:
req (str): request body
{
p: prefijo del nombre,
g: genero del nombre,
a: año de nacimiento
}
"""
try:
data = loads(req)
except Exception as e:
data = {}
try:
prefijo = data.get("p") or None
genero = data.get("g") or None
try:
año = int(data.get("a"))
except Exception:
año = None
except Exception as e:
prefijo = genero = año = None
2022-07-19 18:44:48 +00:00
return f"{req} -- {e}", 400
2022-07-19 14:56:46 +00:00
if prefijo is not None:
prefijo = prefijo.strip().lower()
if genero not in ("f", "m"):
genero = None
if prefijo is None and año is None: # Totales globales
with connection.cursor() as cursor:
sql = """
SELECT total, nombre
FROM totales
ORDER BY total DESC
LIMIT 50
"""
cursor.execute(sql)
datos = [(r["total"], r["nombre"]) for r in cursor.fetchall()]
2022-07-19 18:44:48 +00:00
elif prefijo is None and año is not None: # Totales por año
2022-07-19 14:56:46 +00:00
with connection.cursor() as cursor:
sql = """
SELECT contador, nombre
FROM nombres
WHERE
anio = :anio
ORDER BY contador DESC
LIMIT 50
"""
2022-07-19 18:44:48 +00:00
cursor.execute(sql, {"anio": año})
2022-07-19 14:56:46 +00:00
datos = [(r["contador"], r["nombre"]) for r in cursor.fetchall()]
elif prefijo is not None and año is None:
with connection.cursor() as cursor:
sql = """
2022-07-19 18:44:48 +00:00
SELECT total, nombre
FROM totales
2022-07-19 14:56:46 +00:00
WHERE
nombre LIKE :nombre
2022-07-19 18:44:48 +00:00
ORDER BY total DESC
2022-07-19 14:56:46 +00:00
LIMIT 50
"""
2022-07-19 18:44:48 +00:00
cursor.execute(sql, {"nombre": f"{prefijo}%"})
datos = [(r["total"], r["nombre"]) for r in cursor.fetchall()]
2022-07-19 14:56:46 +00:00
else:
with connection.cursor() as cursor:
sql = """
SELECT contador, nombre
FROM nombres
WHERE
anio = :anio AND
nombre LIKE :nombre
ORDER BY contador DESC
LIMIT 50
"""
2022-07-19 18:44:48 +00:00
cursor.execute(sql, {"anio": año, "nombre": f"{prefijo}%"})
2022-07-19 14:56:46 +00:00
datos = [(r["contador"], r["nombre"]) for r in cursor.fetchall()]
if genero:
datos = split_por_genero(datos)[genero]
datos = datos[:10]
chart = pygal.HorizontalBar(height=400, show_legend=False, show_y_labels=True)
chart.x_labels = [nombre.title() for _, nombre in datos[::-1]]
if len(datos) > 1:
chart.title = f"¿Puede ser ... {datos[0][1].title()}? ¿O capaz que {datos[1][1].title()}? ¡Contáme más!"
elif len(datos) == 1:
chart.title = f"¡Hola {datos[0][1].title()}!"
elif len(datos) < 1:
chart.title = "¡No esssistís!"
chart.add("", [contador for contador, _ in datos[::-1]])
2022-07-19 18:44:48 +00:00
return (
chart.render(is_unicode=True),
200,
{"Content-Type": "image/svg+xml"},
)