datasift 3.3.0 → 3.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b1fe731a05bf2f78cee04bd0d37a053991ee0b08
4
- data.tar.gz: 119a97e10c022290c0a239c0fd192b63a13eca3d
3
+ metadata.gz: 231dfbf3fbb478090969896e459179651d9aab7d
4
+ data.tar.gz: dc955abee233f6cb82a5765065796563a89ef268
5
5
  SHA512:
6
- metadata.gz: 660b017e290d8218413938369e93f5bdf3c784971d954497d6b8d14de9049dca430b4a78f13867acf458fe10085815357d7d7b0a0016ec4a962e2eaf87c0890c
7
- data.tar.gz: d99b43dc735b245c684fffde08cdb65ee4fa47c892c91330e6ee67def6a634df015ddeb46c16b6ba7c4ebfcac07c917610c6cc52cb391c3f375f74a74e76dd7c
6
+ metadata.gz: 5adc6aa0777edfef9835b08e1e133a63805cf10e926ab67fda130cca85ca79509e466d91b1c7eb21affa44f6829dd7fdc1c2807e0ae66666581c44aa532b3161
7
+ data.tar.gz: 7074591477540122765b3c91bd3dec1dbd1f2d65371277fb59b24a523455e791f44c21d2fa2572fa4abe04ce21f20a52203485bab10957bc349b8d1ee39ac8b3
data/.rubocop.yml ADDED
@@ -0,0 +1 @@
1
+ inherit_from: .rubocop_todo.yml
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,300 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2015-08-14 10:29:23 +0100 using RuboCop version 0.32.0.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 1
9
+ Lint/ParenthesesAsGroupedExpression:
10
+ Enabled: false
11
+
12
+ # Offense count: 1
13
+ Lint/RescueException:
14
+ Enabled: false
15
+
16
+ # Offense count: 2
17
+ # Cop supports --auto-correct.
18
+ Lint/SpaceBeforeFirstArg:
19
+ Enabled: false
20
+
21
+ # Offense count: 5
22
+ # Cop supports --auto-correct.
23
+ Lint/UnusedBlockArgument:
24
+ Enabled: false
25
+
26
+ # Offense count: 2
27
+ Lint/UselessAssignment:
28
+ Enabled: false
29
+
30
+ # Offense count: 27
31
+ Metrics/AbcSize:
32
+ Max: 106
33
+
34
+ # Offense count: 1
35
+ # Configuration parameters: CountComments.
36
+ Metrics/ClassLength:
37
+ Max: 108
38
+
39
+ # Offense count: 13
40
+ Metrics/CyclomaticComplexity:
41
+ Max: 15
42
+
43
+ # Offense count: 118
44
+ # Configuration parameters: AllowURI, URISchemes.
45
+ LineLength:
46
+ Max: 90
47
+
48
+ # Offense count: 33
49
+ # Configuration parameters: CountComments.
50
+ Metrics/MethodLength:
51
+ Max: 91
52
+
53
+ # Offense count: 1
54
+ # Configuration parameters: CountComments.
55
+ Metrics/ModuleLength:
56
+ Max: 232
57
+
58
+ # Offense count: 8
59
+ # Configuration parameters: CountKeywordArgs.
60
+ Metrics/ParameterLists:
61
+ Max: 8
62
+
63
+ # Offense count: 8
64
+ Metrics/PerceivedComplexity:
65
+ Max: 16
66
+
67
+ # Offense count: 2
68
+ # Cop supports --auto-correct.
69
+ Style/AlignArray:
70
+ Enabled: false
71
+
72
+ # Offense count: 1
73
+ # Cop supports --auto-correct.
74
+ # Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles.
75
+ Style/AlignHash:
76
+ Enabled: false
77
+
78
+ # Offense count: 6
79
+ # Cop supports --auto-correct.
80
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
81
+ Style/AlignParameters:
82
+ Enabled: false
83
+
84
+ # Offense count: 3
85
+ # Cop supports --auto-correct.
86
+ # Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
87
+ Style/BlockDelimiters:
88
+ Enabled: false
89
+
90
+ # Offense count: 20
91
+ # Cop supports --auto-correct.
92
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
93
+ Style/BracesAroundHashParameters:
94
+ Enabled: false
95
+
96
+ # Offense count: 20
97
+ # Cop supports --auto-correct.
98
+ # Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep.
99
+ Style/CaseIndentation:
100
+ Enabled: false
101
+
102
+ # Offense count: 1
103
+ # Cop supports --auto-correct.
104
+ Style/ColonMethodCall:
105
+ Enabled: false
106
+
107
+ # Offense count: 7
108
+ # Cop supports --auto-correct.
109
+ Style/CommentIndentation:
110
+ Enabled: false
111
+
112
+ # Offense count: 6
113
+ # Cop supports --auto-correct.
114
+ Style/DeprecatedHashMethods:
115
+ Enabled: false
116
+
117
+ # Offense count: 14
118
+ Style/Documentation:
119
+ Enabled: false
120
+
121
+ # Offense count: 5
122
+ # Cop supports --auto-correct.
123
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
124
+ Style/EmptyElse:
125
+ Enabled: false
126
+
127
+ # Offense count: 2
128
+ # Cop supports --auto-correct.
129
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
130
+ Style/EmptyLinesAroundBlockBody:
131
+ Enabled: false
132
+
133
+ # Offense count: 2
134
+ # Cop supports --auto-correct.
135
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
136
+ Style/EmptyLinesAroundClassBody:
137
+ Enabled: false
138
+
139
+ # Offense count: 1
140
+ # Configuration parameters: MinBodyLength.
141
+ Style/GuardClause:
142
+ Enabled: false
143
+
144
+ # Offense count: 181
145
+ # Cop supports --auto-correct.
146
+ # Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues.
147
+ Style/HashSyntax:
148
+ Enabled: false
149
+
150
+ # Offense count: 2
151
+ # Cop supports --auto-correct.
152
+ # Configuration parameters: MaxLineLength.
153
+ Style/IfUnlessModifier:
154
+ Enabled: false
155
+
156
+ # Offense count: 2
157
+ # Cop supports --auto-correct.
158
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
159
+ Style/IndentHash:
160
+ Enabled: false
161
+
162
+ # Offense count: 3
163
+ # Cop supports --auto-correct.
164
+ Style/Lambda:
165
+ Enabled: false
166
+
167
+ # Offense count: 12
168
+ # Cop supports --auto-correct.
169
+ Style/LeadingCommentSpace:
170
+ Enabled: false
171
+
172
+ # Offense count: 1
173
+ # Cop supports --auto-correct.
174
+ Style/LineEndConcatenation:
175
+ Enabled: false
176
+
177
+ # Offense count: 2
178
+ # Cop supports --auto-correct.
179
+ Style/MethodCallParentheses:
180
+ Enabled: false
181
+
182
+ # Offense count: 1
183
+ # Cop supports --auto-correct.
184
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
185
+ Style/MethodDefParentheses:
186
+ Enabled: false
187
+
188
+ # Offense count: 2
189
+ Style/MultilineTernaryOperator:
190
+ Enabled: false
191
+
192
+ # Offense count: 4
193
+ # Cop supports --auto-correct.
194
+ Style/NegatedIf:
195
+ Enabled: false
196
+
197
+ # Offense count: 2
198
+ # Cop supports --auto-correct.
199
+ Style/NilComparison:
200
+ Enabled: false
201
+
202
+ # Offense count: 7
203
+ # Cop supports --auto-correct.
204
+ Style/NumericLiterals:
205
+ MinDigits: 10
206
+
207
+ # Offense count: 2
208
+ # Cop supports --auto-correct.
209
+ # Configuration parameters: PreferredDelimiters.
210
+ Style/PercentLiteralDelimiters:
211
+ Enabled: false
212
+
213
+ # Offense count: 1
214
+ # Configuration parameters: NamePrefix, NamePrefixBlacklist.
215
+ Style/PredicateName:
216
+ Enabled: false
217
+
218
+ # Offense count: 14
219
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
220
+ Style/RaiseArgs:
221
+ Enabled: false
222
+
223
+ # Offense count: 11
224
+ # Cop supports --auto-correct.
225
+ Style/RedundantBegin:
226
+ Enabled: false
227
+
228
+ # Offense count: 19
229
+ # Cop supports --auto-correct.
230
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
231
+ Style/SignalException:
232
+ Enabled: false
233
+
234
+ # Offense count: 2
235
+ # Cop supports --auto-correct.
236
+ Style/SpaceAfterComma:
237
+ Enabled: false
238
+
239
+ # Offense count: 1
240
+ # Cop supports --auto-correct.
241
+ Style/SpaceAfterMethodName:
242
+ Enabled: false
243
+
244
+ # Offense count: 1
245
+ # Cop supports --auto-correct.
246
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
247
+ Style/SpaceAroundEqualsInParameterDefault:
248
+ Enabled: false
249
+
250
+ # Offense count: 7
251
+ # Cop supports --auto-correct.
252
+ # Configuration parameters: MultiSpaceAllowedForOperators.
253
+ Style/SpaceAroundOperators:
254
+ Enabled: false
255
+
256
+ # Offense count: 1
257
+ # Cop supports --auto-correct.
258
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
259
+ Style/SpaceBeforeBlockBraces:
260
+ Enabled: false
261
+
262
+ # Offense count: 15
263
+ # Cop supports --auto-correct.
264
+ # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
265
+ Style/SpaceInsideHashLiteralBraces:
266
+ Enabled: false
267
+
268
+ # Offense count: 3
269
+ # Cop supports --auto-correct.
270
+ Style/SpaceInsideParens:
271
+ Enabled: false
272
+
273
+ # Offense count: 23
274
+ # Cop supports --auto-correct.
275
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
276
+ Style/StringLiterals:
277
+ Enabled: false
278
+
279
+ # Offense count: 1
280
+ # Cop supports --auto-correct.
281
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
282
+ Style/TrailingBlankLines:
283
+ Enabled: false
284
+
285
+ # Offense count: 1
286
+ # Cop supports --auto-correct.
287
+ # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
288
+ Style/TrailingComma:
289
+ Enabled: false
290
+
291
+ # Offense count: 2
292
+ # Cop supports --auto-correct.
293
+ Style/UnneededPercentQ:
294
+ Enabled: false
295
+
296
+ # Offense count: 3
297
+ # Cop supports --auto-correct.
298
+ # Configuration parameters: WordRegex.
299
+ Style/WordArray:
300
+ MinSize: 4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  CHANGELOG
2
2
  ================================
