elasticsearch-extensions 0.0.0 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +10 -19
- data/README.md +27 -15
- data/Rakefile +66 -0
- data/elasticsearch-extensions.gemspec +31 -15
- data/lib/elasticsearch-extensions.rb +1 -0
- data/lib/elasticsearch/extensions.rb +2 -2
- data/lib/elasticsearch/extensions/ansi.rb +21 -0
- data/lib/elasticsearch/extensions/ansi/actions.rb +203 -0
- data/lib/elasticsearch/extensions/ansi/helpers.rb +63 -0
- data/lib/elasticsearch/extensions/ansi/response.rb +47 -0
- data/lib/elasticsearch/extensions/version.rb +1 -1
- metadata +173 -8
data/LICENSE.txt
CHANGED
@@ -1,22 +1,13 @@
|
|
1
|
-
Copyright (c) 2013
|
1
|
+
Copyright (c) 2013 Elasticsearch
|
2
2
|
|
3
|
-
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
4
6
|
|
5
|
-
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
CHANGED
@@ -1,29 +1,41 @@
|
|
1
1
|
# Elasticsearch::Extensions
|
2
2
|
|
3
|
-
|
3
|
+
This library provides a set of extensions to the
|
4
|
+
[`elasticsearch`](https://github.com/elasticsearch/elasticsearch-ruby) Rubygem.
|
5
|
+
|
6
|
+
## Extensions
|
4
7
|
|
5
8
|
## Installation
|
6
9
|
|
7
|
-
|
10
|
+
Install the package from [Rubygems](https://rubygems.org):
|
11
|
+
|
12
|
+
gem install elasticsearch-extensions
|
13
|
+
|
14
|
+
To use an unreleased version, either add it to your `Gemfile` for [Bundler](http://gembundler.com):
|
8
15
|
|
9
|
-
gem 'elasticsearch-extensions'
|
16
|
+
gem 'elasticsearch-extensions', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
|
10
17
|
|
11
|
-
|
18
|
+
or install it from a source code checkout:
|
12
19
|
|
13
|
-
|
20
|
+
git clone https://github.com/elasticsearch/elasticsearch-ruby.git
|
21
|
+
cd elasticsearch-ruby/elasticsearch-extensions
|
22
|
+
bundle install
|
23
|
+
rake install
|
14
24
|
|
15
|
-
|
25
|
+
## License
|
16
26
|
|
17
|
-
|
27
|
+
This software is licensed under the Apache 2 license, quoted below.
|
18
28
|
|
19
|
-
|
29
|
+
Copyright (c) 2013 Elasticsearch <http://www.elasticsearch.org>
|
20
30
|
|
21
|
-
|
31
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
32
|
+
you may not use this file except in compliance with the License.
|
33
|
+
You may obtain a copy of the License at
|
22
34
|
|
23
|
-
|
35
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
24
36
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
37
|
+
Unless required by applicable law or agreed to in writing, software
|
38
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
39
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
40
|
+
See the License for the specific language governing permissions and
|
41
|
+
limitations under the License.
|
data/Rakefile
CHANGED
@@ -1 +1,67 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
desc "Run unit tests"
|
4
|
+
task :default => 'test:unit'
|
5
|
+
task :test => 'test:unit'
|
6
|
+
|
7
|
+
# ----- Test tasks ------------------------------------------------------------
|
8
|
+
|
9
|
+
require 'rake/testtask'
|
10
|
+
namespace :test do
|
11
|
+
Rake::TestTask.new(:unit) do |test|
|
12
|
+
test.libs << 'lib' << 'test'
|
13
|
+
test.test_files = FileList["test/unit/**/*_test.rb"]
|
14
|
+
# test.verbose = true
|
15
|
+
# test.warning = true
|
16
|
+
end
|
17
|
+
|
18
|
+
Rake::TestTask.new(:integration) do |test|
|
19
|
+
test.libs << 'lib' << 'test'
|
20
|
+
test.test_files = FileList["test/integration/**/*_test.rb"]
|
21
|
+
end
|
22
|
+
|
23
|
+
Rake::TestTask.new(:all) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.test_files = FileList["test/unit/**/*_test.rb", "test/integration/**/*_test.rb"]
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::TestTask.new(:profile) do |test|
|
29
|
+
test.libs << 'lib' << 'test'
|
30
|
+
test.test_files = FileList["test/profile/**/*_test.rb"]
|
31
|
+
end
|
32
|
+
|
33
|
+
namespace :server do
|
34
|
+
desc "Start Elasticsearch nodes for tests"
|
35
|
+
task :start do
|
36
|
+
$LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__)
|
37
|
+
require 'elasticsearch/transport'
|
38
|
+
require 'elasticsearch/transport/extensions/test_cluster'
|
39
|
+
Elasticsearch::TestCluster.start
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Stop Elasticsearch nodes for tests"
|
43
|
+
task :stop do
|
44
|
+
$LOAD_PATH << File.expand_path('../lib', __FILE__) << File.expand_path('../test', __FILE__)
|
45
|
+
require 'elasticsearch/transport'
|
46
|
+
require 'elasticsearch/transport/extensions/test_cluster'
|
47
|
+
Elasticsearch::TestCluster.stop
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# ----- Documentation tasks ---------------------------------------------------
|
53
|
+
|
54
|
+
require 'yard'
|
55
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
56
|
+
t.options = %w| --embed-mixins --markup=markdown |
|
57
|
+
end
|
58
|
+
|
59
|
+
# ----- Code analysis tasks ---------------------------------------------------
|
60
|
+
|
61
|
+
if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
|
62
|
+
require 'cane/rake_task'
|
63
|
+
Cane::RakeTask.new(:quality) do |cane|
|
64
|
+
cane.abc_max = 15
|
65
|
+
cane.no_style = true
|
66
|
+
end
|
67
|
+
end
|
@@ -3,21 +3,37 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'elasticsearch/extensions/version'
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "elasticsearch-extensions"
|
8
|
+
s.version = Elasticsearch::Extensions::VERSION
|
9
|
+
s.authors = ["Karel Minarik"]
|
10
|
+
s.email = ["karel.minarik@elasticsearch.org"]
|
11
|
+
s.description = %q{Extensions for the Elasticsearch Rubygem}
|
12
|
+
s.summary = %q{Extensions for the Elasticsearch Rubygem}
|
13
|
+
s.homepage = ""
|
14
|
+
s.license = "Apache 2"
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
|
+
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
s.add_dependency "elasticsearch", '0.4.0'
|
22
|
+
s.add_dependency "ansi"
|
23
|
+
|
24
|
+
|
25
|
+
s.add_development_dependency "bundler", "> 1"
|
26
|
+
s.add_development_dependency "rake"
|
27
|
+
|
28
|
+
s.add_development_dependency "shoulda-context"
|
29
|
+
s.add_development_dependency "mocha"
|
30
|
+
s.add_development_dependency "turn"
|
31
|
+
s.add_development_dependency "yard"
|
32
|
+
s.add_development_dependency "ruby-prof"
|
33
|
+
|
34
|
+
if defined?(RUBY_VERSION) && RUBY_VERSION > '1.9'
|
35
|
+
s.add_development_dependency "simplecov"
|
36
|
+
s.add_development_dependency "cane"
|
37
|
+
s.add_development_dependency "require-prof"
|
38
|
+
end
|
23
39
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'elasticsearch/extensions'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'elasticsearch/extensions'
|
4
|
+
|
5
|
+
require 'ansi'
|
6
|
+
require 'ansi/table'
|
7
|
+
require 'ansi/terminal'
|
8
|
+
|
9
|
+
require 'delegate'
|
10
|
+
require 'elasticsearch/transport/transport/response'
|
11
|
+
|
12
|
+
require 'elasticsearch/extensions/ansi/helpers'
|
13
|
+
require 'elasticsearch/extensions/ansi/actions'
|
14
|
+
require 'elasticsearch/extensions/ansi/response'
|
15
|
+
|
16
|
+
module Elasticsearch
|
17
|
+
module Extensions
|
18
|
+
module ANSI
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Extensions
|
5
|
+
module ANSI
|
6
|
+
|
7
|
+
module Actions
|
8
|
+
|
9
|
+
# Display shard allocation
|
10
|
+
#
|
11
|
+
def display_allocation_on_nodes(json, options={})
|
12
|
+
return unless json['routing_nodes']
|
13
|
+
|
14
|
+
output = [] << ''
|
15
|
+
|
16
|
+
json['routing_nodes']['nodes'].each do |id, shards|
|
17
|
+
output << (json['nodes'][id]['name'] || id).to_s.ansi(:bold) + " [#{id}]".ansi(:faint)
|
18
|
+
if shards.empty?
|
19
|
+
output << "No shards".ansi(:cyan)
|
20
|
+
else
|
21
|
+
output << Helpers.table(shards.map do |shard|
|
22
|
+
[
|
23
|
+
shard['index'],
|
24
|
+
shard['shard'].to_s.ansi( shard['primary'] ? :bold : :clear ),
|
25
|
+
shard['primary'] ? '◼'.ansi(:green) : '◻'.ansi(:yellow)
|
26
|
+
]
|
27
|
+
end)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
unless json['routing_nodes']['unassigned'].empty?
|
32
|
+
output << 'Unassigned: '.ansi(:faint, :yellow) + "#{json['routing_nodes']['unassigned'].size} shards"
|
33
|
+
output << Helpers.table( json['routing_nodes']['unassigned'].map do |shard|
|
34
|
+
primary = shard['primary']
|
35
|
+
|
36
|
+
[
|
37
|
+
shard['index'],
|
38
|
+
shard['shard'].to_s.ansi( primary ? :bold : :clear ),
|
39
|
+
primary ? '◼'.ansi(:red) : '◻'.ansi(:yellow)
|
40
|
+
]
|
41
|
+
end, border: false)
|
42
|
+
end
|
43
|
+
|
44
|
+
output.join("\n")
|
45
|
+
end
|
46
|
+
|
47
|
+
# Display search results
|
48
|
+
#
|
49
|
+
def display_hits(json, options={})
|
50
|
+
return unless json['hits'] && json['hits']['hits']
|
51
|
+
|
52
|
+
output = [] << ''
|
53
|
+
hits = json['hits']['hits']
|
54
|
+
source = json['hits']['hits'].any? { |h| h['fields'] } ? 'fields' : '_source'
|
55
|
+
properties = hits.map { |h| h[source] ? h[source].keys : nil }.compact.flatten.uniq
|
56
|
+
max_property_length = properties.map { |d| d.to_s.size }.compact.max.to_i + 1
|
57
|
+
|
58
|
+
hits.each_with_index do |hit, i|
|
59
|
+
title = hit[source] && hit[source].select { |k, v| ['title', 'name'].include?(k) }.to_a.first
|
60
|
+
size_length = hits.size.to_s.size+2
|
61
|
+
padding = size_length
|
62
|
+
|
63
|
+
output << "#{i+1}. ".rjust(size_length).ansi(:faint) +
|
64
|
+
" <#{hit['_id']}> " +
|
65
|
+
(title ? title.last.to_s.ansi(:bold) : '')
|
66
|
+
output << Helpers.___
|
67
|
+
|
68
|
+
['_score', '_index', '_type'].each do |property|
|
69
|
+
output << ' '*padding + "#{property}: ".rjust(max_property_length+1).ansi(:faint) + hit[property].to_s if hit[property]
|
70
|
+
end
|
71
|
+
|
72
|
+
hit[source].each do |property, value|
|
73
|
+
output << ' '*padding + "#{property}: ".rjust(max_property_length+1).ansi(:faint) + value.to_s
|
74
|
+
end if hit[source]
|
75
|
+
|
76
|
+
# Highlight
|
77
|
+
if hit['highlight']
|
78
|
+
output << ""
|
79
|
+
output << ' '*(padding+max_property_length+1) + "Highlights".ansi(:faint) + "\n" +
|
80
|
+
' '*(padding+max_property_length+1) + ('─'*10).ansi(:faint)
|
81
|
+
|
82
|
+
hit['highlight'].each do |property, matches|
|
83
|
+
line = ""
|
84
|
+
line << ' '*padding + "#{property}: ".rjust(max_property_length+1).ansi(:faint)
|
85
|
+
|
86
|
+
matches.each_with_index do |match, e|
|
87
|
+
line << ' '*padding + ''.rjust(max_property_length+1) if e > 0
|
88
|
+
line << '…'.ansi(:faint) unless hit[source][property] && hit[source][property].size <= match.size
|
89
|
+
line << match.strip.ansi(:faint).gsub(/\n/, ' ')
|
90
|
+
.gsub(/<em>([^<]+)<\/em>/, '\1'.ansi(:clear, :bold))
|
91
|
+
.ansi(:faint)
|
92
|
+
line << '…'.ansi(:faint) unless hit[source][property] && hit[source][property].size <= match.size
|
93
|
+
line << ' '*padding + ''.rjust(max_property_length+1) if e > 0
|
94
|
+
line << "\n"
|
95
|
+
end
|
96
|
+
output << line
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
output << ""
|
101
|
+
end
|
102
|
+
output << Helpers.___
|
103
|
+
output << "#{hits.size.to_s.ansi(:bold)} of #{json['hits']['total'].to_s.ansi(:bold)} results".ansi(:faint)
|
104
|
+
|
105
|
+
output.join("\n")
|
106
|
+
end
|
107
|
+
|
108
|
+
# Display terms facets
|
109
|
+
#
|
110
|
+
def display_terms_facets(json, options={})
|
111
|
+
return unless json['facets']
|
112
|
+
|
113
|
+
output = [] << ''
|
114
|
+
|
115
|
+
facets = json['facets'].select { |name, values| values['_type'] == 'terms' }
|
116
|
+
|
117
|
+
facets.each do |name, values|
|
118
|
+
longest = values['terms'].map { |t| t['term'].size }.max
|
119
|
+
max = values['terms'].map { |t| t['count'] }.max
|
120
|
+
padding = longest.to_i + max.to_s.size + 5
|
121
|
+
ratio = ((Helpers.width)-padding)/max.to_f
|
122
|
+
|
123
|
+
output << "#{'Facet: '.ansi(:faint)}#{Helpers.humanize(name)}" << Helpers.___
|
124
|
+
values['terms'].each_with_index do |value, i|
|
125
|
+
output << value['term'].ljust(longest).ansi(:bold) +
|
126
|
+
" [" + value['count'].to_s.rjust(max.to_s.size) + "] " +
|
127
|
+
" " + '█' * (value['count']*ratio).ceil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
output.join("\n")
|
132
|
+
end
|
133
|
+
|
134
|
+
# Display date histogram facets
|
135
|
+
#
|
136
|
+
def display_date_histogram_facets(json, options={})
|
137
|
+
return unless json['facets']
|
138
|
+
|
139
|
+
output = [] << ''
|
140
|
+
|
141
|
+
facets = json['facets'].select { |name, values| values['_type'] == 'date_histogram' }
|
142
|
+
facets.each do |name, values|
|
143
|
+
max = values['entries'].map { |t| t['count'] }.max
|
144
|
+
padding = 27
|
145
|
+
ratio = ((Helpers.width)-padding)/max.to_f
|
146
|
+
|
147
|
+
interval = options[:interval] || 'day'
|
148
|
+
output << "#{'Facet: '.ansi(:faint)}#{Helpers.humanize(name)} #{interval ? ('(by ' + interval + ')').ansi(:faint) : ''}"
|
149
|
+
output << Helpers.___
|
150
|
+
values['entries'].each_with_index do |value, i|
|
151
|
+
output << Helpers.date(Time.at(value['time'].to_i/1000).utc, interval).rjust(21).ansi(:bold) +
|
152
|
+
" [" + value['count'].to_s.rjust(max.to_s.size) + "] " +
|
153
|
+
" " + '█' * (value['count']*ratio).ceil
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
output.join("\n")
|
158
|
+
end
|
159
|
+
|
160
|
+
# Display statistical facets
|
161
|
+
#
|
162
|
+
def display_statistical_facets(json, options={})
|
163
|
+
return unless json['facets']
|
164
|
+
|
165
|
+
output = [] << ''
|
166
|
+
|
167
|
+
facets = json['facets'].select { |name, values| values['_type'] == 'statistical' }
|
168
|
+
|
169
|
+
facets.each do |name, facet|
|
170
|
+
output << "#{'Facet: '.ansi(:faint)}#{Helpers.humanize(name)}" << Helpers.___
|
171
|
+
output << Helpers.table(facet.reject { |k,v| ['_type'].include? k }.to_a.map do |pair|
|
172
|
+
[ Helpers.humanize(pair[0]), pair[1] ]
|
173
|
+
end)
|
174
|
+
end
|
175
|
+
output.join("\n")
|
176
|
+
end
|
177
|
+
|
178
|
+
# Display the analyze output
|
179
|
+
#
|
180
|
+
def display_analyze_output(json, options={})
|
181
|
+
return unless json['tokens']
|
182
|
+
|
183
|
+
output = [] << ''
|
184
|
+
|
185
|
+
max_length = json['tokens'].map { |d| d['token'].to_s.size }.max
|
186
|
+
|
187
|
+
output << Helpers.table(json['tokens'].map do |t|
|
188
|
+
[
|
189
|
+
t['position'],
|
190
|
+
t['token'].ljust(max_length+5).ansi(:bold),
|
191
|
+
"#{t['start_offset']}–#{t['end_offset']}",
|
192
|
+
t['type']
|
193
|
+
]
|
194
|
+
end).to_s
|
195
|
+
output.join("\n")
|
196
|
+
end
|
197
|
+
|
198
|
+
extend self
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Elasticsearch
|
4
|
+
module Extensions
|
5
|
+
module ANSI
|
6
|
+
|
7
|
+
module Helpers
|
8
|
+
|
9
|
+
# Shortcut for {::ANSI::Table.new}
|
10
|
+
#
|
11
|
+
def table(data, options={}, &format)
|
12
|
+
::ANSI::Table.new(data, options, &format)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Terminal width, based on {::ANSI::Terminal.terminal_width}
|
16
|
+
#
|
17
|
+
def width
|
18
|
+
::ANSI::Terminal.terminal_width-5
|
19
|
+
end
|
20
|
+
|
21
|
+
# Humanize a string
|
22
|
+
#
|
23
|
+
def humanize(string)
|
24
|
+
string.to_s.gsub(/\_/, ' ').split.map { |s| s.capitalize}.join(' ')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Return date formatted by interval
|
28
|
+
#
|
29
|
+
def date(date, interval='day')
|
30
|
+
case interval
|
31
|
+
when 'minute'
|
32
|
+
date.strftime('%a %m/%d %H:%M') + ' – ' + (date+60).strftime('%H:%M')
|
33
|
+
when 'hour'
|
34
|
+
date.strftime('%a %m/%d %H:%M') + ' – ' + (date+60*60).strftime('%H:%M')
|
35
|
+
when 'day'
|
36
|
+
date.strftime('%a %m/%d')
|
37
|
+
when 'week'
|
38
|
+
days_to_monday = date.wday!=0 ? date.wday-1 : 6
|
39
|
+
days_to_sunday = date.wday!=0 ? 7-date.wday : 0
|
40
|
+
start = (date - days_to_monday*24*60*60).strftime('%a %m/%d')
|
41
|
+
stop = (date+(days_to_sunday*24*60*60)).strftime('%a %m/%d')
|
42
|
+
"#{start} – #{stop}"
|
43
|
+
when 'month'
|
44
|
+
date.strftime('%B %Y')
|
45
|
+
when 'year'
|
46
|
+
date.strftime('%Y')
|
47
|
+
else
|
48
|
+
date.strftime('%Y-%m-%d %H:%M')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Output divider
|
53
|
+
#
|
54
|
+
def ___
|
55
|
+
('─'*Helpers.width).ansi(:faint)
|
56
|
+
end
|
57
|
+
|
58
|
+
extend self
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Elasticsearch
|
2
|
+
module Extensions
|
3
|
+
module ANSI
|
4
|
+
|
5
|
+
# Wrapper for the Elasticsearch response body, which adds a {#to_ansi} method
|
6
|
+
#
|
7
|
+
class ResponseBody < DelegateClass(Hash)
|
8
|
+
def initialize(body)
|
9
|
+
super(body)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return a [colorized and formatted](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
13
|
+
# representation of the Elasticsearch response body
|
14
|
+
#
|
15
|
+
def to_ansi(options={})
|
16
|
+
output = Actions.public_methods.select do |m|
|
17
|
+
m.to_s =~ /^display_/
|
18
|
+
end.map do |m|
|
19
|
+
Actions.send(m, self, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
output.compact.join("\n")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module Elasticsearch
|
31
|
+
module Transport
|
32
|
+
module Transport
|
33
|
+
|
34
|
+
class Response
|
35
|
+
# Wrap the response body in the {Extensions::ANSI::ResponseBody} class
|
36
|
+
#
|
37
|
+
def body_to_ansi
|
38
|
+
Extensions::ANSI::ResponseBody.new @body
|
39
|
+
end
|
40
|
+
|
41
|
+
alias_method :body_original, :body
|
42
|
+
alias_method :body, :body_to_ansi
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticsearch-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,56 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: elasticsearch
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.4.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.4.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: ansi
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
14
46
|
- !ruby/object:Gem::Dependency
|
15
47
|
name: bundler
|
16
48
|
requirement: !ruby/object:Gem::Requirement
|
17
49
|
none: false
|
18
50
|
requirements:
|
19
|
-
- -
|
51
|
+
- - ! '>'
|
20
52
|
- !ruby/object:Gem::Version
|
21
|
-
version: '1
|
53
|
+
version: '1'
|
22
54
|
type: :development
|
23
55
|
prerelease: false
|
24
56
|
version_requirements: !ruby/object:Gem::Requirement
|
25
57
|
none: false
|
26
58
|
requirements:
|
27
|
-
- -
|
59
|
+
- - ! '>'
|
28
60
|
- !ruby/object:Gem::Version
|
29
|
-
version: '1
|
61
|
+
version: '1'
|
30
62
|
- !ruby/object:Gem::Dependency
|
31
63
|
name: rake
|
32
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,7 +75,135 @@ dependencies:
|
|
43
75
|
- - ! '>='
|
44
76
|
- !ruby/object:Gem::Version
|
45
77
|
version: '0'
|
46
|
-
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: shoulda-context
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: mocha
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: turn
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: yard
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: ruby-prof
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: simplecov
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: cane
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: require-prof
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
description: Extensions for the Elasticsearch Rubygem
|
47
207
|
email:
|
48
208
|
- karel.minarik@elasticsearch.org
|
49
209
|
executables: []
|
@@ -56,7 +216,12 @@ files:
|
|
56
216
|
- README.md
|
57
217
|
- Rakefile
|
58
218
|
- elasticsearch-extensions.gemspec
|
219
|
+
- lib/elasticsearch-extensions.rb
|
59
220
|
- lib/elasticsearch/extensions.rb
|
221
|
+
- lib/elasticsearch/extensions/ansi.rb
|
222
|
+
- lib/elasticsearch/extensions/ansi/actions.rb
|
223
|
+
- lib/elasticsearch/extensions/ansi/helpers.rb
|
224
|
+
- lib/elasticsearch/extensions/ansi/response.rb
|
60
225
|
- lib/elasticsearch/extensions/version.rb
|
61
226
|
homepage: ''
|
62
227
|
licenses:
|
@@ -82,6 +247,6 @@ rubyforge_project:
|
|
82
247
|
rubygems_version: 1.8.23
|
83
248
|
signing_key:
|
84
249
|
specification_version: 3
|
85
|
-
summary: Extensions for the Elasticsearch
|
250
|
+
summary: Extensions for the Elasticsearch Rubygem
|
86
251
|
test_files: []
|
87
252
|
has_rdoc:
|