steem_api 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b012ea3331a8c114577548112d1cad319f6dc922ed6c7c72547c112f1d69f97d
4
- data.tar.gz: cbca2f46ef2902a5ab6c2e5605d034b12252a129090833079c21dc0e246ae94d
3
+ metadata.gz: d808e15bb5bd8b10b70af26c21af568880d3d8e25d892fe98ad777e1b9da1464
4
+ data.tar.gz: 1e7813932ab8c9568b8885260409aa1731ea0a31acefec85c2e01529c3b6d558
5
5
  SHA512:
6
- metadata.gz: a14aded1056a590678a659e00f16109278a3811b06e1b22ad74b5571d5804ea08c5d0034e6db874c1709c6139fb86019ac34fc62670a062808914c3dee0a9f56
7
- data.tar.gz: e47cb2770f955868967c0995bba4ac4ea1008a583bba6cb2665b6e2335a0bacf0d194f94e665fca84f83ae5f4a1341dae0b5bb8bca35afe767613cf3783ea4dd
6
+ metadata.gz: a61f2735cf47ccecf244af806d5cccb72779c3ccfc8bcd524cf4c0e2385f6ec1f9d0d1af1426c33824b562a856b9647d402fb8ab94304308642c6e6ca31022e4
7
+ data.tar.gz: e40ea12b512db4aab6d7b2a33651445442b6020633f106dae9ce8acbaeabcee10d87968ca8c75da926cdf91eedf3e171f268799e17a9b7b459cc78cab2badb43
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'pry'
4
+
3
5
  # Specify your gem's dependencies in steem_api.gemspec
4
6
  gemspec
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
  require 'steem_api'
4
4
  require 'awesome_print'
5
+ require 'pry'
5
6
 
6
7
  Rake::TestTask.new(:test) do |t|
7
8
  t.libs << 'test'
@@ -76,6 +77,39 @@ namespace :created do
76
77
  ap customs
77
78
  puts "# Total custom_json_operation: #{customs.values.sum}"
78
79
  end
80
+
81
+ desc 'Lists comment_operations count grouped by author and date.'
82
+ task :comments, [:author, :days_ago, :min_count] do |t, args|
83
+ now = Time.now.utc
84
+ author = args[:author]
85
+ after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
86
+ min_count = (args[:min_count] || 1000).to_i
87
+
88
+ comments = SteemApi::Tx::Comment.all
89
+
90
+ if !!author || author == '%'
91
+ unless author == '%'
92
+ comments = comments.where(author: author)
93
+ end
94
+ elsif author =~ /.*%.*/
95
+ comments = comments.where('author LIKE ?', author)
96
+ end
97
+
98
+ comments = comments.where('timestamp > ?', after_timestamp)
99
+ comments = comments.group('CAST(timestamp AS DATE)', :author)
100
+ comments = comments.order('cast_timestamp_as_date ASC')
101
+
102
+ comments = comments.count
103
+
104
+ comments = comments.map do |k, v|
105
+ [k, v] if v >= min_count
106
+ end.compact.to_h
107
+
108
+ puts "# Daily creation count by #{author.nil? ? 'all authors' : author} since #{after_timestamp} ..."
109
+ ap comments
110
+ puts "# Total authors: #{comments.keys.uniq.size}"
111
+ puts "# Total comments: #{comments.values.sum}"
112
+ end
79
113
  end
80
114
 
81
115
  desc 'Lists sum of transfers grouped by date, from, and to.'
@@ -97,6 +131,22 @@ task :transfers, [:minimum_amount, :symbol, :days_ago] do |t, args|
97
131
  ap transfers.sum(:amount)
98
132
  end
99
133
 
134
+ desc 'Lists sum of delegations grouped by year and from.'
135
+ task :delegations, [:minimum_amount, :days_ago] do |t, args|
136
+ now = Time.now.utc
137
+ minimum_amount = (args[:minimum_amount] || '1000000').to_f
138
+ after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
139
+
140
+ delegations = SteemApi::Tx::DelegateVestingShare.where('vesting_shares > ?', minimum_amount)
141
+ delegations = delegations.where('timestamp > ?', after_timestamp)
142
+ delegations = delegations.group("FORMAT(timestamp, 'yyyy')", :delegator)
143
+ delegations = delegations.order('format_timestamp_yyyy ASC')
144
+
145
+ puts "Daily delegation sum over #{'%.3f' % minimum_amount} since #{after_timestamp} ..."
146
+ ap delegations.count(:vesting_shares).map{|k, v| [k[1], v] if v > 50}.compact.to_h
147
+ # ap delegations.sum(:vesting_shares)
148
+ end
149
+
100
150
  desc 'Lists sum of powered up grouped by date, from, and to.'