3
+ ## v.3.4.0 (2015-08-20)
4
+ ### Added
5
+ * Support for [Open Data Processing](https://datasift.com/products/open-data-processing-for-twitter/) batch uploads (Thanks @giovannelli)
6
+ * Explicit supprot for 413 and 422 errors from API
7
+ * Ability to get at API response headers using the ```object.response``` accessor. (Thanks again @giovannelli)
8
+
9
+ ### Changed
10
+ * Bumped [rest-client](https://github.com/rest-client/rest-client) dependency to ~> 1.8
11
+ * The OpenSSL version you select within the DataSift gem no longer changes the default OpenSSL version in your wider application; it only affects API calls made by the DataSift gem to DataSift's API
12
+
3
13
  ## v.3.3.0 (2015-08-05)
4
14
  ### Added
5
15
  * Explicit support for 429 errors from the API
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.3.0
1
+ 3.4.0
data/datasift.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.test_files = `git ls-files -- {test}/*`.split("\n")
16
16
  s.require_paths = ["lib"]
17
17
 
18
- s.add_runtime_dependency('rest-client', '~> 1.6')
18
+ s.add_runtime_dependency('rest-client', '~> 1.8')
19
19
  s.add_runtime_dependency('multi_json', '~> 1.7')
20
20
  s.add_runtime_dependency('websocket-td', '~> 0.0.5')
21
21
  s.add_development_dependency('bundler', '~> 1.0')
@@ -0,0 +1,61 @@
1
+ require './../auth'
2
+ class TwitterGnipBatchEg < DataSiftExample
3
+ def initialize
4
+ super
5
+ @datasift = DataSift::Client.new(@config)
6
+ run
7
+ end
8
+
9
+ def run
10
+ begin
11
+ # "gnip_1" is the default mapping used to map Tweets ingested from Gnip into a
12
+ # format DataSift can use. Using this mapping will altomatically define the
13
+ # IDML you need to use for this source
14
+ resource = [{
15
+ parameters: {
16
+ mapping: "gnip_1"
17
+ }
18
+ }]
19
+ puts "Creating Managed Source for ODP Ingestion\n"
20
+ source = @datasift.managed_source.create('twitter_gnip', 'Ruby ODP API', {}, resource)
21
+ puts "Manage Source with ID #{source[:data][:id]} created"
22
+
23
+ lines = 0
24
+ payload = ''
25
+ # Read interactions out of the fake Tweets fixture file
26
+ File.readlines('./../../test/fixtures/data/fake_gnip_tweets.json').each do |line|
27
+ lines += 1
28
+ payload += line
29
+
30
+ # Upload interactions as batches of five
31
+ if lines % 5 == 0
32
+ puts "\nUploading a batch of five interactions\n"
33
+ puts @datasift.odp.ingest(source[:data][:id], payload)[:data].to_json
34
+ payload = ''
35
+ end
36
+ end
37
+
38
+ puts "\nCleanup after this test and delete the Managed Source"
39
+ @datasift.managed_source.delete(source[:data][:id])
40
+
41
+ rescue DataSiftError => dse
42
+ puts dse.message
43
+ # Then match specific one to take action - All errors thrown by the client extend
44
+ # DataSiftError
45
+ case dse
46
+ when ConnectionError
47
+ # some connection error
48
+ when AuthError
49
+ when BadRequestError
50
+ when PayloadTooLargeError
51
+ # You've probably hit your x_ingestion_data_ratelimit_limit rate limit; back off
52
+ # and try again in a bit. Check your x_ingestion_request_ratelimit_reset header
53
+ # to see when you can retry this request successfully
54
+ else
55
+ # do something else...
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ TwitterGnipBatchEg.new
@@ -11,18 +11,16 @@ module DataSift
11
11
  @config = config
12
12
  config[:api_host] = 'api.datasift.com' unless config.has_key?(:api_host)
13
13
  config[:stream_host] = 'websocket.datasift.com' unless config.has_key?(:stream_host)
14
+ config[:ingestion_host] = 'in.datasift.com' unless config.has_key?(:ingestion_host)
14
15
  config[:api_version] = 'v1.2' unless config.has_key?(:api_version)
15
16
  config[:enable_ssl] = true unless config.has_key?(:enable_ssl)
16
- # Only SSLv3, TLSv1 and TLSv1.2 currently supported, TLSv1.2 preferred
17
- # this is fixed in REST client and is scheduled for the 1.7.0 release
18
- # see https://github.com/rest-client/rest-client/pull/123
19
17
 
20
18
  ssl_default = "TLSv1_2"
21
19
  if RUBY_VERSION.to_i == 1
20
+ # Ruby 1.x does not seem to support > TLSv1
22
21
  ssl_default = "TLSv1"
23
22
  end
24
- OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] = config[:ssl_version] ||
25
- ssl_default
23
+ config[:ssl_version] = config[:ssl_version] || ssl_default
26
24
 
27
25
  # max 320 seconds retry - http://dev.datasift.com/docs/streaming-api/reconnecting
28
26
  config[:max_retry_time] = 320 unless config.key?(:max_retry_time)
data/lib/datasift.rb CHANGED
@@ -21,6 +21,7 @@ require dir + '/account'
21
21
  require dir + '/account_identity'
22
22
  require dir + '/account_identity_token'
23
23
  require dir + '/account_identity_limit'
24
+ require dir + '/odp'
24
25
  #
25
26
  require 'rbconfig'
26
27
 
@@ -51,7 +52,7 @@ module DataSift
51
52
  raise InvalidConfigError.new('Config cannot be nil') if config.nil?
52
53
  if !config.key?(:username) || !config.key?(:api_key)
53
54
  raise InvalidConfigError.new('A valid username and API key are required. ' +
54
- 'You can check your API credentials at https://datasift.com/settings')
55
+ 'You can check your API credentials at https://app.datasift.com/settings')
55
56
  end
56
57
 
57
58
  @config = config
@@ -66,11 +67,12 @@ module DataSift
66
67
  @account_identity = DataSift::AccountIdentity.new(config)
67
68
  @account_identity_token = DataSift::AccountIdentityToken.new(config)
68
69
  @account_identity_limit = DataSift::AccountIdentityLimit.new(config)
70
+ @odp = DataSift::Odp.new(config)
69
71
  end
70
72
 
71
73
  attr_reader :historics, :push, :managed_source, :managed_source_resource,
72
74
  :managed_source_auth, :historics_preview, :pylon, :account,
73
- :account_identity, :account_identity_token, :account_identity_limit
75
+ :account_identity, :account_identity_token, :account_identity_limit, :odp
74
76
 
75
77
  # Checks if the syntax of the given CSDL is valid
76
78
  #
@@ -167,7 +169,7 @@ module DataSift
167
169
  url += "#{URI.parse(url).query ? '&' : '?'}#{encode params}"
168
170
  payload = nil
169
171
  else
170
- payload = MultiJson.dump(params)
172
+ payload = params.is_a?(String) ? params : MultiJson.dump(params)
171
173
  headers.update({ :content_type => 'application/json' })
172
174
  end
173
175
 
@@ -178,10 +180,11 @@ module DataSift
178
180
  :timeout => timeout,
179
181
  :payload => payload,
180
182
  :url => url,
181
- :ssl_version => OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version],
183
+ :ssl_version => config[:ssl_version],
182
184
  :verify_ssl => OpenSSL::SSL::VERIFY_PEER
183
185
  )
184
186
 
187
+ response = nil
185
188
  begin
186
189
  response = RestClient::Request.execute options
187
190
  if !response.nil? && response.length > 0
@@ -223,7 +226,19 @@ module DataSift
223
226
  body = e.http_body
224
227
  if code && body
225
228
  error = MultiJson.load(body)
226
- handle_api_error(e.http_code, (error['error'] ? error['error'] : '') + " for URL #{url}")
229
+ response_on_error = {
230
+ :data => nil,
231
+ :datasift => {
232
+ :x_ratelimit_limit => e.response.headers[:x_ratelimit_limit],
233
+ :x_ratelimit_remaining => e.response.headers[:x_ratelimit_remaining],
234
+ :x_ratelimit_cost => e.response.headers[:x_ratelimit_cost]
235
+ },
236
+ :http => {
237
+ :status => e.response.code,
238
+ :headers => e.response.headers
239
+ }
240
+ }
241
+ handle_api_error(e.http_code, (error['error'] ? error['error'] : '') + " for URL #{url}", response_on_error)
227
242
  else
228
243
  process_client_error(e)
229
244
  end
@@ -238,8 +253,12 @@ module DataSift
238
253
  private
239
254
 
240
255
  def self.build_url(path, config)
241
- 'http' + (config[:enable_ssl] ? 's' : '') + '://' + config[:api_host] +
242
- '/' + config[:api_version] + '/' + path
256
+ url = 'http' + (config[:enable_ssl] ? 's' : '') + '://' + config[:api_host]
257
+ if !config[:api_version].nil?
258
+ url += '/' + config[:api_version] + '/' + path
259
+ else
260
+ url += '/' + path
261
+ end
243
262
  end
244
263
 
245
264
  # Returns true if username or api key are not set
@@ -257,22 +276,26 @@ module DataSift
257
276
  params.collect { |param, value| [param, CGI.escape(value.to_s)].join('=') }.join('&')
258
277
  end
259
278
 
260
- def self.handle_api_error(code, body)
279
+ def self.handle_api_error(code, body, response)
261
280
  case code
262
281
  when 400
263
- raise BadRequestError.new(code, body)
282
+ raise BadRequestError.new(code, body, response)
264
283
  when 401
265
- raise AuthError.new(code, body)
284
+ raise AuthError.new(code, body, response)
266
285
  when 404
267
- raise ApiResourceNotFoundError.new(code, body)
286
+ raise ApiResourceNotFoundError.new(code, body, response)
268
287
  when 409
269
- raise ConflictError.new(code, body)
288
+ raise ConflictError.new(code, body, response)
270
289
  when 410
271
- raise GoneError.new(code, body)
290
+ raise GoneError.new(code, body, response)
291
+ when 413
292
+ raise PayloadTooLargeError.new(code, body, response)
293
+ when 422
294
+ raise UnprocessableEntityError.new(code, body, response)
272
295
  when 429
273
- raise TooManyRequestsError.new(code, body)
296
+ raise TooManyRequestsError.new(code, body, response)
274
297
  else
275
- raise DataSiftError.new(code, body)
298
+ raise DataSiftError.new(code, body, response)
276
299
  end
277
300
  end
278
301
 
@@ -310,7 +333,7 @@ module DataSift
310
333
  raise BadParametersError.new('on_close - 2 parameter required') unless on_close.arity == 2
311
334
  end
312
335
  begin
313
- stream = WebsocketTD::Websocket.new('websocket.datasift.com', '/multi', "username=#{config[:username]}&api_key=#{config[:api_key]}")
336
+ stream = WebsocketTD::Websocket.new(config[:stream_host], '/multi', "username=#{config[:username]}&api_key=#{config[:api_key]}")
314
337
  connection = LiveStream.new(config, stream)
