search-kit 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +39 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +21 -0
- data/Rakefile +6 -0
- data/bin/search-kit +7 -0
- data/config/locales/en.yml +6 -0
- data/lib/search_kit.rb +41 -0
- data/lib/search_kit/cli.rb +21 -0
- data/lib/search_kit/client.rb +9 -0
- data/lib/search_kit/configuration.rb +17 -0
- data/lib/search_kit/documents.rb +58 -0
- data/lib/search_kit/documents/cli.rb +70 -0
- data/lib/search_kit/errors.rb +9 -0
- data/lib/search_kit/events.rb +57 -0
- data/lib/search_kit/events/cli.rb +52 -0
- data/lib/search_kit/events/cli/complete.rb +34 -0
- data/lib/search_kit/events/cli/list.rb +48 -0
- data/lib/search_kit/events/cli/pending.rb +48 -0
- data/lib/search_kit/events/cli/publish.rb +42 -0
- data/lib/search_kit/events/cli/status.rb +43 -0
- data/lib/search_kit/events/publish.rb +48 -0
- data/lib/search_kit/indices.rb +57 -0
- data/lib/search_kit/indices/cli.rb +65 -0
- data/lib/search_kit/logger.rb +31 -0
- data/lib/search_kit/messaging.rb +44 -0
- data/lib/search_kit/search.rb +29 -0
- data/lib/search_kit/search/cli.rb +49 -0
- data/lib/search_kit/search/cli/actions.rb +104 -0
- data/lib/search_kit/version.rb +20 -0
- data/scripts/console +7 -0
- data/search-kit.gemspec +41 -0
- metadata +236 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'ansi'
|
3
|
+
|
4
|
+
module SearchKit
|
5
|
+
class Events
|
6
|
+
class CLI < Thor
|
7
|
+
autoload :Complete, 'search_kit/events/cli/complete'
|
8
|
+
autoload :List, 'search_kit/events/cli/list'
|
9
|
+
autoload :Pending, 'search_kit/events/cli/pending'
|
10
|
+
autoload :Publish, 'search_kit/events/cli/publish'
|
11
|
+
autoload :Status, 'search_kit/events/cli/status'
|
12
|
+
|
13
|
+
include Messaging
|
14
|
+
|
15
|
+
namespace :events
|
16
|
+
|
17
|
+
desc "complete ID", "Complete event for a given ID"
|
18
|
+
def complete(id)
|
19
|
+
Complete.new(client, id).perform
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "pending", "Get all pending events, --channel to filter by channel"
|
23
|
+
option :channel, aliases: ['-c']
|
24
|
+
def pending
|
25
|
+
channel = options.fetch('channel', nil)
|
26
|
+
if channel
|
27
|
+
Pending.new(client, channel).perform
|
28
|
+
else
|
29
|
+
List.new(client).perform
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "publish CHANNEL", "Publish an event to CHANNEL"
|
34
|
+
option :payload, aliases: ['-p'], type: :hash, required: true
|
35
|
+
def publish(channel)
|
36
|
+
Publish.new(client, channel, options).perform
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "status ID", "Check status of a specific event ID"
|
40
|
+
def status(id)
|
41
|
+
Status.new(client, id).perform
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def client
|
47
|
+
@client ||= Events.new
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Events
|
5
|
+
class CLI < Thor
|
6
|
+
# An extraction of the CLI command, "complete".
|
7
|
+
#
|
8
|
+
class Complete
|
9
|
+
include Messaging
|
10
|
+
|
11
|
+
attr_reader :client, :id
|
12
|
+
|
13
|
+
def initialize(client, id)
|
14
|
+
@client = client
|
15
|
+
@id = id
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform
|
19
|
+
client.complete(id)
|
20
|
+
|
21
|
+
info "Event #{id} completed"
|
22
|
+
rescue Errors::EventNotFound
|
23
|
+
warning "No event found for #{id}"
|
24
|
+
rescue Faraday::ConnectionFailed
|
25
|
+
warning "Remote events service not found"
|
26
|
+
rescue JSON::ParserError => error
|
27
|
+
warning "Response unreadable: #{error}"
|
28
|
+
error.backtrace.each(&method(:warning))
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Events
|
5
|
+
class CLI < Thor
|
6
|
+
# An extraction of the CLI command, "pending". When the pending comand
|
7
|
+
# is not given any parameters, it looks for all pending events despite
|
8
|
+
# of channel - or in other words, the index of events.
|
9
|
+
#
|
10
|
+
class List
|
11
|
+
include Messaging
|
12
|
+
|
13
|
+
attr_reader :client
|
14
|
+
|
15
|
+
def initialize(client)
|
16
|
+
@client = client
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform
|
20
|
+
report_events
|
21
|
+
rescue Faraday::ConnectionFailed
|
22
|
+
warning "Remote events service not found"
|
23
|
+
rescue JSON::ParserError => error
|
24
|
+
warning "Response unreadable: #{error}"
|
25
|
+
error.backtrace.each(&method(:warning))
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def report_events
|
31
|
+
if events.any?
|
32
|
+
info "Pending events:"
|
33
|
+
events.each { |event| info(event.to_json) }
|
34
|
+
else
|
35
|
+
info "No pending events found"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def events
|
40
|
+
return @events if @events
|
41
|
+
response = client.index
|
42
|
+
@events = response.fetch(:data, [])
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Events
|
5
|
+
class CLI < Thor
|
6
|
+
# An extraction of the CLI command, "list", when given the `channel`
|
7
|
+
# option.
|
8
|
+
#
|
9
|
+
class Pending
|
10
|
+
include Messaging
|
11
|
+
|
12
|
+
attr_reader :client, :channel
|
13
|
+
|
14
|
+
def initialize(client, channel = nil)
|
15
|
+
@client = client
|
16
|
+
@channel = channel
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform
|
20
|
+
report_events
|
21
|
+
rescue Faraday::ConnectionFailed
|
22
|
+
warning "Remote events service not found"
|
23
|
+
rescue JSON::ParserError => error
|
24
|
+
warning "Response unreadable: #{error}"
|
25
|
+
error.backtrace.each(&method(:warning))
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def report_events
|
31
|
+
if events.any?
|
32
|
+
info "Pending events for channel `#{channel}`:"
|
33
|
+
events.each { |event| info(event.to_json) }
|
34
|
+
else
|
35
|
+
info "No pending events found for channel `#{channel}`"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def events
|
40
|
+
return @events if @events
|
41
|
+
response = client.pending(channel)
|
42
|
+
@events = response.fetch(:data, [])
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Events
|
5
|
+
class CLI < Thor
|
6
|
+
# An extraction of the CLI command, "publish".
|
7
|
+
#
|
8
|
+
class Publish
|
9
|
+
include Messaging
|
10
|
+
|
11
|
+
attr_reader :client, :channel, :payload
|
12
|
+
|
13
|
+
def initialize(client, channel, options = {})
|
14
|
+
@client = client
|
15
|
+
@channel = channel
|
16
|
+
@payload = options.fetch('payload', {})
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform
|
20
|
+
info "Event published, status @ #{status_uri}"
|
21
|
+
rescue Faraday::ConnectionFailed
|
22
|
+
warning "Remote events service not found"
|
23
|
+
rescue Errors::PublicationFailed => error
|
24
|
+
warning "Publication failed: #{error}"
|
25
|
+
rescue JSON::ParserError => error
|
26
|
+
warning "Response unreadable: #{error}"
|
27
|
+
error.backtrace.each(&method(:warning))
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def status_uri
|
33
|
+
return @status_uri if @status_uri
|
34
|
+
response = client.publish(channel, payload)
|
35
|
+
links = response.fetch(:data, {}).fetch(:links, {})
|
36
|
+
@status_uri = links.fetch(:self, '')
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Events
|
5
|
+
class CLI < Thor
|
6
|
+
# An extraction of the CLI command, "all".
|
7
|
+
#
|
8
|
+
class Status
|
9
|
+
include Messaging
|
10
|
+
|
11
|
+
attr_reader :client, :id
|
12
|
+
|
13
|
+
def initialize(client, id)
|
14
|
+
@client = client
|
15
|
+
@id = id
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform
|
19
|
+
info "Event #{id} status: #{status}"
|
20
|
+
rescue Errors::EventNotFound
|
21
|
+
warning "No event found for #{id}"
|
22
|
+
rescue Faraday::ConnectionFailed
|
23
|
+
warning "Remote events service not found"
|
24
|
+
rescue JSON::ParserError => error
|
25
|
+
warning "Response unreadable: #{error}"
|
26
|
+
error.backtrace.each(&method(:warning))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def status
|
32
|
+
response = client.show(id)
|
33
|
+
|
34
|
+
response
|
35
|
+
.fetch(:data, {})
|
36
|
+
.fetch(:attributes, {})
|
37
|
+
.fetch(:state, '')
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SearchKit
|
2
|
+
class Events
|
3
|
+
# An extraction of the publication client action, which contains a certain
|
4
|
+
# amount of logic in handling success/failure, parameter building and
|
5
|
+
# API interaction.
|
6
|
+
#
|
7
|
+
class Publish
|
8
|
+
SUCCESS = 202
|
9
|
+
|
10
|
+
attr_reader :channel, :connection, :payload
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@connection = options.fetch(:connection)
|
14
|
+
@channel = options.fetch(:channel)
|
15
|
+
@payload = options.fetch(:payload)
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform
|
19
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
20
|
+
|
21
|
+
if success?
|
22
|
+
body
|
23
|
+
else
|
24
|
+
fail Errors::PublicationFailed, body.fetch(:error)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def success?
|
31
|
+
response.status == SUCCESS
|
32
|
+
end
|
33
|
+
|
34
|
+
def response
|
35
|
+
@response ||= connection.post("/api/events", params)
|
36
|
+
end
|
37
|
+
|
38
|
+
def params
|
39
|
+
{
|
40
|
+
type: 'events',
|
41
|
+
data: { attributes: { channel: channel, payload: payload } }
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module SearchKit
|
6
|
+
class Indices
|
7
|
+
autoload :CLI, 'search_kit/indices/cli'
|
8
|
+
|
9
|
+
attr_reader :connection
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@connection = SearchKit::Client.connection
|
13
|
+
end
|
14
|
+
|
15
|
+
def show(slug)
|
16
|
+
response = connection.get(slug)
|
17
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
18
|
+
|
19
|
+
fail Errors::IndexNotFound if response.status == 404
|
20
|
+
|
21
|
+
body
|
22
|
+
end
|
23
|
+
|
24
|
+
def create(name)
|
25
|
+
options = { data: { type: 'indices', attributes: { name: name } } }
|
26
|
+
response = connection.post('/', options)
|
27
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
28
|
+
|
29
|
+
fail Errors::Unprocessable if response.status == 422
|
30
|
+
fail Errors::BadRequest if response.status == 400
|
31
|
+
|
32
|
+
body
|
33
|
+
end
|
34
|
+
|
35
|
+
def update(slug, options)
|
36
|
+
options = { data: { type: 'indices', attributes: options } }
|
37
|
+
response = connection.patch(slug, options)
|
38
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
39
|
+
|
40
|
+
fail Errors::BadRequest if response.status == 400
|
41
|
+
fail Errors::IndexNotFound if response.status == 404
|
42
|
+
fail Errors::Unprocessable if response.status == 422
|
43
|
+
|
44
|
+
body
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete(slug)
|
48
|
+
response = connection.delete(slug)
|
49
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
50
|
+
|
51
|
+
fail Errors::IndexNotFound if response.status == 404
|
52
|
+
|
53
|
+
body
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Indices
|
5
|
+
class CLI < Thor
|
6
|
+
include Messaging
|
7
|
+
|
8
|
+
namespace :indices
|
9
|
+
|
10
|
+
desc "show slug", "View an index"
|
11
|
+
def show(slug)
|
12
|
+
response = client.show(slug)
|
13
|
+
info response.to_json
|
14
|
+
rescue Errors::IndexNotFound
|
15
|
+
warning "No index for that slug found"
|
16
|
+
rescue Faraday::ConnectionFailed
|
17
|
+
warning "No running service found"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "create NAME", "Create an index"
|
21
|
+
def create(name)
|
22
|
+
response = client.create(name)
|
23
|
+
info response.to_json
|
24
|
+
rescue Errors::BadRequest
|
25
|
+
warning "Bad create request"
|
26
|
+
rescue Errors::Unprocessable
|
27
|
+
warning "Options given unprocessable"
|
28
|
+
rescue Faraday::ConnectionFailed
|
29
|
+
warning "No running service found"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "update SLUG", "Update an index"
|
33
|
+
option :name
|
34
|
+
def update(slug)
|
35
|
+
response = client.update(slug, options)
|
36
|
+
info response.to_json
|
37
|
+
rescue Errors::BadRequest
|
38
|
+
warning "Bad update request"
|
39
|
+
rescue Errors::IndexNotFound
|
40
|
+
warning "No index for that slug found"
|
41
|
+
rescue Errors::Unprocessable
|
42
|
+
warning "Options given unprocessable"
|
43
|
+
rescue Faraday::ConnectionFailed
|
44
|
+
warning "No running service found"
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "archive SLUG", "Archive an index"
|
48
|
+
def archive(slug)
|
49
|
+
response = client.delete(slug)
|
50
|
+
info response.to_json
|
51
|
+
rescue Errors::IndexNotFound
|
52
|
+
warning "No index for that slug found"
|
53
|
+
rescue Faraday::ConnectionFailed
|
54
|
+
warning "No running service found"
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def client
|
60
|
+
@client ||= Indices.new
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|