ayadn 3.0 → 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 +4 -4
- data/.travis.yml +1 -4
- data/CHANGELOG.md +12 -4
- data/README.md +2 -5
- data/ayadn.gemspec +0 -2
- data/doc/01-index.md +0 -3
- data/doc/02-install.md +0 -4
- data/doc/06-post.md +0 -16
- data/doc/{18-contact.md → 16-contact.md} +0 -0
- data/doc/{19-examples.md → 17-examples.md} +0 -0
- data/doc/18-develop.md +165 -0
- data/lib/ayadn/action.rb +206 -396
- data/lib/ayadn/alias.rb +1 -1
- data/lib/ayadn/annotations.rb +15 -27
- data/lib/ayadn/api.rb +39 -28
- data/lib/ayadn/app.rb +19 -29
- data/lib/ayadn/authorize.rb +22 -13
- data/lib/ayadn/blacklist.rb +6 -19
- data/lib/ayadn/channel_object.rb +75 -0
- data/lib/ayadn/check.rb +19 -11
- data/lib/ayadn/cnx.rb +9 -15
- data/lib/ayadn/databases.rb +15 -27
- data/lib/ayadn/debug.rb +9 -9
- data/lib/ayadn/descriptions.rb +1 -99
- data/lib/ayadn/diagnostics.rb +16 -15
- data/lib/ayadn/endpoints.rb +18 -22
- data/lib/ayadn/errors.rb +1 -1
- data/lib/ayadn/fileops.rb +12 -12
- data/lib/ayadn/filtered_post_object.rb +11 -0
- data/lib/ayadn/ids.rb +0 -3
- data/lib/ayadn/logs.rb +4 -4
- data/lib/ayadn/mark.rb +34 -30
- data/lib/ayadn/nicerank.rb +7 -7
- data/lib/ayadn/nowplaying.rb +8 -22
- data/lib/ayadn/pinboard.rb +8 -12
- data/lib/ayadn/post.rb +18 -18
- data/lib/ayadn/post_object.rb +118 -0
- data/lib/ayadn/preferences_object.rb +290 -0
- data/lib/ayadn/profile.rb +2 -2
- data/lib/ayadn/scroll.rb +58 -67
- data/lib/ayadn/search.rb +22 -15
- data/lib/ayadn/set.rb +93 -83
- data/lib/ayadn/settings.rb +25 -33
- data/lib/ayadn/status.rb +24 -26
- data/lib/ayadn/stream.rb +68 -66
- data/lib/ayadn/stream_object.rb +56 -0
- data/lib/ayadn/switch.rb +2 -2
- data/lib/ayadn/user_object.rb +116 -0
- data/lib/ayadn/version.rb +1 -1
- data/lib/ayadn/view.rb +255 -278
- data/lib/ayadn/workers.rb +172 -174
- data/spec/integration/action_spec.rb +55 -34
- data/spec/mock/ayadn.sqlite +0 -0
- data/spec/unit/annotations_spec.rb +54 -41
- data/spec/unit/api_spec.rb +78 -7
- data/spec/unit/blacklistworkers_spec.rb +92 -20
- data/spec/unit/databases_spec.rb +117 -36
- data/spec/unit/endpoints_spec.rb +82 -10
- data/spec/unit/nicerank_spec.rb +56 -27
- data/spec/unit/post_spec.rb +94 -21
- data/spec/unit/set_spec.rb +141 -210
- data/spec/unit/view_spec.rb +105 -32
- data/spec/unit/workers_spec.rb +143 -52
- metadata +12 -37
- data/doc/16-movie.md +0 -39
- data/doc/17-tvshow.md +0 -46
- data/lib/ayadn/nowwatching.rb +0 -118
- data/lib/ayadn/tvshow.rb +0 -162
data/lib/ayadn/status.rb
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
module Ayadn
|
3
3
|
class Status
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
attr_reader :thor
|
6
|
+
|
7
|
+
def initialize thor = Thor::Shell::Color.new
|
8
|
+
@thor = thor
|
7
9
|
end
|
8
10
|
|
9
11
|
def done
|
@@ -18,11 +20,11 @@ module Ayadn
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def downloaded(name)
|
21
|
-
info("downloaded", "#{Settings.config
|
23
|
+
info("downloaded", "#{Settings.config.paths.downloads}/#{name}", "green")
|
22
24
|
end
|
23
25
|
|
24
26
|
def links_saved(name)
|
25
|
-
info("done", "links exported to file #{Settings.config
|
27
|
+
info("done", "links exported to file #{Settings.config.paths.lists}/#{name}", "green")
|
26
28
|
end
|
27
29
|
|
28
30
|
def downloading
|
@@ -81,6 +83,18 @@ module Ayadn
|
|
81
83
|
say_yellow :starring, "post #{post_id}"
|
82
84
|
end
|
83
85
|
|
86
|
+
def all_hashtag_links hashtag
|
87
|
+
info("info", "links from posts containing hashtag '##{hashtag}':", "cyan")
|
88
|
+
end
|
89
|
+
|
90
|
+
def all_search_links words
|
91
|
+
info("info", "links from posts containing word(s) '#{words}':", "cyan")
|
92
|
+
end
|
93
|
+
|
94
|
+
def all_stars_links
|
95
|
+
info("info", "links from your starred posts:", "cyan")
|
96
|
+
end
|
97
|
+
|
84
98
|
def not_deleted(post_id)
|
85
99
|
info("error", "could not delete post #{post_id} (post isn't yours, or is already deleted)", "red")
|
86
100
|
end
|
@@ -185,10 +199,6 @@ module Ayadn
|
|
185
199
|
info("blocked", username, "green")
|
186
200
|
end
|
187
201
|
|
188
|
-
def error_missing_title
|
189
|
-
info("error", "please specify (part of) a movie title", "red")
|
190
|
-
end
|
191
|
-
|
192
202
|
def error_missing_username
|
193
203
|
info("error", "please specify a username", "red")
|
194
204
|
end
|
@@ -218,7 +228,7 @@ module Ayadn
|
|
218
228
|
|
219
229
|
def writing
|
220
230
|
puts "\n"
|
221
|
-
say_cyan :author, "#{Settings.config
|
231
|
+
say_cyan :author, "#{Settings.config.identity.handle}"
|
222
232
|
puts "\n"
|
223
233
|
end
|
224
234
|
|
@@ -233,7 +243,7 @@ module Ayadn
|
|
233
243
|
|
234
244
|
def message_from(username)
|
235
245
|
puts "\n"
|
236
|
-
say_yellow :from, "#{Settings.config
|
246
|
+
say_yellow :from, "#{Settings.config.identity.handle}"
|
237
247
|
say_yellow :to, "#{username[0]}"
|
238
248
|
end
|
239
249
|
|
@@ -251,15 +261,15 @@ module Ayadn
|
|
251
261
|
end
|
252
262
|
|
253
263
|
def reply
|
254
|
-
say_cyan :max, "#{Settings.config
|
264
|
+
say_cyan :max, "#{Settings.config.post_max_length} characters"
|
255
265
|
end
|
256
266
|
|
257
267
|
def post
|
258
|
-
say_cyan :max, "#{Settings.config
|
268
|
+
say_cyan :max, "#{Settings.config.post_max_length} characters"
|
259
269
|
end
|
260
270
|
|
261
271
|
def message
|
262
|
-
say_cyan :max, "#{Settings.config
|
272
|
+
say_cyan :max, "#{Settings.config.message_max_length} characters"
|
263
273
|
end
|
264
274
|
|
265
275
|
def valid_colors(colors_list)
|
@@ -420,18 +430,6 @@ module Ayadn
|
|
420
430
|
info("connexion", "fetching informations from #{source}", "green")
|
421
431
|
end
|
422
432
|
|
423
|
-
def no_movie
|
424
|
-
info("error", "sorry, can't find this movie", "red")
|
425
|
-
end
|
426
|
-
|
427
|
-
def no_show
|
428
|
-
info("error", "sorry, can't find this show", "red")
|
429
|
-
end
|
430
|
-
|
431
|
-
def no_show_infos
|
432
|
-
info("error", "sorry, can't find informations about this show", "red")
|
433
|
-
end
|
434
|
-
|
435
433
|
def no_force(target)
|
436
434
|
say do
|
437
435
|
say_error "'#{target}' can't be displayed (could be muted, blocked, in the Blacklist, etc)"
|
@@ -528,7 +526,7 @@ module Ayadn
|
|
528
526
|
end
|
529
527
|
|
530
528
|
def server_error(bool)
|
531
|
-
if bool
|
529
|
+
if bool
|
532
530
|
say do
|
533
531
|
say_error "Ayadn couldn't get the JSON reponse"
|
534
532
|
say_yellow :next, "trying again in 10 seconds"
|
data/lib/ayadn/stream.rb
CHANGED
@@ -5,31 +5,30 @@ module Ayadn
|
|
5
5
|
|
6
6
|
require_relative("scroll")
|
7
7
|
|
8
|
-
def initialize api, view, workers
|
8
|
+
def initialize api, view, workers, check, status
|
9
9
|
@api = api
|
10
10
|
@view = view
|
11
11
|
@workers = workers
|
12
|
-
@check =
|
13
|
-
@status =
|
12
|
+
@check = check
|
13
|
+
@status = status
|
14
14
|
end
|
15
15
|
|
16
16
|
def global settings
|
17
|
-
Settings.global[:force] = true if settings[:force]
|
18
17
|
options = settings.dup
|
19
18
|
options[:filter] = nicerank_true()
|
20
19
|
@view.downloading(options)
|
21
20
|
unless options[:scroll]
|
22
|
-
|
23
|
-
Settings.global
|
24
|
-
@check.no_new_posts(
|
25
|
-
Databases.save_max_id(
|
26
|
-
@view.render(
|
21
|
+
stream_object = StreamObject.new(@api.get_global(options))
|
22
|
+
Settings.global.force ? niceranks = {} : niceranks = NiceRank.new.get_ranks(stream_object)
|
23
|
+
@check.no_new_posts(stream_object, options, 'global')
|
24
|
+
Databases.save_max_id(stream_object, 'global') unless stream_object.meta.max_id.nil?
|
25
|
+
@view.render(stream_object, options, niceranks)
|
27
26
|
end
|
28
27
|
if options[:scroll]
|
29
28
|
@view.clear_screen()
|
30
29
|
Scroll.new(@api, @view).global(options)
|
31
30
|
end
|
32
|
-
puts "\n" if Settings.options
|
31
|
+
puts "\n" if Settings.options.timeline.compact && options[:raw].nil?
|
33
32
|
end
|
34
33
|
|
35
34
|
|
@@ -47,97 +46,98 @@ module Ayadn
|
|
47
46
|
end
|
48
47
|
|
49
48
|
def stream meth, options, target
|
50
|
-
Settings.global[:force] = true if options[:force]
|
51
49
|
@view.downloading(options)
|
52
50
|
unless options[:scroll]
|
53
51
|
stream = @api.send("get_#{meth}".to_sym, options)
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
stream_object = StreamObject.new(stream)
|
53
|
+
@check.no_new_posts(stream_object, options, target)
|
54
|
+
Databases.save_max_id(stream_object)
|
55
|
+
@view.render(stream_object, options)
|
57
56
|
end
|
58
57
|
if options[:scroll]
|
59
58
|
@view.clear_screen()
|
60
59
|
Scroll.new(@api, @view).send(meth, options)
|
61
60
|
end
|
62
|
-
puts "\n" if Settings.options
|
61
|
+
puts "\n" if Settings.options.timeline.compact && options[:raw].nil?
|
63
62
|
end
|
64
63
|
|
65
64
|
|
66
65
|
def mentions username, options
|
67
|
-
Settings.global[:force] = true if options[:force]
|
68
66
|
@check.no_username(username)
|
69
67
|
username = @workers.add_arobase(username)
|
70
68
|
@view.downloading(options)
|
71
69
|
unless options[:scroll]
|
72
70
|
stream = @api.get_mentions(username, options)
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
stream_object = StreamObject.new(stream)
|
72
|
+
@check.no_user(stream_object, username)
|
73
|
+
Databases.save_max_id(stream_object)
|
74
|
+
@check.no_data(stream_object, 'mentions')
|
76
75
|
options = options.dup
|
77
76
|
options[:in_mentions] = true
|
78
|
-
@view.render(
|
77
|
+
@view.render(stream_object, options)
|
79
78
|
end
|
80
79
|
if options[:scroll]
|
81
80
|
@view.clear_screen()
|
82
81
|
Scroll.new(@api, @view).mentions(username, options)
|
83
82
|
end
|
84
|
-
puts "\n" if Settings.options
|
83
|
+
puts "\n" if Settings.options.timeline.compact && options[:raw].nil?
|
85
84
|
end
|
86
85
|
|
87
86
|
def posts username, options
|
88
|
-
Settings.global[:force] = true if options[:force]
|
89
87
|
@check.no_username(username)
|
90
88
|
username = @workers.add_arobase(username)
|
91
89
|
@view.downloading(options)
|
92
90
|
stream = @api.get_posts(username, options)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
stream_object = StreamObject.new(stream)
|
92
|
+
@check.no_user(stream_object, username)
|
93
|
+
Databases.save_max_id(stream_object) unless stream_object.meta.marker.nil?
|
94
|
+
@check.no_data(stream_object, 'mentions')
|
95
|
+
unless options[:raw] || Settings.global.force
|
97
96
|
# this is just to show a message rather than an empty screen
|
98
|
-
if Settings.options
|
97
|
+
if Settings.options.blacklist.active
|
99
98
|
if Databases.is_in_blacklist?('mention', username)
|
100
99
|
@status.no_force("#{username.downcase}")
|
101
100
|
exit
|
102
101
|
end
|
103
102
|
end
|
104
103
|
end
|
105
|
-
if
|
106
|
-
unless options[:raw] || Settings.global
|
104
|
+
if stream_object.posts[0].user.you_muted || stream_object.posts[0].user.you_blocked
|
105
|
+
unless options[:raw] || Settings.global.force
|
107
106
|
@status.no_force("#{username.downcase}")
|
108
107
|
exit
|
109
108
|
end
|
110
109
|
end
|
111
|
-
@view.render(
|
110
|
+
@view.render(stream_object, options)
|
112
111
|
Scroll.new(@api, @view).posts(username, options) if options[:scroll]
|
113
|
-
puts "\n" if Settings.options
|
112
|
+
puts "\n" if Settings.options.timeline.compact && options[:raw].nil?
|
114
113
|
end
|
115
114
|
|
116
115
|
def whatstarred(username, options)
|
117
116
|
@check.no_username(username)
|
118
117
|
username = @workers.add_arobase(username)
|
119
118
|
@view.downloading(options) unless options["again"]
|
120
|
-
|
121
119
|
if options["again"]
|
122
120
|
stream = FileOps.cached_list("whatstarred")
|
121
|
+
stream_object = StreamObject.new(stream)
|
123
122
|
Errors.no_data('cached whatstarred') if stream.nil?
|
124
123
|
else
|
125
124
|
stream = @api.get_whatstarred(username, options)
|
125
|
+
stream_object = StreamObject.new(stream)
|
126
126
|
end
|
127
127
|
|
128
|
-
@check.no_user(
|
129
|
-
@check.no_data(
|
128
|
+
@check.no_user(stream_object, username)
|
129
|
+
@check.no_data(stream_object, 'whatstarred')
|
130
130
|
|
131
131
|
if options["cache"] && options["again"].nil?
|
132
|
-
FileOps.cache_list(
|
132
|
+
FileOps.cache_list(stream_object.input, "whatstarred")
|
133
133
|
end
|
134
134
|
|
135
135
|
if options[:extract]
|
136
|
-
@view.all_stars_links(
|
136
|
+
@view.all_stars_links(stream_object)
|
137
137
|
else
|
138
|
-
@view.render(
|
138
|
+
@view.render(stream_object, options)
|
139
139
|
end
|
140
|
-
puts "\n" if Settings.options
|
140
|
+
puts "\n" if Settings.options.timeline.compact
|
141
141
|
end
|
142
142
|
|
143
143
|
def followings(username, options)
|
@@ -155,15 +155,15 @@ module Ayadn
|
|
155
155
|
Errors.no_data('followings') if list.empty?
|
156
156
|
if options["lastpost"] && options["again"].nil?
|
157
157
|
count = list.size
|
158
|
-
@
|
158
|
+
@status.thor.say_status :downloading, "please wait, it may take a while...", :red
|
159
159
|
puts "\n"
|
160
160
|
idx = 0
|
161
|
-
list.each do |str_id,obj|
|
161
|
+
list.each do |str_id, obj|
|
162
162
|
idx += 1
|
163
163
|
tmp_username = "@#{obj[0]}"
|
164
|
-
colored_username = tmp_username.color(Settings.options
|
164
|
+
colored_username = tmp_username.color(Settings.options.colors.username)
|
165
165
|
iter = "#{idx}/#{count}"
|
166
|
-
@
|
166
|
+
@status.thor.say_status iter.to_sym, "last post from #{colored_username}", :cyan
|
167
167
|
resp = @api.get_posts(tmp_username, {count: 1})
|
168
168
|
obj << resp["data"][0]
|
169
169
|
end
|
@@ -244,7 +244,7 @@ module Ayadn
|
|
244
244
|
@view.if_raw(stream, options)
|
245
245
|
@view.clear_screen
|
246
246
|
@view.show_interactions(stream['data'])
|
247
|
-
puts "\n" if Settings.options
|
247
|
+
puts "\n" if Settings.options.timeline.compact
|
248
248
|
end
|
249
249
|
|
250
250
|
def whoreposted(post_id, options)
|
@@ -261,7 +261,7 @@ module Ayadn
|
|
261
261
|
details = @api.get_details(post_id, options)
|
262
262
|
end
|
263
263
|
|
264
|
-
@check.
|
264
|
+
@check.no_details(details, post_id)
|
265
265
|
id = @workers.get_original_id(post_id, details)
|
266
266
|
|
267
267
|
if options["cache"] && options["again"].nil?
|
@@ -301,7 +301,7 @@ module Ayadn
|
|
301
301
|
details = @api.get_details(post_id, options)
|
302
302
|
end
|
303
303
|
|
304
|
-
@check.
|
304
|
+
@check.no_details(details, post_id)
|
305
305
|
id = @workers.get_original_id(post_id, details)
|
306
306
|
|
307
307
|
if options["cache"] && options["again"].nil?
|
@@ -329,54 +329,54 @@ module Ayadn
|
|
329
329
|
|
330
330
|
def convo(post_id, options)
|
331
331
|
@check.bad_post_id(post_id)
|
332
|
-
|
333
|
-
Settings.global[:force] = true
|
334
|
-
else
|
332
|
+
unless options[:force]
|
335
333
|
post_id = @workers.get_real_post_id(post_id)
|
336
334
|
end
|
337
335
|
@view.downloading(options)
|
338
336
|
details = @api.get_details(post_id, options)
|
339
|
-
@check.
|
337
|
+
@check.no_details(details, post_id)
|
340
338
|
id = @workers.get_original_id(post_id, details)
|
341
339
|
stream = @api.get_convo(id, options)
|
342
|
-
|
343
|
-
|
340
|
+
stream_object = StreamObject.new(stream)
|
341
|
+
@check.no_post(stream_object, id)
|
342
|
+
Databases.pagination_insert("replies:#{id}", stream_object.meta.max_id)
|
344
343
|
options = options.dup
|
345
344
|
options[:reply_to] = details['data']['reply_to'].to_i unless details['data']['reply_to'].nil?
|
346
345
|
options[:post_id] = post_id.to_i
|
347
|
-
@view.render(
|
346
|
+
@view.render(stream_object, options)
|
348
347
|
Scroll.new(@api, @view).convo(id, options) if options[:scroll]
|
349
|
-
puts "\n" if Settings.options
|
348
|
+
puts "\n" if Settings.options.timeline.compact && options[:raw].nil?
|
350
349
|
end
|
351
350
|
|
352
351
|
def messages(channel_id, options)
|
353
352
|
if options[:silent]
|
354
|
-
Settings.options
|
353
|
+
Settings.options.marker.messages = false
|
355
354
|
end
|
356
355
|
channel_id = @workers.get_channel_id_from_alias(channel_id)
|
357
356
|
@view.downloading(options)
|
358
357
|
resp = @api.get_messages(channel_id, options)
|
358
|
+
stream_object = StreamObject.new(resp)
|
359
359
|
name = "channel:#{channel_id}"
|
360
|
-
@check.no_new_posts(
|
361
|
-
if Settings.options
|
362
|
-
unless
|
363
|
-
marked = @api.update_marker(name,
|
360
|
+
@check.no_new_posts(stream_object, options, name)
|
361
|
+
if Settings.options.marker.messages
|
362
|
+
unless stream_object.meta.max_id.nil?
|
363
|
+
marked = @api.update_marker(name, stream_object.meta.max_id)
|
364
364
|
updated = JSON.parse(marked)
|
365
365
|
if updated['meta']['code'] != 200
|
366
366
|
raise "couldn't update channel #{channel_id} as read"
|
367
367
|
end
|
368
368
|
end
|
369
369
|
end
|
370
|
-
Databases.save_max_id(
|
371
|
-
@view.if_raw(
|
372
|
-
@check.no_data(
|
373
|
-
@view.render(
|
370
|
+
Databases.save_max_id(stream_object)
|
371
|
+
@view.if_raw(stream_object, options)
|
372
|
+
@check.no_data(stream_object, 'messages') unless options[:scroll]
|
373
|
+
@view.render(stream_object, options)
|
374
374
|
Scroll.new(@api, @view).messages(channel_id, options) if options[:scroll]
|
375
|
-
puts "\n" if Settings.options
|
375
|
+
puts "\n" if Settings.options.timeline.compact && options[:raw].nil?
|
376
376
|
end
|
377
377
|
|
378
378
|
def random_posts(options)
|
379
|
-
Settings.global
|
379
|
+
Settings.global.force = true
|
380
380
|
#_, cols = @view.winsize
|
381
381
|
#max_posts = cols / 16
|
382
382
|
max_posts = 6
|
@@ -390,8 +390,10 @@ module Ayadn
|
|
390
390
|
begin
|
391
391
|
@random_post_id = rand(@max_id)
|
392
392
|
@resp = @api.get_details(@random_post_id, {})
|
393
|
+
next if @resp.nil?
|
394
|
+
next if @resp['data'].nil? || @resp['data'].empty?
|
393
395
|
next if @resp['data']['is_deleted']
|
394
|
-
@view.show_simple_post([@resp['data']], {})
|
396
|
+
@view.show_simple_post([PostObject.new(@resp['data'])], {})
|
395
397
|
counter += 1
|
396
398
|
if counter == max_posts
|
397
399
|
wait.downto(1) do |i|
|
@@ -430,7 +432,7 @@ module Ayadn
|
|
430
432
|
end
|
431
433
|
|
432
434
|
def nicerank_true
|
433
|
-
return true if Settings.options
|
435
|
+
return true if Settings.options.nicerank.filter
|
434
436
|
end
|
435
437
|
|
436
438
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Ayadn
|
3
|
+
|
4
|
+
class StreamMarkerObject
|
5
|
+
|
6
|
+
attr_reader :input, :name, :updated_at, :version, :last_read_id, :percentage, :id
|
7
|
+
|
8
|
+
def initialize hash
|
9
|
+
@input = hash["marker"].nil? ? {} : hash["marker"]
|
10
|
+
@name = @input["name"]
|
11
|
+
@updated_at = @input["updated_at"]
|
12
|
+
@version = @input["version"]
|
13
|
+
@last_read_id = @input["last_read_id"]
|
14
|
+
@percentage = @input["percentage"]
|
15
|
+
@id = @input["id"]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class StreamMetaObject
|
20
|
+
|
21
|
+
attr_reader :input, :marker, :min_id, :code, :max_id, :more
|
22
|
+
|
23
|
+
def initialize hash
|
24
|
+
@input = hash["meta"].nil? ? {} : hash["meta"]
|
25
|
+
@marker = hash["meta"].nil? ? nil : StreamMarkerObject.new(@input)
|
26
|
+
@min_id = @input["min_id"]
|
27
|
+
@code = @input["code"]
|
28
|
+
@max_id = @input["max_id"]
|
29
|
+
@more = @input["more"]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class StreamDataObject
|
34
|
+
|
35
|
+
attr_reader :input, :posts
|
36
|
+
|
37
|
+
def initialize hash
|
38
|
+
@input = hash["data"]
|
39
|
+
@posts = @input.blank? ? [] : @input.map { |post| PostObject.new(post) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class StreamObject
|
44
|
+
|
45
|
+
attr_reader :input, :meta, :data, :posts
|
46
|
+
attr_accessor :view
|
47
|
+
|
48
|
+
def initialize hash
|
49
|
+
@input = hash
|
50
|
+
@meta = StreamMetaObject.new(@input)
|
51
|
+
@data = StreamDataObject.new(@input)
|
52
|
+
@posts = @data.posts
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|