steem-mechanize 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2752cbbde70dad7ede8aa1e11b8562f5f1c3cfc8
4
+ data.tar.gz: 827e2f15f4c373f2a1a7e62890c136afc8e96d4e
5
+ SHA512:
6
+ metadata.gz: f8c6393b5863f8a171271ba49b205bb8620a0529b94fc399e97afd5e571c1251361a53ac7429ccdd2cd2a4623f30efd07ea4094cbf0eaf838360a30cf9860b3a
7
+ data.tar.gz: 37c3053013ac22c03c46401d9ae2e19a3a2f1060d8cfa930c7798d7fd505f68cc0614324fe04052d96ef00c5ee413915d4bfaa3194281e5bd0e3002d2fb2bd6b
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,63 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ steem-mechanize (0.0.1)
5
+ mechanize (~> 2.7, >= 2.7.5)
6
+ steem-ruby (~> 0.9, >= 0.9.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ bitcoin-ruby (0.0.18)
12
+ domain_name (0.5.20180417)
13
+ unf (>= 0.0.5, < 1.0.0)
14
+ ffi (1.9.23)
15
+ hashie (3.5.7)
16
+ http-cookie (1.0.3)
17
+ domain_name (~> 0.5)
18
+ json (2.1.0)
19
+ little-plugger (1.1.4)
20
+ logging (2.2.2)
21
+ little-plugger (~> 1.1)
22
+ multi_json (~> 1.10)
23
+ mechanize (2.7.5)
24
+ domain_name (~> 0.5, >= 0.5.1)
25
+ http-cookie (~> 1.0)
26
+ mime-types (>= 1.17.2)
27
+ net-http-digest_auth (~> 1.1, >= 1.1.1)
28
+ net-http-persistent (~> 2.5, >= 2.5.2)
29
+ nokogiri (~> 1.6)
30
+ ntlm-http (~> 0.1, >= 0.1.1)
31
+ webrobots (>= 0.0.9, < 0.2)
32
+ mime-types (3.1)
33
+ mime-types-data (~> 3.2015)
34
+ mime-types-data (3.2016.0521)
35
+ mini_portile2 (2.3.0)
36
+ multi_json (1.13.1)
37
+ net-http-digest_auth (1.4.1)
38
+ net-http-persistent (2.9.4)
39
+ nokogiri (1.8.2)
40
+ mini_portile2 (~> 2.3.0)
41
+ ntlm-http (0.1.1)
42
+ rake (12.3.1)
43
+ steem-ruby (0.9.0)
44
+ bitcoin-ruby (~> 0.0, >= 0.0.18)
45
+ ffi (~> 1.9, >= 1.9.23)
46
+ hashie (~> 3.5, >= 3.5.7)
47
+ json (~> 2.1, >= 2.1.0)
48
+ logging (~> 2.2, >= 2.2.0)
49
+ unf (0.1.4)
50
+ unf_ext
51
+ unf_ext (0.0.7.5)
52
+ webrobots (0.1.2)
53
+
54
+ PLATFORMS
55
+ ruby
56
+
57
+ DEPENDENCIES
58
+ bundler (~> 1.16, >= 1.16.1)
59
+ rake (~> 12.3, >= 12.3.0)
60
+ steem-mechanize!
61
+
62
+ BUNDLED WITH
63
+ 1.16.1
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 steem-ruby
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ [![Gem Version](https://badge.fury.io/rb/steem-mechanize.svg)](https://badge.fury.io/rb/steem-mechanize)
2
+
3
+ # `steem-mechanize`
4
+
5
+ Steem Mechanize is an extension to [`steem-ruby`](https://github.com/steemit/steem-ruby) that replaces its `Net::HTTP` client with a [mechanize](https://github.com/sparklemotion/mechanize).
6
+
7
+ ## Feature
8
+
9
+ There one only feature provided by this gem: Persistent HTTP
10
+
11
+ All other functionality is identical to `steem-ruby`. This gem achieves HTTP persistence by instantiating a Mechanize Agent as a singleton and using this agent for all requests.
12
+
13
+ This is like having one dedicated browser performing all POST requests for json-rpc. For certain applications, this can represent a signifiant performance boost over what `Net::HTTP` can offer.
14
+
15
+ This gem also serves to demonstrate how easy it is to replace the default client used for performing `json-rpc` requests by `steem-ruby`. The entire feature can be reviewed here:
16
+
17
+ [`lib/steem/mechanize/rpc/mechanize_client.rb`](lib/steem/mechanize/rpc/mechanize_client.rb)
18
+
19
+ ## Getting Started
20
+
21
+ The `steem-mechanize` gem is compatible with Ruby 2.2.5 or later.
22
+
23
+ ### Install the gem for your project
24
+
25
+ *(Assuming that [Ruby is installed](https://www.ruby-lang.org/en/downloads/) on your computer, as well as [RubyGems](http://rubygems.org/pages/download))*
26
+
27
+ To install the gem on your computer, run in shell:
28
+
29
+ ```bash
30
+ gem install steem-mechanize
31
+ ```
32
+
33
+ ... then add in your code:
34
+
35
+ ```ruby
36
+ require 'steem-mechanize'
37
+ ```
38
+
39
+ To add the gem as a dependency to your project with [Bundler](http://bundler.io/), you can add this line in your Gemfile:
40
+
41
+ ```ruby
42
+ gem 'steem-mechanize'
43
+ ```
44
+
45
+ Once installed, use it just like [`steem-ruby`](https://github.com/steemit/steem-ruby).
46
+
47
+ ### Tests
48
+
49
+ * Clone the client repository into a directory of your choice:
50
+ * `git clone https://github.com/steemit/steem-mechanize.git`
51
+ * Navigate into the new folder
52
+ * `cd steem-mechanize`
53
+ * To run `threads` tests (which quickly verifies thread safety):
54
+ * `bundle exec rake test:threads`
55
+
56
+ You can also run other tests that are not part of the above `test` execution:
57
+
58
+ * To run `block_range`, which streams blocks (using `json-rpc-batch`)
59
+ * `bundle exec rake stream:block_range`
60
+
61
+ ## Contributions
62
+
63
+ Patches are welcome! Contributors are listed in the `steem-mechanize.gemspec` file. Please run the tests (`rake test`) before opening a pull request and make sure that you are passing all of them. If you would like to contribute, but don't know what to work on, check the issues list.
64
+
65
+ ## Issues
66
+
67
+ When you find issues, please report them!
68
+
69
+ ## License
70
+
71
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,119 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'steem-mechanize'
3
+
4
+ task default: 'test:threads'
5
+
6
+ desc 'Ruby console with steem-mechanize already required.'
7
+ task :console do
8
+ exec 'irb -r steem-mechanize -I ./lib'
9
+ end
10
+
11
+ namespace :test do
12
+ desc 'Tests the mechanized API using multiple threads.'
13
+ task :threads do
14
+ next if !!ENV['TEST']
15
+
16
+ threads = []
17
+ api = Steem::Api.new(url: ENV['TEST_NODE'])
18
+ database_api = Steem::DatabaseApi.new(url: ENV['TEST_NODE'])
19
+ witnesses = {}
20
+ keys = %i(created url total_missed props running_version
21
+ hardfork_version_vote hardfork_time_vote)
22
+
23
+ if defined? Thread.report_on_exception
24
+ Thread.report_on_exception = true
25
+ end
26
+
27
+ database_api.get_active_witnesses do |result|
28
+ print "Found #{result.witnesses.size} witnesses ..."
29
+
30
+ result.witnesses.each do |witness_name|
31
+ threads << Thread.new do
32
+ api.get_witness_by_account(witness_name) do |witness|
33
+ witnesses[witness.owner] = witness.map do |k, v|
34
+ [k, v] if keys.include? k.to_sym
35
+ end.compact.to_h
36
+
37
+ sbd_exchange_rate = witness[:sbd_exchange_rate]
38
+ base = sbd_exchange_rate[:base].to_f
39
+
40
+ if (quote = sbd_exchange_rate[:quote].to_f) > 0
41
+ rate = (base / quote).round(3)
42
+ witnesses[witness.owner][:sbd_exchange_rate] = rate
43
+ else
44
+ witnesses[witness.owner][:sbd_exchange_rate] = nil
45
+ end
46
+
47
+ last_sbd_exchange_update = witness[:last_sbd_exchange_update]
48
+ last_sbd_exchange_update = Time.parse(last_sbd_exchange_update + 'Z')
49
+ last_sbd_exchange_elapsed = '%.2f hours ago' % ((Time.now.utc - last_sbd_exchange_update) / 60)
50
+ witnesses[witness.owner][:last_sbd_exchange_elapsed] = last_sbd_exchange_elapsed
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ threads.each do |thread|
57
+ print '.'
58
+ thread.join
59
+ end
60
+
61
+ puts ' done!'
62
+
63
+ if threads.size != witnesses.size
64
+ puts "Bug: expected #{threads.size} witnesses, only found #{witnesses.size}."
65
+ else
66
+ puts JSON.pretty_generate witnesses rescue puts witnesses
67
+ end
68
+ end
69
+ end
70
+
71
+ namespace :stream do
72
+ desc 'Test the ability to stream a block range.'
73
+ task :block_range do
74
+ block_api = Steem::BlockApi.new(url: ENV['TEST_NODE'])
75
+ api = Steem::Api.new(url: ENV['TEST_NODE'])
76
+ last_block_num = nil
77
+ first_block_num = nil
78
+ last_timestamp = nil
79
+
80
+ loop do
81
+ api.get_dynamic_global_properties do |properties|
82
+ current_block_num = properties.last_irreversible_block_num
83
+ # First pass replays latest a random number of blocks to test chunking.
84
+ first_block_num ||= current_block_num - (rand * 200).to_i
85
+
86
+ if current_block_num >= first_block_num
87
+ range = first_block_num..current_block_num
88
+ puts "Got block range: #{range.size}"
89
+ block_api.get_blocks(block_range: range) do |block, block_num|
90
+ if block.nil?
91
+ puts "Bug: Got nil block for block_num: #{block_num}"
92
+ exit
93
+ end
94
+
95
+ current_timestamp = Time.parse(block.timestamp + 'Z')
96
+
97
+ if !!last_timestamp && block_num != last_block_num + 1
98
+ puts "Bug: Last block number was #{last_block_num} then jumped to: #{block_num}"
99
+ exit
100
+ end
101
+
102
+ if !!last_timestamp && current_timestamp < last_timestamp
103
+ puts "Bug: Went back in time. Last timestamp was #{last_timestamp}, then jumped back to #{current_timestamp}"
104
+ exit
105
+ end
106
+
107
+ puts "\t#{block_num} Timestamp: #{current_timestamp}, witness: #{block.witness}"
108
+ last_block_num = block_num
109
+ last_timestamp = current_timestamp
110
+ end
111
+
112
+ first_block_num = range.max + 1
113
+ end
114
+
115
+ sleep 3
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+ require 'steem'
3
+ require 'mechanize'
4
+
5
+ require 'steem/mechanize/version'
6
+ require 'steem/mechanize/rpc/mechanize_client'
7
+
8
+ # Here, we will monkeypatch steem-ruby to use Mechanize.
9
+ module Steem
10
+ class Api
11
+ def self.default_rpc_client_class
12
+ Steem::Mechanize::RPC::MechanizeClient
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ module Steem
2
+ module Mechanize
3
+ module RPC
4
+ class MechanizeClient < Steem::RPC::HttpClient
5
+ POST_HEADERS = Steem::RPC::HttpClient::POST_HEADERS.merge(
6
+ 'User-Agent' => Steem::Mechanize::AGENT_ID
7
+ )
8
+
9
+ def self.agent
10
+ @agent ||= ::Mechanize.new(Steem::Mechanize::AGENT_ID).tap do |agent|
11
+ agent.user_agent = Steem::Mechanize::AGENT_ID
12
+ agent.max_history = 0
13
+ agent.default_encoding = 'UTF-8'
14
+ end
15
+ end
16
+
17
+ def http_request(request)
18
+ catch :request_with_entity do; begin
19
+ self.class.agent.request_with_entity :post, url, request.body, POST_HEADERS
20
+ rescue Net::HTTP::Persistent::Error => e
21
+ @error_pipe.puts "Warning, retrying after agent reset due to: #{e}"
22
+ @agent = nil
23
+ throw :request_with_entity
24
+ end; end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ module Steem
2
+ module Mechanize
3
+ VERSION = '0.0.1'
4
+ AGENT_ID = "steem-mechanize/#{VERSION}"
5
+ end
6
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'steem/mechanize/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'steem-mechanize'
8
+ spec.version = Steem::Mechanize::VERSION
9
+ spec.authors = ['Anthony Martin']
10
+ spec.email = ['anthony@steem.com']
11
+
12
+ spec.summary = %q{Steem Mechanize Client}
13
+ spec.description = %q{Mechanized ruby client for accessing the Steem blockchain.}
14
+ spec.homepage = 'https://github.com/steem/steem-mechanize'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test)/}) }
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'bundler', '~> 1.16', '>= 1.16.1'
21
+ spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.0'
22
+
23
+ spec.add_dependency 'steem-ruby', '~> 0.9', '>= 0.9.0'
24
+ spec.add_dependency 'mechanize', '~> 2.7', '>= 2.7.5'
25
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: steem-mechanize
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Anthony Martin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.16.1
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.16'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.16.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '12.3'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 12.3.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '12.3'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 12.3.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: steem-ruby
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.9'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.9.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.9'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.9.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: mechanize
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '2.7'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 2.7.5
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.7'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 2.7.5
93
+ description: Mechanized ruby client for accessing the Steem blockchain.
94
+ email:
95
+ - anthony@steem.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files: []
99
+ files:
100
+ - Gemfile
101
+ - Gemfile.lock
102
+ - LICENSE
103
+ - README.md
104
+ - Rakefile
105
+ - lib/steem-mechanize.rb
106
+ - lib/steem/mechanize/rpc/mechanize_client.rb
107
+ - lib/steem/mechanize/version.rb
108
+ - steem-mechanize.gemspec
109
+ homepage: https://github.com/steem/steem-mechanize
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.6.14
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Steem Mechanize Client
133
+ test_files: []