Compare commits
No commits in common. "main" and "faaso" have entirely different histories.
@ -1,6 +1,5 @@
|
|||||||
require "json"
|
require "json"
|
||||||
require "kemal"
|
require "kemal"
|
||||||
require "db"
|
|
||||||
require "pg"
|
require "pg"
|
||||||
require "pool/connection"
|
require "pool/connection"
|
||||||
|
|
||||||
@ -12,6 +11,11 @@ DBHOST = File.read("/secrets/dbhost").strip
|
|||||||
DBURL = "postgres://#{USER}:#{PASS}@#{DBHOST}:5432/nombres"
|
DBURL = "postgres://#{USER}:#{PASS}@#{DBHOST}:5432/nombres"
|
||||||
puts "Connnecting to #{DBURL}"
|
puts "Connnecting to #{DBURL}"
|
||||||
|
|
||||||
|
# Create a connection pool to the database
|
||||||
|
pg = ConnectionPool.new(capacity: 5, timeout: 1.seconds) do
|
||||||
|
PG.connect(DBURL)
|
||||||
|
end
|
||||||
|
|
||||||
def normalize(s : String) : String
|
def normalize(s : String) : String
|
||||||
s.unicode_normalize(:nfkd)
|
s.unicode_normalize(:nfkd)
|
||||||
.chars.reject! { |character|
|
.chars.reject! { |character|
|
||||||
@ -21,7 +25,6 @@ end
|
|||||||
|
|
||||||
# A basic hello world get endpoint
|
# A basic hello world get endpoint
|
||||||
post "/" do |env|
|
post "/" do |env|
|
||||||
db = DB.open DBURL
|
|
||||||
prefijo = env.params.json["p"].as(String)
|
prefijo = env.params.json["p"].as(String)
|
||||||
genero = env.params.json["g"].as(String)
|
genero = env.params.json["g"].as(String)
|
||||||
year = env.params.json["a"].as(String)
|
year = env.params.json["a"].as(String)
|
||||||
@ -32,15 +35,16 @@ post "/" do |env|
|
|||||||
end
|
end
|
||||||
datos = [] of Tuple(String, Int32 | String)
|
datos = [] of Tuple(String, Int32 | String)
|
||||||
# Connect using credentials provided
|
# Connect using credentials provided
|
||||||
|
pg.connection do |cursor|
|
||||||
if prefijo.empty? && year.empty?
|
if prefijo.empty? && year.empty?
|
||||||
result_set = db.query("
|
result_set = cursor.query("
|
||||||
SELECT nombre, total::integer
|
SELECT nombre, total::integer
|
||||||
FROM totales
|
FROM totales
|
||||||
ORDER BY total DESC
|
ORDER BY total DESC
|
||||||
LIMIT 50")
|
LIMIT 50")
|
||||||
elsif prefijo.empty? && !year.empty?
|
elsif prefijo.empty? && !year.empty?
|
||||||
# Per-year totals
|
# Per-year totals
|
||||||
result_set = db.query("
|
result_set = cursor.query("
|
||||||
SELECT nombre, contador::integer
|
SELECT nombre, contador::integer
|
||||||
FROM nombres
|
FROM nombres
|
||||||
WHERE
|
WHERE
|
||||||
@ -49,7 +53,7 @@ post "/" do |env|
|
|||||||
LIMIT 50", year)
|
LIMIT 50", year)
|
||||||
elsif !prefijo.empty? && year.empty?
|
elsif !prefijo.empty? && year.empty?
|
||||||
# Filter only by prefix
|
# Filter only by prefix
|
||||||
result_set = db.query("
|
result_set = cursor.query("
|
||||||
SELECT nombre, total::integer
|
SELECT nombre, total::integer
|
||||||
FROM totales
|
FROM totales
|
||||||
WHERE
|
WHERE
|
||||||
@ -58,7 +62,7 @@ post "/" do |env|
|
|||||||
LIMIT 50", prefijo + "%")
|
LIMIT 50", prefijo + "%")
|
||||||
elsif !prefijo.empty? && !year.empty?
|
elsif !prefijo.empty? && !year.empty?
|
||||||
# We have both
|
# We have both
|
||||||
result_set = db.query("
|
result_set = cursor.query("
|
||||||
SELECT nombre, contador::integer
|
SELECT nombre, contador::integer
|
||||||
FROM nombres
|
FROM nombres
|
||||||
WHERE
|
WHERE
|
||||||
@ -80,6 +84,7 @@ post "/" do |env|
|
|||||||
if datos.empty?
|
if datos.empty?
|
||||||
raise "No data found"
|
raise "No data found"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
# In this context, remove all composite names
|
# In this context, remove all composite names
|
||||||
datos.reject! { |row|
|
datos.reject! { |row|
|
||||||
row[0].to_s.includes? " "
|
row[0].to_s.includes? " "
|
||||||
@ -87,6 +92,7 @@ post "/" do |env|
|
|||||||
datos.insert(0, {"Nombre", "Cuantos?"})
|
datos.insert(0, {"Nombre", "Cuantos?"})
|
||||||
|
|
||||||
if genero
|
if genero
|
||||||
|
pg.connection do |cursor|
|
||||||
datos.reject! { |row|
|
datos.reject! { |row|
|
||||||
# How feminine is this name?
|
# How feminine is this name?
|
||||||
# Yes this database is upper case
|
# Yes this database is upper case
|
||||||
@ -97,7 +103,7 @@ post "/" do |env|
|
|||||||
COALESCE((SELECT frecuencia FROM hombres WHERE nombre='#{row[0]?.to_s.upcase}'), 0) AS hombres
|
COALESCE((SELECT frecuencia FROM hombres WHERE nombre='#{row[0]?.to_s.upcase}'), 0) AS hombres
|
||||||
)
|
)
|
||||||
puts "SQL: #{sql}"
|
puts "SQL: #{sql}"
|
||||||
db.query sql do |result_set|
|
cursor.query sql do |result_set|
|
||||||
result_set.each do
|
result_set.each do
|
||||||
mujeres = result_set.read(Int32)
|
mujeres = result_set.read(Int32)
|
||||||
hombres = result_set.read(Int32)
|
hombres = result_set.read(Int32)
|
||||||
@ -119,6 +125,7 @@ post "/" do |env|
|
|||||||
}
|
}
|
||||||
puts "Data split by gender"
|
puts "Data split by gender"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
datos = datos[..10].map { |row|
|
datos = datos[..10].map { |row|
|
||||||
[row[0].capitalize, row[1]]
|
[row[0].capitalize, row[1]]
|
||||||
}
|
}
|
||||||
@ -134,14 +141,9 @@ post "/" do |env|
|
|||||||
"title" => title,
|
"title" => title,
|
||||||
"data" => datos,
|
"data" => datos,
|
||||||
}.to_json
|
}.to_json
|
||||||
ensure
|
|
||||||
db.try &.close
|
|
||||||
end
|
end
|
||||||
|
|
||||||
get "/ping/" do
|
get "/ping/" do
|
||||||
db = DB.open DBURL
|
pg.connection.exec("SELECT 42")
|
||||||
db.exec("SELECT 42")
|
|
||||||
"OK"
|
"OK"
|
||||||
ensure
|
|
||||||
db.try &.close
|
|
||||||
end
|
end
|
||||||
|
11
deploy.sh
11
deploy.sh
@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh -x
|
#!/bin/sh -x
|
||||||
set -e
|
set -e
|
||||||
export OPENFAAS_URL=http://pinky:8082
|
#export OPENFAAS_URL=http://pinky:8082
|
||||||
#pass faas.ralsina.me | faas-cli login -u admin --password-stdin
|
#pass faas.ralsina.me | faas-cli login -u admin --password-stdin
|
||||||
|
|
||||||
#pass iol-pass | faas-cli secret create iol-pass
|
#pass iol-pass | faas-cli secret create iol-pass
|
||||||
@ -14,18 +14,15 @@ export FAASO_SERVER=http://rocky:8888/admin
|
|||||||
pass faaso-rocky | faaso login
|
pass faaso-rocky | faaso login
|
||||||
pass nombres-user | faaso secret -a historico user
|
pass nombres-user | faaso secret -a historico user
|
||||||
pass nombres-pass | faaso secret -a historico pass
|
pass nombres-pass | faaso secret -a historico pass
|
||||||
echo "rocky.tail20c16.ts.net" | faaso secret -a historico dbhost
|
echo "192.168.0.98" | faaso secret -a historico dbhost
|
||||||
faaso build busqueda
|
faaso build busqueda
|
||||||
faaso scale busqueda 0
|
faaso scale busqueda 0
|
||||||
faaso scale busqueda 1
|
faaso scale busqueda 1
|
||||||
pass nombres-user | faaso secret -a busqueda user
|
pass nombres-user | faaso secret -a busqueda user
|
||||||
pass nombres-pass | faaso secret -a busqueda pass
|
pass nombres-pass | faaso secret -a busqueda pass
|
||||||
echo "rocky.tail20c16.ts.net" | faaso secret -a busqueda dbhost
|
echo "192.168.0.98" | faaso secret -a busqueda dbhost
|
||||||
faaso build historico
|
faaso build historico
|
||||||
faaso scale historico 0
|
faaso scale historico 0
|
||||||
faaso scale historico 1
|
faaso scale historico 1
|
||||||
rsync -rav nombres.ralsina.me/* ralsina@rocky:/data/stacks/web/websites/nombres.ralsina.me/
|
|
||||||
|
|
||||||
faaso build tapas
|
rsync -rav nombres.ralsina.me/* ralsina@pinky:/data/websites/nombres.ralsina.me/
|
||||||
faaso scale tapas 0
|
|
||||||
faaso scale tapas 1
|
|
||||||
|
@ -3,6 +3,10 @@ provider:
|
|||||||
name: openfaas
|
name: openfaas
|
||||||
gateway: http://pinky:8082
|
gateway: http://pinky:8082
|
||||||
functions:
|
functions:
|
||||||
|
tapas:
|
||||||
|
lang: python3-flask
|
||||||
|
handler: ./tapas
|
||||||
|
image: ralsina/tapas:latest
|
||||||
iol:
|
iol:
|
||||||
lang: python3-fastapi
|
lang: python3-fastapi
|
||||||
handler: ./iol
|
handler: ./iol
|
||||||
|
@ -11,6 +11,11 @@ DBHOST = File.read("/secrets/dbhost").strip
|
|||||||
DBURL = "postgres://#{USER}:#{PASS}@#{DBHOST}:5432/nombres"
|
DBURL = "postgres://#{USER}:#{PASS}@#{DBHOST}:5432/nombres"
|
||||||
puts "Connnecting to #{DBURL}"
|
puts "Connnecting to #{DBURL}"
|
||||||
|
|
||||||
|
# Create a connection pool to the database
|
||||||
|
pg = ConnectionPool.new(capacity: 5, timeout: 1.seconds) do
|
||||||
|
PG.connect(DBURL)
|
||||||
|
end
|
||||||
|
|
||||||
# Connect to the database and get information about
|
# Connect to the database and get information about
|
||||||
# the requested names
|
# the requested names
|
||||||
get "/" do |env|
|
get "/" do |env|
|
||||||
@ -26,7 +31,7 @@ get "/" do |env|
|
|||||||
results << [anio.to_s]
|
results << [anio.to_s]
|
||||||
end
|
end
|
||||||
# Connect using credentials provided
|
# Connect using credentials provided
|
||||||
db = DB.open DBURL
|
pg.connection do |cursor|
|
||||||
# Get the information for each name
|
# Get the information for each name
|
||||||
names.map do |name|
|
names.map do |name|
|
||||||
# Normalize: remove diacritics etc.
|
# Normalize: remove diacritics etc.
|
||||||
@ -36,7 +41,7 @@ get "/" do |env|
|
|||||||
}.join("").downcase
|
}.join("").downcase
|
||||||
|
|
||||||
counter_per_year = {} of Int32 => Int32
|
counter_per_year = {} of Int32 => Int32
|
||||||
db.query("
|
cursor.query("
|
||||||
SELECT anio::integer, contador::integer
|
SELECT anio::integer, contador::integer
|
||||||
FROM nombres WHERE nombre = $1", name) do |result_set|
|
FROM nombres WHERE nombre = $1", name) do |result_set|
|
||||||
result_set.each do
|
result_set.each do
|
||||||
@ -47,15 +52,15 @@ get "/" do |env|
|
|||||||
results[anio - 1921] << counter_per_year.fetch(anio, 0).to_s
|
results[anio - 1921] << counter_per_year.fetch(anio, 0).to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
results.to_json
|
results.to_json
|
||||||
ensure
|
|
||||||
db.try &.close
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The `/ping/` endpoint is configured in the container as a healthcheck
|
||||||
|
# You can make it better by checking that your database is responding
|
||||||
|
# or whatever checks you think are important
|
||||||
|
#
|
||||||
get "/ping/" do
|
get "/ping/" do
|
||||||
db = DB.open DBURL
|
pg.connection.exec("SELECT 42")
|
||||||
db.exec("SELECT 42")
|
|
||||||
"OK"
|
"OK"
|
||||||
ensure
|
|
||||||
db.try &.close
|
|
||||||
end
|
end
|
||||||
|
@ -306,7 +306,6 @@
|
|||||||
id="nombres"
|
id="nombres"
|
||||||
placeholder="Nombres separados con comas"
|
placeholder="Nombres separados con comas"
|
||||||
aria-label="Search"
|
aria-label="Search"
|
||||||
value="juan,maria"
|
|
||||||
/>
|
/>
|
||||||
<input type="submit" value="Buscar" onCLick="drawChart2();" />
|
<input type="submit" value="Buscar" onCLick="drawChart2();" />
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
name: tapas
|
|
||||||
runtime: flask
|
|
||||||
options:
|
|
||||||
ship_packages:
|
|
||||||
- jpeg
|
|
||||||
- zlib
|
|
||||||
- freetype
|
|
||||||
devel_packages:
|
|
||||||
- zlib-dev
|
|
||||||
- jpeg-dev
|
|
||||||
- freetype-dev
|
|
||||||
healthcheck_options: "--interval=1m --timeout=2s --start-period=2s --retries=3"
|
|
||||||
healthcheck_command: "curl --fail http://localhost:3000/ping || exit 1"
|
|
||||||
copy_from_build:
|
|
||||||
- "static static"
|
|
||||||
- "venv venv"
|
|
||||||
- "run.sh ."
|
|
||||||
- "funko.py ."
|
|
@ -1,12 +1,10 @@
|
|||||||
from flask import Flask, request
|
from json import loads
|
||||||
from tapita import Cover
|
from tapita import Cover
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
app = Flask("tapas")
|
|
||||||
|
|
||||||
@app.route('/', methods=['POST'])
|
def handle(req):
|
||||||
def handle():
|
|
||||||
"""handle a request to the function
|
"""handle a request to the function
|
||||||
Args:
|
Args:
|
||||||
req (str): request body
|
req (str): request body
|
||||||
@ -17,10 +15,10 @@ def handle():
|
|||||||
"author": "bat",
|
"author": "bat",
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
if not request:
|
if not req:
|
||||||
return "Foo", 200, {"Content-Type": "text/plain"}
|
return "Foo", 200, {"Content-Type": "text/plain"}
|
||||||
try:
|
try:
|
||||||
args = request.json
|
args = loads(req)
|
||||||
except Exception:
|
except Exception:
|
||||||
return "Bad Request", 400
|
return "Bad Request", 400
|
||||||
|
|
||||||
@ -33,9 +31,3 @@ def handle():
|
|||||||
200,
|
200,
|
||||||
{"Content-Type": "text/html"},
|
{"Content-Type": "text/html"},
|
||||||
)
|
)
|
||||||
|
|
||||||
@app.route('/ping')
|
|
||||||
def ping():
|
|
||||||
return "OK"
|
|
||||||
|
|
||||||
|
|
@ -1,2 +1 @@
|
|||||||
flask
|
|
||||||
tapita
|
tapita
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
uwsgi --plugins http,python -H venv --http 0.0.0.0:3000 --master -p 1 -w funko:app
|
|
Loading…
Reference in New Issue
Block a user