tweetkit 0.1.1 → 0.2.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/.env.example +5 -0
- data/.gitignore +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +6 -1
- data/Gemfile.lock +26 -5
- data/LICENSE +21 -0
- data/README.md +6 -4
- data/Rakefile +2 -2
- data/bin/console +19 -0
- data/lib/tweetkit/auth.rb +1 -5
- data/lib/tweetkit/client/response/annotations.rb +0 -0
- data/lib/tweetkit/client/response/attachments.rb +0 -0
- data/lib/tweetkit/client/response/expansions.rb +0 -0
- data/lib/tweetkit/client/response/fields.rb +0 -0
- data/lib/tweetkit/client/response/geo.rb +0 -0
- data/lib/tweetkit/client/response/meta.rb +0 -0
- data/lib/tweetkit/client/response/metrics.rb +0 -0
- data/lib/tweetkit/client/response/response.rb +0 -0
- data/lib/tweetkit/client/response/tweet.rb +0 -0
- data/lib/tweetkit/client/response/tweets.rb +0 -0
- data/lib/tweetkit/client/search/conjunctions.rb +494 -0
- data/lib/tweetkit/client/search/search.rb +23 -0
- data/lib/tweetkit/client/tweets.rb +13 -5
- data/lib/tweetkit/client.rb +0 -1
- data/lib/tweetkit/connection.rb +68 -49
- data/lib/tweetkit/pagination.rb +0 -0
- data/lib/tweetkit/response.rb +585 -62
- data/lib/tweetkit/version.rb +1 -1
- metadata +20 -4
- data/lib/tweetkit/search.rb +0 -121
data/lib/tweetkit/response.rb
CHANGED
@@ -1,65 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
|
-
require 'pry'
|
3
4
|
|
4
5
|
module Tweetkit
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(response)
|
9
|
-
@original_response = response.body
|
10
|
-
parsed_response = JSON.parse(@original_response)
|
11
|
-
@tweets = Tweetkit::Response::Tweets.new(parsed_response)
|
12
|
-
@meta = Tweetkit::Response::Meta.new(@tweets.meta)
|
13
|
-
@expansions = Tweetkit::Response::Expansions.new(@tweets.expansions)
|
14
|
-
end
|
15
|
-
|
16
|
-
class Expansions
|
6
|
+
module Response
|
7
|
+
class Tweets
|
17
8
|
include Enumerable
|
18
9
|
|
19
|
-
attr_accessor :expansions
|
10
|
+
attr_accessor :annotations, :connection, :context_annotations, :entity_annotations, :expansions, :fields, :meta, :options, :original_response, :response, :tweets, :twitter_request
|
20
11
|
|
21
|
-
def initialize(
|
22
|
-
|
12
|
+
def initialize(response, **options)
|
13
|
+
parse! response, **options
|
23
14
|
end
|
24
15
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
16
|
+
def parse!(response, **options)
|
17
|
+
parse_response response
|
18
|
+
extract_and_save_tweets
|
19
|
+
return unless @tweets
|
29
20
|
|
30
|
-
|
31
|
-
|
21
|
+
extract_and_save_meta
|
22
|
+
extract_and_save_expansions
|
23
|
+
extract_and_save_options(**options)
|
24
|
+
extract_and_save_request
|
32
25
|
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class Meta
|
36
|
-
include Enumerable
|
37
|
-
|
38
|
-
attr_accessor :meta
|
39
26
|
|
40
|
-
def
|
41
|
-
@
|
27
|
+
def parse_response(response)
|
28
|
+
@original_response = response.body
|
29
|
+
@response = JSON.parse(@original_response)
|
42
30
|
end
|
43
31
|
|
44
|
-
def
|
45
|
-
data =
|
46
|
-
|
32
|
+
def extract_and_save_tweets
|
33
|
+
if (data = @response['data'])
|
34
|
+
if data.is_a?(Array)
|
35
|
+
@tweets = @response['data'].collect { |tweet| Tweet.new(tweet) }
|
36
|
+
else
|
37
|
+
@tweets = [Tweet.new(@response['data'])]
|
38
|
+
end
|
39
|
+
else
|
40
|
+
@tweets = nil
|
41
|
+
end
|
47
42
|
end
|
48
43
|
|
49
|
-
def
|
50
|
-
meta.
|
44
|
+
def extract_and_save_meta
|
45
|
+
@meta = Meta.new(@response['meta'])
|
51
46
|
end
|
52
|
-
end
|
53
47
|
|
54
|
-
|
55
|
-
|
48
|
+
def extract_and_save_expansions
|
49
|
+
@expansions = Expansions.new(@response['includes'])
|
50
|
+
end
|
56
51
|
|
57
|
-
|
52
|
+
def extract_and_save_options(**options)
|
53
|
+
@options = options
|
54
|
+
end
|
58
55
|
|
59
|
-
def
|
60
|
-
@
|
61
|
-
@
|
62
|
-
@expansions = response['includes']
|
56
|
+
def extract_and_save_request
|
57
|
+
@connection = @options[:connection]
|
58
|
+
@twitter_request = @options[:twitter_request]
|
63
59
|
end
|
64
60
|
|
65
61
|
def each(*args, &block)
|
@@ -70,36 +66,563 @@ module Tweetkit
|
|
70
66
|
tweets.last
|
71
67
|
end
|
72
68
|
|
73
|
-
def
|
74
|
-
|
69
|
+
def tweet
|
70
|
+
tweets.first
|
75
71
|
end
|
76
72
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
73
|
+
def next_page
|
74
|
+
connection.params.merge!({ next_token: meta.next_token })
|
75
|
+
response = connection.get(twitter_request[:previous_url])
|
76
|
+
parse! response,
|
77
|
+
connection: connection,
|
78
|
+
twitter_request: {
|
79
|
+
previous_url: twitter_request[:previous_url],
|
80
|
+
previous_query: twitter_request[:previous_query]
|
81
|
+
}
|
82
|
+
self
|
82
83
|
end
|
83
84
|
|
84
|
-
def
|
85
|
-
|
85
|
+
def prev_page
|
86
|
+
connection.params.merge!({ previous: meta.previous_token })
|
87
|
+
response = connection.get(twitter_request[:previous_url])
|
88
|
+
parse! response,
|
89
|
+
connection: connection,
|
90
|
+
twitter_request: {
|
91
|
+
previous_url: twitter_request[:previous_url],
|
92
|
+
previous_query: twitter_request[:previous_query]
|
93
|
+
}
|
94
|
+
self
|
86
95
|
end
|
87
|
-
end
|
88
96
|
|
89
|
-
|
90
|
-
|
97
|
+
class Tweet
|
98
|
+
attr_accessor :annotations, :attachments, :data
|
99
|
+
|
100
|
+
def initialize(tweet)
|
101
|
+
@data = tweet
|
102
|
+
@annotations = Annotations.new(data['context_annotations'], data['entities'])
|
103
|
+
@attachments = Attachments.new(data['attachments'])
|
104
|
+
end
|
105
|
+
|
106
|
+
def id
|
107
|
+
data['id']
|
108
|
+
end
|
109
|
+
|
110
|
+
def text
|
111
|
+
data['text']
|
112
|
+
end
|
113
|
+
|
114
|
+
def author_id
|
115
|
+
data['author_id']
|
116
|
+
end
|
117
|
+
|
118
|
+
def conversation_id
|
119
|
+
data['conversation_id']
|
120
|
+
end
|
121
|
+
|
122
|
+
def created_at
|
123
|
+
data['created_at']
|
124
|
+
end
|
125
|
+
|
126
|
+
def reply_to
|
127
|
+
in_reply_to_user_id
|
128
|
+
end
|
129
|
+
|
130
|
+
def in_reply_to_user_id
|
131
|
+
data['in_reply_to_user_id']
|
132
|
+
end
|
133
|
+
|
134
|
+
def lang
|
135
|
+
data['lang']
|
136
|
+
end
|
137
|
+
|
138
|
+
def nsfw?
|
139
|
+
possibly_sensitive
|
140
|
+
end
|
141
|
+
|
142
|
+
def sensitive?
|
143
|
+
possibly_sensitive
|
144
|
+
end
|
145
|
+
|
146
|
+
def possibly_sensitive
|
147
|
+
data['possibly_sensitive']
|
148
|
+
end
|
149
|
+
|
150
|
+
def permission
|
151
|
+
reply_settings
|
152
|
+
end
|
153
|
+
|
154
|
+
def reply_settings
|
155
|
+
data['reply_settings']
|
156
|
+
end
|
157
|
+
|
158
|
+
def device
|
159
|
+
source
|
160
|
+
end
|
161
|
+
|
162
|
+
def source
|
163
|
+
data['source']
|
164
|
+
end
|
165
|
+
|
166
|
+
def withheld?
|
167
|
+
withheld && !withheld.empty?
|
168
|
+
end
|
169
|
+
|
170
|
+
def withheld
|
171
|
+
data['withheld']
|
172
|
+
end
|
173
|
+
|
174
|
+
def context_annotations
|
175
|
+
@annotations.context_annotations || nil
|
176
|
+
end
|
177
|
+
|
178
|
+
def entity_annotations
|
179
|
+
entities
|
180
|
+
end
|
181
|
+
|
182
|
+
def entities
|
183
|
+
@annotations.entity_annotations || nil
|
184
|
+
end
|
185
|
+
|
186
|
+
class Attachments
|
187
|
+
attr_accessor :media_keys, :poll_ids
|
188
|
+
|
189
|
+
def initialize(attachments)
|
190
|
+
return unless attachments
|
191
|
+
|
192
|
+
@media_keys = attachments['media_keys']
|
193
|
+
@poll_ids = attachments['poll_ids']
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class Annotations
|
198
|
+
attr_accessor :context_annotations, :entity_annotations
|
199
|
+
|
200
|
+
def initialize(context_annotations, entity_annotations)
|
201
|
+
return unless context_annotations || entity_annotations
|
202
|
+
|
203
|
+
@context_annotations = Context.new(context_annotations)
|
204
|
+
@entity_annotations = Entity.new(entity_annotations)
|
205
|
+
end
|
206
|
+
|
207
|
+
class Context
|
208
|
+
include Enumerable
|
209
|
+
|
210
|
+
attr_accessor :annotations
|
211
|
+
|
212
|
+
def initialize(annotations)
|
213
|
+
return unless annotations
|
214
|
+
|
215
|
+
@annotations = annotations.collect { |annotation| Annotation.new(annotation) }
|
216
|
+
end
|
217
|
+
|
218
|
+
def each(*args, &block)
|
219
|
+
annotations.each(*args, &block)
|
220
|
+
end
|
221
|
+
|
222
|
+
class Annotation
|
223
|
+
attr_accessor :domain, :entity
|
224
|
+
|
225
|
+
def initialize(annotation)
|
226
|
+
@domain = annotation['domain']
|
227
|
+
@entity = annotation['entity']
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
class Entity
|
233
|
+
include Enumerable
|
234
|
+
|
235
|
+
attr_accessor :annotations, :cashtags, :hashtags, :mentions, :urls
|
236
|
+
|
237
|
+
def initialize(entity_annotations)
|
238
|
+
return unless entity_annotations
|
239
|
+
|
240
|
+
@annotations = Annotations.new(entity_annotations['annotations'])
|
241
|
+
@cashtags = Cashtags.new(entity_annotations['cashtags'])
|
242
|
+
@hashtags = Hashtags.new(entity_annotations['hashtags'])
|
243
|
+
@mentions = Mentions.new(entity_annotations['mentions'])
|
244
|
+
@urls = Urls.new(entity_annotations['urls'])
|
245
|
+
end
|
246
|
+
|
247
|
+
def each(*args, &block)
|
248
|
+
annotations.each(*args, &block)
|
249
|
+
end
|
250
|
+
|
251
|
+
class Annotations
|
252
|
+
attr_accessor :annotations
|
253
|
+
|
254
|
+
def initialize(annotations)
|
255
|
+
return unless annotations
|
256
|
+
|
257
|
+
@annotations = annotations.collect { |annotation| Annotation.new(annotation) }
|
258
|
+
end
|
259
|
+
|
260
|
+
class Annotation
|
261
|
+
attr_accessor :end, :probability, :start, :text, :type
|
262
|
+
|
263
|
+
def initialize(annotation)
|
264
|
+
@end = annotation['end']
|
265
|
+
@probability = annotation['probability']
|
266
|
+
@start = annotation['start']
|
267
|
+
@text = annotation['normalized_text']
|
268
|
+
@type = annotation['type']
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
class Cashtags
|
274
|
+
attr_accessor :cashtags
|
275
|
+
|
276
|
+
def initialize(cashtags)
|
277
|
+
return unless cashtags
|
278
|
+
|
279
|
+
@cashtags = cashtags.collect { |cashtag| Cashtag.new(cashtag) }
|
280
|
+
end
|
281
|
+
|
282
|
+
class Cashtag
|
283
|
+
attr_accessor :end, :start, :tag
|
284
|
+
|
285
|
+
def initialize(cashtag)
|
286
|
+
@end = cashtag['end']
|
287
|
+
@start = cashtag['start']
|
288
|
+
@tag = cashtag['tag']
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
class Hashtags
|
294
|
+
attr_accessor :hashtags
|
295
|
+
|
296
|
+
def initialize(hashtags)
|
297
|
+
return unless hashtags
|
298
|
+
|
299
|
+
@hashtags = hashtags.collect { |hashtag| Hashtag.new(hashtag) }
|
300
|
+
end
|
301
|
+
|
302
|
+
class Hashtag
|
303
|
+
attr_accessor :end, :start, :tag
|
304
|
+
|
305
|
+
def initialize(hashtag)
|
306
|
+
@end = hashtag['end']
|
307
|
+
@start = hashtag['start']
|
308
|
+
@tag = hashtag['tag']
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
class Mentions
|
314
|
+
attr_accessor :mentions
|
315
|
+
|
316
|
+
def initialize(mentions)
|
317
|
+
return unless mentions
|
91
318
|
|
92
|
-
|
93
|
-
|
319
|
+
@mentions = mentions.collect { |mention| Mention.new(mention) }
|
320
|
+
end
|
321
|
+
|
322
|
+
class Mention
|
323
|
+
attr_accessor :end, :id, :start, :username
|
324
|
+
|
325
|
+
def initialize(mention)
|
326
|
+
@end = mention['end']
|
327
|
+
@id = mention['id']
|
328
|
+
@start = mention['start']
|
329
|
+
@username = mention['username']
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
class Urls
|
335
|
+
attr_accessor :urls
|
336
|
+
|
337
|
+
def initialize(urls)
|
338
|
+
return unless urls
|
339
|
+
|
340
|
+
@urls = urls.collect { |url| Url.new(url) }
|
341
|
+
end
|
342
|
+
|
343
|
+
class Url
|
344
|
+
attr_accessor :description, :display_url, :end, :expanded_url, :start, :status, :title, :url, :unwound_url
|
345
|
+
|
346
|
+
def initialize(url)
|
347
|
+
@description = url['description']
|
348
|
+
@display_url = url['display_url']
|
349
|
+
@end = url['end']
|
350
|
+
@expanded_url = url['expanded_url']
|
351
|
+
@start = url['start']
|
352
|
+
@status = url['status']
|
353
|
+
@title = url['title']
|
354
|
+
@url = url['url']
|
355
|
+
@unwound_url = url['unwound_url']
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
class Geo
|
363
|
+
attr_accessor :coordinates, :place_id
|
364
|
+
|
365
|
+
def initialize(geo)
|
366
|
+
return unless geo
|
367
|
+
|
368
|
+
@coordinates = Coordinates.new(geo['coordinates'])
|
369
|
+
@place_id = geo['place_id']
|
370
|
+
end
|
371
|
+
|
372
|
+
class Coordinates
|
373
|
+
attr_accessor :coordinates, :type
|
374
|
+
|
375
|
+
def initialize(coordinates)
|
376
|
+
@coordinates = coordinates['coordinates']
|
377
|
+
@type = coordinates['point']
|
378
|
+
end
|
379
|
+
|
380
|
+
def x
|
381
|
+
coordinates[0]
|
382
|
+
end
|
383
|
+
|
384
|
+
def y
|
385
|
+
coordinates[0]
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
class Metrics
|
391
|
+
attr_accessor :public_metrics
|
392
|
+
|
393
|
+
def initialize(**metrics)
|
394
|
+
return unless metrics
|
395
|
+
|
396
|
+
@public_metrics = Public.new(metrics[:public_metrics])
|
397
|
+
end
|
398
|
+
|
399
|
+
class Public
|
400
|
+
attr_accessor :like_count, :quote_count, :reply_count, :retweet_count
|
401
|
+
|
402
|
+
def initialize(public_metric)
|
403
|
+
@like_count = public_metric['like_count']
|
404
|
+
@quote_count = public_metric['quote_count']
|
405
|
+
@reply_count = public_metric['reply_count']
|
406
|
+
@retweet_count = public_metric['retweet_count']
|
407
|
+
end
|
408
|
+
|
409
|
+
def likes
|
410
|
+
@like_count
|
411
|
+
end
|
412
|
+
|
413
|
+
def quotes
|
414
|
+
@quote_count
|
415
|
+
end
|
416
|
+
|
417
|
+
def replies
|
418
|
+
@reply_count
|
419
|
+
end
|
420
|
+
|
421
|
+
def retweets
|
422
|
+
@retweet_count
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
94
426
|
end
|
95
427
|
|
96
|
-
|
97
|
-
|
98
|
-
|
428
|
+
class Expansions
|
429
|
+
attr_accessor :media, :places, :polls, :tweets, :users
|
430
|
+
|
431
|
+
def initialize(expansions)
|
432
|
+
return unless expansions
|
433
|
+
|
434
|
+
@media = Media.new(expansions['media'])
|
435
|
+
@places = expansions['places']
|
436
|
+
@polls = expansions['polls']
|
437
|
+
@tweets = Tweets.new(expansions['tweets'])
|
438
|
+
@users = Users.new(expansions['users'])
|
439
|
+
end
|
440
|
+
|
441
|
+
class Media
|
442
|
+
attr_accessor :media
|
443
|
+
|
444
|
+
def initialize(media)
|
445
|
+
return unless media
|
446
|
+
|
447
|
+
@media = media.collect { |media_object| MediaObject.new(media_object) }
|
448
|
+
end
|
449
|
+
|
450
|
+
class MediaObject
|
451
|
+
attr_accessor :media_key, :type
|
452
|
+
|
453
|
+
def initialize(media_object)
|
454
|
+
@media_key = media_object['media_key']
|
455
|
+
@type = media_object['type']
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
class Places
|
461
|
+
attr_accessor :places
|
462
|
+
|
463
|
+
def initialize(places)
|
464
|
+
return unless places
|
465
|
+
|
466
|
+
@places = places.collect { |place| Place.new(place) }
|
467
|
+
end
|
468
|
+
|
469
|
+
class Place
|
470
|
+
attr_accessor :full_name, :id
|
471
|
+
|
472
|
+
def initialize(place)
|
473
|
+
@full_name = place['full_name']
|
474
|
+
@id = place['id']
|
475
|
+
end
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
class Polls
|
480
|
+
attr_accessor :polls
|
481
|
+
|
482
|
+
def initialize(polls)
|
483
|
+
return unless polls
|
484
|
+
|
485
|
+
@polls = polls.collect { |poll| Poll.new(poll) }
|
486
|
+
end
|
487
|
+
|
488
|
+
class Poll
|
489
|
+
attr_accessor :id, :options
|
490
|
+
|
491
|
+
def initialize(poll)
|
492
|
+
@id = poll['id']
|
493
|
+
@options = Options.new(poll['options'])
|
494
|
+
end
|
495
|
+
|
496
|
+
class Options
|
497
|
+
attr_accessor :options
|
498
|
+
|
499
|
+
def initialize(options)
|
500
|
+
@options = options.collect { |option| Option.new(option) }
|
501
|
+
end
|
502
|
+
|
503
|
+
class Option
|
504
|
+
attr_accessor :label, :position, :votes
|
505
|
+
|
506
|
+
def initialize(option)
|
507
|
+
@label = option['label']
|
508
|
+
@position = option['position']
|
509
|
+
@votes = option['votes']
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
class Tweets
|
517
|
+
attr_accessor :tweets
|
518
|
+
|
519
|
+
def initialize(tweets)
|
520
|
+
return unless tweets
|
521
|
+
|
522
|
+
@tweets = tweets.collect { |tweet| Tweet.new(tweet) }
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
class Users
|
527
|
+
attr_accessor :users
|
528
|
+
|
529
|
+
def initialize(users)
|
530
|
+
return unless users
|
531
|
+
|
532
|
+
@users = users.collect { |user| User.new(user) }
|
533
|
+
end
|
534
|
+
|
535
|
+
class User
|
536
|
+
attr_accessor :id, :name, :username
|
537
|
+
|
538
|
+
def initialize(user)
|
539
|
+
@id = user['id']
|
540
|
+
@name = user['name']
|
541
|
+
@username = user['username']
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
99
545
|
end
|
100
546
|
|
101
|
-
|
102
|
-
|
547
|
+
class Fields
|
548
|
+
attr_accessor :fields, :media_fields, :place_fields, :poll_fields, :tweet_fields, :user_fields
|
549
|
+
|
550
|
+
def initialize(fields)
|
551
|
+
@fields = fields
|
552
|
+
build_and_normalize_fields(fields) unless fields.nil?
|
553
|
+
end
|
554
|
+
|
555
|
+
def build_and_normalize_fields(fields)
|
556
|
+
fields.each_key do |field_type|
|
557
|
+
normalized_field = build_and_normalize_field(@fields[field_type], field_type)
|
558
|
+
instance_variable_set(:"@#{field_type}", normalized_field)
|
559
|
+
self.class.define_method(field_type) { instance_variable_get("@#{field_type}") }
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
def build_and_normalize_field(field, field_type)
|
564
|
+
Field.new(field, field_type)
|
565
|
+
end
|
566
|
+
|
567
|
+
def method_missing(method, **args)
|
568
|
+
return nil if VALID_FIELDS.include?(method.to_s)
|
569
|
+
|
570
|
+
super
|
571
|
+
end
|
572
|
+
|
573
|
+
def respond_to_missing?(method, *args)
|
574
|
+
VALID_FIELDS.include?(method.to_s) || super
|
575
|
+
end
|
576
|
+
|
577
|
+
class Field
|
578
|
+
include Enumerable
|
579
|
+
|
580
|
+
attr_accessor :normalized_field, :original_field
|
581
|
+
|
582
|
+
FIELD_NORMALIZATION_KEY = {
|
583
|
+
'users': 'id'
|
584
|
+
}.freeze
|
585
|
+
|
586
|
+
def initialize(field, field_type)
|
587
|
+
@original_field = field
|
588
|
+
@normalized_field = {}
|
589
|
+
normalization_key = FIELD_NORMALIZATION_KEY[field_type.to_sym]
|
590
|
+
field.each do |data|
|
591
|
+
key = data[normalization_key]
|
592
|
+
@normalized_field[key.to_i] = data
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
def each(*args, &block)
|
597
|
+
@normalized_field.each(*args, &block)
|
598
|
+
end
|
599
|
+
|
600
|
+
def each_data(*args, &block)
|
601
|
+
@normalized_field.values.each(*args, &block)
|
602
|
+
end
|
603
|
+
|
604
|
+
def find(key)
|
605
|
+
@normalized_field[key.to_i]
|
606
|
+
end
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
610
|
+
class Meta
|
611
|
+
attr_accessor :data
|
612
|
+
|
613
|
+
def initialize(meta)
|
614
|
+
return unless meta
|
615
|
+
|
616
|
+
@data = meta
|
617
|
+
end
|
618
|
+
|
619
|
+
def next_token
|
620
|
+
@data['next_token']
|
621
|
+
end
|
622
|
+
|
623
|
+
def previous_token
|
624
|
+
@data['previous_token']
|
625
|
+
end
|
103
626
|
end
|
104
627
|
end
|
105
628
|
end
|
data/lib/tweetkit/version.rb
CHANGED