steem-mechanize 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []