ayadn 1.8.2 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
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