search-kit 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/config/locales/en.yml +112 -3
- data/lib/search_kit.rb +5 -6
- data/lib/search_kit/cli.rb +45 -10
- data/lib/search_kit/cli/documents.rb +75 -0
- data/lib/search_kit/cli/events.rb +88 -0
- data/lib/search_kit/cli/indices.rb +96 -0
- data/lib/search_kit/cli/search.rb +60 -0
- data/lib/search_kit/cli/subscribers.rb +45 -0
- data/lib/search_kit/clients.rb +12 -0
- data/lib/search_kit/clients/documents.rb +71 -0
- data/lib/search_kit/clients/events.rb +77 -0
- data/lib/search_kit/clients/indices.rb +70 -0
- data/lib/search_kit/clients/keys.rb +78 -0
- data/lib/search_kit/clients/populate.rb +72 -0
- data/lib/search_kit/clients/scaffold.rb +36 -0
- data/lib/search_kit/clients/search.rb +33 -0
- data/lib/search_kit/clients/subscribers.rb +54 -0
- data/lib/search_kit/configuration.rb +0 -1
- data/lib/search_kit/errors.rb +4 -1
- data/lib/search_kit/messages.rb +41 -0
- data/lib/search_kit/messages/messaging.rb +64 -0
- data/lib/search_kit/models.rb +14 -0
- data/lib/search_kit/models/document.rb +30 -0
- data/lib/search_kit/models/documents.rb +31 -0
- data/lib/search_kit/models/event.rb +18 -0
- data/lib/search_kit/models/events.rb +31 -0
- data/lib/search_kit/models/key.rb +26 -0
- data/lib/search_kit/models/keys.rb +38 -0
- data/lib/search_kit/models/search.rb +17 -0
- data/lib/search_kit/models/subscriber.rb +26 -0
- data/lib/search_kit/polling.rb +30 -0
- data/lib/search_kit/polling/process.rb +40 -0
- data/lib/search_kit/thor.rb +12 -0
- data/lib/search_kit/version.rb +1 -1
- data/search-kit.gemspec +2 -0
- metadata +58 -20
- data/lib/search_kit/documents.rb +0 -59
- data/lib/search_kit/documents/cli.rb +0 -70
- data/lib/search_kit/events.rb +0 -59
- data/lib/search_kit/events/cli.rb +0 -52
- data/lib/search_kit/events/cli/complete.rb +0 -34
- data/lib/search_kit/events/cli/list.rb +0 -48
- data/lib/search_kit/events/cli/pending.rb +0 -48
- data/lib/search_kit/events/cli/publish.rb +0 -42
- data/lib/search_kit/events/cli/status.rb +0 -43
- data/lib/search_kit/events/poll.rb +0 -32
- data/lib/search_kit/events/poll/process.rb +0 -42
- data/lib/search_kit/events/publish.rb +0 -48
- data/lib/search_kit/indices.rb +0 -58
- data/lib/search_kit/indices/cli.rb +0 -65
- data/lib/search_kit/messaging.rb +0 -44
- data/lib/search_kit/search.rb +0 -30
- data/lib/search_kit/search/cli.rb +0 -49
- data/lib/search_kit/search/cli/actions.rb +0 -104
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module SearchKit
|
5
|
+
module Clients
|
6
|
+
class Scaffold
|
7
|
+
attr_reader :connection, :token
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
uri = [SearchKit.config.app_uri, "scaffold"].join("/")
|
11
|
+
@connection = Faraday.new(uri)
|
12
|
+
@token = SearchKit.config.app_token
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(name, documents)
|
16
|
+
options = {
|
17
|
+
token: token,
|
18
|
+
data: {
|
19
|
+
type: 'indices',
|
20
|
+
attributes: { name: name },
|
21
|
+
relationships: { documents: documents }
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
response = connection.post('', options)
|
26
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
27
|
+
|
28
|
+
fail Errors::BadRequest if response.status == 400
|
29
|
+
fail Errors::Unauthorized if response.status == 401
|
30
|
+
fail Errors::Unprocessable if response.status == 422
|
31
|
+
|
32
|
+
body
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module SearchKit
|
5
|
+
module Clients
|
6
|
+
class Search
|
7
|
+
attr_reader :connection, :token
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
uri = [SearchKit.config.app_uri, "search"].join("/")
|
11
|
+
@connection = Faraday.new(uri)
|
12
|
+
@token = SearchKit.config.app_token
|
13
|
+
end
|
14
|
+
|
15
|
+
def search(slug, options)
|
16
|
+
params = {
|
17
|
+
token: token, data: { type: "searches", attributes: options }
|
18
|
+
}
|
19
|
+
|
20
|
+
response = connection.post(slug, params)
|
21
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
22
|
+
|
23
|
+
fail Errors::BadRequest if response.status == 400
|
24
|
+
fail Errors::Unauthorized if response.status == 401
|
25
|
+
fail Errors::IndexNotFound if response.status == 404
|
26
|
+
fail Errors::Unprocessable if response.status == 422
|
27
|
+
|
28
|
+
SearchKit::Models::Search.new(body.fetch(:data, {}))
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module SearchKit
|
5
|
+
module Clients
|
6
|
+
class Subscribers
|
7
|
+
attr_reader :connection, :token
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
uri = [ SearchKit.config.app_uri, "subscribers" ].join("/")
|
11
|
+
@connection = Faraday.new(uri)
|
12
|
+
@token = SearchKit.config.app_token
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(options = {})
|
16
|
+
options = { data: { type: 'subscribers', attributes: options } }
|
17
|
+
response = connection.post("", options)
|
18
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
19
|
+
|
20
|
+
fail Errors::BadRequest if response.status == 400
|
21
|
+
fail Errors::Unprocessable if response.status == 422
|
22
|
+
|
23
|
+
SearchKit::Models::Subscriber.new body.fetch(:data, {})
|
24
|
+
end
|
25
|
+
|
26
|
+
def info
|
27
|
+
response = connection.get("", token: token)
|
28
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
29
|
+
|
30
|
+
fail Errors::Unauthorized if response.status == 401
|
31
|
+
fail Errors::SubscriberNotFound if response.status == 404
|
32
|
+
|
33
|
+
SearchKit::Models::Subscriber.new body.fetch(:data, {})
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(options = {})
|
37
|
+
options = {
|
38
|
+
token: token, data: { type: 'subscribers', attributes: options }
|
39
|
+
}
|
40
|
+
|
41
|
+
response = connection.patch("", options)
|
42
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
43
|
+
|
44
|
+
fail Errors::BadRequest if response.status == 400
|
45
|
+
fail Errors::Unauthorized if response.status == 401
|
46
|
+
fail Errors::SubscriberNotFound if response.status == 404
|
47
|
+
fail Errors::Unprocessable if response.status == 422
|
48
|
+
|
49
|
+
SearchKit::Models::Subscriber.new body.fetch(:data, {})
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/search_kit/errors.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module SearchKit
|
2
2
|
module Errors
|
3
3
|
class BadRequest < StandardError; end
|
4
|
+
class EventNotFound < StandardError; end
|
4
5
|
class IndexNotFound < StandardError; end
|
6
|
+
class KeyNotFound < StandardError; end
|
5
7
|
class PublicationFailed < StandardError; end
|
6
|
-
class
|
8
|
+
class SubscriberNotFound < StandardError; end
|
9
|
+
class Unauthorized < StandardError; end
|
7
10
|
class Unprocessable < StandardError; end
|
8
11
|
end
|
9
12
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'ansi'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Messages
|
5
|
+
autoload :Messaging, 'search_kit/messages/messaging'
|
6
|
+
|
7
|
+
include Messaging
|
8
|
+
|
9
|
+
def unauthorized
|
10
|
+
warning(I18n.t('http.401'))
|
11
|
+
end
|
12
|
+
|
13
|
+
def bad_request
|
14
|
+
warning(I18n.t('http.400'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def not_found(type = 'Resource')
|
18
|
+
message = I18n.t('http.404', type: type)
|
19
|
+
warning(message)
|
20
|
+
end
|
21
|
+
|
22
|
+
def json_parse_error(type = 'Argument')
|
23
|
+
message = I18n.t('cli.errors.json_parse', type: type)
|
24
|
+
warning(message)
|
25
|
+
end
|
26
|
+
|
27
|
+
def no_service
|
28
|
+
message = I18n.t('cli.errors.no_service', uri: SearchKit.config.app_uri)
|
29
|
+
warning(message)
|
30
|
+
end
|
31
|
+
|
32
|
+
def unprocessable
|
33
|
+
warning(I18n.t('http.422'))
|
34
|
+
end
|
35
|
+
|
36
|
+
def unreadable(error)
|
37
|
+
warning(I18n.t('cli.errors.unreadable', error: error))
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'ansi'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
class Messages
|
5
|
+
# The goal of the Messaging module is to provide an easy to include internal
|
6
|
+
# interface which will allow a SearchKit gem to dutifully log and provide
|
7
|
+
# output of what it's up to and how it may be doing.
|
8
|
+
#
|
9
|
+
module Messaging
|
10
|
+
def info(message)
|
11
|
+
Message.new(message).info
|
12
|
+
end
|
13
|
+
|
14
|
+
def warning(message)
|
15
|
+
Message.new(message).warn
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# Most of the logic for the Messaging module exists in this (not so)
|
21
|
+
# private class. This lets more complex handling of message logic enter
|
22
|
+
# into the module gracefully, for example silence or logging level.
|
23
|
+
#
|
24
|
+
class Message
|
25
|
+
attr_reader :message
|
26
|
+
|
27
|
+
def initialize(message)
|
28
|
+
@message = message
|
29
|
+
end
|
30
|
+
|
31
|
+
def warn
|
32
|
+
Kernel.warn(Prefixed(message.ansi(:red))) if SearchKit.config.verbose
|
33
|
+
SearchKit.logger.warn message
|
34
|
+
end
|
35
|
+
|
36
|
+
def info
|
37
|
+
Kernel.puts(Prefixed(message.ansi(:cyan))) if SearchKit.config.verbose
|
38
|
+
SearchKit.logger.info message
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def Prefixed(*messages)
|
44
|
+
Prefixed.new.join(*messages)
|
45
|
+
end
|
46
|
+
|
47
|
+
class Prefixed
|
48
|
+
attr_reader :body
|
49
|
+
|
50
|
+
def initialize
|
51
|
+
env = SearchKit.config.app_env.to_s.ansi(:magenta)
|
52
|
+
@body = "--> [ #{env} ]: "
|
53
|
+
end
|
54
|
+
|
55
|
+
def join(*messages)
|
56
|
+
[body, *messages].join(" ")
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
module Models
|
5
|
+
autoload :Document, 'search_kit/models/document'
|
6
|
+
autoload :Documents, 'search_kit/models/documents'
|
7
|
+
autoload :Event, 'search_kit/models/event'
|
8
|
+
autoload :Events, 'search_kit/models/events'
|
9
|
+
autoload :Key, 'search_kit/models/key'
|
10
|
+
autoload :Keys, 'search_kit/models/keys'
|
11
|
+
autoload :Search, 'search_kit/models/search'
|
12
|
+
autoload :Subscriber, 'search_kit/models/subscriber'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SearchKit
|
2
|
+
module Models
|
3
|
+
class Document
|
4
|
+
class AttributeNotFound < StandardError; end
|
5
|
+
|
6
|
+
include Virtus.model
|
7
|
+
|
8
|
+
attribute :id
|
9
|
+
attribute :source
|
10
|
+
attribute :score
|
11
|
+
|
12
|
+
def initialize(document_data = {})
|
13
|
+
attributes = document_data.fetch(:attributes, {})
|
14
|
+
|
15
|
+
super(
|
16
|
+
source: attributes,
|
17
|
+
id: attributes.fetch(:id, nil),
|
18
|
+
score: attributes.fetch(:score, nil)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get(field)
|
23
|
+
source.fetch(field.to_sym)
|
24
|
+
rescue KeyError
|
25
|
+
fail AttributeNotFound, field
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SearchKit
|
2
|
+
module Models
|
3
|
+
class Documents
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def self.[](*arguments)
|
7
|
+
new(arguments)
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :contents, :member_class
|
11
|
+
|
12
|
+
def initialize(contents = [])
|
13
|
+
@contents = contents
|
14
|
+
@member_class = SearchKit::Models::Document
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(new_doc)
|
18
|
+
case new_doc
|
19
|
+
when Hash then contents << member_class.new(new_doc)
|
20
|
+
when member_class then contents << new_doc
|
21
|
+
else contents
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def each(&block)
|
26
|
+
contents.each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SearchKit
|
2
|
+
module Models
|
3
|
+
class Event
|
4
|
+
include Virtus.model
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :channel
|
8
|
+
attribute :state
|
9
|
+
attribute :payload, Hash
|
10
|
+
|
11
|
+
def initialize(event_data = {})
|
12
|
+
attributes = event_data.fetch(:attributes, {})
|
13
|
+
super(attributes)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SearchKit
|
2
|
+
module Models
|
3
|
+
class Events
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def self.[](*arguments)
|
7
|
+
new(arguments)
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :contents, :member_class
|
11
|
+
|
12
|
+
def initialize(contents = [])
|
13
|
+
@contents = contents
|
14
|
+
@member_class = SearchKit::Models::Event
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(new_event)
|
18
|
+
case new_event
|
19
|
+
when Hash then contents << member_class.new(new_event)
|
20
|
+
when member_class then contents << new_event
|
21
|
+
else contents
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def each(&block)
|
26
|
+
contents.each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
|
3
|
+
module SearchKit
|
4
|
+
module Models
|
5
|
+
class Key
|
6
|
+
include Virtus.model
|
7
|
+
|
8
|
+
attribute :id, String
|
9
|
+
attribute :name, String
|
10
|
+
attribute :privilege, String
|
11
|
+
attribute :token, String
|
12
|
+
attribute :uri, String
|
13
|
+
|
14
|
+
def initialize(key_data = {})
|
15
|
+
attributes = key_data.fetch(:attributes, {})
|
16
|
+
uri = key_data.fetch(:links, {}).fetch(:self, '')
|
17
|
+
|
18
|
+
super(attributes.merge(uri: uri))
|
19
|
+
end
|
20
|
+
|
21
|
+
def creator?
|
22
|
+
privilege == 'creator'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SearchKit
|
2
|
+
module Models
|
3
|
+
class Keys
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def self.[](*arguments)
|
7
|
+
new(arguments)
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :contents, :member_class
|
11
|
+
|
12
|
+
def initialize(contents = [])
|
13
|
+
@contents = contents
|
14
|
+
@member_class = SearchKit::Models::Key
|
15
|
+
end
|
16
|
+
|
17
|
+
def <<(new_key)
|
18
|
+
case new_key
|
19
|
+
when Hash then contents << member_class.new(new_key)
|
20
|
+
when member_class then contents << new_key
|
21
|
+
else contents
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def each(&block)
|
26
|
+
contents.each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def creator
|
30
|
+
self.class.new(select(&:creator?))
|
31
|
+
end
|
32
|
+
|
33
|
+
def tokens
|
34
|
+
contents.map(&:token)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|