ayadn 1.8.2 → 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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/CHANGELOG.md +73 -52
  4. data/README.md +17 -3
  5. data/ayadn.gemspec +3 -4
  6. data/doc/01-index.md +6 -5
  7. data/doc/02-install.md +23 -1
  8. data/doc/03-first-steps.md +22 -28
  9. data/doc/04-options.md +1 -1
  10. data/doc/05-streams.md +29 -9
  11. data/doc/06-post.md +13 -5
  12. data/doc/07-actions.md +63 -1
  13. data/doc/08-listings.md +112 -4
  14. data/doc/09-accounts.md +17 -3
  15. data/doc/10-nicerank.md +5 -5
  16. data/doc/11-blacklist.md +8 -14
  17. data/doc/12-alias.md +1 -13
  18. data/doc/14-set.md +8 -110
  19. data/doc/15-nowplaying.md +16 -4
  20. data/doc/18-contact.md +14 -13
  21. data/doc/19-examples.md +2 -0
  22. data/lib/ayadn/action.rb +322 -183
  23. data/lib/ayadn/alias.rb +17 -45
  24. data/lib/ayadn/annotations.rb +1 -1
  25. data/lib/ayadn/api.rb +7 -8
  26. data/lib/ayadn/app.rb +99 -12
  27. data/lib/ayadn/authorize.rb +92 -57
  28. data/lib/ayadn/blacklist.rb +52 -62
  29. data/lib/ayadn/check.rb +81 -74
  30. data/lib/ayadn/cnx.rb +77 -26
  31. data/lib/ayadn/databases.rb +890 -105
  32. data/lib/ayadn/debug.rb +30 -89
  33. data/lib/ayadn/descriptions.rb +876 -329
  34. data/lib/ayadn/endpoints.rb +2 -2
  35. data/lib/ayadn/errors.rb +9 -9
  36. data/lib/ayadn/extend.rb +8 -1
  37. data/lib/ayadn/fileops.rb +10 -8
  38. data/lib/ayadn/mark.rb +79 -56
  39. data/lib/ayadn/migration.rb +427 -0
  40. data/lib/ayadn/nicerank.rb +74 -72
  41. data/lib/ayadn/nowplaying.rb +123 -60
  42. data/lib/ayadn/nowwatching.rb +26 -10
  43. data/lib/ayadn/pinboard.rb +12 -7
  44. data/lib/ayadn/post.rb +40 -37
  45. data/lib/ayadn/profile.rb +5 -2
  46. data/lib/ayadn/scroll.rb +20 -5
  47. data/lib/ayadn/search.rb +30 -22
  48. data/lib/ayadn/set.rb +146 -50
  49. data/lib/ayadn/settings.rb +66 -67
  50. data/lib/ayadn/status.rb +459 -234
  51. data/lib/ayadn/stream.rb +80 -46
  52. data/lib/ayadn/switch.rb +51 -47
  53. data/lib/ayadn/tvshow.rb +47 -15
  54. data/lib/ayadn/version.rb +1 -1
  55. data/lib/ayadn/view.rb +119 -60
  56. data/lib/ayadn/workers.rb +144 -92
  57. data/lib/ayadn.rb +7 -8
  58. data/spec/mock/ayadn/accounts.sqlite +0 -0
  59. data/spec/mock/ayadn.sqlite +0 -0
  60. data/spec/unit/annotations_spec.rb +12 -13
  61. data/spec/unit/api_spec.rb +3 -4
  62. data/spec/unit/blacklistworkers_spec.rb +18 -23
  63. data/spec/unit/databases_spec.rb +51 -36
  64. data/spec/unit/endpoints_spec.rb +5 -2
  65. data/spec/unit/extend_spec.rb +24 -0
  66. data/spec/unit/nicerank_spec.rb +13 -13
  67. data/spec/unit/post_spec.rb +47 -36
  68. data/spec/unit/set_spec.rb +67 -96
  69. data/spec/unit/view_spec.rb +12 -6
  70. data/spec/unit/workers_spec.rb +38 -12
  71. data/tags +1285 -0
  72. metadata +29 -39
  73. data/spec/mock/aliases.db +0 -0
  74. data/spec/mock/blacklist.db +0 -0
  75. data/spec/mock/bookmarks.db +0 -0
  76. data/spec/mock/channels.db +0 -0
  77. data/spec/mock/index.db +0 -0
  78. data/spec/mock/nicerank.db +0 -0
  79. data/spec/mock/pagination.db +0 -0
  80. data/spec/mock/users.db +0 -0
  81. data/spec/unit/status_spec.rb +0 -9
data/lib/ayadn/check.rb CHANGED
@@ -3,185 +3,192 @@ module Ayadn
3
3
 
4
4
  class Check
5
5
 
6
- def self.same_username(stream)
6
+ def initialize
7
+ @status = Status.new
8
+ end
9
+
10
+ def same_username(stream)
7
11
  stream['data']['username'] == Settings.config[:identity][:username]
8
12
  end
9
13
 
10
- def self.auto_save_muted(list)
11
- FileOps.save_muted_list(list) if Settings.options[:backup][:auto_save_lists]
14
+ def auto_save_muted(list)
15
+ FileOps.save_muted_list(list) if Settings.options[:backup][:lists]
12
16
  end
13
17
 
14
- def self.auto_save_followers(list)
15
- FileOps.save_followers_list(list) if Settings.options[:backup][:auto_save_lists]
18
+ def auto_save_followers(list)
19
+ FileOps.save_followers_list(list) if Settings.options[:backup][:lists]
16
20
  end
17
21
 
18
- def self.auto_save_followings(list)
19
- FileOps.save_followings_list(list) if Settings.options[:backup][:auto_save_lists]
22
+ def auto_save_followings(list)
23
+ FileOps.save_followings_list(list) if Settings.options[:backup][:lists]
20
24
  end
21
25
 
22
- def self.no_username username
23
- abort(Status.error_missing_username) if username.empty?
26
+ def no_username username
27
+ if username.empty?
28
+ @status.error_missing_username
29
+ exit
30
+ end
24
31
  end
25
32
 
26
- def self.no_data stream, target
33
+ def no_data stream, target
27
34
  if stream['data'].empty?
28
35
  Errors.warn "In action/#{target}: no data"
29
- abort(Status.empty_list)
36
+ @status.empty_list
37
+ exit
30
38
  end
31
39
  end
32
40
 
33
- def self.no_new_posts stream, options, title
34
- if options[:new]
41
+ def no_new_posts stream, options, title
42
+ if options[:new] == true
35
43
  unless Databases.has_new?(stream, title)
36
- abort(Status.no_new_posts)
44
+ @status.no_new_posts
45
+ exit
37
46
  end
38
47
  end
39
48
  end
40
49
 
41
- def self.no_post stream, post_id
50
+ def no_post stream, post_id
42
51
  if stream['meta']['code'] == 404
43
- puts Status.post_404(post_id)
52
+ @status.post_404(post_id)
44
53
  Errors.info("Impossible to find #{post_id}")
45
54
  exit
46
55
  end
47
56
  end
48
57
 
49
- def self.bad_post_id post_id
50
- abort(Status.error_missing_post_id) unless post_id.is_integer?
58
+ def bad_post_id post_id
59
+ unless post_id.is_integer?
60
+ @status.error_missing_post_id
61
+ exit
62
+ end
51
63
  end
52
64
 
53
- def self.no_user stream, username
65
+ def bad_post_ids(post_ids)
66
+ post_ids.each do |id|
67
+ unless id.is_integer?
68
+ @status.error_missing_post_id
69
+ exit
70
+ end
71
+ end
72
+ end
73
+
74
+ def no_user stream, username
54
75
  if stream['meta']['code'] == 404
55
- puts Status.user_404(username)
76
+ @status.user_404(username)
56
77
  Errors.info("User #{username} doesn't exist")
57
78
  exit
58
79
  end
59
80
  end