101
151
  task :powerup, [:minimum_amount, :symbol, :days_ago, :not_to_self] do |t, args|
102
152
  now = Time.now.utc
@@ -216,38 +266,55 @@ task :app_names, [:app, :days_ago] do |t, args|
216
266
  end
217
267
 
218
268
  desc 'Do all crosschecks of given account.'
219
- task :crosscheck, [:account] do |t, args|
220
- account = args[:account]
221
-
222
- Rake::Task["crosscheck:powerdowns"].invoke(account)
223
- Rake::Task["crosscheck:powerups"].invoke(account)
224
- Rake::Task["crosscheck:transfers"].invoke(account)
225
- Rake::Task["crosscheck:vesting_from"].invoke(account)
226
- Rake::Task["crosscheck:vesting_to"].invoke(account)
269
+ task :crosscheck, [:account, :after_timestamp] do |t, args|
270
+ account_name = args[:account]
271
+ after_timestamp = args[:after_timestamp]
272
+
273
+ abort 'Account name required.' if account_name.nil? || account_name == ''
274
+
275
+ if after_timestamp.nil? || after_timestamp == ''
276
+ account = SteemApi::Account.find_by(name: account_name)
277
+
278
+ abort "No account found: #{account_name}" if account.nil?
279
+ end
280
+
281
+ Rake::Task["crosscheck:powerdowns"].invoke(account_name, after_timestamp)
282
+ Rake::Task["crosscheck:powerups"].invoke(account_name, after_timestamp)
283
+ Rake::Task["crosscheck:transfers"].invoke(account_name, after_timestamp)
284
+ Rake::Task["crosscheck:vesting_from"].invoke(account_name, after_timestamp)
285
+ Rake::Task["crosscheck:vesting_to"].invoke(account_name, after_timestamp)
227
286
  end
228
287
 
229
288
  namespace :crosscheck do
230
289
  desc 'List of accounts grouped by transfer count crosschecked by memo of given account.'
231
- task :transfers, [:account] do |t, args|
290
+ task :transfers, [:account, :after_timestamp] do |t, args|
232
291
  exchanges = %w(bittrex poloniex openledger blocktrades deepcrypto8 gopax
233
292
  binanceexchange teambitwala changelly hitbtc-exchange korbit roomofsatoshi
234
293
  shapeshiftio)
235
- account = args[:account]
236
-
237
- if account.nil? || account == ''
238
- puts 'Account name required.'
239
- exit
240
- elsif exchanges.include? account
241
- puts 'That procedure is not recommended.'
242
- exit
294
+ account_name = args[:account]
295
+ after_timestamp = args[:after_timestamp]
296
+
297
+ if account_name.nil? || account_name == ''
298
+ abort 'Account name required.'
299
+ elsif exchanges.include? account_name
300
+ abort 'That procedure is not recommended.'
301
+ end
302
+
303
+ if after_timestamp.nil? || after_timestamp == ''
304
+ account = SteemApi::Account.find_by(name: account_name)
305
+
306
+ abort "No account found: #{account_name}" if account.nil?
307
+
308
+ after_timestamp = account.created
243
309
  end
244
310
 
245
311
  all = SteemApi::Tx::Transfer.where(type: 'transfer')
246
312
  transfers = all.where.not(memo: '')
313
+ transfers = transfers.where('timestamp >= ?', after_timestamp)
247
314
  transfers = transfers.where(to: exchanges)
248
315
  transfers = if account =~ /%/
249
316
  table = SteemApi::Tx::Transfer.arel_table
250
- transfers.where(table[:from].matches(account))
317
+ transfers.where(table[:from].matches(account_name))
251
318
  else
252
319
  transfers.where(from: account)
253
320
  end
@@ -263,23 +330,30 @@ namespace :crosscheck do
263
330
  end
264
331
 
265
332
  desc 'List of accounts grouped by vesting transfers from a given account'
266
- task :vesting_from, [:account] do |t, args|
267
- account = args[:account]
333
+ task :vesting_from, [:account, :after_timestamp] do |t, args|
334
+ account_name = args[:account]
335
+ after_timestamp = args[:after_timestamp]
336
+
337
+ abort 'Account name required.' if account_name.nil? || account_name == ''
268
338
 
269
- if account.nil? || account == ''
270
- puts 'Account name required.'
271
- exit
339
+ if after_timestamp.nil? || after_timestamp == ''
340
+ account = SteemApi::Account.find_by(name: account_name)
341
+
342
+ abort "No account found: #{account_name}" if account.nil?
343
+
344
+ after_timestamp = account.created
272
345
  end
273
346
 
274
347
  table = SteemApi::Tx::Transfer.arel_table
275
348
  all = SteemApi::Tx::Transfer.where(type: 'transfer_to_vesting')
