require "http/client" require "http/headers" require "http/request" require "ishi/html" require "json" require "uuid" class Handler def format_buffer(buffer, canvas_name, title = "") # Process the gnuplot output so it works in the page # # buffer is the Ishi output # name is a string to replace for gnuplot_canvas so # we can have multiple charts in a page # title is added on top of the chart html = buffer.to_s.split("\n") html = html[html.index("")] html = "#{title}" + html.join("\n") + %(
Sorry, your browser seems not to support the HTML 5 canvas element
) # This ID needs to be unique in case # we have 2 charts in the same page html.gsub("gnuplot_canvas", canvas_name) end def query(sql) # Runs a SQL query against the Rqlite database. # # Returns an array of values (which need to be casted) # Or nil if there are no results params = URI::Params.encode({"q": sql}) response = HTTP::Client.get URI.new( "http", "10.61.0.1", 4001, "/db/query", params) # This API only has a values key when there are actual results results = JSON.parse(response.body)["results"][0].as_h if results.has_key?("values") return results["values"].as_a end # No result, return nil nil end nombres = [] of String def normalize_name(s) # Remove diacritics, turn lowercase normalized = s.unicode_normalize(:nfkd).chars normalized.reject! { |c| !c.ascii_letter? }.join("").downcase end def run(request : HTTP::Request) unless (body = request.body).nil? query = JSON.parse(body) nombres = query["i"].as_s.split(",").map { |n| n.strip } nombres.reject! { |n| n.size == 0 } end if nombres.nil? || nombres.empty? nombres = ["maria", "juan"] end # Remove all diacritics and whatnot nombres = nombres.map { |n| normalize_name n } puts "Processing #{nombres}" buffer = IO::Memory.new Ishi.new(buffer) do canvas_size(800, 300) show_key(true) xrange(1922..2015) nombres.map { |nombre| sql = "SELECT anio, contador FROM nombres WHERE nombre = '#{nombre}' ORDER BY anio" x = Array(Int32).new y = Array(Int32).new results = query(sql) if results.nil? # No results, all 0s x = (1922..2015).to_a y = x.map {|_| 0} else # We got results displayed = true results.map { |r| x << r[0].as_i y << r[1].as_i } end plot(x, y, title: nombre.titleize, style: :lines, linewidth: 3) } end return { body: format_buffer(buffer, "historico"), status_code: 200, headers: HTTP::Headers{"Content-Type" => "text/html"}, } end end