60
81
 
61
- def self.has_been_unfollowed(username, resp)
82
+ def has_been_unfollowed(username, resp)
62
83
  if resp['meta']['code'] == 200
63
- puts Status.unfollowed(username)
64
- Logs.rec.info "Unfollowed #{username}."
84
+ @status.unfollowed(username)
65
85
  else
66
- Errors.whine(Status.not_unfollowed(username), resp)
86
+ @status.not_unfollowed(username)
67
87
  end
68
88
  end
69
89
 
70
- def self.has_been_unmuted(username, resp)
90
+ def has_been_unmuted(username, resp)
71
91
  if resp['meta']['code'] == 200
72
- puts Status.unmuted(username)
73
- Logs.rec.info "Unmuted #{username}."
92
+ @status.unmuted(username)
74
93
  else
75
- Errors.whine(Status.not_unmuted(username), resp)
94
+ @status.not_unmuted(username)
76
95
  end
77
96
  end
78
97
 
79
- def self.already_starred(resp)
98
+ def already_starred(resp)
80
99
  if resp['data']['you_starred']
81
- puts "\nYou already starred this post.\n".color(:red)
100
+ @status.already_starred
82
101
  exit
83
102
  end
84
103
  end
85
104
 
86
- def self.already_reposted(resp)
105
+ def already_reposted(resp)
87
106
  if resp['data']['you_reposted']
88
- puts "\nYou already reposted this post.\n".color(:red)
107
+ @status.already_reposted
89
108
  exit
90
109
  end
91
110
  end
92
111
 
93
- def self.has_been_starred(post_id, resp)
112
+ def has_been_starred(post_id, resp)
94
113
  if resp['meta']['code'] == 200
95
- puts Status.starred(post_id)
96
- Logs.rec.info "Starred #{post_id}."
114
+ @status.starred(post_id)
97
115
  else
98
- Errors.whine(Status.not_starred(post_id), resp)
116
+ @status.not_starred(post_id)
99
117
  end
100
118
  end
101
119
 
102
- def self.has_been_reposted(post_id, resp)
120
+ def has_been_reposted(post_id, resp)
103
121
  if resp['meta']['code'] == 200
104
- puts Status.reposted(post_id)
105
- Logs.rec.info "Reposted #{post_id}."
122
+ @status.reposted(post_id)
106
123
  else
107
- Errors.whine(Status.not_reposted(post_id), resp)
124
+ @status.not_reposted(post_id)
108
125
  end
109
126
  end
110
127
 
111
- def self.has_been_blocked(username, resp)
128
+ def has_been_blocked(username, resp)
112
129
  if resp['meta']['code'] == 200
113
- puts Status.blocked(username)
114
- Logs.rec.info "Blocked #{username}."
130
+ @status.blocked(username)
115
131
  else
116
- Errors.whine(Status.not_blocked(username), resp)
132
+ @status.not_blocked(username)
117
133
  end
118
134
  end
119
135
 
120
- def self.has_been_muted(username, resp)
136
+ def has_been_muted(username, resp)
121
137
  if resp['meta']['code'] == 200
122
- puts Status.muted(username)
123
- Logs.rec.info "Muted #{username}."
138
+ @status.muted(username)
124
139
  else
125
- Errors.whine(Status.not_muted(username), resp)
140
+ @status.not_muted(username)
126
141
  end
127
142
  end
128
143
 
129
- def self.has_been_followed(username, resp)
144
+ def has_been_followed(username, resp)
130
145
  if resp['meta']['code'] == 200
131
- puts Status.followed(username)
132
- Logs.rec.info "Followed #{username}."
146
+ @status.followed(username)
133
147
  else
134
- Errors.whine(Status.not_followed(username), resp)
148
+ @status.not_followed(username)
135
149
  end
136
150
  end
137
151
 
138
- def self.has_been_deleted(post_id, resp)
152
+ def has_been_deleted(post_id, resp)
139
153
  if resp['meta']['code'] == 200
140
- puts Status.deleted(post_id)
141
- Logs.rec.info "Deleted post #{post_id}."
154
+ @status.deleted(post_id)
142
155
  else
143
- Errors.whine(Status.not_deleted(post_id), resp)
156
+ @status.not_deleted(post_id)
144
157
  end
145
158
  end
146
159
 
147
- def self.message_has_been_deleted(message_id, resp)
160
+ def message_has_been_deleted(message_id, resp)
148
161
  if resp['meta']['code'] == 200
149
- puts Status.deleted_m(message_id)
150
- Logs.rec.info "Deleted message #{message_id}."
162
+ @status.deleted_m(message_id)
151
163
  else
152
- Errors.whine(Status.not_deleted(message_id), resp)
164
+ @status.not_deleted_m(message_id)
153
165
  end
154
166
  end
155
167
 
156
- def self.has_been_unblocked(username, resp)
168
+ def has_been_unblocked(username, resp)
157
169
  if resp['meta']['code'] == 200
158
- puts Status.unblocked(username)
159
- Logs.rec.info "Unblocked #{username}."
170
+ @status.unblocked(username)
160
171
  else
161
- Errors.whine(Status.not_unblocked(username), resp)
172
+ @status.not_unblocked(username)
162
173
  end
163
174
  end
164
175
 
165
- def self.has_been_unstarred(post_id, resp)
176
+ def has_been_unstarred(post_id, resp)
166
177
  if resp['meta']['code'] == 200
167
- puts Status.unstarred(post_id)
168
- Logs.rec.info "Unstarred #{post_id}."
178
+ @status.unstarred(post_id)
169
179
  else
170
- Errors.whine(Status.not_unstarred(post_id), resp)
180
+ @status.not_unstarred(post_id)
171
181
  end
172
182
  end
173
183
 
174
- def self.has_been_unreposted(post_id, resp)
184
+ def has_been_unreposted(post_id, resp)
175
185
  if resp['meta']['code'] == 200
176
- puts Status.unreposted(post_id)
177
- Logs.rec.info "Unreposted #{post_id}."
186
+ @status.unreposted(post_id)
178
187
  else
179
- Errors.whine(Status.not_unreposted(post_id), resp)
188
+ @status.not_unreposted(post_id)
180
189
  end
181
190
  end
182
191
 
183
-
184
-
185
192
  end
186
193
 
187
194
  end
data/lib/ayadn/cnx.rb CHANGED
@@ -7,14 +7,22 @@ module Ayadn
7
7
  begin
8
8
  RestClient.get(url) {|response, request, result| response}
9
9
  rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError, RestClient::RequestTimeout => e
10
+ thor = Thor::Shell::Color.new
10
11
  if working == true
11
12
  working = false
12
- puts "\nOoops, '#{url}' didn't respond. Trying again in 5 secs.\n".color(:red)
13
+ thor.say_status :error, "'#{url}' didn't respond", :red
14
+ thor.say_status :info, "trying again in 5 secs", :yellow
13
15
  sleep 5
14
16
  retry
15
17
  end
16
- puts "\nConnexion error.\n\n".color(:red)
18
+ thor.say_status :error, "connection problem", :red
17
19
  Errors.global_error({error: e, caller: caller, data: [url]})
20
+ rescue Interrupt
21
+ thor = Thor::Shell::Color.new
22
+ puts "\n"
23
+ thor.say_status :canceled, "connection canceled", :red
24
+ puts "\n"
25
+ exit
18
26
  rescue => e
19
27
  Errors.global_error({error: e, caller: caller, data: [url]})
20
28
  end
@@ -35,6 +43,12 @@ module Ayadn
35
43
  end
36
44
  Errors.nr "URL: #{url}"
37
45
  return {'meta' => {'code' => 666}, 'data' => "#{e}"}.to_json
46
+ rescue Interrupt
47
+ thor = Thor::Shell::Color.new
48
+ puts "\n"
49
+ thor.say_status :canceled, "connection canceled", :red
50
+ puts "\n"
51
+ exit
38
52
  rescue => e
