steem_api 1.1.3 → 1.1.4

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 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