algoliasearch 1.26.1 → 1.27.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/.travis.yml +4 -1
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +4 -20
- data/lib/algolia/client.rb +22 -0
- data/lib/algolia/error.rb +9 -1
- data/lib/algolia/index.rb +87 -0
- data/lib/algolia/version.rb +1 -1
- data/spec/client_spec.rb +91 -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: 9036ce666897c7cfb05a637b80ffcebc26a08560ac655bca29f0bbaa631aa2e6
|
4
|
+
data.tar.gz: 39a1e847147a3d9f08fa529045abaec8725d95c7cb4f8a496646c0b2dd25f9d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db1d480cc1aa22bf2c2ea547740ab905440928dab50680afb21998bffa9b6ffd29aef6dda35a0263bf5c4a61c398a7d6e260c045efe636fc1a0dbc781dd15b44
|
7
|
+
data.tar.gz: 22e70e7d376ca9ef5fca68e13b381eedd854afef4d315a2d2e18c6c2b64562e2d1952d8a17dad309171bc33dc489728004cbf9bc668fd39fc6d4e81a18bc2aa8
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
# ChangeLog
|
2
2
|
|
3
|
+
## [1.27.0](https://github.com/algolia/algoliasearch-client-ruby/releases/tag/1.27.0) (2019-09-16)
|
4
|
+
|
5
|
+
**Added**
|
6
|
+
|
7
|
+
* Introduce `Algolia::Index.exists` method. [358](https://github.com/algolia/algoliasearch-client-ruby/issues/358)
|
8
|
+
|
9
|
+
Check whether an index exists or not.
|
10
|
+
|
11
|
+
* Introduce `Algolia::Index.find_object` method. [359](https://github.com/algolia/algoliasearch-client-ruby/issues/359)
|
12
|
+
|
13
|
+
Find object by the given condition.
|
14
|
+
|
15
|
+
* Introduce `Algolia::Index.get_object_position` method. [359](https://github.com/algolia/algoliasearch-client-ruby/issues/359)
|
16
|
+
|
17
|
+
Retrieve the given object position in a set of results.
|
18
|
+
|
19
|
+
* Introduce `Algolia.get_secured_api_key_remaining_validity` method. [361](https://github.com/algolia/algoliasearch-client-ruby/issues/361)
|
20
|
+
|
21
|
+
Returns the remaining validity time for the given API key in seconds.
|
22
|
+
|
23
|
+
|
3
24
|
## [1.26.1](https://github.com/algolia/algoliasearch-client-ruby/compare/1.26.0...1.26.1) (2019-07-31)
|
4
25
|
|
5
26
|
### Chore
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
algoliasearch (1.26.
|
4
|
+
algoliasearch (1.26.1)
|
5
5
|
httpclient (~> 2.8, >= 2.8.3)
|
6
6
|
json (>= 1.5.1)
|
7
7
|
|
@@ -10,12 +10,6 @@ GEM
|
|
10
10
|
specs:
|
11
11
|
addressable (2.4.0)
|
12
12
|
backports (3.15.0)
|
13
|
-
coveralls (0.7.2)
|
14
|
-
multi_json (~> 1.3)
|
15
|
-
rest-client (= 1.6.7)
|
16
|
-
simplecov (>= 0.7)
|
17
|
-
term-ansicolor (= 1.2.2)
|
18
|
-
thor (= 0.18.1)
|
19
13
|
crack (0.4.3)
|
20
14
|
safe_yaml (~> 1.0.0)
|
21
15
|
diff-lcs (1.3)
|
@@ -41,9 +35,6 @@ GEM
|
|
41
35
|
json (2.2.0)
|
42
36
|
launchy (2.4.3)
|
43
37
|
addressable (~> 2.3)
|
44
|
-
mime-types (3.2.2)
|
45
|
-
mime-types-data (~> 3.2015)
|
46
|
-
mime-types-data (3.2019.0331)
|
47
38
|
multi_json (1.13.1)
|
48
39
|
multipart-post (2.1.1)
|
49
40
|
net-http-persistent (2.9.4)
|
@@ -51,10 +42,8 @@ GEM
|
|
51
42
|
pusher-client (0.6.2)
|
52
43
|
json
|
53
44
|
websocket (~> 1.0)
|
54
|
-
rake (12.3.
|
55
|
-
rdoc (6.
|
56
|
-
rest-client (1.6.7)
|
57
|
-
mime-types (>= 1.16)
|
45
|
+
rake (12.3.3)
|
46
|
+
rdoc (6.2.0)
|
58
47
|
rspec (3.8.0)
|
59
48
|
rspec-core (~> 3.8.0)
|
60
49
|
rspec-expectations (~> 3.8.0)
|
@@ -276,10 +265,6 @@ GEM
|
|
276
265
|
json (>= 1.8, < 3)
|
277
266
|
simplecov-html (~> 0.10.0)
|
278
267
|
simplecov-html (0.10.2)
|
279
|
-
term-ansicolor (1.2.2)
|
280
|
-
tins (~> 0.8)
|
281
|
-
thor (0.18.1)
|
282
|
-
tins (0.13.2)
|
283
268
|
travis (1.8.10)
|
284
269
|
backports
|
285
270
|
faraday (~> 0.9)
|
@@ -291,7 +276,7 @@ GEM
|
|
291
276
|
typhoeus (~> 0.6, >= 0.6.8)
|
292
277
|
typhoeus (0.8.0)
|
293
278
|
ethon (>= 0.8.0)
|
294
|
-
webmock (3.
|
279
|
+
webmock (3.7.2)
|
295
280
|
addressable (>= 2.3.6)
|
296
281
|
crack (>= 0.3.2)
|
297
282
|
hashdiff (>= 0.4.0, < 2.0.0)
|
@@ -302,7 +287,6 @@ PLATFORMS
|
|
302
287
|
|
303
288
|
DEPENDENCIES
|
304
289
|
algoliasearch!
|
305
|
-
coveralls
|
306
290
|
rake
|
307
291
|
rdoc
|
308
292
|
rspec (>= 2.5.0)
|
data/lib/algolia/client.rb
CHANGED
@@ -774,6 +774,28 @@ module Algolia
|
|
774
774
|
end
|
775
775
|
end
|
776
776
|
|
777
|
+
#
|
778
|
+
# Returns the remaining validity time for the given API key in seconds
|
779
|
+
#
|
780
|
+
# @param [String] secured_api_key the secured API key to check
|
781
|
+
#
|
782
|
+
# @return [Integer] remaining validity in seconds
|
783
|
+
#
|
784
|
+
def Algolia.get_secured_api_key_remaining_validity(secured_api_key)
|
785
|
+
now = Time.now.to_i
|
786
|
+
decoded_key = Base64.decode64(secured_api_key)
|
787
|
+
regex = 'validUntil=(\d+)'
|
788
|
+
matches = decoded_key.match(regex)
|
789
|
+
|
790
|
+
if matches === nil
|
791
|
+
raise ValidUntilNotFoundError.new('The SecuredAPIKey doesn\'t have a validUntil parameter.')
|
792
|
+
end
|
793
|
+
|
794
|
+
valid_until = matches[1].to_i
|
795
|
+
|
796
|
+
valid_until - now
|
797
|
+
end
|
798
|
+
|
777
799
|
#
|
778
800
|
# This method allows to query multiple indexes with one API call
|
779
801
|
#
|
data/lib/algolia/error.rb
CHANGED
@@ -20,4 +20,12 @@ module Algolia
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
|
23
|
+
# An exception class raised when the given object was not found.
|
24
|
+
class AlgoliaObjectNotFoundError < AlgoliaError
|
25
|
+
end
|
26
|
+
|
27
|
+
# An exception class raised when the validUntil parameter is not found
|
28
|
+
class ValidUntilNotFoundError < AlgoliaError
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/lib/algolia/index.rb
CHANGED
@@ -264,6 +264,75 @@ module Algolia
|
|
264
264
|
client.post(Protocol.objects_uri, { :requests => requests }.to_json, :read, request_options)['results']
|
265
265
|
end
|
266
266
|
|
267
|
+
#
|
268
|
+
# Find object by the given condition.
|
269
|
+
#
|
270
|
+
# Options can be passed in request_options body:
|
271
|
+
# - query (string): pass a query
|
272
|
+
# - paginate (bool): choose if you want to iterate through all the
|
273
|
+
# documents (true) or only the first page (false). Default is true.
|
274
|
+
# The function takes a block to filter the results from search query
|
275
|
+
# Usage example:
|
276
|
+
# index.find_object({'query' => '', 'paginate' => true}) {|obj| obj.key?('company') and obj['company'] == 'Apple'}
|
277
|
+
#
|
278
|
+
# @param request_options contains extra parameters to send with your query
|
279
|
+
#
|
280
|
+
# @return [Hash] the matching object and its position in the result set
|
281
|
+
#
|
282
|
+
def find_object(request_options = {})
|
283
|
+
paginate = true
|
284
|
+
page = 0
|
285
|
+
|
286
|
+
query = request_options[:query] || request_options['query'] || ''
|
287
|
+
request_options.delete(:query)
|
288
|
+
request_options.delete('query')
|
289
|
+
|
290
|
+
if request_options.has_key? :paginate
|
291
|
+
paginate = request_options[:paginate]
|
292
|
+
end
|
293
|
+
|
294
|
+
if request_options.has_key? 'paginate'
|
295
|
+
paginate = request_options['paginate']
|
296
|
+
end
|
297
|
+
|
298
|
+
request_options.delete(:paginate)
|
299
|
+
request_options.delete('paginate')
|
300
|
+
|
301
|
+
while true
|
302
|
+
request_options['page'] = page
|
303
|
+
res = search(query, request_options)
|
304
|
+
|
305
|
+
res['hits'].each_with_index do |hit, i|
|
306
|
+
if yield(hit)
|
307
|
+
return {
|
308
|
+
'object' => hit,
|
309
|
+
'position' => i,
|
310
|
+
'page' => page,
|
311
|
+
}
|
312
|
+
end
|
313
|
+
end if block_given?
|
314
|
+
|
315
|
+
has_next_page = page + 1 < res['nbPages']
|
316
|
+
if !paginate || !has_next_page
|
317
|
+
raise AlgoliaObjectNotFoundError.new('Object not found')
|
318
|
+
end
|
319
|
+
|
320
|
+
page += 1
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
#
|
325
|
+
# Retrieve the given object position in a set of results.
|
326
|
+
#
|
327
|
+
# @param [Array] objects the result set to browse
|
328
|
+
# @param [String] object_id the object to look for
|
329
|
+
#
|
330
|
+
# @return [Integer] position of the object, or -1 if it's not in the array
|
331
|
+
#
|
332
|
+
def self.get_object_position(objects, object_id)
|
333
|
+
objects['hits'].find_index { |hit| hit['objectID'] == object_id } || -1
|
334
|
+
end
|
335
|
+
|
267
336
|
#
|
268
337
|
# Check the status of a task on the server.
|
269
338
|
# All server task are asynchronous and you can check the status of a task with this method.
|
@@ -1208,6 +1277,24 @@ module Algolia
|
|
1208
1277
|
res
|
1209
1278
|
end
|
1210
1279
|
|
1280
|
+
#
|
1281
|
+
# Check whether an index exists or not
|
1282
|
+
#
|
1283
|
+
# @return [Boolean]
|
1284
|
+
#
|
1285
|
+
def exists
|
1286
|
+
begin
|
1287
|
+
get_settings
|
1288
|
+
rescue AlgoliaProtocolError => e
|
1289
|
+
if e.code === 404
|
1290
|
+
return false
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
raise e
|
1294
|
+
end
|
1295
|
+
return true
|
1296
|
+
end
|
1297
|
+
|
1211
1298
|
# Deprecated
|
1212
1299
|
alias_method :get_user_key, :get_api_key
|
1213
1300
|
alias_method :list_user_keys, :list_api_keys
|
data/lib/algolia/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -175,6 +175,16 @@ describe 'Client' do
|
|
175
175
|
@index.delete_index rescue "not fatal"
|
176
176
|
end
|
177
177
|
|
178
|
+
it "should tell if index exists" do
|
179
|
+
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
180
|
+
expect(@index.exists).to be true
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should tell if index does not exist" do
|
184
|
+
index = Algolia::Index.new('nonexistent_index')
|
185
|
+
expect(index.exists).to be false
|
186
|
+
end
|
187
|
+
|
178
188
|
it "should add a simple object" do
|
179
189
|
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
180
190
|
res = @index.search("john")
|
@@ -436,6 +446,73 @@ describe 'Client' do
|
|
436
446
|
end
|
437
447
|
end
|
438
448
|
|
449
|
+
it 'should find objects when needed' do
|
450
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
451
|
+
|
452
|
+
index.save_objects!([
|
453
|
+
{:company => 'Algolia', :name => 'Julien Lemoine', :objectID => 'julien-lemoine'},
|
454
|
+
{:company => 'Algolia', :name => 'Nicolas Dessaigne', :objectID => 'nicolas-dessaigne'},
|
455
|
+
{:company => 'Amazon', :name =>' "Jeff Bezos', :objectID => '162590850'},
|
456
|
+
{:company => 'Apple', :name => 'Steve Jobs', :objectID => '162590860'},
|
457
|
+
{:company => 'Apple', :name => 'Steve Wozniak', :objectID => '162590870'},
|
458
|
+
{:company => 'Arista Networks', :name => 'Jayshree Ullal', :objectID => '162590880'},
|
459
|
+
{:company => 'Google', :name => 'Larry Page', :objectID => '162590890'},
|
460
|
+
{:company => 'Google', :name => 'Rob Pike', :objectID => '162590900'},
|
461
|
+
{:company => 'Google', :name => 'Sergueï Brin', :objectID => '162590910'},
|
462
|
+
{:company => 'Microsoft', :name => 'Bill Gates', :objectID => '162590920'},
|
463
|
+
{:company => 'SpaceX', :name => 'Elon Musk', :objectID => '162590930'},
|
464
|
+
{:company => 'Tesla', :name => 'Elon Musk', :objectID => '162590940'},
|
465
|
+
{:company => 'Yahoo', :name => 'Marissa Mayer', :objectID => '162590950'},
|
466
|
+
])
|
467
|
+
|
468
|
+
res = index.search('algolia')
|
469
|
+
Algolia::Index.get_object_position(res, 'nicolas-dessaigne').should eq(0)
|
470
|
+
Algolia::Index.get_object_position(res, 'julien-lemoine').should eq(1)
|
471
|
+
Algolia::Index.get_object_position(res, '').should eq(-1)
|
472
|
+
|
473
|
+
expect {
|
474
|
+
index.find_object({'query' => '', 'paginate' => true})
|
475
|
+
}.to raise_exception(
|
476
|
+
Algolia::AlgoliaObjectNotFoundError,
|
477
|
+
'Object not found'
|
478
|
+
)
|
479
|
+
|
480
|
+
expect {
|
481
|
+
index.find_object({'query' => '', 'paginate' => true}) { false }
|
482
|
+
}.to raise_exception(
|
483
|
+
Algolia::AlgoliaObjectNotFoundError,
|
484
|
+
'Object not found'
|
485
|
+
)
|
486
|
+
|
487
|
+
obj = index.find_object({'query' => '', 'paginate' => true}) { true }
|
488
|
+
obj['position'].should eq(0)
|
489
|
+
obj['page'].should eq(0)
|
490
|
+
|
491
|
+
# we use a lambda and convert it to a block with `&`
|
492
|
+
# so as not to repeat the condition
|
493
|
+
condition = lambda do |obj|
|
494
|
+
obj.key?('company') and obj['company'] == 'Apple'
|
495
|
+
end
|
496
|
+
|
497
|
+
expect {
|
498
|
+
index.find_object({'query' => 'algolia', 'paginate' => true}, &condition)
|
499
|
+
}.to raise_exception(
|
500
|
+
Algolia::AlgoliaObjectNotFoundError,
|
501
|
+
'Object not found'
|
502
|
+
)
|
503
|
+
|
504
|
+
expect {
|
505
|
+
index.find_object({'query' => '', 'paginate' => false, 'hitsPerPage' => 5}, &condition)
|
506
|
+
}.to raise_exception(
|
507
|
+
Algolia::AlgoliaObjectNotFoundError,
|
508
|
+
'Object not found'
|
509
|
+
)
|
510
|
+
|
511
|
+
obj = index.find_object({'query' => '', 'paginate' => true, 'hitsPerPage' => 5}, &condition)
|
512
|
+
obj['position'].should eq(0)
|
513
|
+
obj['page'].should eq(2)
|
514
|
+
end
|
515
|
+
|
439
516
|
it "should copy the index" do
|
440
517
|
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
441
518
|
begin
|
@@ -615,7 +692,7 @@ describe 'Client' do
|
|
615
692
|
expect { Algolia.multiple_queries([{"query" => ""}]) }.to raise_error(ArgumentError)
|
616
693
|
end
|
617
694
|
|
618
|
-
it "
|
695
|
+
it "should accept custom batch" do
|
619
696
|
@index.clear_index! rescue "Not fatal"
|
620
697
|
request = { "requests" => [
|
621
698
|
{
|
@@ -1277,6 +1354,19 @@ describe 'Client' do
|
|
1277
1354
|
expect{Algolia.list_indexes('headers' => { 'X-Algolia-API-Key' => 'NotExistentAPIKey' })}.to raise_error(Algolia::AlgoliaProtocolError)
|
1278
1355
|
end
|
1279
1356
|
|
1357
|
+
it 'should retrieve the remaining validity time in seconds' do
|
1358
|
+
now = Time.now.to_i
|
1359
|
+
|
1360
|
+
key = Algolia.generate_secured_api_key('foo', :validUntil => now - (10 * 60))
|
1361
|
+
expect(Algolia.get_secured_api_key_remaining_validity(key)).to be < 0
|
1362
|
+
|
1363
|
+
key = Algolia.generate_secured_api_key('foo', :validUntil => now + (10 * 60))
|
1364
|
+
expect(Algolia.get_secured_api_key_remaining_validity(key)).to be > 0
|
1365
|
+
|
1366
|
+
key = Algolia.generate_secured_api_key('foo', [])
|
1367
|
+
expect { Algolia.get_secured_api_key_remaining_validity(key) }.to raise_error(Algolia::ValidUntilNotFoundError)
|
1368
|
+
end
|
1369
|
+
|
1280
1370
|
context 'DNS timeout' do
|
1281
1371
|
before(:each) do
|
1282
1372
|
@client = Algolia::Client.new :application_id => ENV['ALGOLIA_APPLICATION_ID'], :api_key => ENV['ALGOLIA_API_KEY'],
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algoliasearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.27.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Algolia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
@@ -145,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
requirements: []
|
148
|
-
rubygems_version: 3.0.
|
148
|
+
rubygems_version: 3.0.4
|
149
149
|
signing_key:
|
150
150
|
specification_version: 4
|
151
151
|
summary: A simple Ruby client for the algolia.com REST API
|