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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/config/locales/en.yml +112 -3
  4. data/lib/search_kit.rb +5 -6
  5. data/lib/search_kit/cli.rb +45 -10
  6. data/lib/search_kit/cli/documents.rb +75 -0
  7. data/lib/search_kit/cli/events.rb +88 -0
  8. data/lib/search_kit/cli/indices.rb +96 -0
  9. data/lib/search_kit/cli/search.rb +60 -0
  10. data/lib/search_kit/cli/subscribers.rb +45 -0
  11. data/lib/search_kit/clients.rb +12 -0
  12. data/lib/search_kit/clients/documents.rb +71 -0
  13. data/lib/search_kit/clients/events.rb +77 -0
  14. data/lib/search_kit/clients/indices.rb +70 -0
  15. data/lib/search_kit/clients/keys.rb +78 -0
  16. data/lib/search_kit/clients/populate.rb +72 -0
  17. data/lib/search_kit/clients/scaffold.rb +36 -0
  18. data/lib/search_kit/clients/search.rb +33 -0
  19. data/lib/search_kit/clients/subscribers.rb +54 -0
  20. data/lib/search_kit/configuration.rb +0 -1
  21. data/lib/search_kit/errors.rb +4 -1
  22. data/lib/search_kit/messages.rb +41 -0
  23. data/lib/search_kit/messages/messaging.rb +64 -0
  24. data/lib/search_kit/models.rb +14 -0
  25. data/lib/search_kit/models/document.rb +30 -0
  26. data/lib/search_kit/models/documents.rb +31 -0
  27. data/lib/search_kit/models/event.rb +18 -0
  28. data/lib/search_kit/models/events.rb +31 -0
  29. data/lib/search_kit/models/key.rb +26 -0
  30. data/lib/search_kit/models/keys.rb +38 -0
  31. data/lib/search_kit/models/search.rb +17 -0
  32. data/lib/search_kit/models/subscriber.rb +26 -0
  33. data/lib/search_kit/polling.rb +30 -0
  34. data/lib/search_kit/polling/process.rb +40 -0
  35. data/lib/search_kit/thor.rb +12 -0
  36. data/lib/search_kit/version.rb +1 -1
  37. data/search-kit.gemspec +2 -0
  38. metadata +58 -20
  39. data/lib/search_kit/documents.rb +0 -59
  40. data/lib/search_kit/documents/cli.rb +0 -70
  41. data/lib/search_kit/events.rb +0 -59
  42. data/lib/search_kit/events/cli.rb +0 -52
  43. data/lib/search_kit/events/cli/complete.rb +0 -34
  44. data/lib/search_kit/events/cli/list.rb +0 -48
  45. data/lib/search_kit/events/cli/pending.rb +0 -48
  46. data/lib/search_kit/events/cli/publish.rb +0 -42
  47. data/lib/search_kit/events/cli/status.rb +0 -43
  48. data/lib/search_kit/events/poll.rb +0 -32
  49. data/lib/search_kit/events/poll/process.rb +0 -42
  50. data/lib/search_kit/events/publish.rb +0 -48
  51. data/lib/search_kit/indices.rb +0 -58
  52. data/lib/search_kit/indices/cli.rb +0 -65
  53. data/lib/search_kit/messaging.rb +0 -44
  54. data/lib/search_kit/search.rb +0 -30
  55. data/lib/search_kit/search/cli.rb +0 -49
  56. 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
@@ -1,6 +1,5 @@
1
1
  require 'ostruct'
2
2
  require 'yaml'
3
- require 'uri'
4
3
  require 'user_config'
5
4
 
6
5
  module SearchKit
@@ -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 EventNotFound < StandardError; end
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