315
338
  KNOWN_SOCKETS[connection] = Time.new.to_i
316
339
  stream.on_ping = lambda { |data|
@@ -362,12 +385,12 @@ module DataSift
362
385
  if use_closed && !on_close.nil?
363
386
  on_close.call(connection, message)
364
387
  else
365
- on_error.call(connection, ReconnectTimeoutError.new("Connecting to DataSift has failed, re-connection was attempted but
366
- multiple consecutive failures where encountered. As a result no further
367
- re-connection will be automatically attempted. Manually invoke connect() after
368
- investigating the cause of the failure, be sure to observe DataSift's
369
- re-connect policies available at http://dev.datasift.com/docs/streaming-api/reconnecting
370
- - Error { #{message}}"))
388
+ on_error.call(connection, ReconnectTimeoutError.new("Connecting to DataSift has " \
389
+ "failed, re-connection was attempted but multiple consecutive failures where " \
390
+ "encountered. As a result no further re-connection will be automatically " \
391
+ "attempted. Manually invoke connect() after investigating the cause of the " \
392
+ "failure, be sure to observe DataSift's re-connect policies available at " \
393
+ "http://dev.datasift.com/docs/streaming-api/reconnecting - Error {#{message}}"))
371
394
  end
372
395
  else
373
396
  sleep config[:retry_timeout]
data/lib/errors.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # Custom error class for rescuing DataSift errors
2
2
  class DataSiftError < StandardError
3
- attr_reader :status
4
- attr_reader :body
3
+ attr_reader :status, :body, :response
5
4
 
6
- def initialize(http_status = nil, http_body = nil)
5
+ def initialize(http_status = nil, http_body = nil, response_on_error = nil)
7
6
  @status = http_status
8
7
  @body = http_body
8
+ @response = response_on_error
9
9
  end
10
10
 
11
11
  def message
@@ -48,6 +48,14 @@ end
48
48
  class GoneError < DataSiftError
49
49
  end
50
50
 
51
+ # Standard error returned when receiving a 413 response from the API
52
+ class PayloadTooLargeError < DataSiftError
53
+ end
54
+
55
+ # Standard error returned when receiving a 422 response from the API
56
+ class UnprocessableEntityError < DataSiftError
57
+ end
58
+
51
59
  # Standard error returned when receiving a 429 response from the API
52
60
  class TooManyRequestsError < DataSiftError
53
61
  end
data/lib/odp.rb ADDED
@@ -0,0 +1,14 @@
1
+ module DataSift
2
+ ##
3
+ # Use DataSift's Open Data Processing (ODP) to upload your own data to
4
+ # DataSift for processing
5
+ class Odp < DataSift::ApiResource
6
+ def ingest(source_id, data)
7
+ fail ArgumentError, 'source_id is required' if source_id.nil?
8
+ fail ArgumentError, 'data payload is required' if data.nil?
9
+
10
+ config = @config.merge(api_host: @config[:ingestion_host], api_version: nil)
11
+ DataSift.request(:POST, source_id, config, data)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path('../../../test_helper', __FILE__)
2
+
3
+ describe 'DataSift::Odp' do
4
+ before do
5
+ auth = DataSiftExample.new
6
+ @datasift = auth.datasift
7
+ @data = OpenStruct.new
8
+ end
9
+
10
+ ##
11
+ # Batch Upload
12
+ #
13
+ describe '#ingest (success)' do
14
+ before do
15
+ VCR.use_cassette('odp/batch/before_upload') do
16
+ resource = [{ parameters: { mapping: "gnip_1" } }]
17
+ @source = @datasift.managed_source.create('twitter_gnip', 'Ruby ODP API', {}, resource)
18
+ end
19
+ end
20
+
21
+ after do
22
+ VCR.use_cassette('odp/batch/after_upload') do
23
+ @datasift.managed_source.delete @source[:data][:id]
24
+ end
25
+ end
26
+
27
+ it 'can batch upload gnip twitter data' do
28
+ VCR.use_cassette('odp/batch/upload_success') do
29
+ payload = File.open(File.expand_path('../../fixtures/data/fake_gnip_tweets.json', File.dirname(__FILE__))).read
30
+ response = @datasift.odp.ingest(@source[:data][:id], payload)
31
+ assert_equal STATUS.valid, response[:http][:status]
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#ingest (failure)' do
37
+ it 'handles 404 when Managed Source can not be found' do
38
+ VCR.use_cassette('odp/batch/upload_failure_no_source') do
39
+ payload = File.open(File.expand_path('../../fixtures/data/fake_gnip_tweets.json', File.dirname(__FILE__))).read
40
+ assert_raises ApiResourceNotFoundError do
41
+ response = @datasift.odp.ingest('invalid_source_id', payload)
42
+ end
43
+ end
44
+ end
45
+
46
+ it 'raises BadParametersError when payload is missing' do
47
+ assert_raises ArgumentError do
48
+ @datasift.odp.ingest('invalid_source_id')
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"delete","uri":"https://api.datasift.com/v1.2/source/delete?id=3446d92fd7274adeaf8b27f4e99f3b60","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["*/*; q=0.5, application/xml"],"Accept-Encoding":["gzip, deflate"],"User-Agent":["DataSift/v1.2 Ruby/v3.4.0"],"Authorization":["<USERNAME:API_KEY>"],"Content-Type":["application/x-www-form-urlencoded"]}},"response":{"status":{"code":204,"message":"No Content"},"headers":{"Server":["nginx"],"Date":["Fri, 14 Aug 2015 19:27:56 GMT"],"Content-Type":["text/html"],"Connection":["close"],"X-Api-Version":["1.2"],"P3p":["CP=\"CAO PSA\""],"X-Ratelimit-Limit":["10000"],"X-Ratelimit-Remaining":["9816"],"X-Ratelimit-Cost":["25"],"X-Ratelimit-Reset":["1439582455"],"X-Ratelimit-Reset-Ttl":["1979"],"Access-Control-Allow-Origin":["*"],"Access-Control-Allow-Headers":["Authorization,Content-Type"],"X-Served-By":["ded2584"],"X-Frame-Options":["SAMEORIGIN"]},"body":{"encoding":"UTF-8","base64_string":""},"http_version":null},"recorded_at":"Fri, 14 Aug 2015 19:27:56 GMT"}],"recorded_with":"VCR 2.9.3"}
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"post","uri":"https://api.datasift.com/v1.2/source/create","body":{"encoding":"UTF-8","base64_string":"PEJBU0U2NF9TVFJJTkc+\n"},"headers":{"Accept":["*/*; q=0.5, application/xml"],"Accept-Encoding":["gzip, deflate"],"User-Agent":["DataSift/v1.2 Ruby/v3.4.0"],"Authorization":["<USERNAME:API_KEY>"],"Content-Type":["application/json"],"Content-Length":["110"]}},"response":{"status":{"code":201,"message":"Created"},"headers":{"Server":["nginx"],"Date":["Fri, 14 Aug 2015 19:27:36 GMT"],"Content-Type":["application/json"],"Transfer-Encoding":["chunked"],"Connection":["close"],"X-Api-Version":["1.2"],"P3p":["CP=\"CAO PSA\""],"X-Ratelimit-Limit":["10000"],"X-Ratelimit-Remaining":["9842"],"X-Ratelimit-Cost":["25"],"X-Ratelimit-Reset":["1439582455"],"X-Ratelimit-Reset-Ttl":["2000"],"Access-Control-Allow-Origin":["*"],"Access-Control-Allow-Headers":["Authorization,Content-Type"],"X-Served-By":["ded2587"],"X-Frame-Options":["SAMEORIGIN"]},"body":{"encoding":"UTF-8","base64_string":"eyJpZCI6IjM0NDZkOTJmZDcyNzRhZGVhZjhiMjdmNGU5OWYzYjYwIiwic3Rh\ndHVzIjoic3RvcHBlZCIsInNvdXJjZV90eXBlIjoidHdpdHRlcl9nbmlwIiwi\nbmFtZSI6IlJ1YnkgT0RQIEFQSSIsImF1dGgiOltdLCJyZXNvdXJjZXMiOlt7\nInJlc291cmNlX2lkIjoiMjUyM2FhMDUzNWIzNGYzNmFmMzlhYmEzZTJkY2Rj\nYmIiLCJwYXJhbWV0ZXJzIjp7InVuaXF1ZV9pZF9sb2NhdGlvbiI6ImlkIiwi\naW50ZXJhY3Rpb25fdHlwZSI6InR3aXR0ZXJfZ25pcCIsImF1Z21lbnRhdGlv\nbnMiOlsiZ2VuZGVyIiwia2xvdXQiLCJsYW5ndWFnZWRldGVjdGlvbiIsInNh\nbGllbmNlX2NvbnRlbnQiLCJzYWxpZW5jZV90aXRsZSIsInRyZW5kcyIsInpl\nbnlhX2NvbnRlbnQiLCJ6ZW55YV90aXRsZSJdLCJpZG1sIjoiIyBNYXBzIHRo\nZSBHbmlwIEFjdGl2aXR5U3RyZWFtIGZvcm1hdCB0byBhIFR3aXR0ZXIgb2Jq\nZWN0XG5bbWFpbl1cbnR3aXR0ZXIgPSAoYXBwbHkoXCJjcmVhdGVfcG9zdFwi\nKSBbIHJvb3QudmVyYiA9PSBcInBvc3RcIiBdIHxcbiAgICAgICAgICAgYXBw\nbHkoXCJjcmVhdGVfc2hhcmVcIikgWyByb290LnZlcmIgPT0gXCJzaGFyZVwi\nXSB8XG4gICAgICAgICAgIGFwcGx5KFwiY3JlYXRlX2RlbGV0ZVwiKSBbIHJv\nb3QudmVyYiA9PSBcImRlbGV0ZVwiIF0gfFxuICAgICAgICAgICBhcHBseShc\nImNyZWF0ZV9zdGF0dXNfd2l0aGhlbGRcIikgWyByb290LnZlcmIgPT0gXCJz\ndGF0dXNfd2l0aGhlbGRcIiBdIHxcbiAgICAgICAgICAgYXBwbHkoXCJjcmVh\ndGVfc2NydWJfZ2VvXCIpIFsgcm9vdC52ZXJiID09IFwic2NydWJfZ2VvXCIg\nXSB8XG4gICAgICAgICAgIGFwcGx5KFwiY3JlYXRlX290aGVyX2NvbXBsaWFu\nY2VcIilcbiAgICAgICAgICApXG5cbiMgZGVsZXRlcyBoYXZlIGFuIGV4dHJh\nIHRvcC1sZXZlbCBmaWVsZFxuZGVsZXRlZCA9IHRydWUgW3Jvb3QudmVyYiA9\nPSBcImRlbGV0ZVwiXVxuXG5bY3JlYXRlX2RlbGV0ZV1cbmlkICAgICAgICAg\nID0gb2JqZWN0LmlkLnNwbGl0KFwiOlwiKVsyXVxuY3JlYXRlZF9hdCAgPSB0\naW1lc3RhbXBNcy5kYXRlKClcbnVzZXIgICAgICAgID0gYWN0b3IuYXBwbHko\nXCJjcmVhdGVfYWN0b3JcIilcblxuW2NyZWF0ZV9zdGF0dXNfd2l0aGhlbGRd\nXG5jcmVhdGVkX2F0ICAgICAgICAgPSB0aW1lc3RhbXBNcy5kYXRlKClcbnN0\nYXR1cyAgICAgICAgICAgICA9IHZlcmJcbndpdGhoZWxkLmNvdW50cmllcyA9\nIG9iamVjdC53aXRoaGVsZF9pbl9jb3VudHJpZXNcblxuIyB0aGUgb2JqZWN0\nIHJlZmVycyB0byB0aGUgc3RhdHVzIG1lc3NhZ2UgYW5kIHRoZXJlJ3MgYSB1\nc2VyX2lkIGZpZWxkIGluc3RlYWQgb2YgYW4gYWN0b3JcbmlkICAgICAgICAg\nID0gb2JqZWN0LmlkLm1hdGNoKFwiLio/KFxcXFxkKylcIilbMF1cbnVzZXIu\naWQgICAgID0gb2JqZWN0LnVzZXJfaWQubWF0Y2goXCIuKj8oXFxcXGQrKVwi\nKVswXS5pbnQoKVxudXNlci5pZF9zdHIgPSBvYmplY3QudXNlcl9pZC5tYXRj\naChcIi4qPyhcXFxcZCspXCIpWzBdXG5cbltjcmVhdGVfc2NydWJfZ2VvXVxu\nY3JlYXRlZF9hdCAgPSB0aW1lc3RhbXBNcy5kYXRlKClcbnN0YXR1cyAgICAg\nID0gdmVyYlxudXNlciAgICAgICAgPSBhY3Rvci5hcHBseShcImNyZWF0ZV9h\nY3RvclwiKVxuc2NydWJfZ2VvLnVwX3RvX3N0YXR1c19pZCA9IHRhcmdldC51\ncF90b19pZC5tYXRjaChcIi4qPyhcXFxcZCspXCIpWzBdXG5cbltjcmVhdGVf\nb3RoZXJfY29tcGxpYW5jZV1cbmNyZWF0ZWRfYXQgID0gdGltZXN0YW1wTXMu\nZGF0ZSgpXG5zdGF0dXMgICAgICA9IHZlcmJcbnVzZXIgICAgICAgID0gb2Jq\nZWN0LmFwcGx5KFwiY3JlYXRlX2FjdG9yXCIpXG53aXRoaGVsZC5jb3VudHJp\nZXMgPSB3aXRoaGVsZF9pbl9jb3VudHJpZXNcblxuW2NyZWF0ZV9nZW9fZnJv\nbV9wb2x5XVxubGF0aXR1ZGUgICAgPSBnZW8uY29vcmRpbmF0ZXNbMF0uZXh0\ncmFjdCh0aGlzWzFdKS5hdmVyYWdlKClcbmxvbmdpdHVkZSAgID0gZ2VvLmNv\nb3JkaW5hdGVzWzBdLmV4dHJhY3QodGhpc1swXSkuYXZlcmFnZSgpXG5cbltj\ncmVhdGVfZ2VvX2Zyb21fcG9pbnRdXG5sYXRpdHVkZSAgICA9IGdlby5jb29y\nZGluYXRlc1swXVxubG9uZ2l0dWRlICAgPSBnZW8uY29vcmRpbmF0ZXNbMV1c\nblxuW2NyZWF0ZV9sb2NfZ2VvX2Zyb21fcG9seV1cbmxhdGl0dWRlICAgID0g\nbG9jYXRpb24uZ2VvLmNvb3JkaW5hdGVzWzBdLmV4dHJhY3QodGhpc1sxXSku\nYXZlcmFnZSgpXG5sb25naXR1ZGUgICA9IGxvY2F0aW9uLmdlby5jb29yZGlu\nYXRlc1swXS5leHRyYWN0KHRoaXNbMF0pLmF2ZXJhZ2UoKVxuXG5bY3JlYXRl\nX2xvY19nZW9fZnJvbV9wb2ludF1cbmxhdGl0dWRlICAgID0gbG9jYXRpb24u\nZ2VvLmNvb3JkaW5hdGVzWzBdXG5sb25naXR1ZGUgICA9IGxvY2F0aW9uLmdl\nby5jb29yZGluYXRlc1sxXVxuXG5bY3JlYXRlX3Bvc3RdXG5pZCAgICAgICAg\nICAgICAgPSBpZC5zcGxpdChcIjpcIilbMl1cbmxpbmsgICAgICAgICAgICA9\nIGxpbmtcbnVzZXIgICAgICAgICAgICA9IGFjdG9yLmFwcGx5KFwiY3JlYXRl\nX2FjdG9yXCIpXG5sYW5nICAgICAgICAgICAgPSB0d2l0dGVyX2xhbmdcbnRl\neHQgICAgICAgICAgICA9IGJvZHkuc2l6ZSgxMDAwKVxuY3JlYXRlZF9hdCAg\nICAgID0gcG9zdGVkVGltZS5kYXRlKClcbmZpbHRlcl9sZXZlbCAgICA9IHR3\naXR0ZXJfZmlsdGVyX2xldmVsXG5zb3VyY2UgICAgICAgICAgPSBnZW5lcmF0\nb3IuZGlzcGxheU5hbWVcbmhhc2h0YWdzICAgICAgICA9IHR3aXR0ZXJfZW50\naXRpZXMuaGFzaHRhZ3MgWyB0cnVuY2F0ZWQgIT0gdHJ1ZSBdIC5leHRyYWN0\nKHRleHQpXG5tZW50aW9ucyAgICAgICAgPSB0d2l0dGVyX2VudGl0aWVzLnVz\nZXJfbWVudGlvbnMuZXh0cmFjdChzY3JlZW5fbmFtZSlcbm1lbnRpb25faWRz\nICAgICA9IHR3aXR0ZXJfZW50aXRpZXMudXNlcl9tZW50aW9ucy5leHRyYWN0\nKGlkKVxubWVkaWEgICAgICAgICAgID0gdHdpdHRlcl9lbnRpdGllcy5tZWRp\nYS5leHRyYWN0KGJsYWNrbGlzdChcImluZGljZXNcIikpXG5wbGFjZSAgICAg\nICAgICAgPSBsb2NhdGlvbi5hcHBseShcImNyZWF0ZV9wbGFjZVwiKVxuc3lt\nYm9scyAgICAgICAgID0gc3ltYm9scy5leHRyYWN0KHRleHQpXG5nZW8gICAg\nICAgICAgICAgPSAoYXBwbHkoXCJjcmVhdGVfZ2VvX2Zyb21fcG9pbnRcIikg\nICAgIFsgcm9vdC5nZW8udHlwZSA9PSBcIlBvaW50XCIgXSAgICAgICAgICAg\nfCAjIHRyeSB0aGUgYWNjdXJhdGUgcG9pbnRcbiAgICAgICAgICAgICAgICAg\nICAgICAgYXBwbHkoXCJjcmVhdGVfZ2VvX2Zyb21fcG9seVwiKSAgICAgIFsg\ncm9vdC5nZW8udHlwZSA9PSBcIlBvbHlnb25cIiBdICAgICAgICAgfCAjIHRy\neSBhbiBhY2N1cmF0ZSBwb2x5XG4gICAgICAgICAgICAgICAgICAgICAgICAg\nICAgICAgICAgICAgICBhcHBseShcImNyZWF0ZV9sb2NfZ2VvX2Zyb21fcG9p\nbnRcIikgWyByb290LmxvY2F0aW9uLmdlby50eXBlID09IFwiUG9pbnRcIiBd\nICB8ICMgdHJ5IHRoZSBsb2NhdGlvbiBwb2ludFxuICAgICAgICAgICAgICAg\nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5\nKFwiY3JlYXRlX2xvY19nZW9fZnJvbV9wb2x5XCIpICBbIHJvb3QubG9jYXRp\nb24uZ2VvLnR5cGUgPT0gXCJQb2x5Z29uXCIgXSkgIyB0cnkgdGhlIGxvY2F0\naW9uIHBvbHlcblxuIyBzcGxpdCBsaW5rcyBsaWtlIGh0dHA6XC9cL3R3aXR0\nZXIuY29tXC9zY3JlZW5fbmFtZVwvc3RhdHVzZXNcL3N0YXR1c19pZFxuaW5f\ncmVwbHlfdG9fc2NyZWVuX25hbWUgICA9IGluUmVwbHlUby5saW5rLnNwbGl0\nKFwiXFxcL1wiKSBbM11cbmluX3JlcGx5X3RvX3N0YXR1c19pZCAgICAgPSBp\nblJlcGx5VG8ubGluay5zcGxpdChcIlxcXC9cIikgWzVdXG5cbiMgZXh0cmFj\ndCBsaW5rcyBmcm9tIHR3aXR0ZXIgZW50aXRpZXNcbmxpbmtzICAgICAgICAg\nICA9IHR3aXR0ZXJfZW50aXRpZXMudXJscy5leHRyYWN0KChleHBhbmRlZF91\ncmwgfCB1cmwpKVswOjVdXG5kb21haW5zICAgICAgICAgPSB0d2l0dGVyX2Vu\ndGl0aWVzLnVybHMuZXh0cmFjdCgoZXhwYW5kZWRfdXJsLnVybCgpLmhvc3Qg\nfCB1cmwudXJsKCkuaG9zdCkpWzA6NV1cbmRpc3BsYXlfdXJscyAgICA9IHR3\naXR0ZXJfZW50aXRpZXMudXJscy5leHRyYWN0KGRpc3BsYXlfdXJsKVswOjVd\nXG5cbltjcmVhdGVfc2hhcmVdXG5yZXR3ZWV0ICAgICA9IGFwcGx5KFwiY3Jl\nYXRlX3Bvc3RcIilcbnJldHdlZXRlZCAgID0gb2JqZWN0LmFwcGx5KFwiY3Jl\nYXRlX3Bvc3RcIilcbmlkICAgICAgICAgID0gaWQuc3BsaXQoXCI6XCIpWzJd\nXG5cbiMgd2UgY2FuIGdldCB0aGUgb3JkZXIgdGhlIHJldHdlZXQgd2FzIG1h\nZGUgaW4gYnkgZ2V0dGluZyB0aGUgb3JpZ2luYWwgdHdlZXRzIHJldHdlZXQg\nY291bnRcbnJldHdlZXQuY291bnQgPSByZXR3ZWV0Q291bnQuaW50KCkuZGVm\nYXVsdCgwKVxuXG4jIHRoZSByZXR3ZWV0IGlzIG9mdGVuIHRydW5jYXRlZCBi\neSB0d2l0dGVyLiBsZXQncyBmb3JtYXQgaXQgb3Vyc2VsZlxucmV0d2VldC50\nZXh0ID0gXCJSVCBAJXM6ICVzXCIuZm9ybWF0KG9iamVjdC5hY3Rvci5wcmVm\nZXJyZWRVc2VybmFtZSwgb2JqZWN0LmJvZHkpXG5cbiMgd2UgZG9uJ3QgbWFw\nIHRoZSBmYXZvcml0ZXMgY291bnQgb2YgYSBuZXcgdHdlZXQgc2luY2UgaXQn\nbGwgbGlrZWx5IGJlIHplcm9cbnJldHdlZXRlZC5mYXZvdXJpdGVzX2NvdW50\nID0gb2JqZWN0LmZhdm9yaXRlc0NvdW50XG5cbiMgcHJlcGVuZCB0aGUgcmV0\nd2VldGVkIHVzZXIgc2NyZWVuIG5hbWUgYW5kIGlkIHRvIHRoZSBtZW50aW9u\ncyBsaXN0XG5yZXR3ZWV0Lm1lbnRpb25zID0gQHJldHdlZXQubWVudGlvbnMu\ncHJlcGVuZChAcmV0d2VldGVkLnVzZXIuc2NyZWVuX25hbWUpXG5yZXR3ZWV0\nLm1lbnRpb25faWRzID0gQHJldHdlZXQubWVudGlvbl9pZHMucHJlcGVuZChA\ncmV0d2VldGVkLnVzZXIuaWQpXG5cbltjcmVhdGVfcGxhY2VdXG5jb3VudHJ5\nICAgICAgICAgPSBjb3VudHJ5X2NvZGVcbmNvdW50cnlfY29kZSAgICA9IHR3\naXR0ZXJfY291bnRyeV9jb2RlXG5mdWxsX25hbWUgICAgICAgPSBkaXNwbGF5\nTmFtZVxubmFtZSAgICAgICAgICAgID0gbmFtZVxucGxhY2VfdHlwZSAgICAg\nID0gdHdpdHRlcl9wbGFjZV90eXBlXG51cmwgICAgICAgICAgICAgPSBsaW5r\nXG5cbltjcmVhdGVfYWN0b3JdXG5pZCAgICAgICAgICAgICAgICAgICAgICA9\nIGlkLm1hdGNoKFwiLio/KFxcXFxkKylcIilbMF0uaW50KClcbmlkX3N0ciAg\nICAgICAgICAgICAgICAgID0gaWQubWF0Y2goXCIuKj8oXFxcXGQrKVwiKVsw\nXVxudXJsICAgICAgICAgICAgICAgICAgICAgPSBsaW5rXG5uYW1lICAgICAg\nICAgICAgICAgICAgICA9IGRpc3BsYXlOYW1lXG5wcm9maWxlX2ltYWdlX3Vy\nbCAgICAgICA9IGltYWdlXG5wcm9maWxlX2ltYWdlX3VybF9odHRwcyA9IGlt\nYWdlXG5kZXNjcmlwdGlvbiAgICAgICAgICAgICA9IHN1bW1hcnlcbmNyZWF0\nZWRfYXQgICAgICAgICAgICAgID0gcG9zdGVkVGltZS5kYXRlKClcbmxvY2F0\naW9uICAgICAgICAgICAgICAgID0gbG9jYXRpb24uZGlzcGxheU5hbWVcbnV0\nY19vZmZzZXQgICAgICAgICAgICAgID0gdXRjT2Zmc2V0LmludCgpXG5zY3Jl\nZW5fbmFtZSAgICAgICAgICAgICA9IHByZWZlcnJlZFVzZXJuYW1lXG5sYW5n\nICAgICAgICAgICAgICAgICAgICA9IGxhbmd1YWdlc1swXVxudGltZV96b25l\nICAgICAgICAgICAgICAgPSB0d2l0dGVyVGltZVpvbmVcbmZyaWVuZHNfY291\nbnQgICAgICAgICAgID0gZnJpZW5kc0NvdW50XG5mb2xsb3dlcnNfY291bnQg\nICAgICAgICA9IGZvbGxvd2Vyc0NvdW50XG5saXN0ZWRfY291bnQgICAgICAg\nICAgICA9IGxpc3RlZENvdW50XG5zdGF0dXNlc19jb3VudCAgICAgICAgICA9\nIHN0YXR1c2VzQ291bnRcbnZlcmlmaWVkICAgICAgICAgICAgICAgID0gdmVy\naWZpZWRcbmZhdm91cml0ZXNfY291bnQgICAgICAgID0gZmF2b3JpdGVzQ291\nbnQiLCJjYXRlZ29yeSI6InR3aXR0ZXJjYXRlZ29yeV8xIn19XSwicGFyYW1l\ndGVycyI6W10sImNyZWF0ZWRfYXQiOjE0Mzk1ODA0NTZ9\n"},"http_version":null},"recorded_at":"Fri, 14 Aug 2015 19:27:36 GMT"}],"recorded_with":"VCR 2.9.3"}
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"post","uri":"https://in.datasift.com/invalid_source_id","body":{"encoding":"UTF-8","base64_string":"PEJBU0U2NF9TVFJJTkc+\n"},"headers":{"Accept":["*/*; q=0.5, application/xml"],"Accept-Encoding":["gzip, deflate"],"User-Agent":["DataSift/ Ruby/v3.4.0"],"Authorization":["<USERNAME:API_KEY>"],"Content-Type":["application/json"],"Content-Length":["27255"]}},"response":{"status":{"code":404,"message":"Not Found"},"headers":{"Cache-Control":["private"],"Content-Type":["application/json"],"Server":["DataSift Ingestion/1.0"],"X-Ingestion-Data-Ratelimit-Reset":["0"],"X-Ingestion-Request-Ratelimit-Limit":["10000"],"X-Ingestion-Request-Ratelimit-Reset":["60"],"X-Ingestion-Data-Ratelimit-Remaining":["36864000"],"X-Ingestion-Request-Ratelimit-Reset-Ttl":["1439580312"],"X-Ingestion-Data-Ratelimit-Reset-Ttl":["1439580252"],"X-Ingestion-Data-Ratelimit-Limit":["36864000"],"X-Ingestion-Request-Ratelimit-Remaining":["9999"],"Transfer-Encoding":["chunked"],"Strict-Transport-Security":["max-age=31536000"]},"body":{"encoding":"ASCII-8BIT","base64_string":"eyJlcnJvciI6IlVua25vd24gdXNlciBzb3VyY2UifQ==\n"},"http_version":null},"recorded_at":"Fri, 14 Aug 2015 19:24:12 GMT"}],"recorded_with":"VCR 2.9.3"}
@@ -0,0 +1 @@
1
+ {"http_interactions":[{"request":{"method":"post","uri":"https://in.datasift.com/3446d92fd7274adeaf8b27f4e99f3b60","body":{"encoding":"UTF-8","base64_string":"PEJBU0U2NF9TVFJJTkc+\n"},"headers":{"Accept":["*/*; q=0.5, application/xml"],"Accept-Encoding":["gzip, deflate"],"User-Agent":["DataSift/ Ruby/v3.4.0"],"Authorization":["<USERNAME:API_KEY>"],"Content-Type":["application/json"],"Content-Length":["27255"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Cache-Control":["private"],"Content-Type":["application/json"],"Server":["DataSift Ingestion/1.0"],"X-Ingestion-Data-Ratelimit-Reset":["60"],"X-Ingestion-Request-Ratelimit-Limit":["10000"],"X-Ingestion-Request-Ratelimit-Reset":["60"],"X-Ingestion-Data-Ratelimit-Remaining":["36836754"],"X-Ingestion-Request-Ratelimit-Reset-Ttl":["1439580536"],"X-Ingestion-Data-Ratelimit-Reset-Ttl":["1439580536"],"X-Ingestion-Data-Ratelimit-Limit":["36864000"],"X-Ingestion-Request-Ratelimit-Remaining":["9999"],"Transfer-Encoding":["chunked"],"Strict-Transport-Security":["max-age=31536000"]},"body":{"encoding":"ASCII-8BIT","base64_string":"eyJhY2NlcHRlZCI6MTAsInRvdGFsX21lc3NhZ2VfYnl0ZXMiOjI3MjQ2fQ==\n"},"http_version":null},"recorded_at":"Fri, 14 Aug 2015 19:27:56 GMT"}],"recorded_with":"VCR 2.9.3"}
@@ -0,0 +1,10 @@
1
+ {"id":"tag:search.twitter.com,2005:587648815764746240","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:36136637","link":"http://www.twitter.com/davidmarkwales","displayName":"Dave Thomas","postedTime":"2009-04-28T18:14:12.000Z","image":"https://pbs.twimg.com/profile_images/1173129755/image_normal.jpg","summary":"Instagram: davidmarkwales","links":[{"href":null,"rel":"me"}],"friendsCount":340,"followersCount":122,"listedCount":3,"statusesCount":499,"twitterTimeZone":"London","verified":false,"utcOffset":"3600","preferredUsername":"davidmarkwales","languages":["en"],"location":{"objectType":"place","displayName":"Liverpool"},"favoritesCount":33},"verb":"post","postedTime":"2015-04-13T16:09:30.000Z","generator":{"displayName":"Twitter for Android","link":"http://twitter.com/download/android"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/davidmarkwales/statuses/587648815764746240","body":"@asda has cancelled my home delivery today, no reason given, not even a courtesy call or email to let me know. Any idea why they would?","object":{"objectType":"note","id":"object:search.twitter.com,2005:587648815764746240","summary":"@asda has cancelled my home delivery today, no reason given, not even a courtesy call or email to let me know. Any idea why they would?","link":"http://twitter.com/davidmarkwales/statuses/587648815764746240","postedTime":"2015-04-13T16:09:30.000Z"},"favoritesCount":0,"location":{"objectType":"place","displayName":"Garston, England","name":"Garston","country_code":"United Kingdom","twitter_country_code":"GB","link":"https://api.twitter.com/1.1/geo/id/12f69ad404352073.json","geo":{"type":"Polygon","coordinates":[[[-2.940659,53.331287],[-2.940659,53.38523],[-2.818002,53.38523],[-2.818002,53.331287]]]}},"geo":{"type":"Point","coordinates":[53.345841,-2.87278]},"twitter_entities":{"hashtags":[],"trends":[],"urls":[],"user_mentions":[{"screen_name":"asda","name":"Asda","id":20123366,"id_str":"20123366","indices":[0,5]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"BedBathBeyond\" OR to:\"WilliamsSonoma\" OR to:\"GAP\" OR to:\"Abercrombie\" OR to:\"hm\" OR to:\"VictoriasSecret\" OR to:\"LLBean\" OR to:\"LandsEnd\" OR to:\"eBay\" OR to:\"Overstock_help\" OR to:\"Overstock\" OR to:\"QVC\" OR to:\"BandQ\" OR to:\"asda\" OR to:\"waitrose\" OR to:\"LidlUK\" OR to:\"Ocado\" OR to:\"Burberry\" OR to:\"marksandspencer\" OR to:\"johnlewisretail\" OR to:\"nextofficial\" OR to:\"ASOS\" OR to:\"Topshop\" OR to:\"ZARA\" OR to:\"NewLookFashion\")","tag":"retailers"}],"language":{"value":"en"}}}
2
+ {"id":"tag:search.twitter.com,2005:587648834689445889","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:3157665856","link":"http://www.twitter.com/emilywlittle","displayName":"Emily ","postedTime":"2015-04-11T20:20:40.000Z","image":"https://pbs.twimg.com/profile_images/586987964225445912/ubKhVysy_normal.jpg","summary":null,"links":[{"href":null,"rel":"me"}],"friendsCount":61,"followersCount":20767,"listedCount":0,"statusesCount":128,"twitterTimeZone":"Amsterdam","verified":false,"utcOffset":"7200","preferredUsername":"emilywlittle","languages":["en"],"favoritesCount":0},"verb":"post","postedTime":"2015-04-13T16:09:34.000Z","generator":{"displayName":"Yappem","link":"http://www.yappem.com/"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/emilywlittle/statuses/587648834689445889","body":"@amazon online bookstore http://t.co/Cz3XUWDvva http://t.co/6lNnsbABii","object":{"objectType":"note","id":"object:search.twitter.com,2005:587648834689445889","summary":"@amazon online bookstore http://t.co/Cz3XUWDvva http://t.co/6lNnsbABii","link":"http://twitter.com/emilywlittle/statuses/587648834689445889","postedTime":"2015-04-13T16:09:34.000Z"},"favoritesCount":0,"twitter_entities":{"hashtags":[],"trends":[],"urls":[{"url":"http://t.co/Cz3XUWDvva","expanded_url":"http://goo.gl/iXPwB4","display_url":"goo.gl/iXPwB4","indices":[25,47]}],"user_mentions":[{"screen_name":"amazon","name":"Amazon","id":20793816,"id_str":"20793816","indices":[0,7]}],"symbols":[],"media":[{"id":587648834580455424,"id_str":"587648834580455424","indices":[48,70],"media_url":"http://pbs.twimg.com/media/CCe_gGXXIAAWYU6.jpg","media_url_https":"https://pbs.twimg.com/media/CCe_gGXXIAAWYU6.jpg","url":"http://t.co/6lNnsbABii","display_url":"pic.twitter.com/6lNnsbABii","expanded_url":"http://twitter.com/emilywlittle/status/587648834689445889/photo/1","type":"photo","sizes":{"small":{"w":340,"h":340,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"medium":{"w":600,"h":600,"resize":"fit"},"large":{"w":600,"h":600,"resize":"fit"}}}]},"twitter_extended_entities":{"media":[{"id":587648834580455424,"id_str":"587648834580455424","indices":[48,70],"media_url":"http://pbs.twimg.com/media/CCe_gGXXIAAWYU6.jpg","media_url_https":"https://pbs.twimg.com/media/CCe_gGXXIAAWYU6.jpg","url":"http://t.co/6lNnsbABii","display_url":"pic.twitter.com/6lNnsbABii","expanded_url":"http://twitter.com/emilywlittle/status/587648834689445889/photo/1","type":"photo","sizes":{"small":{"w":340,"h":340,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"},"medium":{"w":600,"h":600,"resize":"fit"},"large":{"w":600,"h":600,"resize":"fit"}}}]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"amazon\" OR to:\"amazonhelp\" OR to:\"BestBuy\" OR to:\"BestBuySupport\" OR to:\"jcpenney\" OR to:\"Kohls\" OR to:\"kroger\" OR to:\"Macys\" OR to:\"Sears\" OR to:\"searscares\" OR to:\"ToysRUs\" OR to:\"Walmart\" OR to:\"Target\" OR to:\"costco\" OR to:\"publix\" OR to:\"publixhelp\" OR to:\"Nordstrom\" OR to:\"neimanmarcus\" OR to:\"marksandspencer\" OR to:\"tesco\" OR to:\"AldiUK\" OR to:\"AldiUSA\" OR to:\"LoblawsON\" OR to:\"safeway\" OR to:\"WholeFoods\" OR to:\"sainsburys\" OR to:\"woolworths\" OR to:\"TrueValue\" OR to:\"IKEAUSA\")","tag":"retailers"}],"urls":[{"url":"http://t.co/Cz3XUWDvva","expanded_url":"https://www.yappem.com/redirect/?pid=782008","expanded_status":403},{"url":"http://t.co/6lNnsbABii","expanded_url":"http://twitter.com/emilywlittle/status/587648834689445889/photo/1","expanded_status":200}],"language":{"value":"en"}}}
3
+ {"id":"tag:search.twitter.com,2005:587648869485379585","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:265357386","link":"http://www.twitter.com/dr_acula365","displayName":"Andy","postedTime":"2011-03-13T12:16:17.000Z","image":"https://pbs.twimg.com/profile_images/2438808933/to47tp1pbrww1gqwbe9k_normal.jpeg","summary":"Just a guy who likes sport, music and food. You'll find me in the LGBT thread on f365 forum. Please don't follow me if you are under 18. You will be blocked.","links":[{"href":null,"rel":"me"}],"friendsCount":185,"followersCount":128,"listedCount":3,"statusesCount":916,"twitterTimeZone":"Casablanca","verified":false,"utcOffset":"3600","preferredUsername":"dr_acula365","languages":["en"],"location":{"objectType":"place","displayName":"Newcastle"},"favoritesCount":0},"verb":"post","postedTime":"2015-04-13T16:09:43.000Z","generator":{"displayName":"Tweetbot for iΟS","link":"http://tapbots.com/tweetbot"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/dr_acula365/statuses/587648869485379585","body":"@Tesco when your website says next day click and collect and the email says pick up from 3pm, when do you actually mean I can pick it up?","object":{"objectType":"note","id":"object:search.twitter.com,2005:587648869485379585","summary":"@Tesco when your website says next day click and collect and the email says pick up from 3pm, when do you actually mean I can pick it up?","link":"http://twitter.com/dr_acula365/statuses/587648869485379585","postedTime":"2015-04-13T16:09:43.000Z"},"favoritesCount":0,"twitter_entities":{"hashtags":[],"trends":[],"urls":[],"user_mentions":[{"screen_name":"Tesco","name":"Tesco","id":271986064,"id_str":"271986064","indices":[0,6]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"amazon\" OR to:\"amazonhelp\" OR to:\"BestBuy\" OR to:\"BestBuySupport\" OR to:\"jcpenney\" OR to:\"Kohls\" OR to:\"kroger\" OR to:\"Macys\" OR to:\"Sears\" OR to:\"searscares\" OR to:\"ToysRUs\" OR to:\"Walmart\" OR to:\"Target\" OR to:\"costco\" OR to:\"publix\" OR to:\"publixhelp\" OR to:\"Nordstrom\" OR to:\"neimanmarcus\" OR to:\"marksandspencer\" OR to:\"tesco\" OR to:\"AldiUK\" OR to:\"AldiUSA\" OR to:\"LoblawsON\" OR to:\"safeway\" OR to:\"WholeFoods\" OR to:\"sainsburys\" OR to:\"woolworths\" OR to:\"TrueValue\" OR to:\"IKEAUSA\")","tag":"retailers"}],"language":{"value":"en"}}}
4
+ {"id":"tag:search.twitter.com,2005:587648932337098752","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:2642049675","link":"http://www.twitter.com/michaeljohnmcr","displayName":"Michael Delaney","postedTime":"2014-06-25T22:59:21.000Z","image":"https://pbs.twimg.com/profile_images/544998090609291264/W-4vCwC7_normal.jpeg","summary":"邁克爾 ❌❌","links":[{"href":null,"rel":"me"}],"friendsCount":48,"followersCount":19,"listedCount":0,"statusesCount":302,"twitterTimeZone":"Azores","verified":false,"utcOffset":"0","preferredUsername":"michaeljohnmcr","languages":["en"],"favoritesCount":10},"verb":"post","postedTime":"2015-04-13T16:09:58.000Z","generator":{"displayName":"Twitter for iPhone","link":"http://twitter.com/download/iphone"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/michaeljohnmcr/statuses/587648932337098752","body":"@asda I need a number to make a complaint with in the uk can't find it online","object":{"objectType":"note","id":"object:search.twitter.com,2005:587648932337098752","summary":"@asda I need a number to make a complaint with in the uk can't find it online","link":"http://twitter.com/michaeljohnmcr/statuses/587648932337098752","postedTime":"2015-04-13T16:09:58.000Z"},"favoritesCount":0,"location":{"objectType":"place","displayName":"Manchester, England","name":"Manchester","country_code":"United Kingdom","twitter_country_code":"GB","link":"https://api.twitter.com/1.1/geo/id/315b740b108481f6.json","geo":{"type":"Polygon","coordinates":[[[-2.319934,53.343623],[-2.319934,53.5702824],[-2.147026,53.5702824],[-2.147026,53.343623]]]}},"geo":{"type":"Point","coordinates":[53.38604,-2.251666]},"twitter_entities":{"hashtags":[],"trends":[],"urls":[],"user_mentions":[{"screen_name":"asda","name":"Asda","id":20123366,"id_str":"20123366","indices":[0,5]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"BedBathBeyond\" OR to:\"WilliamsSonoma\" OR to:\"GAP\" OR to:\"Abercrombie\" OR to:\"hm\" OR to:\"VictoriasSecret\" OR to:\"LLBean\" OR to:\"LandsEnd\" OR to:\"eBay\" OR to:\"Overstock_help\" OR to:\"Overstock\" OR to:\"QVC\" OR to:\"BandQ\" OR to:\"asda\" OR to:\"waitrose\" OR to:\"LidlUK\" OR to:\"Ocado\" OR to:\"Burberry\" OR to:\"marksandspencer\" OR to:\"johnlewisretail\" OR to:\"nextofficial\" OR to:\"ASOS\" OR to:\"Topshop\" OR to:\"ZARA\" OR to:\"NewLookFashion\")","tag":"retailers"}],"language":{"value":"en"}}}
5
+ {"id":"tag:search.twitter.com,2005:587649014415278080","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:14577165","link":"http://www.twitter.com/marinmaven","displayName":"marinmaven","postedTime":"2008-04-28T23:11:01.000Z","image":"https://pbs.twimg.com/profile_images/489833602222661632/dKsJXZaX_normal.jpeg","summary":"I am a San Francisco native who grew up on the Peninsula. I muse about politics, economics, culture, and living in Marin and beyond.","links":[{"href":"http://www.marinmaven.com/","rel":"me"}],"friendsCount":2316,"followersCount":2360,"listedCount":123,"statusesCount":19661,"twitterTimeZone":"Pacific Time (US & Canada)","verified":false,"utcOffset":"-25200","preferredUsername":"marinmaven","languages":["en"],"location":{"objectType":"place","displayName":"ÜT: 38.006898,-122.531684"},"favoritesCount":355},"verb":"post","postedTime":"2015-04-13T16:10:17.000Z","generator":{"displayName":"Twitter for iPhone","link":"http://twitter.com/download/iphone"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/marinmaven/statuses/587649014415278080","body":"@Macys I have sent you an email detailing what has happened.","object":{"objectType":"note","id":"object:search.twitter.com,2005:587649014415278080","summary":"@Macys I have sent you an email detailing what has happened.","link":"http://twitter.com/marinmaven/statuses/587649014415278080","postedTime":"2015-04-13T16:10:17.000Z"},"inReplyTo":{"link":"http://twitter.com/Macys/statuses/587641764682403841"},"favoritesCount":0,"twitter_entities":{"hashtags":[],"trends":[],"urls":[],"user_mentions":[{"screen_name":"Macys","name":"Macy's","id":50687788,"id_str":"50687788","indices":[0,6]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"amazon\" OR to:\"amazonhelp\" OR to:\"BestBuy\" OR to:\"BestBuySupport\" OR to:\"jcpenney\" OR to:\"Kohls\" OR to:\"kroger\" OR to:\"Macys\" OR to:\"Sears\" OR to:\"searscares\" OR to:\"ToysRUs\" OR to:\"Walmart\" OR to:\"Target\" OR to:\"costco\" OR to:\"publix\" OR to:\"publixhelp\" OR to:\"Nordstrom\" OR to:\"neimanmarcus\" OR to:\"marksandspencer\" OR to:\"tesco\" OR to:\"AldiUK\" OR to:\"AldiUSA\" OR to:\"LoblawsON\" OR to:\"safeway\" OR to:\"WholeFoods\" OR to:\"sainsburys\" OR to:\"woolworths\" OR to:\"TrueValue\" OR to:\"IKEAUSA\")","tag":"retailers"}],"language":{"value":"en"}}}
6
+ {"id":"tag:search.twitter.com,2005:587649047697215488","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:265357386","link":"http://www.twitter.com/dr_acula365","displayName":"Andy","postedTime":"2011-03-13T12:16:17.000Z","image":"https://pbs.twimg.com/profile_images/2438808933/to47tp1pbrww1gqwbe9k_normal.jpeg","summary":"Just a guy who likes sport, music and food. You'll find me in the LGBT thread on f365 forum. Please don't follow me if you are under 18. You will be blocked.","links":[{"href":null,"rel":"me"}],"friendsCount":185,"followersCount":128,"listedCount":3,"statusesCount":917,"twitterTimeZone":"Casablanca","verified":false,"utcOffset":"3600","preferredUsername":"dr_acula365","languages":["en"],"location":{"objectType":"place","displayName":"Newcastle"},"favoritesCount":0},"verb":"post","postedTime":"2015-04-13T16:10:25.000Z","generator":{"displayName":"Tweetbot for iΟS","link":"http://tapbots.com/tweetbot"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/dr_acula365/statuses/587649047697215488","body":"@Tesco the store has no idea where my order will be and suggests I go back tomorrow as it \"might\" be with them by then.","object":{"objectType":"note","id":"object:search.twitter.com,2005:587649047697215488","summary":"@Tesco the store has no idea where my order will be and suggests I go back tomorrow as it \"might\" be with them by then.","link":"http://twitter.com/dr_acula365/statuses/587649047697215488","postedTime":"2015-04-13T16:10:25.000Z"},"favoritesCount":0,"twitter_entities":{"hashtags":[],"trends":[],"urls":[],"user_mentions":[{"screen_name":"Tesco","name":"Tesco","id":271986064,"id_str":"271986064","indices":[0,6]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"amazon\" OR to:\"amazonhelp\" OR to:\"BestBuy\" OR to:\"BestBuySupport\" OR to:\"jcpenney\" OR to:\"Kohls\" OR to:\"kroger\" OR to:\"Macys\" OR to:\"Sears\" OR to:\"searscares\" OR to:\"ToysRUs\" OR to:\"Walmart\" OR to:\"Target\" OR to:\"costco\" OR to:\"publix\" OR to:\"publixhelp\" OR to:\"Nordstrom\" OR to:\"neimanmarcus\" OR to:\"marksandspencer\" OR to:\"tesco\" OR to:\"AldiUK\" OR to:\"AldiUSA\" OR to:\"LoblawsON\" OR to:\"safeway\" OR to:\"WholeFoods\" OR to:\"sainsburys\" OR to:\"woolworths\" OR to:\"TrueValue\" OR to:\"IKEAUSA\")","tag":"retailers"}],"language":{"value":"en"}}}
7
+ {"id":"tag:search.twitter.com,2005:587649057914490880","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:509474447","link":"http://www.twitter.com/DebbieMeldrum","displayName":"Debstweeted","postedTime":"2012-03-01T00:24:28.000Z","image":"https://pbs.twimg.com/profile_images/483673950602682368/dsKmu4AK_normal.jpeg","summary":"Professional. Linguist. Fashion follower. Juice addict. Day dreamer. Number 11.","links":[{"href":null,"rel":"me"}],"friendsCount":677,"followersCount":132,"listedCount":3,"statusesCount":323,"twitterTimeZone":null,"verified":false,"utcOffset":null,"preferredUsername":"DebbieMeldrum","languages":["en"],"location":{"objectType":"place","displayName":"Aberdeen"},"favoritesCount":337},"verb":"post","postedTime":"2015-04-13T16:10:28.000Z","generator":{"displayName":"Twitter for iPad","link":"http://twitter.com/#!/download/ipad"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/DebbieMeldrum/statuses/587649057914490880","body":"@Topshop really want to but unfortunately my local Topshop in #Aberdeen doesn't stock it 😟","object":{"objectType":"note","id":"object:search.twitter.com,2005:587649057914490880","summary":"@Topshop really want to but unfortunately my local Topshop in #Aberdeen doesn't stock it 😟","link":"http://twitter.com/DebbieMeldrum/statuses/587649057914490880","postedTime":"2015-04-13T16:10:28.000Z"},"inReplyTo":{"link":"http://twitter.com/Topshop/statuses/587648638467366912"},"favoritesCount":0,"location":{"objectType":"place","displayName":"Aberdeen, Scotland","name":"Aberdeen","country_code":"United Kingdom","twitter_country_code":"GB","link":"https://api.twitter.com/1.1/geo/id/73cc26d418860ddd.json","geo":{"type":"Polygon","coordinates":[[[-2.1899763,57.107695],[-2.1899763,57.2134174],[-2.0641046,57.2134174],[-2.0641046,57.107695]]]}},"geo":{"type":"Point","coordinates":[57.170311,-2.094876]},"twitter_entities":{"hashtags":[{"text":"Aberdeen","indices":[62,71]}],"trends":[],"urls":[],"user_mentions":[{"screen_name":"Topshop","name":"Topshop","id":20908109,"id_str":"20908109","indices":[0,8]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"BedBathBeyond\" OR to:\"WilliamsSonoma\" OR to:\"GAP\" OR to:\"Abercrombie\" OR to:\"hm\" OR to:\"VictoriasSecret\" OR to:\"LLBean\" OR to:\"LandsEnd\" OR to:\"eBay\" OR to:\"Overstock_help\" OR to:\"Overstock\" OR to:\"QVC\" OR to:\"BandQ\" OR to:\"asda\" OR to:\"waitrose\" OR to:\"LidlUK\" OR to:\"Ocado\" OR to:\"Burberry\" OR to:\"marksandspencer\" OR to:\"johnlewisretail\" OR to:\"nextofficial\" OR to:\"ASOS\" OR to:\"Topshop\" OR to:\"ZARA\" OR to:\"NewLookFashion\")","tag":"retailers"}],"language":{"value":"en"}}}
8
+ {"id":"tag:search.twitter.com,2005:587649092089733120","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:274108611","link":"http://www.twitter.com/IAmKatieDevs","displayName":"Katie Devlin","postedTime":"2011-03-29T19:02:59.000Z","image":"https://pbs.twimg.com/profile_images/454566612080033793/du2a4BhY_normal.jpeg","summary":"Boston bred, fashion fanatic, music enthusiast, IBMer. {{MY tweets are MY own}}","links":[{"href":null,"rel":"me"}],"friendsCount":382,"followersCount":234,"listedCount":10,"statusesCount":1673,"twitterTimeZone":"Quito","verified":false,"utcOffset":"-18000","preferredUsername":"IAmKatieDevs","languages":["en"],"location":{"objectType":"place","displayName":"Boston, MA"},"favoritesCount":263},"verb":"post","postedTime":"2015-04-13T16:10:36.000Z","generator":{"displayName":"Hootsuite","link":"http://www.hootsuite.com"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/IAmKatieDevs/statuses/587649092089733120","body":"@BedBathBeyond marries wedding registry with augmented reality http://t.co/0bojF4HY12 #mobile #mcommerce","object":{"objectType":"note","id":"object:search.twitter.com,2005:587649092089733120","summary":"@BedBathBeyond marries wedding registry with augmented reality http://t.co/0bojF4HY12 #mobile #mcommerce","link":"http://twitter.com/IAmKatieDevs/statuses/587649092089733120","postedTime":"2015-04-13T16:10:36.000Z"},"favoritesCount":0,"twitter_entities":{"hashtags":[{"text":"mobile","indices":[86,93]},{"text":"mcommerce","indices":[94,104]}],"trends":[],"urls":[{"url":"http://t.co/0bojF4HY12","expanded_url":"http://www.mobilecommercedaily.com/bed-bath-and-beyond-marries-wedding-registry-with-augmented-reality","display_url":"mobilecommercedaily.com/bed-bath-and-b…","indices":[63,85]}],"user_mentions":[{"screen_name":"BedBathBeyond","name":"Bed Bath & Beyond","id":372817561,"id_str":"372817561","indices":[0,14]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"BedBathBeyond\" OR to:\"WilliamsSonoma\" OR to:\"GAP\" OR to:\"Abercrombie\" OR to:\"hm\" OR to:\"VictoriasSecret\" OR to:\"LLBean\" OR to:\"LandsEnd\" OR to:\"eBay\" OR to:\"Overstock_help\" OR to:\"Overstock\" OR to:\"QVC\" OR to:\"BandQ\" OR to:\"asda\" OR to:\"waitrose\" OR to:\"LidlUK\" OR to:\"Ocado\" OR to:\"Burberry\" OR to:\"marksandspencer\" OR to:\"johnlewisretail\" OR to:\"nextofficial\" OR to:\"ASOS\" OR to:\"Topshop\" OR to:\"ZARA\" OR to:\"NewLookFashion\")","tag":"retailers"}],"urls":[{"url":"http://t.co/0bojF4HY12","expanded_url":"http://www.mobilecommercedaily.com/bed-bath-and-beyond-marries-wedding-registry-with-augmented-reality","expanded_status":200}],"language":{"value":"en"}}}
9
+ {"id":"tag:search.twitter.com,2005:587649207844081664","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:944015658","link":"http://www.twitter.com/dianekendall716","displayName":"diane kendall","postedTime":"2012-11-12T16:59:18.000Z","image":"https://pbs.twimg.com/profile_images/534077775309975553/b0Z9SWCF_normal.jpeg","summary":null,"links":[{"href":null,"rel":"me"}],"friendsCount":24,"followersCount":10,"listedCount":0,"statusesCount":34,"twitterTimeZone":null,"verified":false,"utcOffset":null,"preferredUsername":"dianekendall716","languages":["en"],"favoritesCount":63},"verb":"post","postedTime":"2015-04-13T16:11:03.000Z","generator":{"displayName":"Mobile Web (M5)","link":"https://mobile.twitter.com"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/dianekendall716/statuses/587649207844081664","body":"@marksandspencer black please","object":{"objectType":"note","id":"object:search.twitter.com,2005:587649207844081664","summary":"@marksandspencer black please","link":"http://twitter.com/dianekendall716/statuses/587649207844081664","postedTime":"2015-04-13T16:11:03.000Z"},"inReplyTo":{"link":"http://twitter.com/marksandspencer/statuses/587541076187090944"},"favoritesCount":0,"twitter_entities":{"hashtags":[],"trends":[],"urls":[],"user_mentions":[{"screen_name":"marksandspencer","name":"M&S","id":37916167,"id_str":"37916167","indices":[0,16]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"BedBathBeyond\" OR to:\"WilliamsSonoma\" OR to:\"GAP\" OR to:\"Abercrombie\" OR to:\"hm\" OR to:\"VictoriasSecret\" OR to:\"LLBean\" OR to:\"LandsEnd\" OR to:\"eBay\" OR to:\"Overstock_help\" OR to:\"Overstock\" OR to:\"QVC\" OR to:\"BandQ\" OR to:\"asda\" OR to:\"waitrose\" OR to:\"LidlUK\" OR to:\"Ocado\" OR to:\"Burberry\" OR to:\"marksandspencer\" OR to:\"johnlewisretail\" OR to:\"nextofficial\" OR to:\"ASOS\" OR to:\"Topshop\" OR to:\"ZARA\" OR to:\"NewLookFashion\")","tag":"retailers"},{"value":"lang:en (to:\"amazon\" OR to:\"amazonhelp\" OR to:\"BestBuy\" OR to:\"BestBuySupport\" OR to:\"jcpenney\" OR to:\"Kohls\" OR to:\"kroger\" OR to:\"Macys\" OR to:\"Sears\" OR to:\"searscares\" OR to:\"ToysRUs\" OR to:\"Walmart\" OR to:\"Target\" OR to:\"costco\" OR to:\"publix\" OR to:\"publixhelp\" OR to:\"Nordstrom\" OR to:\"neimanmarcus\" OR to:\"marksandspencer\" OR to:\"tesco\" OR to:\"AldiUK\" OR to:\"AldiUSA\" OR to:\"LoblawsON\" OR to:\"safeway\" OR to:\"WholeFoods\" OR to:\"sainsburys\" OR to:\"woolworths\" OR to:\"TrueValue\" OR to:\"IKEAUSA\")","tag":"retailers"}],"language":{"value":"en"}}}
10
+ {"id":"tag:search.twitter.com,2005:587649264156811264","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:920532930","link":"http://www.twitter.com/karengodfrey06","displayName":"Karen Godfrey-Young","postedTime":"2012-11-02T07:26:39.000Z","image":"https://pbs.twimg.com/profile_images/579378574119051264/NutpKf5S_normal.jpg","summary":"Wife/ Mother / Grandma","links":[{"href":null,"rel":"me"}],"friendsCount":89,"followersCount":61,"listedCount":0,"statusesCount":1771,"twitterTimeZone":null,"verified":false,"utcOffset":null,"preferredUsername":"karengodfrey06","languages":["en"],"location":{"objectType":"place","displayName":" Oxfordshire"},"favoritesCount":1383},"verb":"post","postedTime":"2015-04-13T16:11:17.000Z","generator":{"displayName":"Twitter for Android","link":"http://twitter.com/download/android"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/karengodfrey06/statuses/587649264156811264","body":"@AldiUK nothing is happening. Opens to blank white page? \nI shop with you every week so would love to enter comp xx","object":{"objectType":"note","id":"object:search.twitter.com,2005:587649264156811264","summary":"@AldiUK nothing is happening. Opens to blank white page? \nI shop with you every week so would love to enter comp xx","link":"http://twitter.com/karengodfrey06/statuses/587649264156811264","postedTime":"2015-04-13T16:11:17.000Z"},"inReplyTo":{"link":"http://twitter.com/AldiUK/statuses/587623827787493376"},"favoritesCount":0,"twitter_entities":{"hashtags":[],"trends":[],"urls":[],"user_mentions":[{"screen_name":"AldiUK","name":"Aldi Stores UK","id":28596803,"id_str":"28596803","indices":[0,7]}],"symbols":[]},"twitter_filter_level":"low","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"value":"lang:en (to:\"amazon\" OR to:\"amazonhelp\" OR to:\"BestBuy\" OR to:\"BestBuySupport\" OR to:\"jcpenney\" OR to:\"Kohls\" OR to:\"kroger\" OR to:\"Macys\" OR to:\"Sears\" OR to:\"searscares\" OR to:\"ToysRUs\" OR to:\"Walmart\" OR to:\"Target\" OR to:\"costco\" OR to:\"publix\" OR to:\"publixhelp\" OR to:\"Nordstrom\" OR to:\"neimanmarcus\" OR to:\"marksandspencer\" OR to:\"tesco\" OR to:\"AldiUK\" OR to:\"AldiUSA\" OR to:\"LoblawsON\" OR to:\"safeway\" OR to:\"WholeFoods\" OR to:\"sainsburys\" OR to:\"woolworths\" OR to:\"TrueValue\" OR to:\"IKEAUSA\")","tag":"retailers"}],"language":{"value":"en"}}}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datasift
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DataSift
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-08-05 00:00:00.000000000 Z
13
+ date: 2015-08-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '1.6'
21
+ version: '1.8'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '1.6'
28
+ version: '1.8'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: multi_json
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -77,6 +77,8 @@ extensions: []
77
77
  extra_rdoc_files: []
78
78
  files:
79
79
  - ".gitignore"
80
+ - ".rubocop.yml"
81
+ - ".rubocop_todo.yml"
80
82
  - ".travis.yml"
81
83
  - ".yardopts"
82
84
  - CHANGELOG.md
@@ -95,6 +97,7 @@ files:
95
97
  - examples/core_api_eg.rb
96
98
  - examples/historics_eg.rb
97
99
  - examples/historics_preview_eg.rb
100
+ - examples/ingestion/twitter_gnip_batch_eg.rb
98
101
  - examples/live_stream_eg.rb
99
102
  - examples/managed_source_fb_eg.rb
100
103
  - examples/managed_source_ig_eg.rb
@@ -115,10 +118,12 @@ files:
115
118
  - lib/managed_source.rb
116
119
  - lib/managed_source_auth.rb
117
120
  - lib/managed_source_resource.rb
121
+ - lib/odp.rb
118
122
  - lib/push.rb
119
123
  - lib/pylon.rb
120
124
  - test/datasift/core_api_test.rb
121
125
  - test/datasift/historics_preview_api_test.rb
126
+ - test/datasift/odp/batch_upload_test.rb
122
127
  - test/datasift/push_api_test.rb
123
128
  - test/fixtures/cassettes/core/after_historic_dpu.json
124
129
  - test/fixtures/cassettes/core/balance_get.json
@@ -132,6 +137,10 @@ files:
132
137
  - test/fixtures/cassettes/core/validate_invalid_hash.json
133
138
  - test/fixtures/cassettes/core/validate_success_bool.json
134
139
  - test/fixtures/cassettes/core/validate_success_hash.json
140
+ - test/fixtures/cassettes/odp/batch/after_upload.json
141
+ - test/fixtures/cassettes/odp/batch/before_upload.json
142
+ - test/fixtures/cassettes/odp/batch/upload_failure_no_source.json
143
+ - test/fixtures/cassettes/odp/batch/upload_success.json
135
144
  - test/fixtures/cassettes/preview/before_preview_create.json
136
145
  - test/fixtures/cassettes/preview/before_preview_get.json
137
146
  - test/fixtures/cassettes/preview/preview_create_success.json
@@ -160,6 +169,7 @@ files:
160
169
  - test/fixtures/cassettes/push/push_stop.json
161
170
  - test/fixtures/cassettes/push/push_update.json
162
171
  - test/fixtures/cassettes/push/push_validate.json
172
+ - test/fixtures/data/fake_gnip_tweets.json
163
173
  - test/test_helper.rb
164
174
  homepage: https://github.com/datasift/datasift-ruby
165
175
  licenses:
@@ -181,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
191
  version: 1.3.5
182
192
  requirements: []
183
193
  rubyforge_project:
184
- rubygems_version: 2.4.6
194
+ rubygems_version: 2.4.8
185
195
  signing_key:
186
196
  specification_version: 4
187
197
  summary: DataSift is a simple wrapper for the DataSift API.