2023-01-23 14:13:43 +01:00
#!/usr/bin/env ruby
# encoding: utf-8
# ruby: 3.0.2
= begin
2023-01-28 05:56:17 +01:00
backend to query part database
Copyright ( C ) 2023 King Kévin < kingkevin @cuvoodoo . info >
SPDX - License - Identifier : GPL - 3 . 0 - or - later
2023-01-23 14:13:43 +01:00
to install sinatra
2023-03-08 12:51:50 +01:00
gem install sinatra puma
2023-01-23 14:13:43 +01:00
= end
require 'set'
2023-02-26 12:11:27 +01:00
require 'sqlite3'
2023-01-23 14:13:43 +01:00
require 'json'
require 'sinatra'
2023-01-29 09:56:49 +01:00
require 'uri'
require 'net/http'
2023-01-31 03:37:49 +01:00
require 'cgi'
2023-01-23 14:13:43 +01:00
2023-01-28 07:00:44 +01:00
DEBUG = false
2023-01-26 11:55:56 +01:00
# maximum number of parts returned
2023-01-23 14:13:43 +01:00
PARTS_LIMIT = 100
2023-02-26 12:11:27 +01:00
# database file
DB_PATH = " partdb.db "
raise " DB file #{ DB_PATH } does not exist " unless File . file? DB_PATH
2023-01-26 11:55:56 +01:00
# folder name for served pages
PUBLIC = " public "
# folder name for part attachments (in PUBLIC)
ATTACHMENTS = " attachments "
2023-01-28 07:00:07 +01:00
# port for this service
2023-01-28 10:15:36 +01:00
PORT = 4245
2023-01-26 11:55:56 +01:00
2023-01-23 14:13:43 +01:00
# 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'
2023-01-28 07:00:07 +01:00
set :port , PORT
2023-01-23 14:13:43 +01:00
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
2023-02-26 12:11:27 +01:00
@db = SQLite3 :: Database . new ( DB_PATH )
@db . results_as_hash = true
2023-01-23 14:13:43 +01:00
end
after do
response . headers [ " Access-Control-Allow-Origin " ] = " * "
response . headers [ " Access-Control-Allow-Headers " ] = " Content-Type "
end
get '/' do
2023-01-30 01:04:07 +01:00
content_type 'text/html'
send_file File . join ( settings . public_folder , 'index.html' )
2023-01-23 14:13:43 +01:00
end
def get_part_by_id ( id )
2023-01-26 07:17:20 +01:00
return nil unless id
2023-01-29 10:22:47 +01:00
statement = @db . prepare ( " SELECT part.id, part.name, part.description, part.details, part.datasheet, manufacturer.name AS manufacturer, part.mpn AS mpn, part.package, part.page AS page, part.family AS parent, p2.name AS family FROM part LEFT JOIN manufacturer ON manufacturer.id = part.manufacturer LEFT JOIN part AS p2 ON p2.id = part.family WHERE part.id = ? " )
2023-01-25 07:48:36 +01:00
part = statement . execute ( id ) . to_a [ 0 ]
2023-01-23 14:13:43 +01:00
return nil unless part
2023-01-26 07:17:20 +01:00
parent = get_part_by_id ( part [ " parent " ] )
# merge parent info
if parent then
part . each do | k , v |
part [ k ] || = parent [ k ]
2023-01-23 14:13:43 +01:00
end
end
2023-01-30 12:12:40 +01:00
# add distributors
part [ " distributors " ] = [ ]
statement = @db . prepare ( " SELECT distribution.sku AS sku, distributor.name AS name, distributor.product_page AS url FROM distribution LEFT JOIN distributor ON distributor.id = distribution.distributor WHERE distribution.part = ? " )
statement . execute ( id ) . each do | distribution |
2023-03-31 08:31:14 +02:00
distribution [ " url " ] . gsub! ( " %s " , distribution [ " sku " ] ) if distribution [ " url " ]
2023-01-30 12:12:40 +01:00
part [ " distributors " ] << distribution
2023-01-25 07:47:48 +01:00
end
2023-01-25 08:46:21 +01:00
# add inventory
statement = @db . prepare ( " SELECT location.name AS location, inventory.quantity AS stock FROM inventory LEFT JOIN location ON location.id = inventory.location WHERE inventory.part = ? ORDER BY inventory.quantity DESC LIMIT 1 " )
inventory = statement . execute ( id ) . to_a [ 0 ]
if inventory then
part [ " location " ] = inventory [ " location " ]
part [ " stock " ] = inventory [ " stock " ]
end
2023-01-25 11:22:26 +01:00
# add properties
2023-01-30 12:12:40 +01:00
part [ " properties " ] = [ ]
2023-01-31 21:54:27 +01:00
statement = @db . prepare ( " SELECT property.name AS name, properties.value AS value FROM properties JOIN property ON property.id = properties.property WHERE properties.part = ? " )
2023-01-26 07:17:20 +01:00
statement . execute ( id ) . each do | row |
2023-01-30 12:12:40 +01:00
part [ " properties " ] << row
2023-01-25 11:22:26 +01:00
end
2023-01-30 12:12:40 +01:00
part [ " properties " ] += parent [ " properties " ] if parent
2023-01-26 11:55:56 +01:00
# add attachments
part [ " attachments " ] = [ ]
2023-01-30 04:37:35 +01:00
dir = PUBLIC + " / " + ATTACHMENTS + " / " + part [ " name " ] . gsub ( " / " , " _ " )
2023-01-28 02:41:32 +01:00
if File . directory? ( dir ) then
Dir . entries ( dir ) . each do | file |
path = dir + " / " + file
next unless File . file? path
2023-01-30 04:37:35 +01:00
part [ " attachments " ] << ATTACHMENTS + " / " + part [ " name " ] . gsub ( " / " , " _ " ) + " / " + file
2023-01-28 02:41:32 +01:00
end
2023-01-26 11:55:56 +01:00
end
2023-01-28 10:16:51 +01:00
part [ " attachments " ] . sort!
2023-01-30 12:12:40 +01:00
part [ " attachments " ] += parent [ " attachments " ] if parent
2023-01-30 04:18:56 +01:00
# add components for assembly
2023-01-30 12:12:40 +01:00
part [ " components " ] = [ ]
2023-01-30 12:30:11 +01:00
statement = @db . prepare ( " SELECT part.name AS name, part.description AS description, assembly.quantity AS quantity FROM assembly JOIN part ON part.id = assembly.component WHERE assembly.assembled = ? " )
2023-01-30 04:18:56 +01:00
statement . execute ( id ) . each do | row |
2023-01-30 12:12:40 +01:00
part [ " components " ] << row
2023-01-30 04:18:56 +01:00
end
2023-01-30 12:12:40 +01:00
part [ " components " ] += parent [ " components " ] if parent
2023-01-23 14:13:43 +01:00
# clean up
2023-01-25 05:15:15 +01:00
delete = [ " parent " ]
2023-01-23 14:13:43 +01:00
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
2023-01-30 04:51:15 +01:00
get '/part?' do
halt 404 , " name required " unless params [ 'name' ]
part = get_part_by_name ( params [ 'name' ] )
halt 404 unless part
part . to_json
end
# search in names, description, and category
def search ( terms )
2023-01-25 11:58:17 +01:00
statements = [ ]
statements << @db . prepare ( " SELECT id FROM part WHERE name LIKE ? " )
2023-01-28 00:20:29 +01:00
statements << @db . prepare ( " SELECT id FROM part WHERE mpn LIKE ? " )
2023-01-25 11:58:17 +01:00
statements << @db . prepare ( " SELECT id FROM part WHERE description LIKE ? " )
2023-01-31 21:54:27 +01:00
statements << @db . prepare ( " SELECT properties.part AS id FROM properties JOIN property ON property.id = properties.property WHERE property.name = 'category' AND properties.value LIKE ? " )
2023-01-31 10:24:33 +01:00
children = @db . prepare ( " SELECT id FROM part WHERE family = ? " )
2023-01-25 11:58:17 +01:00
term_ids = [ ]
terms . each do | term |
ids = Set . new
# OR term location
statements . each do | statement |
statement . execute ( " % #{ term } % " ) . each do | row |
ids << row [ " id " ]
2023-01-31 10:24:33 +01:00
children . execute ( row [ " id " ] ) . each do | child |
ids << child [ " id " ]
end
2023-01-25 11:58:17 +01:00
end
end
term_ids << ids
end
# AND terms
ids = term_ids . shift
term_ids . each do | term_id |
ids & = term_id
end
2023-01-23 14:13:43 +01:00
parts = ids . collect { | id | get_part_by_id ( id ) }
parts . compact!
parts = parts [ 0 , PARTS_LIMIT ]
parts . sort! { | x , y | x [ " name " ] < = > y [ " name " ] }
2023-01-30 04:51:15 +01:00
end
get '/search/:terms' do
2023-01-31 10:12:11 +01:00
halt 429 if $searching
2023-01-30 04:51:15 +01:00
terms = params [ 'terms' ] . split ( " " )
terms . keep_if { | term | term . length > = 3 }
halt 400 if terms . empty?
2023-01-31 10:12:11 +01:00
$searching = true
2023-01-30 04:51:15 +01:00
parts = search ( terms )
2023-01-31 10:12:11 +01:00
$searching = false
2023-01-30 04:51:15 +01:00
parts . to_json
end
get '/search?' do
2023-01-31 10:12:11 +01:00
halt 429 if $searching
2023-01-30 04:51:15 +01:00
halt 400 , " terms needed " unless params [ 'terms' ]
terms = params [ 'terms' ] . split ( " " )
terms . keep_if { | term | term . length > = 3 }
halt 400 if terms . empty?
2023-01-31 10:12:11 +01:00
$searching = true
2023-01-30 04:51:15 +01:00
parts = search ( terms )
2023-01-31 10:12:11 +01:00
$searching = false
2023-01-23 14:13:43 +01:00
parts . to_json
end
2023-01-26 00:42:54 +01:00
def delete_part ( id )
# first delete all children
statement = @db . prepare ( " SELECT id FROM part WHERE family = ? " )
statement . execute ( id ) . each do | row |
puts " child: #{ row [ 'id' ] } "
delete_part ( row [ 'id' ] )
puts " deleted "
end
# delete all fields
statements = [ ]
2023-01-31 21:54:27 +01:00
statements << @db . prepare ( " DELETE FROM properties WHERE part = ? " )
2023-01-26 00:42:54 +01:00
statements << @db . prepare ( " DELETE FROM assembly WHERE assembled = ? " )
statements << @db . prepare ( " DELETE FROM assembly WHERE component = ? " )
statements << @db . prepare ( " DELETE FROM distribution WHERE part = ? " )
2023-01-31 21:54:27 +01:00
statements << @db . prepare ( " DELETE FROM properties WHERE part = ? " )
2023-01-26 00:42:54 +01:00
statements << @db . prepare ( " DELETE FROM inventory WHERE part = ? " )
statements << @db . prepare ( " DELETE FROM part WHERE id = ? " )
statements . each do | statement |
statement . execute ( id )
end
end
get '/delete/:id' do
statement = @db . prepare ( " SELECT id FROM part WHERE id = ? " )
result = statement . execute ( params [ 'id' ] )
halt 400 if result . to_a . empty?
delete_part ( params [ 'id' ] )
return 200
end
2023-01-27 02:04:03 +01:00
2023-01-29 09:07:09 +01:00
def add_part ( part )
2023-01-27 02:04:03 +01:00
if part [ " id " ] then
# ensure part to update exists
statement = @db . prepare ( " SELECT id FROM part WHERE id = ? " )
2023-02-01 01:46:40 +01:00
raise ScriptError . new ( " id not valid " ) if statement . execute ( part [ " id " ] ) . to_a . empty?
2023-01-27 02:04:03 +01:00
else
# add new part
2023-02-01 01:46:40 +01:00
raise ScriptError . new ( " name required " ) unless part [ " name " ] and part [ " name " ] . length > 0
2023-01-27 02:04:03 +01:00
statement = @db . prepare ( " SELECT id FROM part WHERE name = ? " )
2023-02-01 01:46:40 +01:00
raise ScriptError . new ( " name already existing " ) unless statement . execute ( part [ " name " ] ) . to_a . empty?
2023-01-27 02:04:03 +01:00
insert = @db . prepare ( " INSERT INTO part (name) VALUES (?) " ) ;
insert . execute ( part [ " name " ] )
part [ " id " ] = statement . execute ( part [ " name " ] ) . to_a [ 0 ] [ " id " ]
end
2023-01-31 00:06:09 +01:00
old_part = get_part_by_id ( part [ " id " ] )
2023-01-28 00:06:38 +01:00
# update family
family = nil
field = " family "
if part [ field ] then
2023-01-30 01:04:50 +01:00
if part [ field ] . empty? then
update = @db . prepare ( " UPDATE part SET #{ field } = NULL WHERE id = ? " )
update . execute ( part [ " id " ] )
else
statement = @db . prepare ( " SELECT id FROM part WHERE name = ? " )
family = statement . execute ( part [ field ] ) . to_a
2023-02-01 01:46:40 +01:00
raise ScriptError . new ( " family not existing " ) if family . empty?
2023-01-30 01:04:50 +01:00
update = @db . prepare ( " UPDATE part SET #{ field } = ? WHERE id = ? " )
update . execute ( family [ 0 ] [ " id " ] , part [ " id " ] )
family = get_part_by_id ( family [ 0 ] [ " id " ] )
end
2023-01-28 00:06:38 +01:00
end
2023-01-27 02:04:03 +01:00
# update fields
2023-01-29 10:09:42 +01:00
fields_txt = [ " name " , " description " , " details " , " mpn " , " package " , " datasheet " , " page " ] ;
2023-01-27 02:04:03 +01:00
fields_txt . each do | field |
2023-01-28 00:06:38 +01:00
next unless part [ field ]
2023-01-30 01:09:37 +01:00
if family and family [ field ] == part [ field ] then
update = @db . prepare ( " UPDATE part SET #{ field } = NULL WHERE id = ? " )
update . execute ( part [ " id " ] )
else
update = @db . prepare ( " UPDATE part SET #{ field } = ? WHERE id = ? " )
update . execute ( part [ field ] , part [ " id " ] )
end
2023-01-27 02:04:03 +01:00
end
# update manufacturer and package
2023-01-29 10:09:42 +01:00
field_ref = [ " manufacturer " ]
2023-01-27 02:04:03 +01:00
field_ref . each do | field |
2023-01-28 02:41:32 +01:00
next if family and family [ field ] == part [ field ]
2023-01-27 02:04:03 +01:00
if part [ field ] then
statement = @db . prepare ( " SELECT id FROM #{ field } WHERE LOWER(name) = ? " )
ref = statement . execute ( part [ field ] . downcase ) . to_a [ 0 ]
unless ref then
insert = @db . prepare ( " INSERT INTO #{ field } (name) VALUES (?) " ) ;
insert . execute ( part [ field ] )
end
2023-01-27 23:15:12 +01:00
ref = statement . execute ( part [ field ] . downcase ) . to_a [ 0 ]
2023-01-27 02:04:03 +01:00
update = @db . prepare ( " UPDATE part SET #{ field } = ? WHERE id = ? " )
update . execute ( ref [ " id " ] , part [ " id " ] )
else
update = @db . prepare ( " UPDATE part SET #{ field } = NULL WHERE id = ? " )
update . execute ( part [ " id " ] )
end
end
# update inventory
field = " location "
part [ field ] = nil if part [ field ] and 0 == part [ field ] . length
if part [ field ] then
2023-03-08 12:53:11 +01:00
delete = @db . prepare ( " DELETE FROM inventory WHERE part = ? " )
delete . execute ( part [ " id " ] )
2023-01-27 02:04:03 +01:00
statement = @db . prepare ( " SELECT id FROM #{ field } WHERE LOWER(name) = ? " )
ref = statement . execute ( part [ field ] . downcase ) . to_a [ 0 ]
unless ref then
insert = @db . prepare ( " INSERT INTO #{ field } (name) VALUES (?) " ) ;
insert . execute ( part [ field ] )
end
2023-01-27 23:15:12 +01:00
ref = statement . execute ( part [ field ] . downcase ) . to_a [ 0 ]
2023-01-27 02:04:03 +01:00
statement = @db . prepare ( " SELECT id FROM inventory WHERE part = ? AND location = ? " )
ref_inv = statement . execute ( part [ " id " ] , ref [ " id " ] ) . to_a [ 0 ]
unless ref_inv then
2023-01-30 12:12:40 +01:00
insert = @db . prepare ( " INSERT INTO inventory (part, location, quantity) VALUES (?,?,?) " )
2023-01-28 02:41:32 +01:00
insert . execute ( part [ " id " ] , ref [ " id " ] , part [ " stock " ] . to_i )
2023-01-27 02:04:03 +01:00
end
ref_inv = statement . execute ( part [ " id " ] , ref [ " id " ] ) . to_a [ 0 ]
update = @db . prepare ( " UPDATE inventory SET quantity = ? WHERE id = ? " )
update . execute ( part [ " stock " ] . to_i , ref_inv [ " id " ] )
else
delete = @db . prepare ( " DELETE FROM inventory WHERE part = ? " )
delete . execute ( part [ " id " ] )
end
2023-01-28 00:34:12 +01:00
# update distributors
field = " distributors "
part [ field ] = nil if part [ field ] and 0 == part [ field ] . length
delete = @db . prepare ( " DELETE FROM distribution WHERE part = ? " )
delete . execute ( part [ " id " ] )
if part [ field ] then
2023-01-30 12:12:40 +01:00
part [ field ] . each do | row |
next unless row [ " name " ] and ! row [ " name " ] . empty?
next unless row [ " sku " ] and ! row [ " sku " ] . empty?
2023-01-28 00:34:12 +01:00
statement = @db . prepare ( " SELECT id FROM distributor WHERE LOWER(name) = ? " )
2023-01-30 12:12:40 +01:00
ref = statement . execute ( row [ " name " ] . downcase ) . to_a [ 0 ]
unless ref then
insert = @db . prepare ( " INSERT INTO distributor (name) VALUES (?) " ) ;
insert . execute ( row [ " name " ] )
ref = statement . execute ( row [ " name " ] . downcase ) . to_a [ 0 ]
end
insert = @db . prepare ( " INSERT INTO distribution (distributor,part,sku) VALUES (?,?,?) " )
insert . execute ( ref [ " id " ] , part [ " id " ] , row [ " sku " ] )
2023-01-28 00:34:12 +01:00
end
end
2023-01-27 23:15:41 +01:00
# update properties
field = " properties "
if part [ field ] then
2023-01-31 21:54:27 +01:00
delete = @db . prepare ( " DELETE FROM properties WHERE part = ? " )
2023-01-30 04:18:56 +01:00
delete . execute ( part [ " id " ] )
2023-01-30 12:12:40 +01:00
part [ field ] . each do | row |
next unless row [ " name " ] and ! row [ " name " ] . empty?
next unless row [ " value " ] and ! row [ " value " ] . empty?
next if family and family [ " properties " ] and family [ " properties " ] . include? ( row )
2023-01-27 23:15:41 +01:00
statement = @db . prepare ( " SELECT id FROM property WHERE LOWER(name) = ? " )
2023-01-30 12:12:40 +01:00
ref = statement . execute ( row [ " name " ] . downcase ) . to_a [ 0 ]
2023-01-27 23:15:41 +01:00
unless ref then
insert = @db . prepare ( " INSERT INTO property (name) VALUES (?) " ) ;
2023-01-30 12:12:40 +01:00
insert . execute ( row [ " name " ] )
ref = statement . execute ( row [ " name " ] . downcase ) . to_a [ 0 ]
2023-01-27 23:15:41 +01:00
end
2023-01-31 21:54:27 +01:00
insert = @db . prepare ( " INSERT INTO properties (property,part,value) VALUES (?,?,?) " )
2023-01-30 12:12:40 +01:00
insert . execute ( ref [ " id " ] , part [ " id " ] , row [ " value " ] )
2023-01-27 23:15:41 +01:00
end
end
2023-01-30 04:18:56 +01:00
# update components
field = " components "
if part [ field ] then
delete = @db . prepare ( " DELETE FROM assembly WHERE assembled = ? " )
delete . execute ( part [ " id " ] )
2023-01-30 12:12:40 +01:00
part [ field ] . each do | row |
next unless row [ " name " ] and ! row [ " name " ] . empty?
next unless row [ " quantity " ]
2023-01-30 04:18:56 +01:00
statement = @db . prepare ( " SELECT id FROM part WHERE LOWER(name) = ? " )
2023-01-30 12:12:40 +01:00
ref = statement . execute ( row [ " name " ] . downcase ) . to_a [ 0 ]
2023-02-01 01:46:40 +01:00
#raise ScriptError.new("component #{name} does not exist") unless ref
2023-01-30 04:18:56 +01:00
next unless ref
2023-01-30 12:12:40 +01:00
row [ " quantity " ] || = 0
2023-01-30 04:18:56 +01:00
insert = @db . prepare ( " INSERT INTO assembly (assembled,component,quantity) VALUES (?,?,?) " ) ;
2023-01-30 12:12:40 +01:00
insert . execute ( part [ " id " ] , ref [ " id " ] , row [ " quantity " ] )
2023-01-30 04:18:56 +01:00
end
end
2023-01-31 00:06:09 +01:00
# update attachments
dir_old = PUBLIC + " / " + ATTACHMENTS + " / " + old_part [ " name " ] . gsub ( " / " , " _ " )
dir_new = PUBLIC + " / " + ATTACHMENTS + " / " + part [ " name " ] . gsub ( " / " , " _ " )
unless dir_old == dir_new then
File . rename ( dir_old , dir_new )
end
2023-01-29 09:07:09 +01:00
end
post '/part' do
request . body . rewind
begin
part = JSON . parse ( request . body . read )
rescue
halt 401 , " not json "
end
puts part if DEBUG
begin
add_part ( part )
2023-02-01 01:46:40 +01:00
rescue ScriptError = > e
2023-01-29 09:07:09 +01:00
halt 401 , e . message
end
2023-01-27 23:15:41 +01:00
return 200
2023-01-27 02:04:03 +01:00
end
2023-01-29 09:56:49 +01:00
get '/import/lcsc/:lcsc' do
halt 401 unless params [ 'lcsc' ] and params [ 'lcsc' ] =~ / ^C \ d+$ /i
uri = URI ( " https://wmsc.lcsc.com/wmsc/product/detail?productCode= #{ params [ 'lcsc' ] } " )
res = Net :: HTTP . get_response ( uri )
halt 401 , " could not get part " unless res . is_a? ( Net :: HTTPSuccess )
json = JSON . parse ( res . body )
#puts json
halt 401 , " part not found " unless 200 == json [ " code " ] and json [ " result " ]
result = json [ " result " ]
part = { }
part [ " name " ] = result [ " productModel " ]
part [ " mpn " ] = result [ " productModel " ]
part [ " description " ] = result [ " productDescEn " ]
part [ " details " ] = result [ " productIntroEn " ]
part [ " manufacturer " ] = result [ " brandNameEn " ]
2023-01-29 10:09:42 +01:00
part [ " package " ] = result [ " encapStandard " ]
2023-02-02 06:54:58 +01:00
part [ " distributors " ] = [ { " name " = > " LCSC " , " sku " = > result [ " productCode " ] } ]
2023-01-29 09:56:49 +01:00
part [ " attachments " ] = result [ " productImages " ]
part [ " datasheet " ] = result [ " pdfUrl " ]
existing = get_part_by_name ( part [ " name " ] )
2023-01-30 04:39:01 +01:00
halt 401 , " part #{ part [ 'name' ] } already exists " if existing
2023-01-29 09:56:49 +01:00
begin
add_part ( part )
2023-02-01 01:46:40 +01:00
rescue ScriptError = > e
2023-01-29 09:56:49 +01:00
halt 401 , e . message
end
i = 0
2023-01-30 00:38:28 +01:00
( part [ " attachments " ] + [ part [ " datasheet " ] ] ) . each do | attachment |
next unless attachment
file = attachment . split ( " / " ) [ - 1 ]
2023-01-30 04:37:35 +01:00
dir = PUBLIC + " / " + ATTACHMENTS + " / " + part [ " name " ] . gsub ( " / " , " _ " )
2023-01-29 09:56:49 +01:00
path = " #{ dir } / #{ i } _ #{ file } "
i += 1
unless File . file? ( path ) then
2023-01-30 00:38:28 +01:00
uri = URI ( attachment )
2023-01-29 09:56:49 +01:00
res = Net :: HTTP . get_response ( uri )
if ( res . is_a? ( Net :: HTTPSuccess ) ) then
Dir . mkdir ( dir ) unless File . directory? ( dir )
File . open ( path , " wb " ) do | f |
f . write res . body
end
end
end
end
2023-01-30 00:38:28 +01:00
return 200 , " #{ part [ 'name' ] } added "
2023-01-29 09:56:49 +01:00
end
2023-01-31 03:37:49 +01:00
get '/attach?' do
2023-03-26 15:39:53 +02:00
halt 400 , " part name or id required " unless params [ 'id' ] or params [ 'name' ]
halt 400 , " attachement URL required " unless params [ 'url' ]
2023-01-31 03:37:49 +01:00
statement = @db . prepare ( " SELECT id, name FROM part WHERE id = ? OR name = ? " )
part = statement . execute ( params [ 'id' ] , params [ 'name' ] ) . to_a [ 0 ]
2023-03-26 15:39:53 +02:00
halt 400 , " unknown part " unless part
2023-01-31 03:37:49 +01:00
file = CGI . unescape ( params [ 'url' ] ) . split ( " / " ) [ - 1 ]
dir = PUBLIC + " / " + ATTACHMENTS + " / " + part [ " name " ] . gsub ( " / " , " _ " )
path = " #{ dir } / #{ file } "
unless File . file? ( path ) then
uri = URI ( params [ 'url' ] )
res = Net :: HTTP . get_response ( uri )
if ( res . is_a? ( Net :: HTTPSuccess ) ) then
Dir . mkdir ( dir ) unless File . directory? ( dir )
File . open ( path , " wb " ) do | f |
f . write res . body
end
2023-03-26 15:39:53 +02:00
else
halt 404 , " download failed "
2023-01-31 03:37:49 +01:00
end
end
end