algoliasearch 1.1.17 → 1.1.18

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14d536f146b031e91b22b0fa8fd6ae490d5313ca
4
- data.tar.gz: 6363a928bb6e679e51b55e73fffdc5b8fdea4b6a
3
+ metadata.gz: ed9bdf3f12f211dae2feda61a34a774cd2290cfd
4
+ data.tar.gz: f90d402531a97f525a1d6e653afd4dc306e91bdf
5
5
  SHA512:
6
- metadata.gz: d618bbb9d33e9af749ba5a0b5a61bb7c94f3c3af1680d28969eb080df1ebc3abb9ccc48f5bb7e0c455eca13ba4080a8af18ea82c955c0ac00f58644253be1fba
7
- data.tar.gz: 4492f1024fe3bdaeacc0523ea0d3e99cc63db2d03cbbc8c8ab5a19cc58b8bcad18f790a23708744e91b9db14d9ba5fe69badfc06bb41c2ccc434d27c31d3777e
6
+ metadata.gz: 3d14cde3da631f5d2dbd769749103c2b27b26e700c2e8626b35581c72b820e945a6d1cce524a09a40b655ed6b64e3819144daf8b0e960de003ecdaef4b640dbe
7
+ data.tar.gz: 16d7cb85403471dad4b9b1a8f494d8ba72b11bc08b712a228682367bf5189cdfbaff45a21960ef0082add8a4a31b0e4c5202c9e579bf0700cb5b820601887b3a
data/ChangeLog CHANGED
@@ -1,5 +1,9 @@
1
1
  CHANGELOG
2
2
 
3
+ 2014-01-06 1.1.18
4
+
5
+ * Fixed batch request builder (broken since last refactoring)
6
+
3
7
  2014-01-02 1.1.17
4
8
 
5
9
  * Ability to use IP rate limit behind a proxy forwarding the end-user's IP
data/README.md CHANGED
@@ -427,7 +427,8 @@ You can also create an API Key with advanced restrictions:
427
427
  * Add a validity period: the key will be valid only for a specific period of time (in seconds),
428
428
  * Specify the maximum number of API calls allowed from an IP address per hour. Each time an API call is performed with this key, a check is performed. If the IP at the origin of the call did more than this number of calls in the last hour, a 403 code is returned. Defaults to 0 (no rate limit). This parameter can be used to protect you from attempts at retrieving your entire content by massively querying the index.
429
429
 
430
- Note: If you are sending the query through your servers, you must use the `Algolia.enable_rate_limit_forward("TheAdminAPIKey", "EndUserIP", "APIKeyWithRateLimit")` function to enable rate-limit.
430
+ Note: If you are sending the query through your servers, you must use the `Algolia.with_rate_limits("EndUserIP", "APIKeyWithRateLimit") do ... end` block to enable rate-limit.
431
+
431
432
  * Specify the maximum number of hits this API key can retrieve in one call. Defaults to 0 (unlimited). This parameter can be used to protect you from attempts at retrieving your entire content by massively querying the index.
432
433
 
