steem_api 1.1.0 → 1.1.1rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -1
  3. data/Rakefile +286 -0
  4. data/lib/steem_api.rb +4 -11
  5. data/lib/steem_api/models/account.rb +5 -0
  6. data/lib/steem_api/models/comment.rb +32 -1
  7. data/lib/steem_api/models/sql_base.rb +12 -3
  8. data/lib/steem_api/models/token.rb +5 -0
  9. data/lib/steem_api/models/transaction.rb +9 -0
  10. data/lib/steem_api/models/tx/account_create.rb +0 -2
  11. data/lib/steem_api/models/tx/account_recover.rb +0 -1
  12. data/lib/steem_api/models/tx/account_update.rb +0 -1
  13. data/lib/steem_api/models/tx/account_witness_proxy.rb +13 -2
  14. data/lib/steem_api/models/tx/account_witness_vote.rb +0 -1
  15. data/lib/steem_api/models/tx/claim_reward_balance.rb +0 -1
  16. data/lib/steem_api/models/tx/comment.rb +0 -1
  17. data/lib/steem_api/models/tx/comments_option.rb +0 -1
  18. data/lib/steem_api/models/tx/convert.rb +0 -1
  19. data/lib/steem_api/models/tx/custom.rb +0 -1
  20. data/lib/steem_api/models/tx/custom/follow.rb +48 -0
  21. data/lib/steem_api/models/tx/custom/reblog.rb +22 -0
  22. data/lib/steem_api/models/tx/custom/witness.rb +11 -0
  23. data/lib/steem_api/models/tx/delegate_vesting_share.rb +0 -1
  24. data/lib/steem_api/models/tx/delete_comment.rb +0 -1
  25. data/lib/steem_api/models/tx/escrow_approve.rb +0 -1
  26. data/lib/steem_api/models/tx/escrow_dispute.rb +0 -1
  27. data/lib/steem_api/models/tx/escrow_release.rb +0 -1
  28. data/lib/steem_api/models/tx/escrow_transfer.rb +0 -1
  29. data/lib/steem_api/models/tx/feed.rb +0 -1
  30. data/lib/steem_api/models/tx/limit_order.rb +0 -1
  31. data/lib/steem_api/models/tx/pow.rb +0 -1
  32. data/lib/steem_api/models/tx/transfer.rb +0 -1
  33. data/lib/steem_api/models/tx/vote.rb +0 -1
  34. data/lib/steem_api/models/tx/withdraw.rb +0 -1
  35. data/lib/steem_api/models/tx/withdraw_vesting_route.rb +0 -1
  36. data/lib/steem_api/models/tx/witness_update.rb +1 -2
  37. data/lib/steem_api/version.rb +1 -1
  38. data/steem_api.gemspec +3 -1
  39. data/steem_source_docs.md +12167 -0
  40. metadata +30 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5bb607cdb89e34897fe95f443ef0831880cde0f0
4
- data.tar.gz: a8642d4dd208c9f70aa81966e13fca95a7b5da49
3
+ metadata.gz: 226138e01ea81d5cb0f30c17c61405883d85a3b2
4
+ data.tar.gz: f6e57a8f7914fe3448c833e2de93baf24e60c10a
5
5
  SHA512:
