pickynode 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: c2f21a70079af8acd312bcbbb122f05bdc0ca054
4
- data.tar.gz: 48fb9df7143e0a11489a1cad359a35fecafecea1
3
+ metadata.gz: d49df9c54a1dd3799f0b66b74f75f217560f283d
4
+ data.tar.gz: 5cba4b0edea26ba858cb83dd2128d4b4cc45b71d
5
5
  SHA512:
6
- metadata.gz: 9667d99ae31c13442a9145f03d638aef0d6aee68c8b7ef275a30c6f905b61f5cc4824586a966d97f7722b324faf244913442a52ec3c74a6991e3c6492af9936c
7
- data.tar.gz: 8361af0fda851ecad2af80f872bfcd87650dbd475958ea541f10aa08f588c24686cb5a7177850aef4f0521cd1e135509f5cf6accc6344a73da8e3ba0aea4c5bf
6
+ metadata.gz: 01e9aa203431912c58a97b78920c685e146f5150d0d1ee18d70999c702b17ec092bdfe480905345a1dace8318ee6fecb3c990ef3ca17c5041b5388ddad1ba52d
7
+ data.tar.gz: d09e13a8f1cb105907833dc8fa69fdff3063a6e7791d70200b72d6ad8319e5639d01da3ee1775d1ff41d81a1f1dfa036bf3108f0b8b2349f546b428ba9755df8
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ gem 'awesome_print', '~> 1.7'
7
7
  gem 'rake', '~> 12.0'
8
8
  gem 'rspec', '~> 3.6'
9
9
  gem 'rubocop', '~> 0.48'
10
+ gem 'simplecov', '~> 0.14', require: false, group: :test
10
11
  gem 'trollop', '~> 2.1'
data/Gemfile.lock CHANGED
@@ -4,6 +4,8 @@ GEM
4
4
  ast (2.3.0)
5
5
  awesome_print (1.7.0)
6
6
  diff-lcs (1.3)
7
+ docile (1.1.5)
8
+ json (2.1.0)
7
9
  parser (2.4.0.0)
8
10
  ast (~> 2.2)
9
11
  powerpack (0.1.1)
@@ -30,6 +32,11 @@ GEM
30
32
  ruby-progressbar (~> 1.7)
31
33
  unicode-display_width (~> 1.0, >= 1.0.1)
32
34
  ruby-progressbar (1.8.1)
35
+ simplecov (0.14.1)
36
+ docile (~> 1.1.0)
37
+ json (>= 1.8, < 3)
38
+ simplecov-html (~> 0.10.0)
39
+ simplecov-html (0.10.1)
33
40
  trollop (2.1.2)
34
41
  unicode-display_width (1.2.1)
35
42
 
@@ -41,6 +48,7 @@ DEPENDENCIES
41
48
  rake (~> 12.0)
42
49
  rspec (~> 3.6)
43
50
  rubocop (~> 0.48)
51
+ simplecov (~> 0.14)
44
52
  trollop (~> 2.1)
45
53
 
46
54
  RUBY VERSION
data/README.md CHANGED
@@ -45,17 +45,17 @@ pickynode --disconnect=USER_AGENT_FILTER
45
45
  ### Help:
46
46
 
47
47
  ```
48
- pickynode v0.1.1
48
+ pickynode v0.1.2
49
49
  Options:
50
50
  -a, --add=<s> Add node type
51
51
  -c, --connect=<s> Connect to node type
52
52
  -b, --ban=<s> Ban node type
53
53
  -d, --debug Debug mode
54
+ -i, --info Local node info
54
55
  -o, --output Output commands
55
- -i, --disconnect=<s> Disconnect from node type
56
+ -s, --disconnect=<s> Disconnect from node type
56
57
  -v, --version Print version and exit
57
58
  -h, --help Show this message
58
-
59
59
  ```
60
60
 
61
61
  The --add and --connect commands pull data from Bitnodes.
data/bin/pickynode CHANGED
@@ -9,6 +9,7 @@ opts = Trollop.options do
9
9
  opt :connect, 'Connect to node type', type: :string
10
10
  opt :ban, 'Ban node type', type: :string
11
11
  opt :debug, 'Debug mode'
12
+ opt :info, 'Local node info'
12
13
  opt :output, 'Output commands'
13
14
  opt :disconnect, 'Disconnect from node type', type: :string
14
15
  end
data/lib/pickynode.rb CHANGED
@@ -9,7 +9,7 @@ require 'uri'
9
9
  # Allows you to easily add/ban/connect/disconnect nodes
10
10
  # based on User Agent.
11
11
  class Pickynode
12
- VERSION = '0.1.1'
12
+ VERSION = '0.1.2'
13
13
 
14
14
  def initialize(opts = {})
15
15
  @opts = opts
@@ -50,6 +50,10 @@ class Pickynode
50
50
  ap addr_types
51
51
  end
52
52
 
53
+ def info
54
+ ap getinfo
55
+ end
56
+
53
57
  def run
54
58
  add(@opts[:add])
55
59
  connect(@opts[:connect])