276
349
  transfers = all.where(table[:from].not_eq(:to))
350
+ transfers = transfers.where('timestamp >= ?', after_timestamp)
277
351
  transfers = transfers.where.not(to: '')
278
352
  transfers = if account =~ /%/
279
353
  table = SteemApi::Tx::Transfer.arel_table
280
- transfers.where(table[:from].matches(account))
354
+ transfers.where(table[:from].matches(account_name))
281
355
  else
282
- transfers.where(from: account)
356
+ transfers.where(from: account_name)
283
357
  end
284
358
 
285
359
  if transfers.none?
@@ -292,23 +366,30 @@ namespace :crosscheck do
292
366
  end
293
367
 
294
368
  desc 'List of accounts grouped by vesting transfers to a given account'
295
- task :vesting_to, [:account] do |t, args|
296
- account = args[:account]
369
+ task :vesting_to, [:account, :after_timestamp] do |t, args|
370
+ account_name = args[:account]
371
+ after_timestamp = args[:after_timestamp]
372
+
373
+ abort 'Account name required.' if account_name.nil? || account_name == ''
297
374
 
298
- if account.nil? || account == ''
299
- puts 'Account name required.'
300
- exit
375
+ if after_timestamp.nil? || after_timestamp == ''
376
+ account = SteemApi::Account.find_by(name: account_name)
377
+
378
+ abort "No account found: #{account_name}" if account.nil?
379
+
380
+ after_timestamp = account.created
301
381
  end
302
382
 
303
383
  table = SteemApi::Tx::Transfer.arel_table
304
384
  all = SteemApi::Tx::Transfer.where(type: 'transfer_to_vesting')
305
385
  transfers = all.where(table[:from].not_eq(table[:to]))
386
+ transfers = transfers.where('timestamp >= ?', after_timestamp)
306
387
  transfers = transfers.where.not(to: '')
307
388
  transfers = if account =~ /%/
308
389
  table = SteemApi::Tx::Transfer.arel_table
309
- transfers.where(table[:to].matches(account))
390
+ transfers.where(table[:to].matches(account_name))
310
391
  else
311
- transfers.where(to: account)
392
+ transfers.where(to: account_name)
312
393
  end
313
394
 
314
395
  if transfers.none?
@@ -321,22 +402,30 @@ namespace :crosscheck do
321
402
  end
322
403
 
323
404
  desc 'List of accounts grouped by powerdown sums crosschecked by given account.'
324
- task :powerdowns, [:account] do |t, args|
325
- account = args[:account]
405
+ task :powerdowns, [:account, :after_timestamp] do |t, args|
406
+ account_name = args[:account]
407
+ after_timestamp = args[:after_timestamp]
408
+
409
+ abort 'Account name required.' if account_name.nil? || account_name == ''
326
410
 
327
- if account.nil? || account == ''
328
- puts 'Account name required.'
329
- exit
411
+ if after_timestamp.nil? || after_timestamp == ''
412
+ account = SteemApi::Account.find_by(name: account_name)
413
+
414
+ abort "No account found: #{account_name}" if account.nil?
415
+
416
+ after_timestamp = account.created
330
417
  end
331
418
 
332
419
  table = SteemApi::Vo::FillVestingWithdraw.arel_table
333
420
  all = SteemApi::Vo::FillVestingWithdraw.where(table[:from_account].not_eq(table[:to_account]))
334
421
  powerdowns = if account =~ /%/
335
- all.where(table[:from_account].matches(account))
422
+ all.where(table[:from_account].matches(account_name))
336
423
  else
337
- all.where(from_account: account)
424
+ all.where(from_account: account_name)
338
425
  end
339
426
 
427
+ powerdowns = powerdowns.where('timestamp >= ?', after_timestamp)
428
+
340
429
  if powerdowns.none?
341
430
  puts "No match."
342
431
  else
@@ -349,22 +438,30 @@ namespace :crosscheck do
349
438
  end
350
439
 
351
440
  desc 'List of accounts grouped by powerup sums crosschecked by given account.'
352
- task :powerups, [:account] do |t, args|
353
- account = args[:account]
441
+ task :powerups, [:account, :after_timestamp] do |t, args|
442
+ account_name = args[:account]
443
+ after_timestamp = args[:after_timestamp]
444
+
445
+ abort 'Account name required.' if account_name.nil? || account_name == ''
354
446
 
355
- if account.nil? || account == ''
356
- puts 'Account name required.'
357
- exit
447
+ if after_timestamp.nil? || after_timestamp == ''
448
+ account = SteemApi::Account.find_by(name: account_name)
449
+
450
+ abort "No account found: #{account_name}" if account.nil?
451
+
452
+ after_timestamp = account.created
358
453
  end
359
454
 
