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/switch.rb
CHANGED
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Ayadn
|
3
|
+
|
4
|
+
class UserMetaObject
|
5
|
+
|
6
|
+
attr_reader :input, :code
|
7
|
+
|
8
|
+
def initialize hash, username = nil
|
9
|
+
@input = hash["meta"].nil? ? {} : hash["meta"]
|
10
|
+
@code = @input["code"]
|
11
|
+
if code == 404
|
12
|
+
Status.new.user_404(username)
|
13
|
+
Errors.info("User #{username} doesn't exist")
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class UserCountsObject
|
20
|
+
|
21
|
+
attr_reader :input, :following, :posts, :followers, :stars
|
22
|
+
|
23
|
+
def initialize hash
|
24
|
+
@input = hash["counts"]
|
25
|
+
@following = @input["following"]
|
26
|
+
@posts = @input["posts"]
|
27
|
+
@followers = @input["followers"]
|
28
|
+
@stars = @input["stars"]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class UserAnnotationObject
|
33
|
+
|
34
|
+
attr_reader :input, :type, :value
|
35
|
+
|
36
|
+
def initialize hash
|
37
|
+
@input = hash
|
38
|
+
@type = @input["type"]
|
39
|
+
@value = @input["value"]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class AvatarImageObject
|
44
|
+
|
45
|
+
attr_reader :input, :url, :width, :is_default, :height
|
46
|
+
|
47
|
+
def initialize hash
|
48
|
+
@input = hash["avatar_image"]
|
49
|
+
@url = @input["url"]
|
50
|
+
@width = @input["width"]
|
51
|
+
@is_default = @input["is_default"]
|
52
|
+
@height = @input["height"]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class CoverImageObject
|
57
|
+
|
58
|
+
attr_reader :input, :url, :width, :is_default, :height
|
59
|
+
|
60
|
+
def initialize hash
|
61
|
+
@input = hash["cover_image"]
|
62
|
+
@url = @input["url"]
|
63
|
+
@width = @input["width"]
|
64
|
+
@is_default = @input["is_default"]
|
65
|
+
@height = @input["height"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class UserDescriptionObject
|
70
|
+
|
71
|
+
attr_reader :input, :text, :entities
|
72
|
+
|
73
|
+
def initialize hash
|
74
|
+
@input = hash["description"].nil? ? {} : hash["description"]
|
75
|
+
@text = @input["text"].nil? ? "" : @input["text"]
|
76
|
+
@entities = EntitiesObject.new(@input)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class UserObject
|
81
|
+
|
82
|
+
attr_accessor :input, :you_muted, :you_can_subscribe, :is_following, :is_follower, :timezone, :you_follow, :counts, :canonical_url, :id, :locale, :type, :annotations, :username, :avatar_image, :description, :is_muted, :follows_you, :you_can_follow, :name, :created_at, :you_blocked, :cover_image, :verified_domain, :meta
|
83
|
+
|
84
|
+
def initialize hash, username = nil
|
85
|
+
@input = hash['data'].nil? ? hash : hash['data']
|
86
|
+
@meta = UserMetaObject.new(hash, username)
|
87
|
+
@you_muted = @input["you_muted"]
|
88
|
+
@you_can_subscribe = @input["you_can_subscribe"]
|
89
|
+
@is_follower = @input["is_follower"]
|
90
|
+
@is_following = @input["is_following"]
|
91
|
+
@timezone = @input["timezone"]
|
92
|
+
@you_follow = @input["you_follow"]
|
93
|
+
@counts = UserCountsObject.new(@input) unless @input.empty?
|
94
|
+
@canonical_url = @input["canonical_url"]
|
95
|
+
@id = @input["id"]
|
96
|
+
@locale = @input["locale"]
|
97
|
+
@type = @input["type"]
|
98
|
+
if !@input["annotations"].nil?
|
99
|
+
@annotations = @input["annotations"].map { |hash| UserAnnotationObject.new(hash) }
|
100
|
+
else
|
101
|
+
@annotations = []
|
102
|
+
end
|
103
|
+
@username = @input["username"]
|
104
|
+
@avatar_image = AvatarImageObject.new(@input) unless @input.empty?
|
105
|
+
@description = UserDescriptionObject.new(@input) unless @input.empty?
|
106
|
+
@is_muted = @input["is_muted"]
|
107
|
+
@follows_you = @input["follows_you"]
|
108
|
+
@you_can_follow = @input["you_can_follow"]
|
109
|
+
@name = @input["name"].to_s.force_encoding("UTF-8")
|
110
|
+
@created_at = @input["created_at"]
|
111
|
+
@you_blocked = @input["you_blocked"]
|
112
|
+
@cover_image = CoverImageObject.new(@input) unless @input.empty?
|
113
|
+
@verified_domain = @input["verified_domain"]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/ayadn/version.rb
CHANGED
data/lib/ayadn/view.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
module Ayadn
|
3
3
|
class View
|
4
4
|
|
5
|
-
def initialize
|
6
|
-
@
|
7
|
-
@
|
5
|
+
def initialize status = Status.new, workers = nil
|
6
|
+
@status = status
|
7
|
+
@workers = workers.nil? ? Workers.new(status) : workers
|
8
8
|
end
|
9
9
|
|
10
10
|
def show_cursor
|
@@ -16,13 +16,18 @@ module Ayadn
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def show_posts_with_index(data, options = {}, niceranks = {})
|
19
|
-
posts, view = build_stream_with_index(data, options, niceranks)
|
19
|
+
posts, view = build_stream_with_index(data.posts, options, niceranks)
|
20
20
|
puts view unless view == ""
|
21
21
|
Databases.save_indexed_posts(posts)
|
22
22
|
end
|
23
23
|
|
24
24
|
def show_posts(data, options = {}, niceranks = {})
|
25
|
-
resp = build_stream_without_index(data, options, niceranks)
|
25
|
+
resp = build_stream_without_index(data.posts, options, niceranks)
|
26
|
+
puts resp unless resp == ""
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_messages messages
|
30
|
+
resp = build_stream_without_index(messages, {}, {})
|
26
31
|
puts resp unless resp == ""
|
27
32
|
end
|
28
33
|
|
@@ -34,7 +39,14 @@ module Ayadn
|
|
34
39
|
end
|
35
40
|
|
36
41
|
def show_raw(stream, options = {})
|
37
|
-
|
42
|
+
if stream.is_a? Hash
|
43
|
+
show_direct_raw stream
|
44
|
+
else
|
45
|
+
jj stream.input
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def show_direct_raw(stream, options = {})
|
38
50
|
jj stream
|
39
51
|
end
|
40
52
|
|
@@ -43,7 +55,7 @@ module Ayadn
|
|
43
55
|
end
|
44
56
|
|
45
57
|
def show_posted(resp)
|
46
|
-
show_simple_post([resp['data']], {})
|
58
|
+
show_simple_post([PostObject.new(resp['data'])], {})
|
47
59
|
puts "\n" if timeline_is_compact
|
48
60
|
end
|
49
61
|
|
@@ -61,57 +73,7 @@ module Ayadn
|
|
61
73
|
|
62
74
|
def show_list_followings(list, target, options = {})
|
63
75
|
if options["lastpost"]
|
64
|
-
|
65
|
-
bucket = []
|
66
|
-
list.each do |k,v|
|
67
|
-
bucket << [k, v[0], v[1], v[2], v[3], v[4], v[5]]
|
68
|
-
end
|
69
|
-
count = bucket.size
|
70
|
-
if options[:username]
|
71
|
-
bucket.sort_by! { |obj| obj[1] }
|
72
|
-
elsif options[:name]
|
73
|
-
bucket.sort_by! { |obj| obj[2] }
|
74
|
-
elsif options[:posts]
|
75
|
-
bucket.sort_by! { |obj| [obj[5], obj[1]] }.reverse!
|
76
|
-
elsif options[:date]
|
77
|
-
bucket.keep_if { |obj| !obj[6].nil? }
|
78
|
-
bucket.sort_by! { |obj| obj[6]["created_at"] }.reverse!
|
79
|
-
end
|
80
|
-
title = if target == "me"
|
81
|
-
"Last post of users you're following".color(:cyan)
|
82
|
-
else
|
83
|
-
"Last post of users ".color(:cyan) + "#{target}".color(:red) + " is following ".color(:cyan)
|
84
|
-
end
|
85
|
-
puts "\t#{title}\n\n"
|
86
|
-
bucket.each.with_index(1) do |obj,index|
|
87
|
-
username = "@#{obj[1]}"
|
88
|
-
colored_username = username.color(color_username)
|
89
|
-
if obj[6].nil?
|
90
|
-
@workers.thor.say_status :warning, "user #{colored_username} has no posts, ignored", :red
|
91
|
-
newline()
|
92
|
-
next
|
93
|
-
end
|
94
|
-
date = @workers.parsed_time(obj[6]["created_at"])
|
95
|
-
mentions = @workers.extract_mentions(obj[6])
|
96
|
-
hashtags = @workers.extract_hashtags(obj[6])
|
97
|
-
text = @workers.colorize_text(obj[6]["text"], mentions, hashtags)
|
98
|
-
total = "(#{obj[5]} posts)"
|
99
|
-
name = obj[2] == "" ? "(no name)" : obj[2]
|
100
|
-
colored_total = total.color(color_link)
|
101
|
-
colored_name = name.color(color_name)
|
102
|
-
colored_date = date.color(color_date)
|
103
|
-
puts "#{colored_username} #{colored_name} #{colored_date} #{colored_total}\n"
|
104
|
-
newline()
|
105
|
-
puts text
|
106
|
-
unless index == count
|
107
|
-
newline()
|
108
|
-
puts "----------\n"
|
109
|
-
newline()
|
110
|
-
else
|
111
|
-
puts "\n"
|
112
|
-
newline()
|
113
|
-
end
|
114
|
-
end
|
76
|
+
show_list_with_lastpost(list, target, options)
|
115
77
|
else
|
116
78
|
puts @workers.build_followings_list(list, target, options)
|
117
79
|
puts "\n"
|
@@ -143,44 +105,13 @@ module Ayadn
|
|
143
105
|
end
|
144
106
|
|
145
107
|
def show_settings
|
146
|
-
table = Terminal::Table.new do |t|
|
147
|
-
if Settings.options[:formats][:table][:borders] == true
|
148
|
-
t.style = { :width => Settings.options[:formats][:table][:width], border_x: '—', border_i: '+', border_y: '|' }
|
149
|
-
else
|
150
|
-
t.style = { :width => Settings.options[:formats][:table][:width], border_x: ' ', border_i: ' ', border_y: ' ' }
|
151
|
-
end
|
152
|
-
t.title = "Current Ayadn settings".color(:cyan)
|
153
|
-
t.headings = [ "Category".color(:red), "Parameter".color(:red), "Value(s)".color(:red) ]
|
154
|
-
@iter = 0
|
155
|
-
opts = Settings.options.dup
|
156
|
-
opts.each do |k,v|
|
157
|
-
v.each do |x,y|
|
158
|
-
t << :separator if @iter >= 1 && timeline_is_compact == false
|
159
|
-
unless y.is_a?(Hash)
|
160
|
-
t << [ k.to_s.color(:cyan), x.to_s.color(:yellow), y.to_s.color(:green) ]
|
161
|
-
else
|
162
|
-
y.each do |c|
|
163
|
-
yk = c[0]
|
164
|
-
tempv = c[1].to_s
|
165
|
-
if tempv.size > 10
|
166
|
-
yv = "#{tempv[0..7]}..."
|
167
|
-
else
|
168
|
-
yv = tempv
|
169
|
-
end
|
170
|
-
t << [ k.to_s.color(:cyan), x.to_s.color(:yellow), "#{yk} = #{yv}".color(:green) ]
|
171
|
-
end
|
172
|
-
end
|
173
|
-
@iter += 1
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
108
|
clear_screen()
|
178
|
-
puts
|
109
|
+
puts Settings.options.to_table
|
179
110
|
puts "\n"
|
180
111
|
end
|
181
112
|
|
182
|
-
def show_userinfos(
|
183
|
-
if timeline_is_compact
|
113
|
+
def show_userinfos(user, token, show_ranks = false)
|
114
|
+
if timeline_is_compact
|
184
115
|
padding = "\n"
|
185
116
|
view = "\n"
|
186
117
|
else
|
@@ -188,106 +119,92 @@ module Ayadn
|
|
188
119
|
view = ""
|
189
120
|
end
|
190
121
|
|
191
|
-
if
|
192
|
-
view << "Name\t\t\t".color(:cyan) +
|
122
|
+
if !user.name.blank?
|
123
|
+
view << "Name\t\t\t".color(:cyan) + user.name.color(color_name)
|
193
124
|
else
|
194
125
|
view << "Name\t\t\t".color(:cyan) + "(no name)".color(:red)
|
195
126
|
end
|
196
127
|
|
197
|
-
view << "#{padding}Username\t\t".color(:cyan) + "@#{
|
128
|
+
view << "#{padding}Username\t\t".color(:cyan) + "@#{user.username}".color(color_username)
|
198
129
|
|
199
|
-
view << "#{padding}ID\t\t\t".color(:cyan) +
|
130
|
+
view << "#{padding}ID\t\t\t".color(:cyan) + user.id.color(color_id)
|
200
131
|
|
201
|
-
view << "#{padding}URL\t\t\t".color(:cyan) +
|
132
|
+
view << "#{padding}URL\t\t\t".color(:cyan) + user.canonical_url.color(color_link)
|
202
133
|
|
203
|
-
unless
|
204
|
-
if
|
205
|
-
domain =
|
134
|
+
unless user.verified_domain.nil?
|
135
|
+
if user.verified_domain =~ (/http/ || /https/)
|
136
|
+
domain = user.verified_domain
|
206
137
|
else
|
207
|
-
domain = "http://#{
|
138
|
+
domain = "http://#{user.verified_domain}"
|
208
139
|
end
|
209
140
|
view << "\nVerified domain\t\t".color(:cyan) + domain.color(color_link)
|
210
141
|
end
|
211
142
|
|
212
143
|
|
213
|
-
view << "#{padding}Account creation\t".color(:cyan) + @workers.parsed_time(
|
214
|
-
view << "#{padding}TimeZone\t\t".color(:cyan) +
|
215
|
-
view << "\nLocale\t\t\t".color(:cyan) +
|
216
|
-
|
217
|
-
view << "#{padding}Posts\t\t\t".color(:cyan) + content['counts']['posts'].to_s.color(color_excerpt)
|
218
|
-
|
144
|
+
view << "#{padding}Account creation\t".color(:cyan) + @workers.parsed_time(user.created_at).color(color_excerpt)
|
145
|
+
view << "#{padding}TimeZone\t\t".color(:cyan) + user.timezone.color(color_excerpt)
|
146
|
+
view << "\nLocale\t\t\t".color(:cyan) + user.locale.color(color_excerpt)
|
219
147
|
|
220
|
-
|
221
|
-
# # this is ok for one user, but do not call this in a loop
|
222
|
-
# # do call them all at once instead if many
|
223
|
-
# ranks = NiceRank.new.get_posts_day([content['id'].to_i])
|
224
|
-
# unless ranks.empty?
|
225
|
-
# view << "#{padding}Posts/day\t\t".color(:cyan) + ranks[0][:posts_day].to_s.color(color_excerpt)
|
226
|
-
# end
|
227
|
-
# end
|
148
|
+
view << "#{padding}Posts\t\t\t".color(:cyan) + user.counts.posts.to_s.color(color_excerpt)
|
228
149
|
|
229
|
-
view << "#{padding}Following\t\t".color(:cyan) +
|
230
|
-
view << "\nFollowers\t\t".color(:cyan) +
|
150
|
+
view << "#{padding}Following\t\t".color(:cyan) + user.counts.following.to_s.color(color_excerpt)
|
151
|
+
view << "\nFollowers\t\t".color(:cyan) + user.counts.followers.to_s.color(color_excerpt)
|
231
152
|
|
232
|
-
if
|
153
|
+
if user.username == Settings.config.identity.username && !token.nil?
|
233
154
|
view << "#{padding}Storage used\t\t".color(:cyan) + "#{token['storage']['used'].to_filesize}".color(color_excerpt)
|
234
155
|
view << "\nStorage available\t".color(:cyan) + "#{token['storage']['available'].to_filesize}".color(color_excerpt)
|
235
156
|
end
|
236
157
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
if content['you_follow']
|
241
|
-
view << "#{padding}You follow ".color(:cyan) + "@#{content['username']}".color(color_username)
|
158
|
+
unless user.username == Settings.config.identity.username
|
159
|
+
if user.you_follow
|
160
|
+
view << "#{padding}You follow ".color(:cyan) + "@#{user.username}".color(color_username)
|
242
161
|
else
|
243
|
-
view << "#{padding}You don't follow ".color(:cyan) + "@#{
|
162
|
+
view << "#{padding}You don't follow ".color(:cyan) + "@#{user.username}".color(color_username)
|
244
163
|
end
|
245
|
-
if
|
246
|
-
view << "\n" + "@#{
|
164
|
+
if user.follows_you
|
165
|
+
view << "\n" + "@#{user.username}".color(color_username) + " follows you".color(:cyan)
|
247
166
|
else
|
248
|
-
view << "\n" + "@#{
|
167
|
+
view << "\n" + "@#{user.username}".color(color_username) + " doesn't follow you".color(:cyan)
|
249
168
|
end
|
250
|
-
if
|
251
|
-
view << "\nYou muted " + "@#{
|
169
|
+
if user.you_muted
|
170
|
+
view << "\nYou muted " + "@#{user.username}".color(color_username)
|
252
171
|
end
|
253
|
-
if
|
254
|
-
view << "\nYou blocked " + "@#{
|
172
|
+
if user.you_blocked
|
173
|
+
view << "\nYou blocked " + "@#{user.username}".color(color_username)
|
255
174
|
end
|
256
175
|
end
|
257
176
|
|
258
|
-
unless
|
259
|
-
view << "\n" unless timeline_is_compact
|
177
|
+
unless user.annotations.empty?
|
178
|
+
view << "\n" unless timeline_is_compact
|
260
179
|
end
|
261
|
-
|
262
|
-
case anno
|
180
|
+
user.annotations.each do |anno|
|
181
|
+
case anno.type
|
263
182
|
when "net.app.core.directory.blog"
|
264
|
-
view << "\nBlog\t\t\t".color(:cyan) + "#{anno
|
183
|
+
view << "\nBlog\t\t\t".color(:cyan) + "#{anno.value['url']}".color(color_link)
|
265
184
|
when "net.app.core.directory.twitter"
|
266
|
-
view << "\nTwitter\t\t\t".color(:cyan) + "#{anno
|
185
|
+
view << "\nTwitter\t\t\t".color(:cyan) + "#{anno.value['username']}".color(:green)
|
267
186
|
when "com.appnetizens.userinput.birthday"
|
268
|
-
view << "\nBirthday\t\t".color(:cyan) + "#{anno
|
187
|
+
view << "\nBirthday\t\t".color(:cyan) + "#{anno.value['birthday']}".color(:green)
|
269
188
|
end
|
270
189
|
end
|
271
190
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
hashtags = content['description']['entities']['hashtags'].map {|m| m['name']}
|
278
|
-
view << "#{padding}#{@workers.colorize_text(content['description']['text'], mentions, hashtags)}\n"
|
279
|
-
view << "\n" unless timeline_is_compact == true
|
191
|
+
if !user.description.blank?
|
192
|
+
mentions = user.description.entities.mentions.map {|m| "@#{m.name}"}
|
193
|
+
hashtags = user.description.entities.hashtags.map {|m| m.name}
|
194
|
+
view << "#{padding}#{@workers.colorize_text(user.description.text, mentions, hashtags)}\n"
|
195
|
+
view << "\n" unless timeline_is_compact
|
280
196
|
end
|
281
197
|
|
282
|
-
view << "\n" if timeline_is_compact
|
198
|
+
view << "\n" if timeline_is_compact
|
283
199
|
|
284
200
|
puts view
|
285
201
|
|
286
202
|
end
|
287
203
|
|
288
|
-
def show_channels(
|
204
|
+
def show_channels(stream, options = {})
|
289
205
|
view = ""
|
290
|
-
bucket = @workers.build_channels(
|
206
|
+
bucket = @workers.build_channels(stream, options)
|
207
|
+
|
291
208
|
bucket.reverse.each do |ch|
|
292
209
|
if options[:broadcasts]
|
293
210
|
next if ch.type != "net.app.core.broadcast"
|
@@ -331,8 +248,7 @@ module Ayadn
|
|
331
248
|
view << "\n"
|
332
249
|
if ch.owner
|
333
250
|
view << "Owner: ".color(:cyan)
|
334
|
-
view << "@#{ch.owner
|
335
|
-
# + (#{ch.owner['name']}) if ch.owner['name']
|
251
|
+
view << "@#{ch.owner.username}".color(color_username)
|
336
252
|
view << "\n"
|
337
253
|
end
|
338
254
|
unless options[:channels] # unless the request comes from Search
|
@@ -344,42 +260,42 @@ module Ayadn
|
|
344
260
|
view << "#{ch.type}".color(color_index)
|
345
261
|
view << "\n"
|
346
262
|
if ch.type == "net.patter-app.room"
|
347
|
-
ann = ch.annotations.select {|a| a
|
263
|
+
ann = ch.annotations.select {|a| a.type == "net.patter-app.settings"}
|
348
264
|
view << "Name: ".color(:cyan)
|
349
|
-
view << "#{ann[0]
|
265
|
+
view << "#{ann[0].value['name']}".color(color_link)
|
350
266
|
view << "\n"
|
351
267
|
view << "Description: ".color(:cyan)
|
352
|
-
view << "#{ann[0]
|
268
|
+
view << "#{ann[0].value['blurb']}".color(color_username)
|
353
269
|
view << "\n"
|
354
|
-
ann = ch.annotations.select {|a| a
|
270
|
+
ann = ch.annotations.select {|a| a.type == "net.app.core.fallback_url"}
|
355
271
|
view << "URL: ".color(:cyan)
|
356
|
-
view << "#{ann[0]
|
272
|
+
view << "#{ann[0].value['url']}".color(color_link)
|
357
273
|
view << "\n"
|
358
274
|
end
|
359
275
|
if ch.type == "net.app.core.broadcast"
|
360
|
-
ann = ch.annotations.select {|a| a
|
276
|
+
ann = ch.annotations.select {|a| a.type == "net.app.core.broadcast.metadata"}
|
361
277
|
view << "Title: ".color(:cyan)
|
362
|
-
view << "#{ann[0]
|
278
|
+
view << "#{ann[0].value['title']}".color(color_link)
|
363
279
|
view << "\n"
|
364
280
|
view << "Description: ".color(:cyan)
|
365
|
-
view << "#{ann[0]
|
281
|
+
view << "#{ann[0].value['description']}".color(color_username)
|
366
282
|
view << "\n"
|
367
|
-
ann = ch.annotations.select {|a| a
|
283
|
+
ann = ch.annotations.select {|a| a.type == "net.app.core.fallback_url"}
|
368
284
|
view << "URL: ".color(:cyan)
|
369
|
-
view << "#{ann[0]
|
285
|
+
view << "#{ann[0].value['url']}".color(color_link)
|
370
286
|
view << "\n"
|
371
287
|
end
|
372
288
|
unless ch.recent_message.nil?
|
373
|
-
unless ch.recent_message
|
374
|
-
view << "Most recent message (#{@workers.parsed_time(ch.recent_message
|
289
|
+
unless ch.recent_message.text.nil?
|
290
|
+
view << "Most recent message (#{@workers.parsed_time(ch.recent_message.created_at)}): ".color(:cyan)
|
375
291
|
view << "\n"
|
376
|
-
view << "---\n#{ch.recent_message
|
292
|
+
view << "---\n#{ch.recent_message.text}\n---"
|
377
293
|
end
|
378
294
|
end
|
379
295
|
if ch.type == "net.paste-app.clips"
|
380
|
-
ann = ch.recent_message
|
296
|
+
ann = ch.recent_message.annotations.select {|a| a.type == "net.paste-app.clip"}
|
381
297
|
view << "\n\n"
|
382
|
-
view << ann[0]
|
298
|
+
view << ann[0].value['content']
|
383
299
|
view << "\n"
|
384
300
|
end
|
385
301
|
view << "\n\n"
|
@@ -393,18 +309,18 @@ module Ayadn
|
|
393
309
|
|
394
310
|
def render(stream, options = {}, niceranks = {})
|
395
311
|
unless options[:raw]
|
396
|
-
get(stream
|
312
|
+
get(stream, options, niceranks)
|
397
313
|
else
|
398
314
|
show_raw(stream)
|
399
315
|
end
|
400
316
|
end
|
401
317
|
|
402
|
-
def get(
|
318
|
+
def get(data, options = {}, niceranks = {})
|
403
319
|
clear_screen()
|
404
320
|
if options[:index]
|
405
|
-
show_posts_with_index(
|
321
|
+
show_posts_with_index(data, options, niceranks)
|
406
322
|
else
|
407
|
-
show_posts(
|
323
|
+
show_posts(data, options, niceranks)
|
408
324
|
end
|
409
325
|
end
|
410
326
|
|
@@ -428,30 +344,15 @@ module Ayadn
|
|
428
344
|
end
|
429
345
|
|
430
346
|
def all_hashtag_links(stream, hashtag)
|
431
|
-
|
432
|
-
@status.info("info", "links from posts containing hashtag '##{hashtag}':", "cyan")
|
433
|
-
links = @workers.links_from_posts(stream)
|
434
|
-
links.uniq!
|
435
|
-
show_links(links)
|
436
|
-
@workers.save_links(links, "hashtag", hashtag)
|
347
|
+
all_links(stream, "hashtag", hashtag)
|
437
348
|
end
|
438
349
|
|
439
350
|
def all_search_links(stream, words)
|
440
|
-
|
441
|
-
@status.info("info", "links from posts containing word(s) '#{words}':", "cyan")
|
442
|
-
links = @workers.links_from_posts(stream)
|
443
|
-
links.uniq!
|
444
|
-
show_links(links)
|
445
|
-
@workers.save_links(links, "search", words)
|
351
|
+
all_links(stream, "search", hashtag)
|
446
352
|
end
|
447
353
|
|
448
354
|
def all_stars_links(stream)
|
449
|
-
|
450
|
-
@status.info("info", "links from your starred posts:", "cyan")
|
451
|
-
links = @workers.links_from_posts(stream)
|
452
|
-
links.uniq!
|
453
|
-
show_links(links)
|
454
|
-
@workers.save_links(links, 'starred')
|
355
|
+
all_links(stream, "starred")
|
455
356
|
end
|
456
357
|
|
457
358
|
def infos(stream, token)
|
@@ -489,8 +390,83 @@ module Ayadn
|
|
489
390
|
|
490
391
|
private
|
491
392
|
|
393
|
+
def all_links stream, type, arg = nil
|
394
|
+
clear_screen()
|
395
|
+
case type
|
396
|
+
when "hashtag"
|
397
|
+
@status.all_hashtag_links(arg)
|
398
|
+
when "search"
|
399
|
+
@status.all_search_links(arg)
|
400
|
+
when "starred"
|
401
|
+
@status.all_stars_links
|
402
|
+
end
|
403
|
+
links = @workers.links_from_posts(stream)
|
404
|
+
links.uniq!
|
405
|
+
show_links(links)
|
406
|
+
arg.nil? ? @workers.save_links(links, type) : @workers.save_links(links, type, arg)
|
407
|
+
end
|
408
|
+
|
409
|
+
### list = id => [username, name, bool, bool, int, message]
|
410
|
+
def show_list_with_lastpost(list, target, options)
|
411
|
+
clear_screen()
|
412
|
+
bucket = []
|
413
|
+
list.each do |k,v|
|
414
|
+
if !v[5].nil?
|
415
|
+
bucket << [k, v[0], v[1], v[2], v[3], v[4], PostObject.new(v[5])]
|
416
|
+
else
|
417
|
+
bucket << [k, v[0], v[1], v[2], v[3], v[4], nil]
|
418
|
+
end
|
419
|
+
end
|
420
|
+
count = bucket.size
|
421
|
+
if options[:username]
|
422
|
+
bucket.sort_by! { |obj| obj[1] }
|
423
|
+
elsif options[:name]
|
424
|
+
bucket.sort_by! { |obj| obj[2] }
|
425
|
+
elsif options[:posts]
|
426
|
+
bucket.sort_by! { |obj| [obj[5], obj[1]] }.reverse!
|
427
|
+
elsif options[:date]
|
428
|
+
bucket.keep_if { |obj| !obj[6].nil? }
|
429
|
+
bucket.sort_by! { |obj| obj[6].created_at }.reverse!
|
430
|
+
end
|
431
|
+
title = if target == "me"
|
432
|
+
"Last post of users you're following".color(:cyan)
|
433
|
+
else
|
434
|
+
"Last post of users ".color(:cyan) + "#{target}".color(:red) + " is following ".color(:cyan)
|
435
|
+
end
|
436
|
+
puts "\t#{title}\n\n"
|
437
|
+
bucket.each.with_index(1) do |obj,index|
|
438
|
+
username = "@#{obj[1]}"
|
439
|
+
colored_username = username.color(color_username)
|
440
|
+
if obj[6].nil?
|
441
|
+
@status.thor.say_status :warning, "user #{colored_username} has no posts, ignored", :red
|
442
|
+
newline()
|
443
|
+
next
|
444
|
+
end
|
445
|
+
date = @workers.parsed_time(obj[6].created_at)
|
446
|
+
mentions = @workers.extract_mentions(obj[6])
|
447
|
+
hashtags = @workers.extract_hashtags(obj[6])
|
448
|
+
text = @workers.colorize_text(obj[6].text, mentions, hashtags)
|
449
|
+
total = "(#{obj[5]} posts)"
|
450
|
+
name = obj[2].blank? ? "(no name)" : obj[2]
|
451
|
+
colored_total = total.color(color_link)
|
452
|
+
colored_name = name.color(color_name)
|
453
|
+
colored_date = date.color(color_date)
|
454
|
+
puts "#{colored_username} #{colored_name} #{colored_date} #{colored_total}\n"
|
455
|
+
newline()
|
456
|
+
puts text
|
457
|
+
unless index == count
|
458
|
+
newline()
|
459
|
+
puts "----------\n"
|
460
|
+
newline()
|
461
|
+
else
|
462
|
+
puts "\n"
|
463
|
+
newline()
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
492
468
|
def newline
|
493
|
-
puts "\n" unless timeline_is_compact
|
469
|
+
puts "\n" unless timeline_is_compact
|
494
470
|
end
|
495
471
|
|
496
472
|
def get_broadcast_alias_from_id(event_id)
|
@@ -503,78 +479,78 @@ module Ayadn
|
|
503
479
|
end
|
504
480
|
|
505
481
|
def filter_nicerank posts, options
|
506
|
-
if options[:filter]
|
507
|
-
if Settings.options
|
508
|
-
|
509
|
-
posts.each do |
|
510
|
-
if Settings.options
|
511
|
-
next if
|
482
|
+
if options[:filter] # if this option is true in Action (it's only for global, actually)
|
483
|
+
if Settings.options.nicerank.filter
|
484
|
+
bucket = []
|
485
|
+
posts.each do |post|
|
486
|
+
if Settings.options.nicerank.unranked
|
487
|
+
next if !post.nicerank # .nicerank is False or Fixnum (yeah...)
|
512
488
|
end
|
513
|
-
unless
|
514
|
-
next if
|
515
|
-
next if
|
489
|
+
unless !post.nicerank
|
490
|
+
next if post.nicerank < Settings.options.nicerank.threshold
|
491
|
+
next if post.is_human == 0
|
516
492
|
end
|
517
|
-
|
493
|
+
bucket << post
|
518
494
|
end
|
519
|
-
return
|
495
|
+
return bucket
|
520
496
|
end
|
521
497
|
end
|
522
498
|
return posts
|
523
499
|
end
|
524
500
|
|
525
|
-
def build_stream_with_index(
|
501
|
+
def build_stream_with_index(posts, options, niceranks)
|
526
502
|
@view = ""
|
527
|
-
posts = filter_nicerank(@workers.build_posts(
|
528
|
-
posts.each do |
|
529
|
-
format = "%03d" %
|
530
|
-
arrow = arrow_count(options,
|
503
|
+
posts = filter_nicerank(@workers.build_posts(posts.reverse, niceranks), options)
|
504
|
+
posts.each do |post|
|
505
|
+
format = "%03d" % post.count
|
506
|
+
arrow = arrow_count(options, post)
|
531
507
|
count = "#{arrow}#{format}"
|
532
|
-
if
|
508
|
+
if post.username == Settings.config.identity.username
|
533
509
|
@view << count.color(color_index).inverse
|
534
|
-
elsif
|
510
|
+
elsif post.mentions.include?(Settings.config.identity.username) && options[:in_mentions].nil?
|
535
511
|
@view << count.color(color_mention).inverse
|
536
512
|
else
|
537
513
|
@view << count.color(color_index)
|
538
514
|
end
|
539
515
|
@view << ": ".color(color_index)
|
540
|
-
@view << build_content(
|
516
|
+
@view << build_content(post)
|
541
517
|
end
|
542
518
|
return posts, @view
|
543
519
|
end
|
544
520
|
|
545
|
-
def build_stream_without_index(
|
521
|
+
def build_stream_without_index(posts, options, niceranks)
|
546
522
|
@view = ""
|
547
|
-
posts = filter_nicerank(@workers.build_posts(
|
548
|
-
posts.each do |
|
549
|
-
|
550
|
-
if
|
551
|
-
@view <<
|
552
|
-
elsif
|
553
|
-
@view <<
|
523
|
+
posts = filter_nicerank(@workers.build_posts(posts.reverse, niceranks), options)
|
524
|
+
posts.each do |post|
|
525
|
+
post.id = arrow_id(options, post)
|
526
|
+
if post.username == Settings.config.identity.username
|
527
|
+
@view << post.id.color(Settings.options.colors.id).inverse + " "
|
528
|
+
elsif post.mentions.include?(Settings.config.identity.username) && options[:in_mentions].nil?
|
529
|
+
@view << post.id.color(color_mention).inverse + " "
|
554
530
|
else
|
555
|
-
@view <<
|
531
|
+
@view << post.id.color(Settings.options.colors.id) + " "
|
556
532
|
end
|
557
|
-
@view << build_content(
|
533
|
+
@view << build_content(post)
|
558
534
|
end
|
559
535
|
@view
|
560
536
|
end
|
561
537
|
|
562
|
-
def arrow_count options,
|
538
|
+
def arrow_count options, post
|
563
539
|
if options[:reply_to]
|
564
|
-
return '⬇︎ ' if options[:reply_to] ==
|
565
|
-
return '⬆︎ ' if options[:post_id] ==
|
540
|
+
return '⬇︎ ' if options[:reply_to] == post.id
|
541
|
+
return '⬆︎ ' if options[:post_id] == post.id
|
566
542
|
return ''
|
567
543
|
end
|
568
544
|
''
|
569
545
|
end
|
570
546
|
|
571
|
-
def arrow_id options,
|
547
|
+
def arrow_id options, post
|
572
548
|
if options[:reply_to]
|
573
|
-
return
|
574
|
-
return
|
575
|
-
return
|
549
|
+
return post.id.to_s.prepend('⬇︎ ') if options[:reply_to] == post.id
|
550
|
+
return post.id.to_s.prepend('⬆︎ ') if options[:post_id] == post.id
|
551
|
+
return post.id.to_s
|
576
552
|
end
|
577
|
-
|
553
|
+
post.id.to_s
|
578
554
|
end
|
579
555
|
|
580
556
|
def build_interactions_stream(data)
|
@@ -620,7 +596,7 @@ module Ayadn
|
|
620
596
|
inter << "welcomed ".color(:green)
|
621
597
|
inter << "you!".color(:yellow)
|
622
598
|
end
|
623
|
-
if timeline_is_compact
|
599
|
+
if timeline_is_compact
|
624
600
|
inter << "\n"
|
625
601
|
else
|
626
602
|
inter << "\n\n"
|
@@ -672,25 +648,25 @@ module Ayadn
|
|
672
648
|
view
|
673
649
|
end
|
674
650
|
|
675
|
-
def build_content(
|
651
|
+
def build_content(post)
|
676
652
|
view = ""
|
677
|
-
view << build_header(
|
678
|
-
view << "\n" unless timeline_is_compact
|
679
|
-
view <<
|
680
|
-
view << "\n" unless timeline_is_compact
|
681
|
-
if
|
682
|
-
view << build_checkins(
|
683
|
-
view << "\n" unless timeline_is_compact
|
684
|
-
end
|
685
|
-
unless
|
653
|
+
view << build_header(post)
|
654
|
+
view << "\n" unless timeline_is_compact
|
655
|
+
view << post.text
|
656
|
+
view << "\n" unless timeline_is_compact
|
657
|
+
if post.has_checkins
|
658
|
+
view << build_checkins(post)
|
659
|
+
view << "\n" unless timeline_is_compact
|
660
|
+
end
|
661
|
+
unless post.links.empty?
|
686
662
|
view << "\n"
|
687
|
-
|
663
|
+
post.links.each do |link|
|
688
664
|
view << link.color(color_link)
|
689
665
|
view << "\n"
|
690
666
|
end
|
691
667
|
end
|
692
|
-
if timeline_is_compact
|
693
|
-
if
|
668
|
+
if timeline_is_compact
|
669
|
+
if post.links.empty?
|
694
670
|
view << "\n"
|
695
671
|
else
|
696
672
|
view
|
@@ -700,75 +676,76 @@ module Ayadn
|
|
700
676
|
end
|
701
677
|
end
|
702
678
|
|
703
|
-
def build_header(
|
679
|
+
def build_header(post)
|
704
680
|
header = ""
|
705
|
-
header <<
|
706
|
-
if Settings.options
|
681
|
+
header << post.handle.color(color_username)
|
682
|
+
if Settings.options.timeline.name
|
707
683
|
header << " "
|
708
|
-
header <<
|
684
|
+
header << post.name.color(color_name)
|
709
685
|
end
|
710
|
-
if Settings.options
|
686
|
+
if Settings.options.timeline.date
|
711
687
|
header << " "
|
712
|
-
if Settings.global
|
713
|
-
header <<
|
688
|
+
if !Settings.global.scrolling
|
689
|
+
header << post.date.color(color_date)
|
714
690
|
else
|
715
|
-
if Settings.options
|
716
|
-
header <<
|
691
|
+
if !Settings.options.scroll.date
|
692
|
+
header << post.date_short.color(color_date)
|
717
693
|
else
|
718
|
-
header <<
|
694
|
+
header << post.date.color(color_date)
|
719
695
|
end
|
720
696
|
end
|
721
697
|
end
|
722
|
-
if Settings.options
|
698
|
+
if Settings.options.timeline.source
|
723
699
|
header << " "
|
724
|
-
header << "[#{
|
700
|
+
header << "[#{post.source_name}]".color(color_source)
|
725
701
|
end
|
726
|
-
if Settings.options
|
727
|
-
header << " <".color(color_symbols) if
|
728
|
-
header << " #{
|
729
|
-
header << " #{
|
730
|
-
header << " >".color(color_symbols) if
|
702
|
+
if Settings.options.timeline.symbols
|
703
|
+
header << " <".color(color_symbols) if post.is_reply
|
704
|
+
header << " #{post.num_stars}*".color(color_symbols) if post.is_starred
|
705
|
+
header << " #{post.num_reposts}x".color(color_symbols) if post.num_reposts > 0
|
706
|
+
header << " >".color(color_symbols) if post.num_replies > 0
|
731
707
|
end
|
732
708
|
header << "\n"
|
733
709
|
end
|
734
710
|
|
735
|
-
def build_checkins(
|
736
|
-
unless
|
737
|
-
num_dots =
|
711
|
+
def build_checkins(post)
|
712
|
+
unless post.checkins['name'].nil?
|
713
|
+
num_dots = post.checkins['name'].length
|
738
714
|
else
|
739
715
|
num_dots = 10
|
740
716
|
end
|
741
|
-
if timeline_is_compact
|
717
|
+
if timeline_is_compact
|
742
718
|
hd = "\n"
|
743
719
|
else
|
744
720
|
hd = (".".color(color_dots)) * num_dots
|
745
721
|
hd << "\n"
|
746
722
|
end
|
747
723
|
formatted = { header: hd }
|
748
|
-
|
724
|
+
post.checkins.each do |key, val|
|
749
725
|
formatted[key] = val
|
750
726
|
end
|
751
727
|
|
752
728
|
formatted[:name] = "" if formatted[:name].nil?
|
753
729
|
chk = formatted[:header]
|
730
|
+
|
754
731
|
unless formatted[:name] == ""
|
755
732
|
chk << formatted[:name].color(color_dots)
|
756
733
|
chk << "\n"
|
757
734
|
end
|
758
|
-
unless formatted[:title].
|
735
|
+
unless formatted[:title].blank? || formatted[:title] == formatted[:name]
|
759
736
|
chk << formatted[:title]
|
760
737
|
chk << "\n"
|
761
738
|
end
|
762
|
-
unless formatted[:address].
|
739
|
+
unless formatted[:address].blank?
|
763
740
|
chk << formatted[:address]
|
764
741
|
chk << "\n"
|
765
742
|
end
|
743
|
+
|
766
744
|
unless formatted[:address_extended].nil?
|
767
745
|
chk << formatted[:address_extended]
|
768
746
|
chk << "\n"
|
769
747
|
end
|
770
|
-
|
771
|
-
unless formatted[:postcode].nil?
|
748
|
+
unless formatted[:postcode].blank?
|
772
749
|
unless formatted[:locality].nil?
|
773
750
|
chk << "#{formatted[:postcode]}, #{formatted[:locality]}"
|
774
751
|
else
|
@@ -817,51 +794,51 @@ module Ayadn
|
|
817
794
|
private
|
818
795
|
|
819
796
|
def color_username
|
820
|
-
Settings.options
|
797
|
+
Settings.options.colors.username
|
821
798
|
end
|
822
799
|
|
823
800
|
def color_name
|
824
|
-
Settings.options
|
801
|
+
Settings.options.colors.name
|
825
802
|
end
|
826
803
|
|
827
804
|
def color_link
|
828
|
-
Settings.options
|
805
|
+
Settings.options.colors.link
|
829
806
|
end
|
830
807
|
|
831
808
|
def color_date
|
832
|
-
Settings.options
|
809
|
+
Settings.options.colors.date
|
833
810
|
end
|
834
811
|
|
835
812
|
def color_id
|
836
|
-
Settings.options
|
813
|
+
Settings.options.colors.id
|
837
814
|
end
|
838
815
|
|
839
816
|
def color_excerpt
|
840
|
-
Settings.options
|
817
|
+
Settings.options.colors.excerpt
|
841
818
|
end
|
842
819
|
|
843
820
|
def color_symbols
|
844
|
-
Settings.options
|
821
|
+
Settings.options.colors.symbols
|
845
822
|
end
|
846
823
|
|
847
824
|
def color_index
|
848
|
-
Settings.options
|
825
|
+
Settings.options.colors.index
|
849
826
|
end
|
850
827
|
|
851
828
|
def color_mention
|
852
|
-
Settings.options
|
829
|
+
Settings.options.colors.mentions
|
853
830
|
end
|
854
831
|
|
855
832
|
def color_source
|
856
|
-
Settings.options
|
833
|
+
Settings.options.colors.source
|
857
834
|
end
|
858
835
|
|
859
836
|
def color_dots
|
860
|
-
Settings.options
|
837
|
+
Settings.options.colors.dots
|
861
838
|
end
|
862
839
|
|
863
840
|
def timeline_is_compact
|
864
|
-
Settings.options
|
841
|
+
Settings.options.timeline.compact
|
865
842
|
end
|
866
843
|
|
867
844
|
end
|