6
- metadata.gz: 63fb423252dbad1ac0474e27854bccffe7684a6da263d9d74979d87cfdba45c258639dbbe068131f97d5fc24f5e9d02452c71aae7b009a3daec0be11a197b38e
7
- data.tar.gz: 19ae69fa09ae91ea7704788076de0c71ae38e02eca695bd8210235b6054640f51c2e67fa57efc3d0dee32d25cd97ab6194385a609055c9d4ed2709ec9d9602fc
6
+ metadata.gz: e57af3a0b625088c75bd91004e1603125998ccdd8dc4cfce62635c648a63d48ea9de380367ccfed5089b7402dee1d2ecc716e543e2348a127a410aeb50076d35
7
+ data.tar.gz: 37c6aa938f78a826ee7f106289b884d002eb2d2335fe3ffb2a23f3403cc15b1bacb889e3563b32bb0b01360be0b6d45447843e9b982e56d7a7c4468613e3499d
data/README.md CHANGED
@@ -1,13 +1,22 @@
1
1
  # SteemApi
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/steem_api.svg)](https://badge.fury.io/rb/steem_api)
4
+
3
5
  ### How To Use (Rails 4+)
4
6
  - Add Gem to Gemfile
5
- * `gem 'steem_api', '~> 1.0'`
7
+ * `gem 'steem_api', '~> 1.1'`
6
8
  - Bundle Install Gems
7
9
  * `bundle install`
10
+
11
+ ### How to Subscribe
12
+
13
+ As of 2018-01-23, [SteemSQL is moving to a monthly subscription model](https://steemit.com/steemsql/@arcange/steemsql-is-moving-to-a-monthly-subscription-model). To use this gem, you must subscribe to @steemsql and store the credentials as environment variables.
8
14
 
9
15
  ### How To Use (Standalone)
10
16
  - `gem install steem_api`
17
+ - export STEEMSQL_HOST=<your steemsql host>
18
+ - export STEEMSQL_USERNAME=<your steemsql username>
19
+ - export STEEMSQL_PASSWORD=<your steemsql password>
11
20
  - `irb`
12
21
  - `require 'steem_api'`
13
22
  - `SteemApi::Comment.last`
@@ -19,6 +28,41 @@
19
28
  - Token
20
29
  - Transaction
21
30
 
31
+ ### Followers
32
+
33
+ How to query today's followers:
34
+
35
+ ```ruby
36
+ followers = SteemApi::Tx::Custom::Follow
37
+ followers.following(:ned).today.count
38
+ ```
39
+
40
+ ### Resteem
41
+
42
+ How to query today's "resteems":
43
+
44
+ ```ruby
45
+ reblogs = SteemApi::Tx::Custom::Reblog
46
+ reblogs.author(:netuoso).today.count
47
+ ```
48
+
49
+ ### Account Witness Proxy
50
+
51
+ How to query current accounts that are actively using a proxy:
52
+
53
+ ```ruby
54
+ proxied = SteemApi::Tx::AccountWitnessProxy.active('netuoso')
55
+ proxied.pluck(:account)
56
+ ```
57
+
58
+ ### Appiations
59
+
60
+ How to query comments by application:
61
+
62
+ ```ruby
63
+ comments = SteemApi::Comment.app('esteem').where(author: 'good-karma')
64
+ ```
65
+
22
66
  ### How To Contribute
23
67
  - Fork this repo
24
68
  - Branch off Master and make your changes
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
+ require 'steem_api'
4
+ require 'awesome_print'
3
5
 
4
6
  Rake::TestTask.new(:test) do |t|
5
7
  t.libs << "test"
@@ -8,3 +10,287 @@ Rake::TestTask.new(:test) do |t|
8
10
  end
9
11
 
10
12
  task :default => :test
13
+
14
+ task :console do
15
+ exec "irb -r steem_api -I ./lib"
16
+ end
17
+
18
+ task :build do
19
+ exec 'gem build steem_api.gemspec'
20
+ end
21
+
22
+ task :push do
23
+ exec "gem push steem_api-#{SteemApi::VERSION}.gem"
24
+ end
25
+
26
+ desc 'Lists sum of transfers grouped by date, from, and to.'
27
+ task :transfers, [:minimum_amount, :symbol, :days_ago] do |t, args|
28
+ now = Time.now.utc
29
+ minimum_amount = (args[:minimum_amount] || '1000000').to_f
30
+ symbol = (args[:symbol] || 'STEEM').upcase
31
+ after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
32
+
33
+ # Only type: transfer; ignore savings, vestings
34
+ transfers = SteemApi::Tx::Transfer.where(type: 'transfer')
35
+ transfers = transfers.where('amount > ?', minimum_amount)
36
+ transfers = transfers.where('amount_symbol = ?', symbol)
37
+ transfers = transfers.where('timestamp > ?', after_timestamp)
38
+ transfers = transfers.group('CAST(timestamp AS DATE)', :from, :to)
39
+ transfers = transfers.order('cast_timestamp_as_date ASC')
40
+
41
+ puts "Daily transfer sum over #{'%.3f' % minimum_amount} #{symbol} since #{after_timestamp} ..."
42
+ ap transfers.sum(:amount)
43
+ end
44
+
45
+ desc 'Lists apps grouped by date, app/version.'
46
+ task :apps, [:app, :days_ago] do |t, args|
47
+ now = Time.now.utc
48
+ app = args[:app]
49
+ after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
50
+
51
+ comments = SteemApi::Comment.normalized_json
52
+ comments = comments.app(app) if !!app
53
+ comments = comments.where('created > ?', after_timestamp)
54
+ comments = comments.group('CAST(created AS DATE)', "JSON_VALUE(json_metadata, '$.app')")
55
+ comments = comments.order('cast_created_as_date ASC')
56
+
57
+ matching = " matching \"#{app}\"" if !!app
58
+ puts "Daily app#{matching} count since #{after_timestamp} ..."
59
+ ap comments.count(:all)
60
+ end
61
+
62
+ desc 'Do all crosschecks of given account.'
63
+ task :crosscheck, [:account] do |t, args|
64
+ account = args[:account]
65
+
66
+ Rake::Task["crosscheck:powerdowns"].invoke(account)
67
+ Rake::Task["crosscheck:powerups"].invoke(account)
68
+ Rake::Task["crosscheck:transfers"].invoke(account)
69
+ Rake::Task["crosscheck:vesting_from"].invoke(account)
70
+ Rake::Task["crosscheck:vesting_to"].invoke(account)
71
+ end
72
+
73
+ namespace :crosscheck do
74
+ desc 'List of accounts grouped by transfer count crosschecked by memo of given account.'
75
+ task :transfers, [:account] do |t, args|
76
+ exchanges = %w(bittrex poloniex openledger blocktrades)
77
+ account = args[:account]
78
+
79
+ if account.nil? || account == ''
80
+ puts 'Account name required.'
81
+ exit
82
+ elsif exchanges.include? account
83
+ puts 'That procedure is not recommended.'
84
+ exit
85
+ end
86
+
87
+ all = SteemApi::Tx::Transfer.where(type: 'transfer')
88
+ transfers = all.where(to: exchanges)
89
+ transfers = if account =~ /%/
90
+ table = SteemApi::Tx::Transfer.arel_table
91
+ transfers.where(table[:from].matches(account))
92
+ else
93
+ transfers.where(from: account)
94
+ end
95
+ crosscheck_transfers = all.where(memo: transfers.select(:memo))
96
+
97
+ if transfers.none?
98
+ puts "No match."
99
+ else
100
+ from = transfers.pluck(:from).uniq.join(', ')
101
+ puts "Accounts grouped by transfer count using common memos as #{from} on common exchanges ..."
102
+ ap crosscheck_transfers.group(:from).order('count_all').count(:all)
103
+ end
104
+ end
105
+
106
+ desc 'List of accounts grouped by vesting transfers from a given account'
107
+ task :vesting_from, [:account] do |t, args|
108
+ account = args[:account]
109
+
110
+ if account.nil? || account == ''
111
+ puts 'Account name required.'
112
+ exit
113
+ end
114
+
115
+ table = SteemApi::Tx::Transfer.arel_table
116
+ all = SteemApi::Tx::Transfer.where(type: 'transfer_to_vesting')
117
+ transfers = all.where(table[:from].not_eq(:to))
118
+ transfers = transfers.where.not(to: '')
119
+ transfers = if account =~ /%/
120
+ table = SteemApi::Tx::Transfer.arel_table
121
+ transfers.where(table[:from].matches(account))
122
+ else
123
+ transfers.where(from: account)
124
+ end
125
+
126
+ if transfers.none?
127
+ puts "No match."
128
+ else
129
+ from = transfers.pluck(:from).uniq.join(', ')
130
+ puts "Accounts grouped by vesting transfer count from #{from} ..."
131
+ ap transfers.group(:to).order('count_all').count(:all)
132
+ end
133
+ end
134
+
135
+ desc 'List of accounts grouped by vesting transfers to a given account'
136
+ task :vesting_to, [:account] do |t, args|
137
+ account = args[:account]
138
+
139
+ if account.nil? || account == ''
140
+ puts 'Account name required.'
141
+ exit
142
+ end
143
+
144
+ table = SteemApi::Tx::Transfer.arel_table
145
+ all = SteemApi::Tx::Transfer.where(type: 'transfer_to_vesting')
146
+ transfers = all.where(table[:from].not_eq(table[:to]))
147
+ transfers = transfers.where.not(to: '')
148
+ transfers = if account =~ /%/
149
+ table = SteemApi::Tx::Transfer.arel_table
150
+ transfers.where(table[:to].matches(account))
151
+ else
152
+ transfers.where(to: account)
153
+ end
154
+
155
+ if transfers.none?
156
+ puts "No match."
157
+ else
158
+ from = transfers.pluck(:to).uniq.join(', ')
159
+ puts "Accounts grouped by vesting transfer count to #{from} ..."
160
+ ap transfers.group(:from).order('count_all').count(:all)
161
+ end
162
+ end
163
+
164
+ desc 'List of accounts grouped by powerdown sums crosschecked by given account.'
165
+ task :powerdowns, [:account] do |t, args|
166
+ account = args[:account]
167
+
168
+ if account.nil? || account == ''
169
+ puts 'Account name required.'
170
+ exit
171
+ end
172
+
173
+ table = SteemApi::Vo::FillVestingWithdraw.arel_table
174
+ all = SteemApi::Vo::FillVestingWithdraw.where(table[:from_account].not_eq(table[:to_account]))
175
+ powerdowns = if account =~ /%/
176
+ all.where(table[:from_account].matches(account))
177
+ else
178
+ all.where(from_account: account)
179
+ end
180
+
181
+ if powerdowns.none?
182
+ puts "No match."
183
+ else
184
+ from = powerdowns.pluck(:from_account).uniq.join(', ')
185
+ puts "Powerdowns grouped by sum from #{from} ..."
186
+ ap powerdowns.group(:to_account).
187
+ order('sum_try_parse_replace_withdrawn_vests_as_float').
188
+ sum("TRY_PARSE(REPLACE(withdrawn, ' VESTS', '') AS float)")
189
+ end
190
+ end
191
+
192
+ desc 'List of accounts grouped by powerup sums crosschecked by given account.'
193
+ task :powerups, [:account] do |t, args|
194
+ account = args[:account]
195
+
196
+ if account.nil? || account == ''
197
+ puts 'Account name required.'
198
+ exit
199
+ end
200
+
201
+ table = SteemApi::Vo::FillVestingWithdraw.arel_table
202
+ all = SteemApi::Vo::FillVestingWithdraw.where(table[:from_account].not_eq(table[:to_account]))
203
+ powerups = if account =~ /%/
204
+ all.where(table[:to_account].matches(account))
205
+ else
206
+ all.where(to_account: account)
207
+ end
208
+
209
+ if powerups.none?
210
+ puts "No match."
211
+ else
212
+ to = powerups.pluck(:to_account).uniq.join(', ')
213
+ puts "Powerups grouped by sum to #{to} ..."
214
+ ap powerups.group(:from_account).
215
+ order('sum_try_parse_replace_withdrawn_vests_as_float').
216
+ sum("TRY_PARSE(REPLACE(withdrawn, ' VESTS', '') AS float)")
217
+ end
218
+ end
219
+ end
220
+
221
+ namespace :rewards do
222
+ desc 'Lists author rewards grouped by date.'
223
+ task :author, [:symbol, :days_ago] do |t, args|
224
+ now = Time.now.utc
225
+ symbol = (args[:symbol] || 'SBD').upcase
226
+ after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
227
+
228
+ rewards = SteemApi::Vo::AuthorReward
229
+ rewards = rewards.where('timestamp > ?', after_timestamp)
230
+ rewards = rewards.group('CAST(timestamp AS DATE)')
231
+ rewards = rewards.order('cast_timestamp_as_date ASC')
232
+
233
+ puts "Daily author reward #{symbol} sum grouped by date since #{after_timestamp} ..."
234
+
235
+ case symbol
236
+ when 'SBD' then ap rewards.sum(:sdb_payout)
237
+ when 'STEEM' then ap rewards.sum(:steem_payout)
238
+ when 'VESTS' then ap rewards.sum(:vesting_payout)
239
+ when 'MVESTS'
240
+ ap rewards.sum('vesting_payout / 1000000')
241
+ else; puts "Unknown symbol: #{symbol}. Symbols supported: SBD, STEEM, VESTS, MVESTS"
242
+ end
243
+ end
244
+
245
+ desc 'Lists curation rewards grouped by date.'
246
+ task :curation, [:symbol, :days_ago] do |t, args|
247
+ now = Time.now.utc
248
+ symbol = (args[:symbol] || 'MVESTS').upcase
249
+ after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
250
+
251
+ rewards = SteemApi::Vo::CurationReward
252
+ rewards = rewards.where('timestamp > ?', after_timestamp)
253
+ rewards = rewards.group('CAST(timestamp AS DATE)')
254
+ rewards = rewards.order('cast_timestamp_as_date ASC')
255
+
256
+ puts "Daily curation reward #{symbol} sum grouped by date since #{after_timestamp} ..."
257
+
258
+ case symbol
259
+ when 'VESTS'
260
+ ap rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float)")
261
+ when 'MVESTS'
262
+ ap rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float) / 1000000")
263
+ else; puts "Unknown symbol: #{symbol}. Symbols supported: VESTS, MVESTS"
264
+ end
265
+ end
266
+ end
267
+
268
+ desc 'Lists proxied grouped by month.'
269
+ task :proxied, [:days_ago] do |t, args|
270
+ now = Time.now.utc
271
+ after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
272
+
273
+ proxied = SteemApi::Tx::AccountWitnessProxy
274
+ proxied = proxied.where('timestamp > ?', after_timestamp)
275
+ proxied = proxied.group("FORMAT(timestamp, 'yyyy-MM')", :proxy)
276
+ proxied = proxied.order('format_timestamp_yyyy_mm ASC')
277
+
278
+ puts "Daily proxied grouped by month since #{after_timestamp} ..."
279
+
280
+ ap proxied.count(:all)
281
+ end
282
+
283
+ # Doesn't look like this table exists.
284
+ # desc 'List conversion SBD conversion request sums grouped by day.'
285
+ # task :convert, [:days_ago] do |t, args|
286
+ # now = Time.now.utc
287
+ # after_timestamp = now - ((args[:days_ago] || '3.5').to_f * 86400)
288
+ #
289
+ # converts = SteemApi::Vo::FillConvertRequest
290
+ # converts = converts.where('timestamp > ?', after_timestamp)
291
+ # converts = converts.group('CAST(timestamp AS DATE)')
292
+ # converts = converts.order('cast_timestamp_as_date ASC')
293
+ #
294
+ # puts "Daily conversion requests failled sum grouped by date since #{after_timestamp} ..."
295
+ # ap converts.sum(:amount)
296
+ # end
@@ -34,6 +34,10 @@ require "steem_api/models/tx/withdraw"
34
34
  require "steem_api/models/tx/withdraw_vesting_route"
