ayadn 2.1 → 3.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.
@@ -6,7 +6,16 @@ module Ayadn
6
6
  working = true
7
7
  begin
8
8
  RestClient.get(url) {|response, request, result| response}
9
- rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError, RestClient::RequestTimeout => e
9
+ rescue RestClient::RequestTimeout => e
10
+ thor = Thor::Shell::Color.new
11
+ thor.say_status :error, "connection timeout", :red
12
+ if working == true
13
+ working = false
14
+ thor.say_status :info, "trying again", :yellow
15
+ retry
16
+ end
17
+ Errors.global_error({error: e, caller: caller, data: [url]})
18
+ rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError => e
10
19
  thor = Thor::Shell::Color.new
11
20
  if working == true
12
21
  working = false
@@ -59,7 +68,7 @@ module Ayadn
59
68
  when 200
60
69
  response
61
70
  when 204
62
- puts "\nError: the NiceRank filter made too many requests to the server. You may either wait for a little while before scrolling the filtered Global again, or set the scroll timer to a greater value (example: `ayadn set scroll timer 5`). (see http://ayadn-app.net/doc).\n".color(:red)
71
+ puts "\nError: the NiceRank filter made too many requests to the server. You may either wait for a little while before scrolling the filtered Global again, or set the scroll timer to a greater value (example: `ayadn set scroll timer 5`). (see https://github.com/ericdke/na/tree/master/doc).\n".color(:red)
63
72
  Errors.global_error({error: "NiceRank: TOO MANY REQUESTS", caller: caller, data: [url, response.inspect, response.headers]})
64
73
  else
65
74
  response
@@ -74,7 +83,15 @@ module Ayadn
74
83
  Debug.http response, url
75
84
  check response
76
85
  end
77
- rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError, RestClient::RequestTimeout => e
86
+ rescue RestClient::RequestTimeout => e
87
+ thor = Thor::Shell::Color.new
88
+ thor.say_status :error, "connection timeout", :red
89
+ if try_cnx < 4
90
+ try_cnx = retry_adn 5, try_cnx
91
+ retry
92
+ end
93
+ Errors.global_error({error: e, caller: caller, data: [url]})
94
+ rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError => e
78
95
  if try_cnx < 4
79
96
  try_cnx = retry_adn 10, try_cnx
80
97
  retry
@@ -1942,17 +1942,5 @@ module Ayadn
1942
1942
  \n\n
1943
1943
  USAGE
1944
1944
  end