39
53
  Errors.global_error({error: e, caller: caller, data: [url]})
40
54
  end
@@ -64,19 +78,27 @@ module Ayadn
64
78
  try_cnx = retry_adn 10, try_cnx
65
79
  retry
66
80
  end
67
- puts "\nConnection error.".color(:red)
81
+ Thor::Shell::Color.new.say_status :error, "connection problem", :red
68
82
  Errors.global_error({error: e, caller: caller, data: [url]})
69
83
  rescue URI::InvalidURIError => e
70
- puts "\nConnection or authorization error.".color(:red)
84
+ Thor::Shell::Color.new.say_status :error, "connection or authorization problem", :red
71
85
  Errors.global_error({error: e, caller: caller, data: [url]})
86
+ rescue Interrupt
87
+ thor = Thor::Shell::Color.new
88
+ puts "\n"
89
+ thor.say_status :canceled, "connection canceled", :red
90
+ puts "\n"
91
+ exit
72
92
  rescue => e
73
93
  Errors.global_error({error: e, caller: caller, data: [url]})
74
94
  end
75
95
  end
76
96
 
77
97
  def self.retry_adn seconds, try_cnx
98
+ thor = Thor::Shell::Color.new
99
+ thor.say_status :error, "unable to connect to App.net", :red
100
+ thor.say_status :info, "trying again in #{seconds} seconds (#{try_cnx}/3)", :yellow
78
101
  Errors.warn "Unable to connect to App.net"
79
- puts "\n\nUnable to connect to App.net\nRetrying in #{seconds} seconds... (#{try_cnx}/3)\n".color(:red)
80
102
  try_cnx += 1
81
103
  sleep seconds
82
104
  puts "\e[H\e[2J"
@@ -84,35 +106,40 @@ module Ayadn
84
106
  end
85
107
 
86
108
  def self.check response
87
- message = JSON.parse(response)['meta']['error_message'] if response.code != 200
109
+ if response.code != 200
110
+ res = JSON.parse(response)
111
+ message = res['meta']['error_message']
112
+ thor = Thor::Shell::Color.new
113
+ puts "\n"
114
+ end
88
115
  case response.code
89
116
  when 200
90
117
  response
91
118
  when 204
92
- puts "\n#{message}".color(:red)
93
- Errors.global_error({error: "NO CONTENT", caller: caller, data: [message, response.headers]})
119
+ thor.say_status :error, message.upcase, :red
120
+ Errors.global_error({error: message, caller: caller, data: [res]})
94
121
  when 400
95
- puts "\n#{message}".color(:red)
96
- Errors.global_error({error: "BAD REQUEST", caller: caller, data: [message, response.headers]})
122
+ thor.say_status :error, message.upcase, :red
123
+ Errors.global_error({error: message, caller: caller, data: [res]})
97
124
  when 401
98
- puts "\n#{message}".color(:red)
99
- Errors.global_error({error: "UNAUTHORIZED", caller: caller, data: [message, response.headers]})
125
+ thor.say_status :error, message.upcase, :red
126
+ Errors.global_error({error: message, caller: caller, data: [res]})
100
127
  when 403
101
- puts "\n#{message}".color(:red)
102
- Errors.global_error({error: "FORBIDDEN", caller: caller, data: [message, response.headers]})
128
+ thor.say_status :error, message.upcase, :red
129
+ Errors.global_error({error: message, caller: caller, data: [res]})
103
130
  when 405
104
- puts "\n#{message}".color(:red)
105
- Errors.global_error({error: "METHOD NOT ALLOWED", caller: caller, data: [message, response.headers]})
131
+ thor.say_status :error, message.upcase, :red
132
+ Errors.global_error({error: message, caller: caller, data: [res]})
106
133
  when 429