360
455
  table = SteemApi::Vo::FillVestingWithdraw.arel_table
361
456
  all = SteemApi::Vo::FillVestingWithdraw.where(table[:from_account].not_eq(table[:to_account]))
362
457
  powerups = if account =~ /%/
363
- all.where(table[:to_account].matches(account))
458
+ all.where(table[:to_account].matches(account_name))
364
459
  else
365
- all.where(to_account: account)
460
+ all.where(to_account: account_name)
366
461
  end
367
462
 
463
+ powerups = powerups.where('timestamp >= ?', after_timestamp)
464
+
368
465
  if powerups.none?
369
466
  puts "No match."
370
467
  else
@@ -377,6 +474,23 @@ namespace :crosscheck do
377
474
  end
378
475
  end
379
476
 
477
+ namespace :count do
478
+ desc 'Count transactions of type (default comment) grouped by date.'
479
+ task :transactions, [:type, :days_ago] do |t, args|
480
+ now = Time.now.utc
481
+ type = args[:type] || 'comment'
482
+ after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
483
+
484
+ trxs = SteemApi::Transaction.where('expiration > ?', after_timestamp)
485
+ trxs = trxs.where("[Transactions].[type] = ?", type)
486
+ trxs = trxs.group('CAST([Transactions].[expiration] AS DATE)')
487
+ trxs = trxs.order('cast_transactions_expiration_as_date ASC')
488
+ trxs = trxs.count
489
+
490
+ ap trxs
491
+ end
492
+ end
493
+
380
494
  namespace :rewards do
381
495
  desc 'Lists author rewards grouped by date.'
382
496
  task :author, [:symbol, :days_ago, :author] do |t, args|
@@ -408,7 +522,11 @@ namespace :rewards do
408
522
  when 'VESTS' then rewards.sum(:vesting_payout)
409
523
  when 'MVESTS'
410
524
  rewards.sum('vesting_payout / 1000000')
411
- else; puts "Unknown symbol: #{symbol}. Symbols supported: SBD, STEEM, VESTS, MVESTS"
525
+ when 'SP'
526
+ rewards.sum("vesting_payout / 1000000 * #{SteemApi::DynamicGlobalProperties.steem_per_mvest.to_f}")
527
+ when 'USD'
528
+ rewards.sum("vesting_payout / 1000000 * #{SteemApi::DynamicGlobalProperties.usd_per_mvest.to_f}")
529
+ else; puts "Unknown symbol: #{symbol}. Symbols supported: SBD, STEEM, VESTS, MVESTS, SP, USD"
412
530
  end
413
531
 
414
532
  ap rewards
@@ -417,16 +535,25 @@ namespace :rewards do
417
535
  end
418
536
 
419
537
  desc 'Lists curation rewards grouped by date.'
420
- task :curation, [:symbol, :days_ago] do |t, args|
538
+ task :curation, [:symbol, :days_ago, :curator] do |t, args|
421
539
  now = Time.now.utc
422
540
  symbol = (args[:symbol] || 'MVESTS').upcase
423
541
  after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
424
-
542
+ curator = args[:curator]
543
+
425
544
  rewards = SteemApi::Vo::CurationReward
426
545
  rewards = rewards.where('timestamp > ?', after_timestamp)
427
546
  rewards = rewards.group('CAST(timestamp AS DATE)')
428
547
  rewards = rewards.order('cast_timestamp_as_date ASC')
429
548
 
549
+ if !!curator
550
+ if curator =~ /%/
551
+ rewards = rewards.where("curator LIKE ?", curator)
552
+ else
553
+ rewards = rewards.where(curator: curator)
554
+ end
555
+ end
556
+
430
557
  puts "Daily curation reward #{symbol} sum grouped by date since #{after_timestamp} ..."
431
558
 
432
559
  case symbol
@@ -434,7 +561,12 @@ namespace :rewards do
434
561
  ap rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float)")
435
562
  when 'MVESTS'
436
563
  ap rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float) / 1000000")
437
- else; puts "Unknown symbol: #{symbol}. Symbols supported: VESTS, MVESTS"
564
+ when 'SP'
565
+ steem_per_mvest = dgpo.total_vesting_fund_steem / (dgpo.total_vesting_shares / 1e6)
566
+ ap rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float) / 1000000 * #{SteemApi::DynamicGlobalProperties.steem_per_mvest.to_f}")
567
+ when 'USD'
568
+ ap rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float) / 1000000 * #{SteemApi::DynamicGlobalProperties.usd_per_mvest.to_f}")
569
+ else; puts "Unknown symbol: #{symbol}. Symbols supported: VESTS, MVESTS, SP, USD"
438
570
  end
439
571
  end
440
572
  end