1945
- def self.migrate
1946
- <<-USAGE
1947
- This command migrates an Ayadn 1.x account to the new 2.x format.
1948
-
1949
- This is an hidden command (doesn't show in the commands menu).
1950
-
1951
- You should only use this command once, when asked by Ayadn.
1952
-
1953
- `ayadn migrate`
1954
- \n\n
1955
- USAGE
1956
- end
1957
1945
  end
1958
1946
  end
@@ -0,0 +1,471 @@
1
+ # encoding: utf-8
2
+ module Ayadn
3
+
4
+ class Diagnostics < Thor
5
+
6
+ desc "nicerank", "Tests the NiceRank API"
7
+ def nicerank
8
+ obj = CheckNiceRank.new
9
+ obj.check
10
+ obj.status.say_end
11
+ end
12
+
13
+ desc "adn", "Tests the App.net API"
14
+ def adn
15
+ obj = CheckADN.new
16
+ obj.check
17
+ obj.status.say_end
18
+ end
19
+
20
+ desc "accounts", "Tests registered Ayadn accounts"
21
+ def accounts
22
+ obj = CheckAccounts.new
23
+ obj.check
24
+ obj.status.say_end
25
+ end
26
+
27
+ desc "ayadn", "Tests the Ayadn Gem"
28
+ def ayadn
29
+ obj = CheckAyadn.new
30
+ obj.check
31
+ obj.status.say_end
32
+ end
33
+
34
+ desc "all", "Run all tests"
35
+ def all
36
+ obj = CheckADN.new
37
+ obj.check
38
+ obj = CheckAyadn.new
39
+ obj.check
40
+ obj = CheckAccounts.new
41
+ obj.check
42
+ obj = CheckNiceRank.new
43
+ obj.check
44
+ obj.status.say_end
45
+ end
46
+ end
47
+
48
+ class CheckBase
49
+
50
+ attr_accessor :response, :status
51
+
52
+ def initialize
53
+ @status = Status.new
54
+ end
55
+
56
+ def get_response(url)
57
+ @response = RestClient.get(url) {|response, request, result| response}
58
+ end
59
+
60
+ def check_response_code
61
+ code = @response.code
62
+ if code == 200
63
+ @status.say_green :status, "OK"
64
+ else
65
+ @status.say_red :status, "#{code}"
66
+ end
67
+ end
68
+
69
+ def rescue_network(error)
70
+ begin
71
+ raise error
72
+ rescue RestClient::RequestTimeout => e
73
+ @status.say_error "connection timeout"
74
+ @status.say_trace e
75
+ rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError => e
76
+ @status.say_error "connection problem"
77
+ @status.say_trace e
78
+ rescue Interrupt
79
+ @status.say_error "operation canceled"
80
+ exit
81
+ rescue => e
82
+ @status.say_error "unknown error"
83
+ @status.say_trace e
84
+ end
85
+ end
86
+ end
87
+
88
+ class CheckNiceRank < CheckBase
89
+
90
+ def check
91
+ begin
92
+ @status.say_header "checking NiceRank server response"
93
+ get_response "http://api.nice.social/user/nicerank?ids=1"
94
+ check_response_code
95
+ ratelimit = @response.headers[:x_ratelimit_remaining]
96
+ if ratelimit.blank?
97
+ @status.say_red :ratelimit, "invalid server response"
98
+ else
99
+ Integer(ratelimit) > 120 ? @status.say_green(:ratelimit, "OK") : @status.say_red(:ratelimit, ratelimit)
100
+ end
101
+ rescue => e
102
+ rescue_network(e)
103
+ end
104
+ end
105
+ end
106
+
107
+ class CheckADN < CheckBase
108
+
109
+ def check
110
+ begin
111
+ check_root_api
112
+ @status.say_header "checking ADN server response"
113
+ get_response "https://api.app.net/config"
114
+ check_response_code
115
+ body = JSON.parse(@response.body)
116
+ if body.blank? || body["data"].blank?
117
+ @status.say_red(:config, "no data")
118
+ else
119
+ @status.say_green(:config, "OK")
120
+ end
121
+ rescue => e
122
+ rescue_network(e)
123
+ end
124
+ end
125
+
126
+ private
127
+
128
+ def check_root_api
129
+ @status.say_header("default root API endpoint")
130
+ api_file = Dir.home + "/ayadn/.api.yml"
131
+ baseURL = if File.exist?(api_file)
132
+ YAML.load(File.read(api_file))[:root]
133
+ else
134
+ "https://api.app.net"
135
+ end
136
+ @status.say_green(:url, baseURL)
137
+ end
138
+ end
139
+
140
+ class CheckAccounts < CheckBase
141
+
142
+ attr_accessor :sql_path, :active_account, :db, :paths, :handle, :userDB
143
+
144
+ def initialize
145
+ super
146
+ @sql_path = Dir.home + "/ayadn/accounts.sqlite"
147
+ end
148
+
149
+ def check
150
+ begin
151
+ @status.say_header("checking accounts database")
152
+ if find_active_account == true
153
+ users = @db.execute("SELECT * FROM Accounts")
154
+ if users.blank?
155
+ @status.say_red(:abort, "no registered Ayadn users")
156
+ else
157
+ @status.say_green(:accounts, users.map { |user| user[2] }.join(", "))
158
+ if @active_account.blank?
159
+ @status.say_red(:warning, "no active account")
160
+ else
161
+ @status.say_header("checking active account")
162
+ check_id_handle
163
+ check_token
164
+ check_paths
165
+ check_config
166
+ @status.say_header("checking #{@handle}'s account database")
167
+ if find_active_tables == true
168
+ check_tables_schemas
169
+ end
170
+ end
171
+ end
172
+ end
173
+ rescue Interrupt
174
+ @status.say_error "operation canceled"
175
+ exit
176
+ rescue Amalgalite::SQLite3::Error => e
177
+ @status.say_error "database error"
178
+ @status.say_trace e
179
+ rescue => e
180
+ @status.say_error "unknown error"
181
+ @status.say_trace e
182
+ end
183
+ end
184
+
185
+ private
186
+
187
+ def check_token
188
+ token = @active_account[5]
189
+ if token.blank?
190
+ @status.say_red(:missing, "authorization token")
191
+ else
192
+ @status.say_green(:auth_token, token[0..20] + "...")
193
+ end
194
+ end
195
+
196
+ def check_tables_schemas
197
+ @status.say_header("checking tables schemas")
198
+ if @userDB.schema.tables.count != 6
199
+ @status.say_red :error, "#{@handle}'s account database is corrupted"
200
+ else
201
+ @userDB.schema.tables.each do |table|
202
+ @status.say_info "checking table #{table[0]}"
203
+ case table[0]
204
+ when "Bookmarks"
205
+ break if check_bookmarks(table) == false
206
+ when "Aliases"
207
+ break if check_aliases(table) == false
208
+ when "Blacklist"
209
+ break if check_blacklist(table) == false
210
+ when "Users"
211
+ break if check_users(table) == false
212
+ when "Pagination"
213
+ break if check_pagination(table) == false
214
+ when "TLIndex"
215
+ break if check_TLIndex(table) == false
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ def check_bookmarks(table)
222
+ if table[1].columns.count != 2
223
+ @status.say_red :error, "#{table[0]} table is corrupted"
224
+ return false
225
+ else
226
+ table[1].columns.each do |name, data|
227
+ if name == "post_id" && data.declared_data_type == "INTEGER"
228
+ @status.say_green(name.to_sym, "OK")
229
+ elsif name == "bookmark" && data.declared_data_type == "TEXT"
230
+ @status.say_green(name.to_sym, "OK")
231
+ else
232
+ @status.say_red :error, "#{table[0]} table is corrupted"
233
+ return false
234
+ end
235
+ end
236
+ end
237
+ return true
238
+ end
239
+
240
+ def check_aliases(table)
241
+ if table[1].columns.count != 2
242
+ @status.say_red :error, "#{table[0]} table is corrupted"
243
+ return false
244
+ else
245
+ table[1].columns.each do |name, data|
246
+ if name == "channel_id" && data.declared_data_type == "INTEGER"
247
+ @status.say_green(name.to_sym, "OK")
248
+ elsif name == "alias" && data.declared_data_type == "VARCHAR(255)"
249
+ @status.say_green(name.to_sym, "OK")
250
+ else
251
+ @status.say_red :error, "#{table[0]} table is corrupted"
252
+ return false
253
+ end
254
+ end
255
+ end
256
+ return true
257
+ end
258
+
259
+ def check_blacklist(table)
260
+ if table[1].columns.count != 2
261
+ @status.say_red :error, "#{table[0]} table is corrupted"
262
+ return false
263
+ else
264
+ table[1].columns.each do |name, data|
265
+ if name == "type" && data.declared_data_type == "VARCHAR(255)"
266
+ @status.say_green(name.to_sym, "OK")
267
+ elsif name == "content" && data.declared_data_type == "TEXT"
268
+ @status.say_green(name.to_sym, "OK")
269
+ else
270
+ @status.say_red :error, "#{table[0]} table is corrupted"
271
+ return false
272
+ end
273
+ end
274
+ end
275
+ return true
276
+ end
277
+
278
+ def check_users(table)
279
+ if table[1].columns.count != 3
280
+ @status.say_red :error, "#{table[0]} table is corrupted"
281
+ return false
282
+ else
283
+ table[1].columns.each do |name, data|
284
+ if name == "user_id" && data.declared_data_type == "INTEGER"
285
+ @status.say_green(name.to_sym, "OK")
286
+ elsif name == "username" && data.declared_data_type == "VARCHAR(20)"
287
+ @status.say_green(name.to_sym, "OK")
288
+ elsif name == "name" && data.declared_data_type == "TEXT"
289
+ @status.say_green(name.to_sym, "OK")
290
+ else
291
+ @status.say_red :error, "#{table[0]} table is corrupted"
292
+ return false
293
+ end
294
+ end
295
+ end
296
+ return true
297
+ end
298
+
299
+ def check_pagination(table)
300
+ if table[1].columns.count != 2
301
+ @status.say_red :error, "#{table[0]} table is corrupted"
302
+ return false
303
+ else
304
+ table[1].columns.each do |name, data|
305
+ if name == "name" && data.declared_data_type == "TEXT"
306
+ @status.say_green(name.to_sym, "OK")
307
+ elsif name == "post_id" && data.declared_data_type == "INTEGER"
308
+ @status.say_green(name.to_sym, "OK")
309
+ else
310
+ @status.say_red :error, "#{table[0]} table is corrupted"
311
+ return false
312
+ end
313
+ end
314
+ end
315
+ return true
316
+ end
317
+
318
+ def check_TLIndex(table)
319
+ if table[1].columns.count != 3
320
+ @status.say_red :error, "#{table[0]} table is corrupted"
321
+ return false
322
+ else
323
+ table[1].columns.each do |name, data|
324
+ if name == "count" && data.declared_data_type == "INTEGER"
325
+ @status.say_green(name.to_sym, "OK")
326
+ elsif name == "post_id" && data.declared_data_type == "INTEGER"
327
+ @status.say_green(name.to_sym, "OK")
328
+ elsif name == "content" && data.declared_data_type == "TEXT"
329
+ @status.say_green(name.to_sym, "OK")
330
+ else
331
+ @status.say_red :error, "#{table[0]} table is corrupted"
332
+ return false
333
+ end
334
+ end
335
+ end
336
+ return true
337
+ end
338
+
339
+ def check_config
340
+ @status.say_header("checking active account settings")
341
+ config_path = @paths[:config] + "/config.yml"
342
+ config = YAML.load(File.read(config_path))
343
+ if config.blank?
344
+ @status.say_error("active user has no config file")
345
+ else
346
+ @status.say_green(:found, "active user config file")
347
+ @status.say_header("difference default/current")
348
+ diff = Settings.defaults.deep_diff(config)
349
+ if diff.blank?
350
+ @status.say_green(:pass, "current user is using default values")
351
+ else
352
+ diff.each do |key, value|
353
+ if value.is_a?(Hash)
354
+ value.each do |inner_key, inner_value|
355
+ default = inner_value[0].nil? ? "none" : inner_value[0]
356
+ current = if inner_key == :deezer
357
+ inner_value[1].nil? ? "none" : inner_value[1][:code][0..10] + "..."
358
+ else
359
+ inner_value[1].nil? ? "none" : inner_value[1]
360
+ end
361
+ @status.say_green(:changed, "#{key}/#{inner_key} - Default: #{default}, Current: #{current}")
362
+ end
363
+ else
364
+ default = value[0].nil? ? "none" : value[0]
365
+ if value[1].nil?
366
+ @status.say_red(:missing, "#{key} - Default: #{default}, Current: none")
367
+ else
368
+ @status.say_green(:changed, "#{key} - Default: #{default}, Current: #{value[1]}")
369
+ end
370
+ end
371
+ end
372
+ end
373
+ end
374
+ end
375
+
376
+ def check_id_handle
377
+ id = @active_account[1]
378
+ @status.say_green(:id, id)
379
+ # username = @active_account[0]
380
+ @handle = @active_account[2]
381
+ @status.say_green(:username, @handle)
382
+ end
383
+
384
+ def check_paths
385
+ home = @active_account[3]
386
+ @status.say_green(:path, home)
387
+ @paths = {
388
+ log: "#{home}/log",
389
+ db: "#{home}/db",
390
+ config: "#{home}/config",
391
+ downloads: "#{home}/downloads",
392
+ posts: "#{home}/posts",
393
+ messages: "#{home}/messages",
394
+ lists: "#{home}/lists"
395
+ }
396
+ @paths.each do |key, value|
397
+ if Dir.exist?(value)
398
+ @status.say_green(key, value)
399
+ else
400
+ @status.say_red(:missing, value)
401
+ end
402
+ end
403
+ end
404
+
405
+ def find_active_account
406
+ if File.exist?(@sql_path)
407
+ @status.say_green(:found, "database accounts file")
408
+ @db = Amalgalite::Database.new(@sql_path)
409
+ if @db.nil?
410
+ @status.say_red :error, "accounts database is not readable"
411
+ return false
412
+ else
413
+ @active_account = Databases.active_account(@db)
414
+ end
415
+ else
416
+ @status.say_red :error, "accounts database is missing"
417
+ return false
418
+ end
419
+ return true
420
+ end
421
+
422
+ def find_active_tables
423
+ tables_path = @paths[:db] + "/ayadn.sqlite"
424
+ if File.exist?(tables_path)
425
+ @status.say_green(:found, "#{@handle}'s database file")
426
+ @userDB = Amalgalite::Database.new(tables_path)
427
+ if @userDB.nil?
428
+ @status.say_red :error, "#{@handle}'s database is not readable"
429
+ return false
430
+ end
431
+ else
432
+ @status.say_red :error, "#{@handle}'s database is missing"
433
+ return false
434
+ end
435
+ return true
436
+ end
437
+ end
438
+
439
+ class CheckAyadn < CheckBase
440
+
441
+ attr_accessor :response
442
+
443
+ def check
444
+ begin
445
+ @status.say_header "checking RubyGems server response"
446
+ get_response "https://rubygems.org/api/v1/gems/ayadn.json"
447
+ check_response_code
448
+ @status.say_header "checking Ayadn version"
449
+ info = JSON.parse(@response.body)
450
+ live = info["version"]
451
+ @status.say_green(:live, "version #{live}")
452
+ if live != VERSION
453
+ @status.say_red(:local, "version #{VERSION}")
454
+ @status.say { @status.say_yellow :update, "run 'gem update ayadn' to get the last version" }
455
+ else
456
+ @status.say_green(:local, "version #{VERSION}")
457
+ end
458
+ rescue JSON::ParserError => e
459
+ @status.say_error "JSON error"
460
+ @status.say_trace e
461
+ rescue Interrupt
462
+ @status.say_error "operation canceled"
463
+ exit
464
+ rescue => e
465
+ rescue_network(e)
466
+ end
467
+ end
468
+
469
+ end
470
+
471
+ end