433
434
  ```ruby
@@ -2,15 +2,15 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: algoliasearch 1.1.17 ruby lib
5
+ # stub: algoliasearch 1.1.18 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "algoliasearch"
9
- s.version = "1.1.17"
9
+ s.version = "1.1.18"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.authors = ["Algolia"]
13
- s.date = "2014-01-02"
13
+ s.date = "2014-01-06"
14
14
  s.description = "A simple Ruby client for the algolia.com REST API"
15
15
  s.email = "contact@algolia.com"
16
16
  s.extra_rdoc_files = [
@@ -29,22 +29,7 @@ module Algolia
29
29
  exceptions = []
30
30
  thread_local_hosts.each do |host|
31
31
  begin
32
- session = host["session"]
33
- session.url = host["base_url"] + uri
34
- case method
35
- when :GET
36
- session.http_get
37
- when :POST
38
- session.post_body = data
39
- session.http_post
40
- when :PUT
41
- session.put(data)
42
- when :DELETE
43
- session.http_delete
44
- end
45
- if session.response_code >= 400 || session.response_code < 200
46
- raise AlgoliaProtocolError.new(session.response_code, "Cannot #{method} to #{session.url}: #{session.body_str} (#{session.response_code})")
47
- end
32
+ session = perform_request(host, uri, method, data)
48
33
  return JSON.parse(session.body_str)
49
34
  rescue AlgoliaProtocolError => e
50
35
  raise if e.code != Protocol::ERROR_TIMEOUT and e.code != Protocol::ERROR_UNAVAILABLE
@@ -74,24 +59,46 @@ module Algolia
74
59
 
75
60
  # this method returns a thread-local array of sessions
76
61
  def thread_local_hosts
77
- if Thread.current[:algolia_hosts].nil?
78
- Thread.current[:algolia_hosts] = hosts.map do |host|
79
- hinfo = {}
80
- hinfo["base_url"] = "http#{@ssl ? 's' : ''}://#{host}"
81
- hinfo["host"] = host
82
- hinfo["session"] = Curl::Easy.new do |s|
83
- s.headers[Protocol::HEADER_API_KEY] = api_key
84
- s.headers[Protocol::HEADER_APP_ID] = application_id
85
- s.headers["Content-Type"] = "application/json; charset=utf-8"
86
- s.headers["User-Agent"] = "Algolia for Ruby #{::Algolia::VERSION}"
87
- s.verbose = true if @debug
88
- s.cacert = File.join File.dirname(__FILE__), '..', '..', 'resources', 'ca-bundle.crt'
89
- s.encoding = ''
90
- end
91
- hinfo
92
- end
62
+ Thread.current[:algolia_hosts] ||= hosts.map do |host|
63
+ hinfo = {}
64
+ hinfo["base_url"] = "http#{@ssl ? 's' : ''}://#{host}"
65
+ hinfo["host"] = host
66
+ hinfo["session"] = init_session
67
+ hinfo
93
68
  end
94
- Thread.current[:algolia_hosts]
69
+ end
70
+
71
+ private
72
+ def perform_request(host, uri, method, data)
73
+ session = host["session"]
74
+ session.url = host["base_url"] + uri
75
+ case method
76
+ when :GET
77
+ session.http_get
78
+ when :POST
79
+ session.post_body = data
80
+ session.http_post
81
+ when :PUT
82
+ session.put(data)
83
+ when :DELETE
84
+ session.http_delete
85
+ end
86
+ if session.response_code >= 400 || session.response_code < 200
87
+ raise AlgoliaProtocolError.new(session.response_code, "Cannot #{method} to #{session.url}: #{session.body_str} (#{session.response_code})")
88
+ end
89
+ session;
90
+ end
91
+
92
+ def init_session
93
+ s = Curl::Easy.new
94
+ s.headers[Protocol::HEADER_API_KEY] = api_key
95
+ s.headers[Protocol::HEADER_APP_ID] = application_id
96
+ s.headers["Content-Type"] = "application/json; charset=utf-8"
97
+ s.headers["User-Agent"] = "Algolia for Ruby #{::Algolia::VERSION}"
98
+ s.verbose = true if @debug
99
+ s.cacert = File.join File.dirname(__FILE__), '..', '..', 'resources', 'ca-bundle.crt'
100
+ s.encoding = ''
101
+ s
95
102
  end
96
103
 
97
104
  end
@@ -49,13 +49,7 @@ module Algolia
49
49
  # @param objs the array of objects to add inside the index.
50
50
  # Each object is represented by an associative array
51
51
  def add_objects(objs)
52
- check_array objs
53
- requests = []
54
- objs.each do |obj|
55
- check_object obj, true
56
- requests.push({"action" => "addObject", "body" => obj})
57
- end
58
- request = {"requests" => requests};
52
+ request = build_batch('addObject', objs, false)
59
53
  Algolia.client.post(Protocol.batch_uri(name), request.to_json)
60
54
  end
61
55
 
@@ -143,7 +137,7 @@ module Algolia
143
137
  # @param hitsPerPage: Pagination parameter used to select the number of hits per page. Defaults to 1000.
144
138
  #
145
139
  def browse(page = 0, hitsPerPage = 1000)
146
- Algolia.client.get(Protocol.browse_uri(name, {"page" => page, "hitsPerPage" => hitsPerPage}))
140
+ Algolia.client.get(Protocol.browse_uri(name, {:page => page, :hitsPerPage => hitsPerPage}))
147
141
  end
148
142
 
149
143
  #
@@ -156,7 +150,7 @@ module Algolia
156
150
  if attributesToRetrieve.nil?
157
151
  Algolia.client.get(Protocol.object_uri(name, objectID, nil))
158
152
  else
159
- Algolia.client.get(Protocol.object_uri(name, objectID, {"attributes" => attributesToRetrieve}))
153
+ Algolia.client.get(Protocol.object_uri(name, objectID, {:attributes => attributesToRetrieve}))
160
154
  end
161
155
  end
162
156
 
@@ -182,10 +176,7 @@ module Algolia
182
176
  # @param objectID the associated objectID, if nil 'obj' must contain an 'objectID' key
183
177
  #
184
178
  def save_object(obj, objectID = nil)
185
- check_object obj
186
- objectID ||= obj[:objectID] || obj["objectID"]
187
- raise ArgumentError.new("Missing 'objectID'") if objectID.nil?
188
- Algolia.client.put(Protocol.object_uri(name, objectID), obj.to_json)
179
+ Algolia.client.put(Protocol.object_uri(name, get_objectID(obj, objectID)), obj.to_json)
189
180
  end
190
181
 
191
182
  # Override the content of object and wait indexing
@@ -204,15 +195,7 @@ module Algolia
204
195
  # @param objs the array of objects to save, each object must contain an 'objectID' key
205
196
  #
206
197
  def save_objects(objs)
207
- check_array objs
208
- requests = []
209
- objs.each do |obj|
210
- check_object obj, true
211
- objectID = obj[:objectID] || obj["objectID"]
212
- raise ArgumentError.new("Missing 'objectID'") if objectID.nil?
213
- requests.push({"action" => "updateObject", "objectID" => objectID, "body" => obj})
214
- end
215
- request = {"requests" => requests};
198
+ request = build_batch('updateObject', objs, true)
216
199
  Algolia.client.post(Protocol.batch_uri(name), request.to_json)
217
200
  end
218
201
 
@@ -233,10 +216,7 @@ module Algolia
233
216
  # @param objectID the associated objectID, if nil 'obj' must contain an 'objectID' key
234
217
  #
235
218
  def partial_update_object(obj, objectID = nil)
236
- check_object obj
237
- objectID ||= obj[:objectID] || obj["objectID"]
238
- raise ArgumentError.new("Missing 'objectID'") if objectID.nil?
239
- Algolia.client.post(Protocol.partial_object_uri(name, objectID), obj.to_json)
219
+ Algolia.client.post(Protocol.partial_object_uri(name, get_objectID(obj, objectID)), obj.to_json)
240
220
  end
241
221
 
242
222
  #
@@ -245,15 +225,7 @@ module Algolia
245
225
  # @param objs an array of objects to update (each object must contains a objectID attribute)
246
226
  #
247
227
  def partial_update_objects(objs)
248
- check_array objs
249
- requests = []
250
- objs.each do |obj|
251
- check_object obj, true
252
- objectID = obj[:objectID] || obj["objectID"]
253
- raise ArgumentError.new("Missing 'objectID'") if objectID.nil?
254
- requests.push({"action" => "partialUpdateObject", "objectID" => objectID, "body" => obj})
255
- end
256
- request = {"requests" => requests};
228
+ request = build_batch('partialUpdateObject', objs, true)
257
229
  Algolia.client.post(Protocol.batch_uri(name), request.to_json)
258
230
  end
259
231
 
@@ -402,7 +374,7 @@ module Algolia
402
374
  # @param validity the number of seconds after which the key will be automatically removed (0 means no time limit for this key)
403
375
  #
404
376
  def add_user_key(acls, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0)
405
- Algolia.client.post(Protocol.index_keys_uri(name), {"acl" => acls, "validity" => validity, "maxQueriesPerIPPerHour" => maxQueriesPerIPPerHour.to_i, "maxHitsPerQuery" => maxHitsPerQuery.to_i}.to_json)
377
+ Algolia.client.post(Protocol.index_keys_uri(name), {:acl => acls, :validity => validity, :maxQueriesPerIPPerHour => maxQueriesPerIPPerHour.to_i, :maxHitsPerQuery => maxHitsPerQuery.to_i}.to_json)
406
378
  end
407
379
 
408
380
  # Delete an existing user key
@@ -426,5 +398,24 @@ module Algolia
426
398
  end
427
399
  end
428
400
 
401
+ def get_objectID(obj, objectID = nil)
402
+ check_object obj
403
+ objectID ||= obj[:objectID] || obj["objectID"]
404
+ raise ArgumentError.new("Missing 'objectID'") if objectID.nil?
405
+ return objectID
406
+ end
407
+
408
+ def build_batch(action, objs, with_object_id = false)
409
+ check_array objs
410
+ {
411
+ :requests => objs.map { |obj|
412
+ check_object obj, true
413
+ h = { :action => action, :body => obj }
414
+ h[:objectID] = get_objectID(obj).to_s if with_object_id
415
+ h
416
+ }
417
+ }
418
+ end
419
+
429
420
  end
430
421
  end
@@ -105,7 +105,7 @@ module Algolia
105
105
  private
106
106
  def Protocol.to_query(params)
107
107
  params.map do |k, v|
108
- "#{CGI.escape(k)}=#{CGI.escape(v.to_s)}"
108
+ "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
109
109
  end.join('&')
110
110
  end
111
111
 
@@ -1,3 +1,3 @@
1
1
  module Algolia
2
- VERSION = "1.1.17"
2
+ VERSION = "1.1.18"
3
3
  end
@@ -28,6 +28,15 @@ describe 'Client' do
28
28
  res["hits"].length.should eq(2)
29
29
  end
30
30
 
31
+ it "should save a set of objects with their ids" do
32
+ @index.save_objects!([
33
+ { :name => "objectid", :email => "objectid1@example.org", :objectID => 101 },
34
+ { :name => "objectid", :email => "objectid2@example.org", :objectID => 102 }
35
+ ])
36
+ res = @index.search("objectid")
37
+ res["hits"].length.should eq(2)
38
+ end
39
+
31
40
  it "should throw an exception if invalid argument" do
32
41
  expect { @index.add_object!([ {:name => "test"} ]) }.to raise_error(ArgumentError)
33
42
  expect { @index.add_objects!([ [ {:name => "test"} ] ]) }.to raise_error(ArgumentError)
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.1.17
4
+ version: 1.1.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algolia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-02 00:00:00.000000000 Z
11
+ date: 2014-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curb