@@ -492,32 +624,77 @@ task :claimed, [:account_name, :days_ago, :symbol] do |t, args|
492
624
  puts "# Total claimed #{symbol}: #{claims.values.sum}"
493
625
  end
494
626
 
495
- task :balance, [:party_a, :party_b, :symbol] do |t, args|
627
+ desc "Total balance of transfers from party a to party b."
628
+ task :balance, [:party_a, :party_b, :symbol, :days_ago] do |t, args|
496
629
  party_a = args[:party_a]
497
630
  party_b = args[:party_b]
498
631
  symbol = args[:symbol].upcase
632
+ days_ago = args[:days_ago]
499
633
 
500
- balance_a = SteemApi::Tx::Transfer.where(to: party_a, from: party_b, amount_symbol: symbol).sum(:amount).to_f
501
- balance_b = SteemApi::Tx::Transfer.where(to: party_b, from: party_a, amount_symbol: symbol).sum(:amount).to_f
634
+ balance_a = SteemApi::Tx::Transfer.where(to: party_a, from: party_b, amount_symbol: symbol)
635
+ balance_a = balance_a.after(days_ago.to_f.days.ago) if !!days_ago
636
+ balance_a = balance_a.sum(:amount).to_f
637
+
638
+ balance_b = SteemApi::Tx::Transfer.where(to: party_b, from: party_a, amount_symbol: symbol)
639
+ balance_b = balance_b.after(days_ago.to_f.days.ago) if !!days_ago
640
+ balance_b = balance_b.sum(:amount).to_f
502
641
 
503
642
  puts "#{party_a}: %.3f #{symbol}, difference: %.3f #{symbol}" % [balance_a, (balance_a - balance_b)]
504
643
  puts "#{party_b}: %.3f #{symbol}, difference: %.3f #{symbol}" % [balance_b, (balance_b - balance_a)]
505
644
  end
506
645
 
507
- # Doesn't look like this table exists.
508
- # desc 'List conversion SBD conversion request sums grouped by day.'
509
- # task :convert, [:days_ago] do |t, args|
510
- # now = Time.now.utc
511
- # after_timestamp = now - ((args[:days_ago] || '3.5').to_f * 86400)
512
- #
513
- # converts = SteemApi::Vo::FillConvertRequest
514
- # converts = converts.where('timestamp > ?', after_timestamp)
515
- # converts = converts.group('CAST(timestamp AS DATE)')
516
- # converts = converts.order('cast_timestamp_as_date ASC')
517
- #
518
- # puts "Daily conversion requests failled sum grouped by date since #{after_timestamp} ..."
519
- # ap converts.sum(:amount)
520
- # end
646
+ desc 'Lists downvotes cast by follower aginst following.'
647
+ task :follow_downvote, [:follower] do |t, args|
648
+ follower = args[:follower]
649
+ follows = SteemApi::Follower.where(follower: follower)
650
+ downvotes = SteemApi::Tx::Vote.where(voter: follower, author: follows.select(:following)).
651
+ where('weight < 0').
652
+ order(:timestamp)
653
+
654
+ puts downvotes.pluck("CONCAT(weight / 100.0, ' %: ', 'https://steemit.com/@', author, '/', permlink)")
655
+ end
656
+
657
+ desc 'List conversion SBD conversion request sums grouped by day.'
658
+ task :convert, [:direction, :days_ago, :segment] do |t, args|
659
+ now = Time.now.utc
660
+ direction = (args[:direction] || 'in').downcase.to_sym
661
+ after_timestamp = now - ((args[:days_ago] || '90').to_f * 86400)
662
+ segment = (args[:segment] || 'daily').downcase.to_sym
663
+
664
+ converts = SteemApi::Vo::FillConvertRequest
665
+ converts = converts.where('timestamp > ?', after_timestamp)
666
+ converts = converts.where("TRY_PARSE(REPLACE(amount_in, ' SBD', '') AS float) > 0")
667
+ converts = converts.where("TRY_PARSE(REPLACE(amount_out, ' STEEM', '') AS float) > 0")
668
+
669
+ case segment
670
+ when :daily
671
+ converts = converts.group('CAST(timestamp AS DATE)')
672
+ converts = converts.order('cast_timestamp_as_date ASC')
673
+ when :monthly
674
+ converts = converts.group("FORMAT(timestamp, 'yyyy-MM')")
675
+ converts = converts.order('format_timestamp_yyyy_mm ASC')
676
+ else
677
+ raise "Unknown segment: #{direction}"
678
+ end
679
+
680
+
681
+ case direction
682
+ when :in
683
+ puts "#{segment.capitalize} conversion requests filled (in) sum grouped by date since #{after_timestamp} ..."
684
+ ap converts.sum("TRY_PARSE(REPLACE(amount_in, ' SBD', '') AS float)")
685
+ when :out
686
+ puts "#{segment.capitalize} conversion requests filled (out) sum grouped by date since #{after_timestamp} ..."
687
+ ap converts.sum("TRY_PARSE(REPLACE(amount_out, ' STEEM', '') AS float)")
688
+ when :ratio
689
+ puts "#{segment.capitalize} conversion requests filled (STEEM ratio) sum grouped by date since #{after_timestamp} ..."
690
+ ap converts.average("TRY_PARSE(REPLACE(amount_out, ' STEEM', '') AS float) / TRY_PARSE(REPLACE(amount_in, ' SBD', '') AS float)")
691
+ when :inverted_ratio
692
+ puts "#{segment.capitalize} conversion requests filled (SBD ratio) sum grouped by date since #{after_timestamp} ..."
693
+ ap converts.average("TRY_PARSE(REPLACE(amount_in, ' SBD', '') AS float) / TRY_PARSE(REPLACE(amount_out, ' STEEM', '') AS float)")
694
+ else
695
+ raise "Unknown direction: #{direction}"
696
+ end
697
+ end
521
698
 
