Initial commit
This commit is contained in:
5
.env
Normal file
5
.env
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
##########################
|
||||||
|
# Services
|
||||||
|
##########################
|
||||||
|
TREE_SOURCE_API_HOSTNAME=https://kf6xwyykee.execute-api.us-east-1.amazonaws.com/production
|
||||||
|
RESTCLIENT_LOG=stdout
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.sw?
|
||||||
12
Gemfile
Normal file
12
Gemfile
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
gem 'sinatra', "~> 2.0"
|
||||||
|
gem "retries", "~> 0.0.5"
|
||||||
|
|
||||||
|
gem "dotenv", "~> 2.5"
|
||||||
|
|
||||||
|
gem "rack-indifferent", "~> 1.2"
|
||||||
|
|
||||||
|
gem "sinatra-router", "~> 0.2.4"
|
||||||
|
|
||||||
|
gem "rest-client", "~> 2.0"
|
||||||
48
Gemfile.lock
Normal file
48
Gemfile.lock
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
domain_name (0.5.20180417)
|
||||||
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
|
dotenv (2.5.0)
|
||||||
|
http-cookie (1.0.3)
|
||||||
|
domain_name (~> 0.5)
|
||||||
|
mime-types (3.1)
|
||||||
|
mime-types-data (~> 3.2015)
|
||||||
|
mime-types-data (3.2016.0521)
|
||||||
|
mustermann (1.0.2)
|
||||||
|
netrc (0.11.0)
|
||||||
|
rack (2.0.5)
|
||||||
|
rack-indifferent (1.2.0)
|
||||||
|
rack (>= 1.5)
|
||||||
|
rack-protection (2.0.3)
|
||||||
|
rack
|
||||||
|
rest-client (2.0.2)
|
||||||
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
|
mime-types (>= 1.16, < 4.0)
|
||||||
|
netrc (~> 0.8)
|
||||||
|
retries (0.0.5)
|
||||||
|
sinatra (2.0.3)
|
||||||
|
mustermann (~> 1.0)
|
||||||
|
rack (~> 2.0)
|
||||||
|
rack-protection (= 2.0.3)
|
||||||
|
tilt (~> 2.0)
|
||||||
|
sinatra-router (0.2.4)
|
||||||
|
sinatra (>= 1.4, < 3.0)
|
||||||
|
tilt (2.0.8)
|
||||||
|
unf (0.1.4)
|
||||||
|
unf_ext
|
||||||
|
unf_ext (0.0.7.5)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
dotenv (~> 2.5)
|
||||||
|
rack-indifferent (~> 1.2)
|
||||||
|
rest-client (~> 2.0)
|
||||||
|
retries (~> 0.0.5)
|
||||||
|
sinatra (~> 2.0)
|
||||||
|
sinatra-router (~> 0.2.4)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.16.2
|
||||||
15
config.ru
Normal file
15
config.ru
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
require 'bundler/setup'
|
||||||
|
require 'dotenv/load'
|
||||||
|
require 'rack/indifferent'
|
||||||
|
require 'sinatra/router'
|
||||||
|
|
||||||
|
require_relative 'lib/api/tree.rb'
|
||||||
|
|
||||||
|
app = Sinatra::Router.new do
|
||||||
|
mount Pruning::API::Tree
|
||||||
|
end
|
||||||
|
|
||||||
|
map '/' do
|
||||||
|
run app
|
||||||
|
end
|
||||||
|
|
||||||
23
lib/api/app.rb
Normal file
23
lib/api/app.rb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
require 'json'
|
||||||
|
require 'sinatra/base'
|
||||||
|
require_relative '../http/query'
|
||||||
|
|
||||||
|
module Pruning
|
||||||
|
module API
|
||||||
|
class App < Sinatra::Base
|
||||||
|
before { content_type :json }
|
||||||
|
after { serialise_response }
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def serialise_response
|
||||||
|
return unless content_type == 'application/json'
|
||||||
|
response.body = [JSON(response.body)]
|
||||||
|
end
|
||||||
|
|
||||||
|
def query
|
||||||
|
Pruning::HTTP::Query.new(params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
17
lib/api/tree.rb
Normal file
17
lib/api/tree.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
require 'rest-client'
|
||||||
|
require_relative 'app'
|
||||||
|
require_relative '../repos/tree'
|
||||||
|
require_relative '../pruner'
|
||||||
|
|
||||||
|
module Pruning
|
||||||
|
module API
|
||||||
|
class Tree < App
|
||||||
|
get '/tree/:name' do
|
||||||
|
tree_repo = Pruning::Repos::Tree.new(RestClient, ENV['TREE_SOURCE_API_HOSTNAME'])
|
||||||
|
complete_tree = tree_repo.get(query.name)
|
||||||
|
pruner = Pruning::Processing::Pruner.new(complete_tree)
|
||||||
|
pruner.prune_tree(query.indicator_ids)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
18
lib/http/query.rb
Normal file
18
lib/http/query.rb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
module Pruning
|
||||||
|
module HTTP
|
||||||
|
class Query < Struct.new(:name, :indicator_ids)
|
||||||
|
def initialize(params = {})
|
||||||
|
values = members.map do |member|
|
||||||
|
value = params.fetch(member, nil)
|
||||||
|
next if value.nil?
|
||||||
|
case member
|
||||||
|
when :indicator_ids then value.map(&:to_i) # break on purpose if indicator_ids is not an array
|
||||||
|
when :name then value.to_s.gsub(/[^A-Za-z]/,'')
|
||||||
|
else value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
super(*values)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
32
lib/pruner.rb
Normal file
32
lib/pruner.rb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
module Pruning
|
||||||
|
module Processing
|
||||||
|
class Pruner
|
||||||
|
|
||||||
|
def initialize(tree, indicator_ids)
|
||||||
|
@tree = tree
|
||||||
|
end
|
||||||
|
|
||||||
|
def prune_tree(nodes, indicator_ids)
|
||||||
|
nodes.delete_if do |node|
|
||||||
|
unwanted_indicator = indicator_node?(node) && !indicator_ids.include?(node['id'])
|
||||||
|
has_no_wanted_indicators_in_children = prune_tree(children(node), indicator_ids)
|
||||||
|
|
||||||
|
unwanted_indicator && has_no_wanted_indicators_in_children
|
||||||
|
end
|
||||||
|
nodes.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def children(node)
|
||||||
|
node.get('sub-themes', false) ||
|
||||||
|
node.get('categories', false) ||
|
||||||
|
node.get('indicators', false) ||
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
def indicator_node?(node)
|
||||||
|
children(node).empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
24
lib/repos/tree.rb
Normal file
24
lib/repos/tree.rb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
require 'rest-client'
|
||||||
|
require 'retries'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
module Pruning
|
||||||
|
module Repos
|
||||||
|
class Tree
|
||||||
|
def initialize(client=RestClient, base_url)
|
||||||
|
@client = client
|
||||||
|
@base_url = base_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(name)
|
||||||
|
resp = @client.get(url(name))
|
||||||
|
JSON(resp.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def url(name)
|
||||||
|
"#{@base_url}/tree/#{name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user