lucid_works 0.7.18 → 0.9.4
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.
- data/.rvmrc +2 -3
- data/Gemfile +2 -8
- data/Gemfile.lock +45 -53
- data/README.rdoc +2 -6
- data/Rakefile +1 -1
- data/config/locales/en.yml +221 -239
- data/lib/lucid_works/activity.rb +8 -5
- data/lib/lucid_works/base.rb +27 -16
- data/lib/lucid_works/cache.rb +13 -0
- data/lib/lucid_works/cluster.rb +84 -0
- data/lib/lucid_works/collection/settings.rb +15 -6
- data/lib/lucid_works/collection.rb +62 -92
- data/lib/lucid_works/datasource/history.rb +2 -1
- data/lib/lucid_works/datasource/mapping.rb +12 -0
- data/lib/lucid_works/datasource/schedule.rb +5 -2
- data/lib/lucid_works/datasource/status.rb +3 -2
- data/lib/lucid_works/datasource.rb +31 -48
- data/lib/lucid_works/datasource_property.rb +2 -1
- data/lib/lucid_works/datasource_type.rb +14 -0
- data/lib/lucid_works/dynamicfield.rb +12 -0
- data/lib/lucid_works/elevation.rb +93 -0
- data/lib/lucid_works/exceptions.rb +0 -4
- data/lib/lucid_works/field.rb +31 -111
- data/lib/lucid_works/field_commons.rb +133 -0
- data/lib/lucid_works/gem_version.rb +1 -1
- data/lib/lucid_works/inflections.rb +3 -0
- data/lib/lucid_works/patch_time.rb +4 -0
- data/lib/lucid_works/request_handler.rb +16 -0
- data/lib/lucid_works/role.rb +23 -8
- data/lib/lucid_works/schema/attribute.rb +1 -1
- data/lib/lucid_works/schema/boolean_attribute.rb +1 -1
- data/lib/lucid_works/schema/integer_attribute.rb +3 -4
- data/lib/lucid_works/server/crawlers_status.rb +15 -0
- data/lib/lucid_works/server.rb +35 -14
- data/lib/lucid_works/simple_naming.rb +1 -7
- data/lib/lucid_works/synonym.rb +1 -1
- data/lib/lucid_works/version.rb +1 -0
- data/lib/lucid_works.rb +8 -1
- data/lucid_works.gemspec +8 -9
- data/spec/fixtures/zookeeper/clusterstate.json +30 -0
- data/spec/fixtures/zookeeper/clusterstate_broken_shard.json +29 -0
- data/spec/fixtures/zookeeper/live_nodes.json +28 -0
- data/spec/fixtures/zookeeper/live_nodes_no_children.json +26 -0
- data/spec/fixtures/zookeeper/live_nodes_one_child.json +36 -0
- data/spec/lib/lucid_works/base_spec.rb +33 -24
- data/spec/lib/lucid_works/cache_spec.rb +44 -0
- data/spec/lib/lucid_works/cluster_spec.rb +109 -0
- data/spec/lib/lucid_works/collection/activity_spec.rb +29 -0
- data/spec/lib/lucid_works/collection/prime_activities_spec.rb +1 -1
- data/spec/lib/lucid_works/collection/settings_spec.rb +31 -0
- data/spec/lib/lucid_works/collection_spec.rb +166 -107
- data/spec/lib/lucid_works/datasource/schedule_spec.rb +75 -46
- data/spec/lib/lucid_works/datasource/status_spec.rb +5 -5
- data/spec/lib/lucid_works/datasource_property_spec.rb +41 -0
- data/spec/lib/lucid_works/datasource_spec.rb +40 -12
- data/spec/lib/lucid_works/datasource_type_spec.rb +31 -0
- data/spec/lib/lucid_works/dynamicfield_spec.rb +214 -0
- data/spec/lib/lucid_works/elevation_spec.rb +175 -0
- data/spec/lib/lucid_works/field_spec.rb +52 -21
- data/spec/lib/lucid_works/fieldtype_spec.rb +0 -1
- data/spec/lib/lucid_works/request_handler_spec.rb +11 -0
- data/spec/lib/lucid_works/role_spec.rb +77 -0
- data/spec/lib/lucid_works/server/crawlers_status_spec.rb +21 -0
- data/spec/lib/lucid_works/server_spec.rb +123 -22
- data/spec/lib/lucid_works/{collection/synonym_spec.rb → synonym_spec.rb} +23 -22
- data/spec/lib/lucid_works/version_spec.rb +6 -0
- metadata +132 -64
- data/spec/lib/lucid_works/collection/acl_config_spec.rb +0 -212
@@ -0,0 +1,93 @@
|
|
1
|
+
class Array
|
2
|
+
def move(from, to)
|
3
|
+
insert(to, delete_at(from))
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
module LucidWorks
|
8
|
+
class Elevation
|
9
|
+
include ActiveModel::Conversion
|
10
|
+
extend ActiveModel::Naming
|
11
|
+
extend SimpleNaming
|
12
|
+
|
13
|
+
attr_reader :id, :collection, :query, :doc_id, :excluded
|
14
|
+
alias :excluded? :excluded
|
15
|
+
|
16
|
+
def initialize(attributes = {})
|
17
|
+
@doc_id = attributes[:doc_id]
|
18
|
+
@collection = attributes[:collection]
|
19
|
+
@query = attributes[:query]
|
20
|
+
@excluded = [true, "true"].include? attributes[:excluded]
|
21
|
+
@persisted = [true, "true"].include? attributes[:persisted]
|
22
|
+
@id = "#{CGI.escape query}~~#{doc_id}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def save
|
26
|
+
settings.elevations[query] ||= []
|
27
|
+
settings.elevations[query] << {'doc' => doc_id, 'exclude' => excluded?}
|
28
|
+
settings.save
|
29
|
+
@persisted = true
|
30
|
+
rescue
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def persisted?
|
35
|
+
@persisted
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
return unless settings.elevations.include?(query)
|
40
|
+
settings.elevations[query].delete_if {|elevation| "#{CGI.escape query}~~#{elevation['doc']}" == id }
|
41
|
+
settings.elevations.delete(query) if settings.elevations[query].empty?
|
42
|
+
settings.save
|
43
|
+
end
|
44
|
+
|
45
|
+
def first?
|
46
|
+
index_of_in_elevations(doc_id) == 0
|
47
|
+
end
|
48
|
+
|
49
|
+
def last?
|
50
|
+
index_of_in_elevations(doc_id) == elevations.size - 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def move_up
|
54
|
+
return if first?
|
55
|
+
current_index = index_of_in_settings(doc_id)
|
56
|
+
new_index = elevation_indexes[elevation_indexes.index(current_index) - 1]
|
57
|
+
settings.elevations[query].move(current_index, new_index)
|
58
|
+
settings.save
|
59
|
+
end
|
60
|
+
|
61
|
+
def move_down
|
62
|
+
return if last?
|
63
|
+
current_index = index_of_in_settings(doc_id)
|
64
|
+
new_index = elevation_indexes[elevation_indexes.index(current_index) + 1]
|
65
|
+
settings.elevations[query].move(current_index, new_index)
|
66
|
+
settings.save
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def settings
|
72
|
+
collection.build_settings(:elevations => collection.settings.elevations)
|
73
|
+
end
|
74
|
+
|
75
|
+
def index_of_in_settings(doc_id)
|
76
|
+
settings.elevations[query].index {|elevation| elevation['doc'] == doc_id }
|
77
|
+
end
|
78
|
+
|
79
|
+
def elevations
|
80
|
+
settings.elevations[query].index.select {|elevation| !elevation['exclude'] }
|
81
|
+
end
|
82
|
+
|
83
|
+
def index_of_in_elevations(doc_id)
|
84
|
+
elevations.index {|elevation| elevation['doc'] == doc_id }
|
85
|
+
end
|
86
|
+
|
87
|
+
def elevation_indexes
|
88
|
+
indexes = []
|
89
|
+
settings.elevations[query].each_with_index {|elevation, index| indexes << index if !elevation['exclude'] }
|
90
|
+
indexes
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/lucid_works/field.rb
CHANGED
@@ -1,39 +1,38 @@
|
|
1
|
+
require 'lucid_works/field_commons'
|
2
|
+
|
1
3
|
module LucidWorks
|
2
4
|
|
3
5
|
class Field < Base
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
include LucidWorks::FieldCommons
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :include_dynamic
|
10
|
+
|
11
|
+
def collection_url(parent)
|
12
|
+
include_dynamic ? "#{super}?include_dynamic=true" : super
|
13
|
+
end
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
]
|
15
|
+
def member_url(parent, id = nil)
|
16
|
+
include_dynamic ? "#{super}?include_dynamic=true" : super
|
17
|
+
end
|
18
|
+
end
|
17
19
|
|
18
20
|
schema do
|
19
|
-
attribute :name, :string, :primary_key => true, :omit_during_update => true
|
20
|
-
attribute :editable, :boolean, :omit_during_update => true
|
21
|
-
attribute :dynamic_base, :string, :omit_during_update => true
|
22
|
-
attributes :indexed, :stored, :facet, :include_in_results,
|
23
|
-
:search_by_default, :highlight, :multi_valued,
|
24
|
-
:term_vectors, :omit_tf, :omit_positions,
|
25
|
-
:use_for_deduplication, :synonym_expansion,
|
26
|
-
:index_for_spellcheck, :index_for_autocomplete,
|
27
|
-
:query_time_stopword_handling,
|
28
|
-
:use_in_find_similar,
|
29
|
-
:type => :boolean
|
30
21
|
attribute :default_boost, :integer
|
31
|
-
|
32
|
-
attribute :
|
33
|
-
attribute :
|
34
|
-
|
35
|
-
|
36
|
-
|
22
|
+
attribute :default_value, :string
|
23
|
+
attribute :dynamic_base, :string, :omit_during_update => true
|
24
|
+
attribute :facet, :boolean
|
25
|
+
attribute :highlight, :boolean
|
26
|
+
attribute :include_in_results, :boolean
|
27
|
+
attribute :num_facets, :integer
|
28
|
+
attribute :query_time_stopword_handling, :boolean
|
29
|
+
attribute :search_by_default, :boolean
|
30
|
+
attribute :short_field_boost, :string
|
31
|
+
attribute :synonym_expansion, :boolean
|
32
|
+
attribute :use_for_deduplication, :boolean
|
33
|
+
attribute :use_in_find_similar, :boolean
|
34
|
+
end
|
35
|
+
|
37
36
|
validates_each :name, :unless => :persisted?, :allow_blank => true do |model, attr, value|
|
38
37
|
model.errors.add(attr, 'must be unique') if model.collection.fields.any? {|f| f.name == value }
|
39
38
|
end
|
@@ -52,92 +51,15 @@ module LucidWorks
|
|
52
51
|
validates_each :use_in_find_similar do |model, attr, value|
|
53
52
|
model.errors.add(attr, 'a field must be indexed for it to be used for find-similar') if value == true && !model.indexed?
|
54
53
|
end
|
55
|
-
validates_each :indexing_options do |model, attr, value|
|
56
|
-
if model.persisted?
|
57
|
-
if value
|
58
|
-
if model.indexed?
|
59
|
-
model.errors.add(attr, "must be one of #{INDEXING_OPTIONS.join(', ')}") unless INDEXING_OPTIONS.include?(value.to_s)
|
60
|
-
end
|
61
|
-
else
|
62
|
-
# If the model is already persisted, but the user has not manually set indexing_options,
|
63
|
-
# just go with the omit_tf/omit_positions we have now.
|
64
|
-
end
|
65
|
-
else # new model
|
66
|
-
if model.indexed?
|
67
|
-
# If this is a new model, and the user set 'indexed' they MUST also set indexing_options
|
68
|
-
model.errors.add(attr, "must be one of #{INDEXING_OPTIONS.join(', ')}") unless INDEXING_OPTIONS.include?(value.to_s)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
before_save :convert_indexing_options_to_term_freq_and_pos
|
74
54
|
|
75
55
|
def initialize(options)
|
76
|
-
super(options.reverse_merge(:
|
56
|
+
super(options.reverse_merge(:short_field_boost => 'high'))
|
77
57
|
end
|
78
58
|
|
79
|
-
def dynamically_generated
|
59
|
+
def dynamically_generated
|
80
60
|
!dynamic_base.blank?
|
81
61
|
end
|
82
|
-
|
83
|
-
def t_field_type
|
84
|
-
self.class.t_field_type(self.field_type)
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.t_field_type(type)
|
88
|
-
I18n.translate(type, :scope => 'activemodel.models.lucid_works.collection.field.field_type')
|
89
|
-
end
|
90
|
-
|
91
|
-
# Indexing_options is a fake attribute that wraps the omit_tf and omit_positions combinations.
|
92
|
-
# Translations are:
|
93
|
-
#
|
94
|
-
# INDEXED? indexing_options omit_tf omit_positions
|
95
|
-
#
|
96
|
-
# false - true true
|
97
|
-
# true :document_only true true
|
98
|
-
# true :document_termfreq false true
|
99
|
-
# true :documents_termfreq_termpos false false
|
100
|
-
#
|
101
|
-
def indexing_options
|
102
|
-
@attributes[:indexing_options] ||=
|
103
|
-
if !indexed? || omit_tf?
|
104
|
-
:document_only
|
105
|
-
else
|
106
|
-
omit_positions? ? :document_termfreq : :document_termfreq_termpos
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# We have to remember the caller's choice of indexing_options, as we can't determine the correct
|
111
|
-
# omit_tf/omit_positions settins until we also know whether 'indexed' is set or not.
|
112
|
-
# So we keep it as an attribute for now, and remove it in a before_save.
|
113
|
-
def indexing_options=(new_value)
|
114
|
-
@attributes[:indexing_options] = new_value
|
115
|
-
end
|
116
|
-
|
117
|
-
# Convert indexing_options to the correct values for omit_tf and omit_positions.
|
118
|
-
# Delete indexing_options from attributes so it is not saved.
|
119
|
-
def convert_indexing_options_to_term_freq_and_pos
|
120
|
-
i_opt = @attributes.delete(:indexing_options)
|
121
|
-
if indexed? && i_opt
|
122
|
-
case i_opt.to_sym
|
123
|
-
when :document_only
|
124
|
-
self.omit_tf = true
|
125
|
-
self.omit_positions = true
|
126
|
-
when :document_termfreq
|
127
|
-
self.omit_tf = false
|
128
|
-
self.omit_positions = true
|
129
|
-
when :document_termfreq_termpos
|
130
|
-
self.omit_tf = false
|
131
|
-
self.omit_positions = false
|
132
|
-
else
|
133
|
-
raise "Unknown indexing option: '#{i_opt}'. Allowed values are: #{INDEXING_OPTIONS.join(', ')}"
|
134
|
-
end
|
135
|
-
else # !indexed?
|
136
|
-
self.omit_tf = true
|
137
|
-
self.omit_positions = true
|
138
|
-
end
|
139
|
-
true
|
140
|
-
end
|
62
|
+
alias :dynamically_generated? :dynamically_generated
|
141
63
|
|
142
64
|
def update_attributes(attrs)
|
143
65
|
attrs = attrs.with_indifferent_access
|
@@ -148,8 +70,6 @@ module LucidWorks
|
|
148
70
|
if [false, '0'].include?(attrs[:indexed])
|
149
71
|
attrs[:facet] ||= false
|
150
72
|
attrs[:synonym_expansion] ||= false
|
151
|
-
attrs[:omit_tf] ||= false
|
152
|
-
attrs[:omit_positions] ||= false
|
153
73
|
attrs[:short_field_boost] ||= 'high'
|
154
74
|
attrs[:search_by_default] ||= false
|
155
75
|
attrs[:use_in_find_similar] ||= false
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module LucidWorks
|
2
|
+
|
3
|
+
module FieldCommons
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
belongs_to :collection
|
8
|
+
|
9
|
+
INDEXING_OPTIONS = [
|
10
|
+
'document_only',
|
11
|
+
'document_termfreq',
|
12
|
+
'document_termfreq_termpos'
|
13
|
+
] unless defined?(INDEXING_OPTIONS)
|
14
|
+
|
15
|
+
BOOST_VALUES = [
|
16
|
+
'none',
|
17
|
+
'moderate',
|
18
|
+
'high'
|
19
|
+
] unless defined?(BOOST_VALUES)
|
20
|
+
|
21
|
+
schema do
|
22
|
+
attribute :name, :string, :primary_key => true, :omit_during_update => true
|
23
|
+
attribute :copy_fields, :list
|
24
|
+
attribute :editable, :boolean, :omit_during_update => true
|
25
|
+
attribute :field_type, :string
|
26
|
+
attribute :index_for_autocomplete, :boolean
|
27
|
+
attribute :index_for_spellcheck, :boolean
|
28
|
+
attribute :indexed, :boolean
|
29
|
+
attribute :indexing_options, :custom, :values => INDEXING_OPTIONS
|
30
|
+
attribute :multi_valued, :boolean
|
31
|
+
attribute :omit_positions, :boolean
|
32
|
+
attribute :omit_tf, :boolean
|
33
|
+
attribute :stored, :boolean
|
34
|
+
attribute :term_vectors, :boolean
|
35
|
+
end
|
36
|
+
|
37
|
+
validates_presence_of :name, :field_type
|
38
|
+
validates_each :indexing_options do |model, attr, value|
|
39
|
+
if model.persisted?
|
40
|
+
if value
|
41
|
+
if model.indexed?
|
42
|
+
model.errors.add(attr, "must be one of #{INDEXING_OPTIONS.join(', ')}") unless INDEXING_OPTIONS.include?(value.to_s)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
# If the model is already persisted, but the user has not manually set indexing_options,
|
46
|
+
# just go with the omit_tf/omit_positions we have now.
|
47
|
+
end
|
48
|
+
else # new model
|
49
|
+
if model.indexed?
|
50
|
+
# If this is a new model, and the user set 'indexed' they MUST also set indexing_options
|
51
|
+
model.errors.add(attr, "must be one of #{INDEXING_OPTIONS.join(', ')}") unless INDEXING_OPTIONS.include?(value.to_s)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
before_save :convert_indexing_options_to_term_freq_and_pos
|
57
|
+
end
|
58
|
+
|
59
|
+
module ClassMethods
|
60
|
+
def t_field_type(type)
|
61
|
+
I18n.translate(type, :scope => 'activemodel.models.collection.field.field_type')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize(options)
|
66
|
+
super(options.reverse_merge(:omit_tf => false))
|
67
|
+
end
|
68
|
+
|
69
|
+
def t_field_type
|
70
|
+
self.class.t_field_type(self.field_type)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Indexing_options is a fake attribute that wraps the omit_tf and omit_positions combinations.
|
74
|
+
# Translations are:
|
75
|
+
#
|
76
|
+
# INDEXED? indexing_options omit_tf omit_positions
|
77
|
+
#
|
78
|
+
# false - true true
|
79
|
+
# true :document_only true true
|
80
|
+
# true :document_termfreq false true
|
81
|
+
# true :documents_termfreq_termpos false false
|
82
|
+
#
|
83
|
+
def indexing_options
|
84
|
+
@attributes[:indexing_options] ||=
|
85
|
+
if !indexed? || omit_tf?
|
86
|
+
:document_only
|
87
|
+
else
|
88
|
+
omit_positions? ? :document_termfreq : :document_termfreq_termpos
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# We have to remember the caller's choice of indexing_options, as we can't determine the correct
|
93
|
+
# omit_tf/omit_positions settins until we also know whether 'indexed' is set or not.
|
94
|
+
# So we keep it as an attribute for now, and remove it in a before_save.
|
95
|
+
def indexing_options=(new_value)
|
96
|
+
@attributes[:indexing_options] = new_value
|
97
|
+
end
|
98
|
+
|
99
|
+
# Convert indexing_options to the correct values for omit_tf and omit_positions.
|
100
|
+
# Delete indexing_options from attributes so it is not saved.
|
101
|
+
def convert_indexing_options_to_term_freq_and_pos
|
102
|
+
i_opt = @attributes.delete(:indexing_options)
|
103
|
+
if indexed? && i_opt
|
104
|
+
case i_opt.to_sym
|
105
|
+
when :document_only
|
106
|
+
self.omit_tf = true
|
107
|
+
self.omit_positions = true
|
108
|
+
when :document_termfreq
|
109
|
+
self.omit_tf = false
|
110
|
+
self.omit_positions = true
|
111
|
+
when :document_termfreq_termpos
|
112
|
+
self.omit_tf = false
|
113
|
+
self.omit_positions = false
|
114
|
+
else
|
115
|
+
raise "Unknown indexing option: '#{i_opt}'. Allowed values are: #{INDEXING_OPTIONS.join(', ')}"
|
116
|
+
end
|
117
|
+
else # !indexed?
|
118
|
+
self.omit_tf = true
|
119
|
+
self.omit_positions = true
|
120
|
+
end
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
def update_attributes(attrs)
|
125
|
+
attrs = attrs.with_indifferent_access
|
126
|
+
if [false, '0'].include?(attrs[:indexed])
|
127
|
+
attrs[:omit_positions] ||= false
|
128
|
+
attrs[:omit_tf] ||= false
|
129
|
+
end
|
130
|
+
super(attrs)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module LucidWorks
|
2
|
+
|
3
|
+
class RequestHandler
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(collection, name)
|
8
|
+
@collection = collection
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_params
|
13
|
+
@collection.search(:qt => '/lucid', :echoParams => 'all')['responseHeader']['params'].symbolize_keys
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/lucid_works/role.rb
CHANGED
@@ -18,10 +18,17 @@ module LucidWorks
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def filters
|
21
|
-
# require 'ruby-debug'; debugger
|
22
21
|
@attributes[:filters]
|
23
22
|
end
|
24
23
|
|
24
|
+
def users_for_text_field
|
25
|
+
@attributes[:users].to_a.join(", ")
|
26
|
+
end
|
27
|
+
|
28
|
+
def groups_for_text_field
|
29
|
+
@attributes[:groups].to_a.join(", ")
|
30
|
+
end
|
31
|
+
|
25
32
|
def filters_for_text_area
|
26
33
|
@attributes[:filters].to_a.join("\n")
|
27
34
|
end
|
@@ -30,24 +37,27 @@ module LucidWorks
|
|
30
37
|
# Accept a comma or space separated list of users, convert to array
|
31
38
|
#
|
32
39
|
def users=(val)
|
33
|
-
@attributes[:users] = string_or_array(val,
|
40
|
+
@attributes[:users] = string_or_array(val, :space_or_comma) rescue "Can't interpret #{val.class} as list of users"
|
34
41
|
end
|
35
42
|
|
36
43
|
def groups=(val)
|
37
|
-
@attributes[:groups] = string_or_array(val,
|
44
|
+
@attributes[:groups] = string_or_array(val, :space_or_comma) rescue "Can't interpret #{val.class} as list of groups"
|
38
45
|
end
|
39
46
|
|
40
47
|
def filters=(val)
|
41
|
-
@attributes[:filters] = string_or_array(val,
|
42
|
-
# require 'ruby-debug'; debugger
|
43
|
-
# @attributes[:filters]
|
48
|
+
@attributes[:filters] = string_or_array(val, :newline) rescue "Can't interpret #{val.class} as list of groups"
|
44
49
|
end
|
45
50
|
|
46
51
|
private
|
47
52
|
|
48
|
-
def string_or_array(val,
|
53
|
+
def string_or_array(val, method)
|
49
54
|
if val.is_a?(String)
|
50
|
-
|
55
|
+
pattern = case method
|
56
|
+
when :space_or_comma ; then (val =~ /,/) ? /[,]+/ : /\s+/
|
57
|
+
when :newline ; then /\r+/
|
58
|
+
else raise "Unrecognized split method #{method}, can't convert #{val} to an Array"
|
59
|
+
end
|
60
|
+
val.split(pattern).map{|item| remove_leading_and_trailing_spaces(item)}
|
51
61
|
elsif val.is_a?(Array)
|
52
62
|
val
|
53
63
|
else
|
@@ -55,5 +65,10 @@ module LucidWorks
|
|
55
65
|
end
|
56
66
|
|
57
67
|
end
|
68
|
+
|
69
|
+
def remove_leading_and_trailing_spaces(string)
|
70
|
+
string.sub(/^\s*(.*?)\s*$/,'\1') # remember everything in the middle, but non-greedy
|
71
|
+
end
|
72
|
+
|
58
73
|
end
|
59
74
|
end
|
@@ -60,7 +60,7 @@ module LucidWorks
|
|
60
60
|
if values
|
61
61
|
# If this attribute was defined with a set of :values,
|
62
62
|
# assume we can get translations for those valuesfrom the L10n database.
|
63
|
-
l10n_scope = %w{activemodel models} + schema.model.name.underscore.split('/') + [name]
|
63
|
+
l10n_scope = %w{activemodel models} + schema.model.name.underscore.split('/').drop(1) + [name]
|
64
64
|
return I18n.t(value, :scope => l10n_scope, :default => value)
|
65
65
|
end
|
66
66
|
value.to_s
|
@@ -13,11 +13,10 @@ module LucidWorks
|
|
13
13
|
|
14
14
|
klass.class_eval <<-EOF, __FILE__, __LINE__+1
|
15
15
|
def #{name}=(new_value)
|
16
|
-
if new_value.blank? && (self.class.schema[:#{name}].nil_when_blank? ||
|
17
|
-
|
18
|
-
new_value = nil
|
16
|
+
new_value = if new_value.blank? && (self.class.schema[:#{name}].nil_when_blank? || self.class.schema[:#{name}].omit_when_blank?)
|
17
|
+
nil
|
19
18
|
else
|
20
|
-
new_value
|
19
|
+
Integer(new_value.to_s) rescue new_value
|
21
20
|
end
|
22
21
|
@attributes[:#{name}] = new_value
|
23
22
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module LucidWorks
|
2
|
+
class Server
|
3
|
+
class CrawlersStatus < Base
|
4
|
+
self.singleton = true
|
5
|
+
|
6
|
+
def self.member_url(parent, id = nil) # :nodoc:
|
7
|
+
"#{parent.uri}/crawlers/status"
|
8
|
+
end
|
9
|
+
|
10
|
+
def ok?
|
11
|
+
self.status == 'OK' rescue false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/lucid_works/server.rb
CHANGED
@@ -8,32 +8,53 @@ module LucidWorks
|
|
8
8
|
has_many :collections, :crawlers
|
9
9
|
has_one :logs, :has_content => false
|
10
10
|
has_one :version
|
11
|
+
has_one :crawlers_status
|
11
12
|
|
12
|
-
|
13
|
+
attr_accessor :server_uri, :path, :protocol, :host, :port, :user, :password
|
13
14
|
|
14
|
-
|
15
|
+
def initialize(server_uri)
|
16
|
+
@server_uri = server_uri
|
17
|
+
uri = URI.parse(@server_uri)
|
18
|
+
@protocol, @host, @port, @user, @password = "#{uri.scheme}://", uri.host, uri.port, uri.user, uri.password
|
19
|
+
end
|
15
20
|
|
16
|
-
def
|
17
|
-
|
18
|
-
@path = options.delete(:path) || DEFAULT_REST_API_PATH
|
21
|
+
def api_uri
|
22
|
+
"#{server_uri}/api"
|
19
23
|
end
|
24
|
+
alias :uri :api_uri # used by associations
|
20
25
|
|
21
|
-
def
|
22
|
-
|
26
|
+
def solr_uri
|
27
|
+
"#{server_uri}/solr"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Location where raw log files may be retrieved
|
31
|
+
def logs_uri
|
32
|
+
"#{server_uri}/logs"
|
23
33
|
end
|
24
|
-
alias :rest_api_uri :uri
|
25
34
|
|
26
35
|
def crawler(name)
|
27
|
-
crawlers.detect {
|
36
|
+
crawlers.detect {|c| c.name == name }
|
28
37
|
end
|
29
38
|
|
30
|
-
def
|
31
|
-
|
39
|
+
def datasource_type(type_name, crawler_name)
|
40
|
+
crawler(crawler_name).datasource_type(type_name)
|
32
41
|
end
|
33
42
|
|
34
|
-
|
35
|
-
|
36
|
-
|
43
|
+
def clustered?
|
44
|
+
begin
|
45
|
+
RestClient.get(solr_uri + "/zookeeper")
|
46
|
+
true
|
47
|
+
rescue RestClient::ResourceNotFound
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def cluster
|
53
|
+
Cluster.new(solr_uri)
|
54
|
+
end
|
55
|
+
|
56
|
+
def datasource_types
|
57
|
+
crawlers.collect(&:datasource_types).flatten
|
37
58
|
end
|
38
59
|
end
|
39
60
|
end
|
@@ -1,13 +1,7 @@
|
|
1
1
|
module LucidWorks
|
2
2
|
module SimpleNaming
|
3
3
|
def model_name
|
4
|
-
|
5
|
-
name.instance_eval do
|
6
|
-
def singular; ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).tr('/', '_').freeze; end
|
7
|
-
def plural; singular.pluralize.freeze; end
|
8
|
-
def collection; ActiveSupport::Inflector.tableize(ActiveSupport::Inflector.demodulize(self)).freeze; end
|
9
|
-
end
|
10
|
-
end
|
4
|
+
ActiveModel::Name.new(self, nil, self.name.sub(/^LucidWorks::/, ''))
|
11
5
|
end
|
12
6
|
end
|
13
7
|
end
|
data/lib/lucid_works/synonym.rb
CHANGED