power-compass 0.7.0 → 0.9.0
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/app/controllers/compass/search_controller.rb +9 -48
- data/config/routes.rb +1 -6
- data/lib/compass/json_formatter.rb +9 -9
- data/lib/compass/search/provider.rb +16 -91
- data/lib/compass/search.rb +29 -0
- data/lib/compass/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac4e50196da52d39be29790e8e91a2b31ce1900a2c8f368aa46e03c6725a3fb4
|
|
4
|
+
data.tar.gz: 922ee98c74a56863508b782944dbe2c72a2b0fc2755bda59429f249c938fc528
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '08022669193bfc3cfb81ee90cae999688010b00f916512c6c7e0949684adf07df7a3f0433d3ab4624190478c86785d2f3e5bc9d95e3484f89d68ece3b169ca3e'
|
|
7
|
+
data.tar.gz: 52fce33d8d2101daef6167250e1d258bf3bc5149267970ee7a85e44ea8ab7078dc2e2813a8262994a149a2547d9db1a74e508d992fbacbfe79ee01972ad28a7f
|
|
@@ -6,60 +6,21 @@ module Compass
|
|
|
6
6
|
include Cors
|
|
7
7
|
|
|
8
8
|
def index
|
|
9
|
-
|
|
10
|
-
results = Compass::Search::Provider.global_search(params.require(:q), current_context)
|
|
11
|
-
render json: { results: results }
|
|
12
|
-
else
|
|
13
|
-
providers
|
|
14
|
-
end
|
|
9
|
+
render json: Compass::Search.providers
|
|
15
10
|
end
|
|
16
11
|
|
|
17
12
|
def show
|
|
18
|
-
|
|
19
|
-
render json: {
|
|
20
|
-
provider: params[:provider_name],
|
|
21
|
-
context_id: params[:context_id],
|
|
22
|
-
**result
|
|
23
|
-
}
|
|
13
|
+
render json: Compass::Search.search(params[:q], params[:provider_name], current_context)
|
|
24
14
|
rescue Compass::Search::UnknownProvider => error
|
|
25
|
-
render json: {
|
|
15
|
+
render status: :not_found, json: {
|
|
26
16
|
error: error.message,
|
|
27
|
-
available_providers:
|
|
28
|
-
}, status: :not_found
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def providers
|
|
32
|
-
render json: {
|
|
33
|
-
context_id: params[:context_id],
|
|
34
|
-
providers: available_provider_names.map do |name|
|
|
35
|
-
provider_class = find_provider_by_name(name)
|
|
36
|
-
|
|
37
|
-
base_info = {
|
|
38
|
-
name: name,
|
|
39
|
-
class_name: provider_class&.name
|
|
40
|
-
}
|
|
41
|
-
begin
|
|
42
|
-
label = provider_class&.new(**current_context)&.label || name.humanize
|
|
43
|
-
base_info.merge(label: label)
|
|
44
|
-
rescue => e
|
|
45
|
-
Rails.logger.warn "Error getting provider info for #{name}: #{e.message}"
|
|
46
|
-
base_info.merge(
|
|
47
|
-
label: name.humanize,
|
|
48
|
-
error: e.message
|
|
49
|
-
)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
17
|
+
available_providers: Compass::Search.providers.map(&:name)
|
|
52
18
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Compass::Search::Provider.find_by_name(name)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def available_provider_names
|
|
62
|
-
Compass::Search::Provider.available_provider_names
|
|
19
|
+
rescue => error
|
|
20
|
+
Compass.logger&.error(
|
|
21
|
+
"[ Compass::SearchController ] #{params[:provider_name]}: #{error.class}: #{error.message} | Query: #{params[:q].inspect}"
|
|
22
|
+
)
|
|
23
|
+
raise
|
|
63
24
|
end
|
|
64
25
|
end
|
|
65
26
|
end
|
data/config/routes.rb
CHANGED
|
@@ -7,12 +7,7 @@ Compass::Engine.routes.draw do
|
|
|
7
7
|
get ":context_id/search", to: "search#index", as: :search
|
|
8
8
|
options ":context_id/search", to: "search#cors"
|
|
9
9
|
|
|
10
|
-
get ":context_id/search
|
|
11
|
-
options ":context_id/search/providers", to: "search#cors"
|
|
12
|
-
|
|
13
|
-
get ":context_id/search/:provider_name", to: "search#show",
|
|
14
|
-
as: :search_provider,
|
|
15
|
-
constraints: { provider_name: /[a-zA-Z_]+/ }
|
|
10
|
+
get ":context_id/search/:provider_name", to: "search#show", as: :search_provider
|
|
16
11
|
options ":context_id/search/:provider_name", to: "search#cors"
|
|
17
12
|
|
|
18
13
|
get ":context_id/notifications", to: "notification#index", as: :notifications
|
|
@@ -45,11 +45,8 @@ module Compass
|
|
|
45
45
|
# @param attr_options [Hash] the options for the attributes
|
|
46
46
|
# @private
|
|
47
47
|
def format(*attrs, **attr_options)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
raise ArgumentError, "Format must be defined for provider #{self.class}" if obj
|
|
51
|
-
|
|
52
|
-
self._json_formatter&.instance_eval(&block)
|
|
48
|
+
define_singleton_method(:format) do |&block|
|
|
49
|
+
self._json_formatter = Formatter.new(attrs + attr_options.keys, attr_options, &block)
|
|
53
50
|
|
|
54
51
|
define_method(:format) do |object|
|
|
55
52
|
self._json_formatter&.to_h(self, object)
|
|
@@ -65,14 +62,17 @@ module Compass
|
|
|
65
62
|
#
|
|
66
63
|
# @param attrs [Array] the attributes to format
|
|
67
64
|
# @param attr_options [Hash] the options for the attributes
|
|
68
|
-
def initialize(attrs, attr_options)
|
|
69
|
-
@attrs =
|
|
65
|
+
def initialize(attrs, attr_options, &block)
|
|
66
|
+
@attrs = {}
|
|
70
67
|
@attr_options = attr_options
|
|
71
|
-
attrs.each do |attr|
|
|
68
|
+
[ *attrs, *attr_options.keys ].each do |attr|
|
|
69
|
+
@attrs[attr] = nil
|
|
72
70
|
define_singleton_method(attr) do |&block|
|
|
73
71
|
@attrs[attr] = block
|
|
74
72
|
end
|
|
75
73
|
end
|
|
74
|
+
|
|
75
|
+
instance_eval(&block)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# Formats an object into a ruby hash.
|
|
@@ -81,7 +81,7 @@ module Compass
|
|
|
81
81
|
# @return [Hash] the formatted hash
|
|
82
82
|
def to_h(service, obj)
|
|
83
83
|
Hash[@attrs.map do |method, formatter|
|
|
84
|
-
value = formatter ?
|
|
84
|
+
value = formatter ? service.instance_exec(obj, &formatter) : service.try(method)
|
|
85
85
|
validate!(method, value)
|
|
86
86
|
|
|
87
87
|
[ method, value ]
|
|
@@ -1,67 +1,10 @@
|
|
|
1
1
|
module Compass
|
|
2
2
|
module Search
|
|
3
|
-
class UnknownProvider < StandardError
|
|
4
|
-
attr_reader :provider_name, :available_providers
|
|
5
|
-
|
|
6
|
-
def initialize(provider_name, available_providers)
|
|
7
|
-
@provider_name = provider_name
|
|
8
|
-
@available_providers = available_providers
|
|
9
|
-
super("Provider '#{provider_name}' not found")
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
3
|
class Provider
|
|
14
4
|
include Compass::Search::Rendering
|
|
5
|
+
include Compass::JsonFormatter
|
|
15
6
|
|
|
16
|
-
|
|
17
|
-
attr_reader :providers
|
|
18
|
-
|
|
19
|
-
# Handles both class objects and string class names
|
|
20
|
-
def constantize_provider(provider)
|
|
21
|
-
provider.is_a?(String) ? provider.constantize : provider
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Aggregates search results from all registered providers
|
|
25
|
-
def global_search(query, context = {})
|
|
26
|
-
Compass.config.search.providers.flat_map do |provider|
|
|
27
|
-
begin
|
|
28
|
-
provider_class = constantize_provider(provider)
|
|
29
|
-
provider_class.new(**context).search(query)
|
|
30
|
-
rescue => e
|
|
31
|
-
Compass.logger&.error("[ Compass::Search::Provider ] #{provider_class}: #{e.class}: #{e.message}")
|
|
32
|
-
[]
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Add this new class method for individual provider search
|
|
38
|
-
def search(query, provider_name, context = {})
|
|
39
|
-
provider_class = find_by_name(provider_name)
|
|
40
|
-
if provider_class
|
|
41
|
-
provider_class.new(**context).search(query)
|
|
42
|
-
else
|
|
43
|
-
raise UnknownProvider.new(provider_name, available_provider_names)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def normalize_name(provider_class)
|
|
48
|
-
provider_class.name.demodulize.underscore.sub(/_?provider$/, "")
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def find_by_name(name)
|
|
52
|
-
Compass.config.search.providers.find do |provider|
|
|
53
|
-
provider_class = constantize_provider(provider)
|
|
54
|
-
normalize_name(provider_class) == name.to_s
|
|
55
|
-
end&.then { |p| constantize_provider(p) }
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def available_provider_names
|
|
59
|
-
Compass.config.search.providers.map do |provider|
|
|
60
|
-
provider_class = constantize_provider(provider)
|
|
61
|
-
normalize_name(provider_class)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
7
|
+
format :url, :label, :category, :tag, :html, :confirm, :extra
|
|
65
8
|
|
|
66
9
|
def initialize(**context)
|
|
67
10
|
@context = context
|
|
@@ -69,46 +12,28 @@ module Compass
|
|
|
69
12
|
end
|
|
70
13
|
|
|
71
14
|
def search(query)
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
label: label,
|
|
75
|
-
search_options: search_options,
|
|
76
|
-
results: Array(records).map { |record| format_result(record) }.compact
|
|
77
|
-
}
|
|
78
|
-
rescue => e
|
|
79
|
-
log_error(e, query)
|
|
80
|
-
{
|
|
81
|
-
label: label,
|
|
82
|
-
search_options: search_options,
|
|
83
|
-
results: []
|
|
84
|
-
}
|
|
15
|
+
fetch_records(query).map { |record| format(record) }
|
|
85
16
|
end
|
|
86
17
|
|
|
87
|
-
def
|
|
88
|
-
self.class.name.demodulize.sub(/Provider$/, "").titleize
|
|
89
|
-
end
|
|
18
|
+
def fetch_records(_query) = must_implement(:fetch_records)
|
|
90
19
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
end
|
|
20
|
+
class_attribute :label
|
|
21
|
+
class_attribute :search_options, default: {}
|
|
94
22
|
|
|
95
|
-
def
|
|
96
|
-
raise NotImplementedError, "#{self.class} must implement #fetch_records"
|
|
97
|
-
end
|
|
23
|
+
def self.label = name.to_s.gsub(/(Provider|Search)/i, "").pluralize
|
|
98
24
|
|
|
99
|
-
def
|
|
25
|
+
def self.as_json(*)
|
|
100
26
|
{
|
|
101
|
-
|
|
102
|
-
label:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}.compact
|
|
27
|
+
provider: name,
|
|
28
|
+
label: label,
|
|
29
|
+
search_options: search_options
|
|
30
|
+
}
|
|
106
31
|
end
|
|
107
32
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def must_implement(method)
|
|
36
|
+
raise NotImplementedError, "#{self.class} must implement ##{method}"
|
|
112
37
|
end
|
|
113
38
|
end
|
|
114
39
|
end
|
data/lib/compass/search.rb
CHANGED
|
@@ -3,5 +3,34 @@ module Compass
|
|
|
3
3
|
autoload :Rendering, "compass/search/rendering"
|
|
4
4
|
autoload :Provider, "compass/search/provider"
|
|
5
5
|
autoload :ViewContext, "compass/search/view_context"
|
|
6
|
+
|
|
7
|
+
class UnknownProvider < StandardError
|
|
8
|
+
attr_reader :provider_name
|
|
9
|
+
|
|
10
|
+
def initialize(provider_name)
|
|
11
|
+
@provider_name = provider_name
|
|
12
|
+
super("Provider '#{provider_name}' not found")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Searches a specific provider
|
|
17
|
+
# @example
|
|
18
|
+
# Compass::Search.search("Tesla", "CarsSearchProvider", { user: current_user })
|
|
19
|
+
#
|
|
20
|
+
# @param query [String] the search query
|
|
21
|
+
# @param provider_name [String] the class name of the provider to search
|
|
22
|
+
# @param context [Hash] the context for the search
|
|
23
|
+
# @return [Array] the formatted search results
|
|
24
|
+
def self.search(query, provider_name, context = {})
|
|
25
|
+
provider = providers.find { |provider| provider.name == provider_name.to_s }
|
|
26
|
+
raise UnknownProvider.new(provider_name) if provider.nil?
|
|
27
|
+
provider.new(**context).search(query)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.providers
|
|
31
|
+
Compass.config.search.providers.map do |provider|
|
|
32
|
+
provider.try(:constantize) || provider
|
|
33
|
+
end
|
|
34
|
+
end
|
|
6
35
|
end
|
|
7
36
|
end
|
data/lib/compass/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: power-compass
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carlos Palhares
|
|
@@ -15,7 +15,7 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '7.
|
|
18
|
+
version: '7.1'
|
|
19
19
|
- - "<"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
21
|
version: '8.0'
|
|
@@ -25,7 +25,7 @@ dependencies:
|
|
|
25
25
|
requirements:
|
|
26
26
|
- - ">="
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: '7.
|
|
28
|
+
version: '7.1'
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
31
|
version: '8.0'
|