@@ -57,9 +61,8 @@ class Pickynode
57
61
  ban(@opts[:ban])
58
62
  disconnect(@opts[:disconnect])
59
63
 
60
- return unless @opts.values.select { |v| v }.empty?
61
-
62
- display
64
+ info if @opts[:info]
65
+ display if @opts.values.select { |v| v }.empty?
63
66
  end
64
67
 
65
68
  def clear_cache
@@ -99,6 +102,12 @@ class Pickynode
99
102
  Net::HTTP.get(URI.parse('https://bitnodes.21.co/api/v1/snapshots/latest/'))
100
103
  end
101
104
 
105
+ def getinfo
106
+ JSON.parse(`bitcoin-cli getinfo`)
107
+ rescue JSON::ParserError
108
+ {}
109
+ end
110
+
102
111
  def getpeerinfo
103
112
  `bitcoin-cli getpeerinfo`
104
113
  end
data/pickynode.gemspec CHANGED
@@ -24,4 +24,5 @@ bitcoin nodes they connect to."
24
24
  s.add_development_dependency 'rspec', '~> 3.6'
25
25
  s.add_development_dependency 'rake', '~> 12.0'
26
26
  s.add_development_dependency 'rubocop', '~> 0.48'
27
+ s.add_development_dependency 'simplecov', '~> 0.14'
27
28
  end
data/spec/mocks.rb CHANGED
@@ -12,6 +12,22 @@ BITNODES_SNAPSHOT = <<-HEREDOC
12
12
  }
13
13
  HEREDOC
14
14
 
15
+ NODE_INFO = <<-HEREDOC
16
+ {
17
+ "version": 1020500,
18
+ "protocolversion": 70012,
19
+ "blocks": 467548,
20
+ "timeoffset": 0,
21
+ "connections": 154,
22
+ "proxy": "",
23
+ "difficulty": 559970892890.8381,
24
+ "testnet": false,
25
+ "paytxfee": 0.00000000,
26
+ "relayfee": 0.00001000,
27
+ "errors": ""
28
+ }
29
+ HEREDOC
30
+
15
31
  PEER_INFO = <<-HEREDOC