107
- puts "\n#{message}".color(:red)
134
+ thor.say_status :error, message.upcase, :red
108
135
  puts "\n\nAyadn made too many requests to the App.net API. You should wait at least ".color(:cyan) + "#{response.headers[:retry_after]} ".color(:red) + "seconds before trying again. Maybe you launched a lot of Ayadn instances at the same time? That's no problem, but in this case you should increase the value of the scroll timer (with `ayadn set scroll timer 5` for example). App.net allows 5000 requests per hour per account maximum.".color(:cyan)
109
- Errors.global_error({error: "TOO MANY REQUESTS", caller: caller, data: [message, response.headers]})
136
+ Errors.global_error({error: message, caller: caller, data: [res]})
110
137
  when 500
111
- puts "\n#{message}".color(:red)
112
- Errors.global_error({error: "APP.NET SERVER ERROR", caller: caller, data: [message, response.headers]})
138
+ thor.say_status :error, message.upcase, :red
139
+ Errors.global_error({error: message, caller: caller, data: [res]})
113
140
  when 507
114
- puts "\n#{message}".color(:red)
115
- Errors.global_error({error: "INSUFFICIENT STORAGE", caller: caller, data: [message, response.headers]})
141
+ thor.say_status :error, message.upcase, :red
142
+ Errors.global_error({error: message, caller: caller, data: [res]})
116
143
  else
117
144
  response
118
145
  end
@@ -125,8 +152,14 @@ module Ayadn
125
152
  check response
126
153
  end
127
154
  rescue SocketError, SystemCallError => e
128
- puts "\nConnection error.".color(:red)
155
+ Thor::Shell::Color.new.say_status :error, "connection problem", :red
129
156
  Errors.global_error({error: e, caller: caller, data: [url]})
157
+ rescue Interrupt
158
+ thor = Thor::Shell::Color.new
159
+ puts "\n"
160
+ thor.say_status :canceled, "connection canceled", :red
161
+ puts "\n"
162
+ exit
130
163
  rescue => e
131
164
  Errors.global_error({error: e, caller: caller, data: [url]})
132
165
  end
@@ -139,8 +172,14 @@ module Ayadn
139
172
  check response
140
173
  end
141
174
  rescue SocketError, SystemCallError => e
142
- puts "\nConnection error.".color(:red)
175
+ Thor::Shell::Color.new.say_status :error, "connection problem", :red
143
176
  Errors.global_error({error: e, caller: caller, data: [url, payload]})
177
+ rescue Interrupt
178
+ thor = Thor::Shell::Color.new
179
+ puts "\n"
180
+ thor.say_status :canceled, "connection canceled", :red
181
+ puts "\n"
182
+ exit
144
183
  rescue => e
145
184
  Errors.global_error({error: e, caller: caller, data: [url, payload]})
146
185
  end
@@ -153,8 +192,14 @@ module Ayadn
153
192
  check response
154
193
  end
155
194
  rescue SocketError, SystemCallError => e
156
- puts "\nConnection error.".color(:red)
195
+ Thor::Shell::Color.new.say_status :error, "connection problem", :red
157
196
  Errors.global_error({error: e, caller: caller, data: [url, payload]})
197
+ rescue Interrupt
198
+ thor = Thor::Shell::Color.new
199
+ puts "\n"
200
+ thor.say_status :canceled, "connection canceled", :red
201
+ puts "\n"
202
+ exit
158
203
  rescue => e
159
204
  Errors.global_error({error: e, caller: caller, data: [url, payload]})
160
205
  end
@@ -167,8 +212,14 @@ module Ayadn
167
212
  check response
168
213
  end
169
214
  rescue SocketError, SystemCallError => e
170
- puts "\nConnection error.".color(:red)
215
+ Thor::Shell::Color.new.say_status :error, "connection problem", :red
171
216
  Errors.global_error({error: e, caller: caller, data: [url, payload]})
217
+ rescue Interrupt
218
+ thor = Thor::Shell::Color.new
219
+ puts "\n"
220
+ thor.say_status :canceled, "connection canceled", :red
221
+ puts "\n"
222
+ exit
172
223
  rescue => e
173
224
  Errors.global_error({error: e, caller: caller, data: [url, payload]})
174
225
  end