119 lines
3.0 KiB
Ruby
Executable File
119 lines
3.0 KiB
Ruby
Executable File
#!/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
|