35
35
  require "steem_api/models/tx/witness_update"
36
36
 
37
+ require "steem_api/models/tx/custom/follow"
38
+ require "steem_api/models/tx/custom/witness"
39
+ require "steem_api/models/tx/custom/reblog"
40
+
37
41
  require "steem_api/models/vo/author_reward"
38
42
  require "steem_api/models/vo/curation_reward"
39
43
  require "steem_api/models/vo/fill_convert_request"
@@ -43,15 +47,4 @@ require "steem_api/models/vo/interest"
43
47
  require "steem_api/models/vo/shutdown_witness"
44
48
 
45
49
  module SteemApi
46
- module Tx
47
- def tx
48
- SteemApi::Transaction.find_by(tx_id: self.tx_id)
49
- end
50
- end
51
-
52
- class Transaction
53
- def block
54
- SteemApi::Block.find(block_num)
55
- end
56
- end
57
50
  end
@@ -3,6 +3,11 @@ module SteemApi
3
3
 
4
4
  self.table_name = :Accounts
5
5
 
6
+ scope :before, lambda { |before, field = 'created'| where("#{field} < ?", before) }
7
+ scope :after, lambda { |after, field = 'created'| where("#{field} > ?", after) }
8
+ scope :today, -> { after(1.day.ago) }
9
+ scope :yesterday, -> { before(1.day.ago).after(2.days.ago) }
10
+
6
11
  def witness?