522
699
  desc 'Build a new version of the steem_api gem.'
523
700
  task :build do
@@ -36,6 +36,7 @@ require "steem_api/models/tx/feed"
36
36
  require "steem_api/models/tx/limit_order"
37
37
  require "steem_api/models/tx/pow"
38
38
  require "steem_api/models/tx/transfer"
39
+ require "steem_api/models/tx/update_proposal_vote"
39
40
  require "steem_api/models/tx/vote"
40
41
  require "steem_api/models/tx/withdraw"
41
42
  require "steem_api/models/tx/withdraw_vesting_route"
@@ -44,6 +45,7 @@ require "steem_api/models/tx/witness_update"
44
45
  require "steem_api/models/tx/custom/follow"
45
46
  require "steem_api/models/tx/custom/witness"
46
47
  require "steem_api/models/tx/custom/reblog"
48
+ require "steem_api/models/tx/custom/community"
47
49
 
48
50
  require "steem_api/models/vo/author_reward"
49
51
  require "steem_api/models/vo/comment_benefactor_reward"
@@ -57,6 +59,8 @@ require "steem_api/models/vo/liquidity_reward"
57
59
  require "steem_api/models/vo/producer_reward"
58
60
  require "steem_api/models/vo/return_vesting_delegation"
59
61
  require "steem_api/models/vo/shutdown_witness"
62
+ require "steem_api/models/vo/sps_fund"
63
+ require "steem_api/models/vo/proposal_pay"
60
64
 
61
65
  module SteemApi
62
66
  end
@@ -8,7 +8,7 @@ module SteemApi
8
8
  scope :today, -> { after(1.day.ago) }
9
9
  scope :yesterday, -> { before(1.day.ago).after(2.days.ago) }
10
10
 
11
- scope :normalized_json, -> { where("json_metadata LIKE '{%}'") }
11
+ scope :normalized_json, -> { where("json_metadata LIKE '{%}' AND ISJSON(json_metadata) > 0") }
12
12
 
13
13
  scope :app, lambda { |app|
14
14
  normalized_json.where("JSON_VALUE(json_metadata, '$.app') LIKE ?", "#{app}/%")
@@ -18,6 +18,10 @@ module SteemApi
18
18
  normalized_json.where("JSON_VALUE(json_metadata, '$.app') LIKE ?", "%/#{version}")
19
19
  }
20
20
 