16
32
  [
17
33
  {
@@ -19,6 +19,12 @@ describe Pickynode do
19
19
  ipv6_ip => '/SecondClient/' }
20
20
  end
21
21
 
22
+ # String to simulate a json error.
23
+ let(:json_error) { 'An error occurred.' }
24
+
25
+ # Parsed information from getinfo.
26
+ let(:parsed_node_info) { JSON.parse(NODE_INFO) }
27
+
22
28
  subject { Pickynode.new(opts) }
23
29
 
24
30
  describe '.add' do
@@ -39,11 +45,18 @@ describe Pickynode do
39
45
  subject.add(false)
40
46
  subject.add(nil)
41
47
  end
48
+
49
+ it 'should recover gracefully if json is malformed' do
50
+ expect(subject).to receive(:bitnodes_snapshot).once
51
+ .and_return(json_error)
52
+ expect(subject).to_not receive(:run_cmd)
53
+ subject.add('Anything')
54
+ end
42
55
  end
43
56
 
44
57
  describe '.ban' do
45
58
  it 'should ban nodes based on user agent' do
46
- expect(subject).to receive(:getpeerinfo).once
59
+ expect(subject).to receive(:`).once
47
60
  .and_return(PEER_INFO)
48
61
  expect(URI).to receive(:parse).with('https://131.114.88.218:33422')
49
62
  .and_call_original
@@ -64,6 +77,13 @@ describe Pickynode do
64
77
  subject.ban(false)
65
78
  subject.ban(nil)
66
79
  end
80
+
81
+ it 'should recover gracefully if json is malformed' do
82
+ expect(subject).to receive(:`).once
83
+ .and_return(json_error)
84
+ expect(subject).to_not receive(:run_cmd)
85
+ subject.ban('Anything')
86
+ end
67
87
  end
68
88
 
69
89
  describe '.connect' do
@@ -84,11 +104,18 @@ describe Pickynode do
84
104
  subject.connect(false)
85
105
  subject.connect(nil)
86
106
  end
107
+
108
+ it 'should recover gracefully if json is malformed' do
109
+ expect(subject).to receive(:bitnodes_snapshot).once
110
+ .and_return(json_error)
111
+ expect(subject).to_not receive(:run_cmd)
112
+ subject.connect('Anything')
113
+ end
87
114
  end
88
115
 
89
116
  describe '.disconnect' do
90
117
  it 'should disconnect nodes based on user agent' do
91
- expect(subject).to receive(:getpeerinfo).once
118
+ expect(subject).to receive(:`).once
92
119
  .and_return(PEER_INFO)
93
120
  expect(subject).to receive(:run_cmd)
94
121
  .with(%(bitcoin-cli disconnectnode "#{ipv6_ip}"))
@@ -104,14 +131,46 @@ describe Pickynode do
104
131
  subject.disconnect(false)
105
132
  subject.disconnect(nil)
106
133
  end
134
+
135
+ it 'should recover gracefully if json is malformed' do
136
+ expect(subject).to receive(:`).once
137
+ .and_return(json_error)
138
+ expect(subject).to_not receive(:run_cmd)
139
+ subject.disconnect('Anything')
140
+ end
107
141
  end
108
142
 
109
143
  describe '.display' do
110
144
  it 'should display connected nodes' do
111
- expect(subject).to receive(:getpeerinfo).and_return(PEER_INFO)
145
+ expect(subject).to receive(:`).once
146
+ .and_return(PEER_INFO)
112
147
  expect(subject).to receive(:ap).with(node_hash).and_return(node_hash)
113
148
  expect(subject.display).to eq(node_hash)
114
149
  end
150
+
151
+ it 'should recover gracefully if json is malformed' do
152
+ expect(subject).to receive(:`).once
153
+ .and_return(json_error)
154
+ expect(subject).to receive(:ap).with({}).and_return({})
155
+ expect(subject.display).to eq({})
156
+ end
157
+ end
158
+
159
+ describe '.info' do
160
+ it 'should display local node info' do
161
+ expect(subject).to receive(:`).once
162
+ .and_return(NODE_INFO)
163
+ expect(subject).to receive(:ap).with(parsed_node_info)
164
+ .and_return(parsed_node_info)
165
+ expect(subject.info).to eq(parsed_node_info)
166
+ end
167
+
168
+ it 'should recover gracefully if json is malformed' do
169
+ expect(subject).to receive(:`).once
170
+ .and_return(json_error)
171
+ expect(subject).to receive(:ap).with({}).and_return({})
172
+ expect(subject.info).to eq({})
173
+ end
115
174
  end
116
175
 
117
176
  describe '.run' do
@@ -119,6 +178,7 @@ describe Pickynode do
119
178
  let(:opts) do
120
179
  {
121
180
  debug: true,
181
+ info: true,
122
182
  add: 'Wanted',
123
183
  connect: 'Now',
124
184
  ban: 'Nefarious',
@@ -126,10 +186,11 @@ describe Pickynode do
126
186
  }
127
187
  end
128
188
 
129
- it 'should call add, connect, ban and disconnect' do
189
+ it 'should call add, connect, ban, disconnect and info' do
130
190
  expect(subject).to receive(:bitnodes_snapshot).once
131
191
  .and_return(BITNODES_SNAPSHOT)
132
- expect(subject).to receive(:getpeerinfo).and_return(PEER_INFO)
192
+ expect(subject).to receive(:getpeerinfo).once
193
+ .and_return(PEER_INFO)
133
194
  expect(subject).to receive(:add).with(opts[:add])
134
195
  .and_call_original
135
196
  expect(subject).to receive(:connect).with(opts[:connect])
@@ -138,9 +199,24 @@ describe Pickynode do
138
199
  .and_call_original
139
200
  expect(subject).to receive(:disconnect).with(opts[:disconnect])
140
201
  .and_call_original
202
+ expect(subject).to receive(:info)
141
203
  expect(subject).to_not receive(:display)
142
204
  subject.run
143
205
  end
206
+
207
+ it 'should recover gracefully if json is malformed' do
208
+ expect(subject).to receive(:bitnodes_snapshot).at_least(1)
209
+ .and_return(json_error)
210
+ expect(subject).to receive(:getpeerinfo).at_least(1)
211
+ .and_return(json_error)
212
+ expect(subject).to receive(:`)
213
+ .and_return(json_error)
214
+ expect(subject).to receive(:info)
215
+ .and_call_original
216
+ expect(subject).to receive(:ap).with({})
217
+ expect(subject).to_not receive(:run_cmd)
218
+ subject.run
219
+ end
144
220
  end
145
221
 
146
222
  context 'without opts' do
@@ -149,12 +225,21 @@ describe Pickynode do
149
225
  end
150
226
 
151
227
  it 'should call display' do
152
- expect(subject).to receive(:getpeerinfo).once
228
+ expect(subject).to receive(:`).once
153
229
  .and_return(PEER_INFO)
154
230
  expect(subject).to receive(:ap).with(node_hash).and_return(node_hash)
155
231
  expect(subject).to receive(:display).and_call_original
156
232
  subject.run
157
233
  end
234
+
235
+ it 'should recover gracefully if json is malformed' do
236
+ expect(subject).to receive(:`).once
237
+ .and_return(json_error)
238
+ expect(subject).to_not receive(:run_cmd)
239
+ expect(subject).to_not receive(:info)
240
+ expect(subject).to receive(:ap).with({}).and_return({})
241
+ subject.run
242
+ end
158
243
  end
159
244
  end
160
245
 
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require File.join('bundler', 'setup')
4
+
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_filter '/spec/'
8
+ end
9
+
4
10
  require 'rspec'
5
11
  require 'pickynode'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pickynode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Ellithorpe
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.48'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.14'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.14'
83
97
  description: Some people are picky about the bitcoin nodes they connect to.
84
98
  email: quest@mac.com
85
99
  executables: