Funciona
This commit is contained in:
parent
cbc815303e
commit
e9ad89f3b3
5
busqueda/.faaso.yml
Normal file
5
busqueda/.faaso.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
hosts:
|
||||||
|
https://faaso-prod.ralsina.me/admin/:
|
||||||
|
- admin
|
||||||
|
- Neih4ziefioshihaezu3Rienga7baeng
|
11
busqueda/README.md
Normal file
11
busqueda/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Readme for Busqueda
|
||||||
|
|
||||||
|
This is a funko using the Crystal runtime for [FaaSO](https://git.ralsina.me/ralsina/faaso)
|
||||||
|
|
||||||
|
## What is Busqueda
|
||||||
|
|
||||||
|
Write here what it is
|
||||||
|
|
||||||
|
## How to use Busqueda
|
||||||
|
|
||||||
|
And so on.
|
148
busqueda/funko.cr
Normal file
148
busqueda/funko.cr
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
require "json"
|
||||||
|
require "kemal"
|
||||||
|
require "pg"
|
||||||
|
require "pool/connection"
|
||||||
|
|
||||||
|
# get credentials from secrets
|
||||||
|
|
||||||
|
USER = File.read("secrets/user").strip
|
||||||
|
PASS = File.read("secrets/pass").strip
|
||||||
|
|
||||||
|
# Create a connection pool to the database
|
||||||
|
pg = ConnectionPool.new(capacity: 5, timeout: 0.01.seconds) do
|
||||||
|
PG.connect("postgres://#{USER}:#{PASS}@pinky:5432/nombres")
|
||||||
|
end
|
||||||
|
|
||||||
|
def normalize(s : String) : String
|
||||||
|
s.unicode_normalize(:nfkd)
|
||||||
|
.chars.reject! { |character|
|
||||||
|
!character.ascii_letter? && (character != ' ')
|
||||||
|
}.join("").downcase
|
||||||
|
end
|
||||||
|
|
||||||
|
# A basic hello world get endpoint
|
||||||
|
post "/" do |env|
|
||||||
|
prefijo = env.params.json["p"].as(String)
|
||||||
|
genero = env.params.json["g"].as(String)
|
||||||
|
year = env.params.json["a"].as(String)
|
||||||
|
|
||||||
|
p! prefijo, genero, year
|
||||||
|
|
||||||
|
prefijo = normalize(prefijo)
|
||||||
|
if !["f", "m"].includes?(genero)
|
||||||
|
genero = nil
|
||||||
|
end
|
||||||
|
datos = [] of Tuple(String, Int32 | String)
|
||||||
|
# Connect using credentials provided
|
||||||
|
pg.connection do |cursor|
|
||||||
|
if prefijo.empty? && year.empty?
|
||||||
|
result_set = cursor.query("
|
||||||
|
SELECT nombre, total::integer
|
||||||
|
FROM totales
|
||||||
|
ORDER BY total DESC
|
||||||
|
LIMIT 50")
|
||||||
|
elsif prefijo.empty? && !year.empty?
|
||||||
|
# Per-year totals
|
||||||
|
result_set = cursor.query("
|
||||||
|
SELECT nombre, contador::integer
|
||||||
|
FROM nombres
|
||||||
|
WHERE
|
||||||
|
anio = $1
|
||||||
|
ORDER BY contador DESC
|
||||||
|
LIMIT 50", year)
|
||||||
|
elsif !prefijo.empty? && year.empty?
|
||||||
|
# Filter only by prefix
|
||||||
|
result_set = cursor.query("
|
||||||
|
SELECT nombre, total::integer
|
||||||
|
FROM totales
|
||||||
|
WHERE
|
||||||
|
nombre LIKE $1
|
||||||
|
ORDER BY total DESC
|
||||||
|
LIMIT 50", prefijo + "%")
|
||||||
|
elsif !prefijo.empty? && !year.empty?
|
||||||
|
# We have both
|
||||||
|
result_set = cursor.query("
|
||||||
|
SELECT nombre, contador::integer
|
||||||
|
FROM nombres
|
||||||
|
WHERE
|
||||||
|
anio = $1 AND
|
||||||
|
nombre LIKE $2
|
||||||
|
ORDER BY contador DESC
|
||||||
|
LIMIT 50", year, prefijo + "%")
|
||||||
|
end
|
||||||
|
|
||||||
|
if !result_set.nil?
|
||||||
|
result_set.each do
|
||||||
|
nombre = result_set.read(String)
|
||||||
|
valor = result_set.read(Int32)
|
||||||
|
datos.push({nombre, valor})
|
||||||
|
end
|
||||||
|
result_set.close
|
||||||
|
end
|
||||||
|
|
||||||
|
if datos.empty?
|
||||||
|
raise "No data found"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# In this context, remove all composite names
|
||||||
|
datos.reject! { |row|
|
||||||
|
row[0].to_s.includes? " "
|
||||||
|
}
|
||||||
|
datos.insert(0, {"Nombre", "Cuantos?"})
|
||||||
|
|
||||||
|
if genero
|
||||||
|
pg.connection do |cursor|
|
||||||
|
datos.reject! { |row|
|
||||||
|
# How feminine is this name?
|
||||||
|
# Yes this database is upper case
|
||||||
|
puts "Checking #{row[1]} #{row[0]}"
|
||||||
|
feminidad = 0
|
||||||
|
sql = %(
|
||||||
|
SELECT COALESCE((SELECT frecuencia FROM mujeres WHERE nombre='#{row[0]?.to_s.upcase}'), 0) AS mujeres,
|
||||||
|
COALESCE((SELECT frecuencia FROM hombres WHERE nombre='#{row[0]?.to_s.upcase}'), 0) AS hombres
|
||||||
|
)
|
||||||
|
puts "SQL: #{sql}"
|
||||||
|
cursor.query sql do |result_set|
|
||||||
|
result_set.each do
|
||||||
|
mujeres = result_set.read(Int32)
|
||||||
|
hombres = result_set.read(Int32)
|
||||||
|
puts "frecuencias: #{mujeres} #{hombres}"
|
||||||
|
if hombres == mujeres == 0
|
||||||
|
feminidad = 0.5
|
||||||
|
else
|
||||||
|
feminidad = mujeres / (hombres + mujeres)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# El overlap en 0.5 es intencional!
|
||||||
|
if (feminidad >= 0.5 && genero == "f") ||
|
||||||
|
(feminidad <= 0.5 && genero == "m")
|
||||||
|
false
|
||||||
|
else
|
||||||
|
true
|
||||||
|
end
|
||||||
|
}
|
||||||
|
puts "Data split by gender"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
datos = datos[..10].map { |row|
|
||||||
|
[row[0].capitalize, row[1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
if datos.size > 1
|
||||||
|
title = "¿Puede ser ... #{datos[0][1].to_s.titleize}? ¿O capaz que #{datos[1][1].to_s.titleize}? ¡Contame más!"
|
||||||
|
elsif datos.size == 1
|
||||||
|
title = "Me parece que ... #{datos[0][1].to_s.titleize}!"
|
||||||
|
else
|
||||||
|
title = "No tengo idea!"
|
||||||
|
end
|
||||||
|
{
|
||||||
|
"title" => title,
|
||||||
|
"data" => datos,
|
||||||
|
}.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
get "/ping/" do
|
||||||
|
pg.connection.exec("SELECT 42")
|
||||||
|
"OK"
|
||||||
|
end
|
11
busqueda/funko.yml
Normal file
11
busqueda/funko.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: busqueda
|
||||||
|
runtime: kemal
|
||||||
|
options:
|
||||||
|
shard_build_options: "--release"
|
||||||
|
ship_packages: []
|
||||||
|
devel_packages: []
|
||||||
|
healthcheck_options: "--interval=1m --timeout=2s --start-period=2s --retries=3"
|
||||||
|
healthcheck_command: "curl --fail http://localhost:3000/ping || exit 1"
|
||||||
|
copy_from_build:
|
||||||
|
- "public public"
|
||||||
|
- "bin/funko ."
|
@ -1,164 +0,0 @@
|
|||||||
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:
|
|
||||||
nombre = nombre.strip().split()[0].strip().upper()
|
|
||||||
mujeres = cursor.execute(sql1, {"nombre": nombre}).fetchone()
|
|
||||||
mujeres = 0 if mujeres is None else mujeres[0]
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
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}
|
|
||||||
|
|
||||||
|
|
||||||
def handle(req):
|
|
||||||
"""handle a request to the function
|
|
||||||
Args:
|
|
||||||
req (str): request body
|
|
||||||
|
|
||||||
{
|
|
||||||
p: prefijo del nombre,
|
|
||||||
g: genero del nombre,
|
|
||||||
y: 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
|
|
||||||
return f"{req} -- {e}", 400
|
|
||||||
|
|
||||||
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()]
|
|
||||||
|
|
||||||
elif prefijo is None and año is not None: # Totales por año
|
|
||||||
with connection.cursor() as cursor:
|
|
||||||
sql = """
|
|
||||||
SELECT contador, nombre
|
|
||||||
FROM nombres
|
|
||||||
WHERE
|
|
||||||
anio = :anio
|
|
||||||
ORDER BY contador DESC
|
|
||||||
LIMIT 50
|
|
||||||
"""
|
|
||||||
cursor.execute(sql, {"anio": año})
|
|
||||||
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 = """
|
|
||||||
SELECT total, nombre
|
|
||||||
FROM totales
|
|
||||||
WHERE
|
|
||||||
nombre LIKE :nombre
|
|
||||||
ORDER BY total DESC
|
|
||||||
LIMIT 50
|
|
||||||
"""
|
|
||||||
cursor.execute(sql, {"nombre": f"{prefijo}%"})
|
|
||||||
datos = [(r["total"], r["nombre"]) for r in cursor.fetchall()]
|
|
||||||
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
|
|
||||||
"""
|
|
||||||
cursor.execute(sql, {"anio": año, "nombre": f"{prefijo}%"})
|
|
||||||
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]])
|
|
||||||
|
|
||||||
return (
|
|
||||||
chart.render(is_unicode=True),
|
|
||||||
200,
|
|
||||||
{"Content-Type": "image/svg+xml"},
|
|
||||||
)
|
|
240
busqueda/public/index.html
Normal file
240
busqueda/public/index.html
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" data-theme="dark">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://www.gstatic.com/charts/loader.js"
|
||||||
|
></script>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<!-- Font -->
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Quicksand:wght@300..700&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.colors.min.css"
|
||||||
|
/>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Kode+Mono&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<script type="text/javascript">
|
||||||
|
google.charts.load("current", { packages: ["corechart"] });
|
||||||
|
google.charts.setOnLoadCallback(drawChart);
|
||||||
|
|
||||||
|
async function drawChart() {
|
||||||
|
fetch("/", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
p: document.getElementById("p").value,
|
||||||
|
g: document.getElementById("g").value,
|
||||||
|
a: document.getElementById("a").value,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((json) => {
|
||||||
|
title = json["title"];
|
||||||
|
data = json["data"];
|
||||||
|
console.log(data);
|
||||||
|
data = google.visualization.arrayToDataTable(data);
|
||||||
|
// var options = {
|
||||||
|
// title: "",
|
||||||
|
// animation: {
|
||||||
|
// startup: true,
|
||||||
|
// duration: 1000,
|
||||||
|
// easing: "out",
|
||||||
|
// },
|
||||||
|
// backgroundColor: "#1c212c",
|
||||||
|
// vAxis: {
|
||||||
|
// minValue: 0,
|
||||||
|
// gridlines: { color: "#666" },
|
||||||
|
// minorGridlines: { color: "#1c212c" },
|
||||||
|
// textStyle: { color: "#aaa" },
|
||||||
|
// },
|
||||||
|
// hAxis: {
|
||||||
|
// gridlines: { color: "#666" },
|
||||||
|
// minorGridlines: { color: "#1c212c" },
|
||||||
|
// textStyle: { color: "#aaa" },
|
||||||
|
// },
|
||||||
|
// legend: { position: "bottom", textStyle: { color: "#aaa" } },
|
||||||
|
// };
|
||||||
|
|
||||||
|
var chart = new google.visualization.BarChart(
|
||||||
|
document.getElementById("chart")
|
||||||
|
);
|
||||||
|
|
||||||
|
chart.draw(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
html * {
|
||||||
|
font-family: "Quicksand", sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="container" style="text-align: center">
|
||||||
|
<header>
|
||||||
|
<h1>Adivinar nombres por edad y género</h1>
|
||||||
|
</header>
|
||||||
|
<div id="chart" style="width: 80vw; height: 50vh; margin: auto"></div>
|
||||||
|
<form
|
||||||
|
onSubmit="return false;"
|
||||||
|
style="margin: auto; margin-top: 2em; width: 80%"
|
||||||
|
>
|
||||||
|
<fieldset class="grid">
|
||||||
|
<input type="text" name="p" id="p" placeholder="Como empieza tu nombre?" />
|
||||||
|
<select name="a" id="a">
|
||||||
|
<option selected value="">Año de nacimiento?</option>
|
||||||
|
<option value="1922">1922</option>
|
||||||
|
<option value="1923">1923</option>
|
||||||
|
<option value="1924">1924</option>
|
||||||
|
<option value="1925">1925</option>
|
||||||
|
<option value="1926">1926</option>
|
||||||
|
<option value="1927">1927</option>
|
||||||
|
<option value="1928">1928</option>
|
||||||
|
<option value="1929">1929</option>
|
||||||
|
<option value="1930">1930</option>
|
||||||
|
<option value="1931">1931</option>
|
||||||
|
<option value="1932">1932</option>
|
||||||
|
<option value="1933">1933</option>
|
||||||
|
<option value="1934">1934</option>
|
||||||
|
<option value="1935">1935</option>
|
||||||
|
<option value="1936">1936</option>
|
||||||
|
<option value="1937">1937</option>
|
||||||
|
<option value="1938">1938</option>
|
||||||
|
<option value="1939">1939</option>
|
||||||
|
<option value="1940">1940</option>
|
||||||
|
<option value="1941">1941</option>
|
||||||
|
<option value="1942">1942</option>
|
||||||
|
<option value="1943">1943</option>
|
||||||
|
<option value="1944">1944</option>
|
||||||
|
<option value="1945">1945</option>
|
||||||
|
<option value="1946">1946</option>
|
||||||
|
<option value="1947">1947</option>
|
||||||
|
<option value="1948">1948</option>
|
||||||
|
<option value="1949">1949</option>
|
||||||
|
<option value="1950">1950</option>
|
||||||
|
<option value="1951">1951</option>
|
||||||
|
<option value="1952">1952</option>
|
||||||
|
<option value="1953">1953</option>
|
||||||
|
<option value="1954">1954</option>
|
||||||
|
<option value="1955">1955</option>
|
||||||
|
<option value="1956">1956</option>
|
||||||
|
<option value="1957">1957</option>
|
||||||
|
<option value="1958">1958</option>
|
||||||
|
<option value="1959">1959</option>
|
||||||
|
<option value="1960">1960</option>
|
||||||
|
<option value="1961">1961</option>
|
||||||
|
<option value="1962">1962</option>
|
||||||
|
<option value="1963">1963</option>
|
||||||
|
<option value="1964">1964</option>
|
||||||
|
<option value="1965">1965</option>
|
||||||
|
<option value="1966">1966</option>
|
||||||
|
<option value="1967">1967</option>
|
||||||
|
<option value="1968">1968</option>
|
||||||
|
<option value="1969">1969</option>
|
||||||
|
<option value="1970">1970</option>
|
||||||
|
<option value="1971">1971</option>
|
||||||
|
<option value="1972">1972</option>
|
||||||
|
<option value="1973">1973</option>
|
||||||
|
<option value="1974">1974</option>
|
||||||
|
<option value="1975">1975</option>
|
||||||
|
<option value="1976">1976</option>
|
||||||
|
<option value="1977">1977</option>
|
||||||
|
<option value="1978">1978</option>
|
||||||
|
<option value="1979">1979</option>
|
||||||
|
<option value="1980">1980</option>
|
||||||
|
<option value="1981">1981</option>
|
||||||
|
<option value="1982">1982</option>
|
||||||
|
<option value="1983">1983</option>
|
||||||
|
<option value="1984">1984</option>
|
||||||
|
<option value="1985">1985</option>
|
||||||
|
<option value="1986">1986</option>
|
||||||
|
<option value="1987">1987</option>
|
||||||
|
<option value="1988">1988</option>
|
||||||
|
<option value="1989">1989</option>
|
||||||
|
<option value="1990">1990</option>
|
||||||
|
<option value="1991">1991</option>
|
||||||
|
<option value="1992">1992</option>
|
||||||
|
<option value="1993">1993</option>
|
||||||
|
<option value="1994">1994</option>
|
||||||
|
<option value="1995">1995</option>
|
||||||
|
<option value="1996">1996</option>
|
||||||
|
<option value="1997">1997</option>
|
||||||
|
<option value="1998">1998</option>
|
||||||
|
<option value="1999">1999</option>
|
||||||
|
<option value="2000">2000</option>
|
||||||
|
<option value="2001">2001</option>
|
||||||
|
<option value="2002">2002</option>
|
||||||
|
<option value="2003">2003</option>
|
||||||
|
<option value="2004">2004</option>
|
||||||
|
<option value="2005">2005</option>
|
||||||
|
<option value="1966">1966</option>
|
||||||
|
<option value="1967">1967</option>
|
||||||
|
<option value="1968">1968</option>
|
||||||
|
<option value="1969">1969</option>
|
||||||
|
<option value="1970">1970</option>
|
||||||
|
<option value="1971">1971</option>
|
||||||
|
<option value="1972">1972</option>
|
||||||
|
<option value="1973">1973</option>
|
||||||
|
<option value="1974">1974</option>
|
||||||
|
<option value="1975">1975</option>
|
||||||
|
<option value="1976">1976</option>
|
||||||
|
<option value="1977">1977</option>
|
||||||
|
<option value="1978">1978</option>
|
||||||
|
<option value="1979">1979</option>
|
||||||
|
<option value="1980">1980</option>
|
||||||
|
<option value="1981">1981</option>
|
||||||
|
<option value="1982">1982</option>
|
||||||
|
<option value="1983">1983</option>
|
||||||
|
<option value="1984">1984</option>
|
||||||
|
<option value="1985">1985</option>
|
||||||
|
<option value="1986">1986</option>
|
||||||
|
<option value="1987">1987</option>
|
||||||
|
<option value="1988">1988</option>
|
||||||
|
<option value="1989">1989</option>
|
||||||
|
<option value="1990">1990</option>
|
||||||
|
<option value="1991">1991</option>
|
||||||
|
<option value="1992">1992</option>
|
||||||
|
<option value="1993">1993</option>
|
||||||
|
<option value="1994">1994</option>
|
||||||
|
<option value="1995">1995</option>
|
||||||
|
<option value="1996">1996</option>
|
||||||
|
<option value="1997">1997</option>
|
||||||
|
<option value="1998">1998</option>
|
||||||
|
<option value="1999">1999</option>
|
||||||
|
<option value="2000">2000</option>
|
||||||
|
<option value="2001">2001</option>
|
||||||
|
<option value="2002">2002</option>
|
||||||
|
<option value="2003">2003</option>
|
||||||
|
<option value="2004">2004</option>
|
||||||
|
<option value="2005">2005</option>
|
||||||
|
</select>
|
||||||
|
<select name="g" id="g" />
|
||||||
|
<option selected value="">Género?</option>
|
||||||
|
<option value="f">Femenino</option>
|
||||||
|
<option value="m">Masculino</option>
|
||||||
|
</select>
|
||||||
|
<input type="submit" value="Buscar" onCLick="drawChart();" />
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,3 +0,0 @@
|
|||||||
pygal
|
|
||||||
requests
|
|
||||||
pyrqlite
|
|
18
busqueda/shard.yml
Normal file
18
busqueda/shard.yml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
name: busqueda
|
||||||
|
version: 0.1.0
|
||||||
|
|
||||||
|
targets:
|
||||||
|
funko:
|
||||||
|
main: main.cr
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
kemal:
|
||||||
|
github: kemalcr/kemal
|
||||||
|
pg:
|
||||||
|
github: will/crystal-pg
|
||||||
|
pool:
|
||||||
|
github: ysbaddaden/pool
|
||||||
|
|
||||||
|
# development_dependencies:
|
||||||
|
# webmock:
|
||||||
|
# github: manastech/webmock.cr
|
Loading…
x
Reference in New Issue
Block a user