21
+ scope :tagged, lambda { |tag|
22
+ normalized_json.where("? IN (SELECT value FROM OPENJSON(json_metadata,'$.tags'))", tag)
23
+ }
24
+
21
25
  scope :decorate_metadata, -> {
22
26
  previous_select = if all.select_values.none?
23
27
  Arel.star
@@ -1,8 +1,19 @@
1
+ require 'open-uri'
2
+
1
3
  module SteemApi
2
4
  class DynamicGlobalProperties < SteemApi::SqlBase
3
5
 
4
6
  self.table_name = :DynamicGlobalProperties
5
7
 
8
+ def self.steem_per_mvest
9
+ dgpo = first
10
+ dgpo.total_vesting_fund_steem / (dgpo.total_vesting_shares / 1e6)
11
+ end
12
+
13
+ def self.usd_per_mvest
14
+ prices = JSON[open('https://postpromoter.net/api/prices').read]
15
+ (SteemApi::DynamicGlobalProperties.steem_per_mvest * prices.fetch('steem_price'))
16
+ end
6
17
  end
7
18
  end
8
19
 
@@ -1,3 +1,5 @@
1
+ require 'steem'
2
+
1
3
  module SteemApi
2
4
  class Transaction < SteemApi::SqlBase
3
5
 
@@ -13,13 +15,31 @@ module SteemApi
13
15
  scope :yesterday, -> { before(1.day.ago).after(2.days.ago) }
14
16
 
15
17
  scope :type, lambda { |type| where(type: type) }
18
+ scope :trx_id, lambda { |trx_id|
19
+ url = "https://anyx.io/v1/account_history_api/get_transaction?id=#{trx_id}"
20
+ trx = JSON[open(url).read]
21
+ expiration = Time.parse(trx.fetch('expiration') + 'Z')
22
+ block_num = trx.fetch('block_num')
23
+ transaction_num = trx.fetch('transaction_num') + 1
24
+
25
+ where(expiration: expiration, block_num: block_num, transaction_num: transaction_num)
26
+ }
27
+
28
+ def trx_id
29
+ @block_api ||= Steem::BlockApi.new
30
+ @trx_id ||= @block_api.get_block(block_num: block_num) do |result|
31
+ return nil if result.nil? || result.block.nil?
32
+
33
+ result.block.transaction_ids[transaction_num - 1]
34
+ end
35
+ end
16
36
 
17
37
  # So you have a Transaction#tx_id and you want to know what the operation was
18
38
  # that lead to it. Well, that's tricky because all of the ops are in their
19
39
  # own tables. This method will (slowly) try to find the appropriate table.
20
40
  def op
21
41
  retries = 0
22
- puts type
42
+
23
43
  # Here, we map the type to class name, if supported. Most of them can be
24
44
  # mapped automatically, e.g. "vote" => "Vote" but some types share tables
25
45
  # with one another. We also use timestamps to narrow the search
@@ -0,0 +1,32 @@
1
+ module SteemApi
2
+ module Tx
3
+ class Custom::Community < SteemApi::Tx::Custom
4
+ default_scope { where(tid: :community) }
5
+
6
+ scope :normalized_json, -> { where("ISJSON(json_metadata) > 0") }
7
+ scope :op, lambda { |op| normalized_json.where("JSON_VALUE(json_metadata, '$[0]') = ?", op) }
8
+ scope :community, lambda { |community| normalized_json.where("JSON_VALUE(json_metadata, '$[1].community') = ?", community) }
9
+ scope :role, lambda { |role| normalized_json.where("JSON_VALUE(json_metadata, '$[1].role') = ?", role) }
10
+ scope :language, lambda { |language| normalized_json.where("JSON_VALUE(json_metadata, '$[1].language') = ?", language) }
11
+ scope :nsfw, lambda { |nsfw = true| normalized_json.where("JSON_VALUE(json_metadata, '$[1].is_nsfw') = ?", nsfw) }
12
+ scope :account, lambda { |account|
13
+ account = [account].flatten
14
+ normalized_json.where("required_auths IN(?) OR required_posting_auths IN(?) OR JSON_VALUE(json_metadata, '$[1].account') IN(?)", account, account, account)
15
+ }
16
+ scope :permlink, lambda { |permlink|
17
+ normalized_json.where("JSON_VALUE(json_metadata, '$[1].permlink') = ?", permlink)
18
+ }
19
+ scope :slug, lambda { |slug|
20
+ normalized_json.where("JSON_VALUE(json_metadata, '$[1].account') = ? AND JSON_VALUE(json_metadata, '$[1].permlink') = ?", *slug.split('/'))
21
+ }
22
+
23
+ def self.ops
24
+ distinct.normalized_json.pluck(Arel.sql "JSON_VALUE(json_metadata, '$[0]') AS ops")
25
+ end
26
+
27
+ def payload
28
+ JSON[json_metadata][1] rescue nil
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ module SteemApi
2
+ module Tx
3
+ class UpdateProposalVote < SteemApi::SqlBase
4
+ belongs_to :voter_record, foreign_key: :account, primary_key: :voter, class_name: 'SteemApi::Account'
5
+
6
+ self.table_name = :TxUpdateProposalVotes
7
+
8
+ scope :proposal, lambda { |id, invert = false|
9
+ if !!invert
10
+ where("? NOT IN (SELECT value FROM OPENJSON(proposal_ids,'$'))", id)
11
+ else
12
+ where("? IN (SELECT value FROM OPENJSON(proposal_ids,'$'))", id)
13
+ end
14
+ }
15
+
16
+ scope :approve, lambda {|approve = true| where(approve: approve)}
17
+ end
18
+ end
19
+ end
20
+
21
+ # Structure
22
+ #
23
+ # SteemApi::Tx::Vote(
24
+ # ID: integer,
25
+ # tx_id: integer,
26
+ # voter: varchar,
27
+ # proposal_ids: varchar,
28
+ # approve: boolean,
29
+ # extensions: varchar,
30
+ # timestamp: datetime
31
+ # )
@@ -0,0 +1,20 @@
1
+ module SteemApi
2
+ module Vo
3
+ class ProposalPay < SteemApi::SqlBase
4
+
5
+ self.table_name = :VOProposalPay
6
+
7
+ end
8
+ end
9
+ end
10
+
11
+ # Structure
12
+ #
13
+ # SteemApi::Vo::ProposalPay(
14
+ # ID: integer,
15
+ # block_num: integer,
16
+ # timestamp: datetime,
17
+ # payment: money,
18
+ # trx_id: varchar,
19
+ # op_in_trx: integer
20
+ # )
@@ -0,0 +1,18 @@
1
+ module SteemApi
2
+ module Vo
3
+ class SpsFund < SteemApi::SqlBase
4
+
5
+ self.table_name = :VOSpsFund
6
+
7
+ end
8
+ end
9
+ end
10
+
11
+ # Structure
12
+ #
13
+ # SteemApi::Vo::SpsFund(
14
+ # ID: integer,
15
+ # block_num: integer,
16
+ # timestamp: datetime,
17
+ # additional_funds: money
18
+ # )
@@ -1,3 +1,3 @@
1
1
  module SteemApi
2
- VERSION = '1.1.3'
2
+ VERSION = '1.1.4'
3
3
  end
@@ -38,4 +38,5 @@ Gem::Specification.new do |spec|
38
38
  spec.add_runtime_dependency "activerecord-sqlserver-adapter", [">= 4", "< 6"]
39
39
  spec.add_runtime_dependency "activesupport", [">= 4", "< 6"]
40
40
  spec.add_runtime_dependency 'awesome_print', '~> 1.7', '>= 1.7.0'
41
+ spec.add_runtime_dependency 'steem-ruby', '~> 0.9', '>= 0.9.4'
41
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steem_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Chaney (netuoso)
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-03-04 00:00:00.000000000 Z
12
+ date: 2019-11-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -313,6 +313,26 @@ dependencies:
313
313
  - - ">="
314
314
  - !ruby/object:Gem::Version
315
315
  version: 1.7.0
316
+ - !ruby/object:Gem::Dependency
317
+ name: steem-ruby
318
+ requirement: !ruby/object:Gem::Requirement
319
+ requirements:
320
+ - - "~>"
321
+ - !ruby/object:Gem::Version
322
+ version: '0.9'
323
+ - - ">="
324
+ - !ruby/object:Gem::Version
325
+ version: 0.9.4
326
+ type: :runtime
327
+ prerelease: false
328
+ version_requirements: !ruby/object:Gem::Requirement
329
+ requirements:
330
+ - - "~>"
331
+ - !ruby/object:Gem::Version
332
+ version: '0.9'
333
+ - - ">="
334
+ - !ruby/object:Gem::Version
335
+ version: 0.9.4
316
336
  description: Rails compatible gem that provides full DB connection and models to SteemSQL.com
317
337
  email:
318
338
  - andrewc@pobox.com
@@ -350,6 +370,7 @@ files:
350
370
  - lib/steem_api/models/tx/comments_option.rb
351
371
  - lib/steem_api/models/tx/convert.rb
352
372
  - lib/steem_api/models/tx/custom.rb
373
+ - lib/steem_api/models/tx/custom/community.rb
353
374
  - lib/steem_api/models/tx/custom/follow.rb
354
375
  - lib/steem_api/models/tx/custom/reblog.rb
355
376
  - lib/steem_api/models/tx/custom/witness.rb
@@ -363,6 +384,7 @@ files:
363
384
  - lib/steem_api/models/tx/limit_order.rb
364
385
  - lib/steem_api/models/tx/pow.rb
365
386
  - lib/steem_api/models/tx/transfer.rb
387
+ - lib/steem_api/models/tx/update_proposal_vote.rb
366
388
  - lib/steem_api/models/tx/vote.rb
367
389
  - lib/steem_api/models/tx/withdraw.rb
368
390
  - lib/steem_api/models/tx/withdraw_vesting_route.rb
@@ -377,8 +399,10 @@ files:
377
399
  - lib/steem_api/models/vo/interest.rb
378
400
  - lib/steem_api/models/vo/liquidity_reward.rb
379
401
  - lib/steem_api/models/vo/producer_reward.rb
402
+ - lib/steem_api/models/vo/proposal_pay.rb
380
403
  - lib/steem_api/models/vo/return_vesting_delegation.rb
381
404
  - lib/steem_api/models/vo/shutdown_witness.rb
405
+ - lib/steem_api/models/vo/sps_fund.rb
382
406
  - lib/steem_api/models/witness.rb
383
407
  - lib/steem_api/version.rb
384
408
  - steem_api.gemspec