7
12
  self.witness_votes != "[]"
8
13
  end
@@ -2,7 +2,38 @@ module SteemApi
2
2
  class Comment < SteemApi::SqlBase
3
3
 
4
4
  self.table_name = :Comments
5
-
5
+
6
+ scope :before, lambda { |before, field = 'created'| where("#{field} < ?", before) }
7
+ scope :after, lambda { |after, field = 'created'| where("#{field} > ?", after) }
8
+ scope :today, -> { after(1.day.ago) }
9
+ scope :yesterday, -> { before(1.day.ago).after(2.days.ago) }
10
+
11
+ scope :normalized_json, -> { where("json_metadata LIKE '{%}'") }
12
+
13
+ scope :app, lambda { |app|
14
+ normalized_json.where("JSON_VALUE(json_metadata, '$.app') LIKE ?", "#{app}/%")
15
+ }
16
+
17
+ scope :app_version, lambda { |version|
18
+ normalized_json.where("JSON_VALUE(json_metadata, '$.app') LIKE ?", "%/#{version}")
19
+ }
20
+
21
+ scope :decorate_metadata, -> {
22
+ previous_select = if all.select_values.none?
23
+ Arel.star
24
+ else
25
+ all.select_values
26
+ end
27
+
28
+ r = normalized_json.select(previous_select)
29
+
30
+ %w(tags image links app format).each do |key|
31
+ r = r.select("JSON_VALUE(json_metadata, '$.#{key}') AS metadata_#{key}")
32
+ end
33
+
34
+ r
35
+ }
36
+
6
37
  def self.find_by_author(user)
7
38
  self.where(author: user)
8
39
  end