From 8649abb725fa7268192e004cf84e29e01da20f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Mon, 23 Jan 2023 14:13:43 +0100 Subject: [PATCH] add server (only with basic search for now) --- public/index.html | 78 ++++++++++++++++++++++++++++++ server.rb | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 public/index.html create mode 100755 server.rb diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..e986e50 --- /dev/null +++ b/public/index.html @@ -0,0 +1,78 @@ + + + + electronic parts database explorer + + + + +
+
+
+
+
+
+ + + + + + + + + +
namedescriptionstock
+
+ + diff --git a/server.rb b/server.rb new file mode 100755 index 0000000..d497060 --- /dev/null +++ b/server.rb @@ -0,0 +1,118 @@ +#!/usr/bin/env ruby +# encoding: utf-8 +# ruby: 3.0.2 +=begin +server to query part database + +to install sinatra +sudo pacman -S ruby-sinatra ruby-webrick +pikaur -S ruby-mysql2 +=end +require 'set' +require 'mysql2' +require 'json' +require 'sinatra' + +DEBUG = true +PARTS_LIMIT = 100 +CREDENTIALS = "credentials.json" +raise "database information #{CREDENTIALS} do not exist" unless File.file? CREDENTIALS + +# open server +configure do + if DEBUG then + set :show_exceptions, true + set :logging, true + else + set :show_exceptions, false + set :environment, :production + set :logging, false + end + set :protection, :except => :json_csrf + + set :bind, 'localhost' + set :port, 4244 + set :public_folder, "public" + set :static, true +end + +before do + response.headers["Access-Control-Allow-Origin"] = "*" + response.headers["Access-Control-Allow-Headers"] = "Content-Type" + if request.request_method == 'OPTIONS' + response.headers["Access-Control-Allow-Methods"] = "GET,POST" + halt 200 + end + + # all replies are only JSON + content_type 'application/json' + # open database + credentials = {} + JSON.parse(IO.read(CREDENTIALS)).each {|key,value| credentials[key.to_sym] = value} + Mysql2::Client.default_query_options.merge!(:as => :hash) + @db = Mysql2::Client.new(credentials) +end + +after do + response.headers["Access-Control-Allow-Origin"] = "*" + response.headers["Access-Control-Allow-Headers"] = "Content-Type" +end + +get '/' do + redirect to('/index.html') +end + +def get_part_by_id(id) + statement = @db.prepare("SELECT part.name, part.description, part.datasheet, manufacturer.name AS manufacturer, package.name AS package, part.pincount AS pincount, part.page AS page, part.family AS family FROM part LEFT JOIN package ON package.id = part.package LEFT JOIN manufacturer ON manufacturer.id = part.manufacturer WHERE part.id = ?") + part = statement.execute(id, :as => :hash).to_a[0] + return nil unless part + # merge with family info + while part and part["family"] do + family = statement.execute(part["family"]).to_a[0] + part["family"] = nil # reset info + break unless family + family.each do |k,v| + part[k] ||= v + end + end + # clean up + delete = ["family"] + delete.each do |k| + part.delete k + end + return part +end + +def get_part_by_name(name) + statement = @db.prepare("SELECT id FROM part WHERE part.name = ?") + id = statement.execute(name).to_a[0] + if id then + return get_part_by_id(id["id"]) + else + return nil + end +end + +get '/part/:name' do + part = get_part_by_name(params['name']) + halt 404 unless part + part.to_json +end + +get '/search/:terms' do + terms = params['terms'].split(" ") + terms.keep_if {|term| term.length >= 3} + ids = Set.new + part_statement = @db.prepare("SELECT id FROM part WHERE name LIKE ?") + terms.each do |term| + part_statement.execute("%#{term}%").each do |row| + ids << row["id"] + end + end + puts ids + parts = ids.collect {|id| get_part_by_id(id)} + parts.compact! + parts = parts[0, PARTS_LIMIT] + parts.sort! {|x,y| x["name"] <=> y["name"]} + parts.to_json +end