yourkarma 0.0.2 → 1.0.0

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
  SHA1:
3
- metadata.gz: efebe6dd64ed479530537b7eae43cfdfbee14d29
4
- data.tar.gz: e65c0cd273366bfeed6310346d07586ca66008d0
3
+ metadata.gz: c4fd1140147e2153167f9d50d43bd133628d1e7f
4
+ data.tar.gz: bf4950dbd9c676d8a536aa14e595f455b78b6de1
5
5
  SHA512:
6
- metadata.gz: e77919d76e388ff2b72a3cc3728f242ff0addffc3e532d3d8228a5e7e9a48c5ebc0fcfe1d113910c616eef0be35b0ef835dbe0aa6ef0121b7a6e82c0a3ae1e97
7
- data.tar.gz: 65a8347b3033de673bac4ea35e9b3020820744a2ffd49637e14d57a174c1b7df11ff5208d346e6801b8d4751512074463e6d21b2f166911615a2d635dbeddfe6
6
+ metadata.gz: e8b2c5c5854c76d2e0edc77596bb58ef1f181cf21390ee9b69b3184df2bc5cb9927ee6e86c31a219e543409bf6b7f85cc3841bd991728374a0d5f6837318eb84
7
+ data.tar.gz: 3587886adcaaa2b23da14db1a396cc79a811c733447d71d09ca04ac52b602460a59e11a5aa7d447bbfeb2c1a7a4d215179dca1a2b6ca8755ecbe216834de1681
data/README.md CHANGED
@@ -13,11 +13,7 @@ Determine connectivity, battery and connection speed for your device.
13
13
 
14
14
  ## TODO
15
15
 
16
- - Bar charts for connection speed and battery
17
- - Option to poll until connected
18
- - Display available data from yourkarma.com/dashboard
19
- - Display updates/news from yourkarma.com/dashboard
20
- - Display connected user count
16
+ See [GitHub issues](https://github.com/gsterndale/yourkarma/issues) for a list of desired features and bug fixes.
21
17
 
22
18
  ## Contributing
23
19
 
@@ -8,8 +8,9 @@ module YourKarma
8
8
  class ConnectionError < StandardError; end
9
9
 
10
10
  HTTP_ERRORS = [Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
11
- Errno::ETIMEDOUT, EOFError, Net::HTTPBadResponse,
12
- Net::HTTPHeaderSyntaxError, Net::ProtocolError, SocketError]
11
+ Errno::ENETUNREACH, Errno::ETIMEDOUT, EOFError,
12
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
13
+ Net::ProtocolError, SocketError]
13
14
 
14
15
  DEFAULT_OPTIONS = {
15
16
  timeout: 10,
@@ -25,9 +26,10 @@ module YourKarma
25
26
  def benchmark
26
27
  uri = URI(options[:benchmark])
27
28
  Timeout::timeout(options[:timeout]) do
28
- return Benchmark.realtime do
29
+ duration = Benchmark.realtime do
29
30
  Net::HTTP.get_response(uri)
30
31
  end
32
+ return duration / options[:timeout].to_f
31
33
  end
32
34
  rescue *HTTP_ERRORS => e
33
35
  raise ConnectionError
data/lib/yourkarma/cli.rb CHANGED
@@ -21,15 +21,34 @@ module YourKarma
21
21
  end
22
22
 
23
23
  def run
24
- reporter = Reporter.new(options)
25
- attrs = Client.new(options).get
26
- device = Device.new(attrs)
27
- benchmark = Benchmarker.new(options).benchmark
24
+ client = Client.new(options)
25
+ benchmarker = Benchmarker.new(options)
26
+ reporter = Reporter.new(options)
27
+ reporter.report_header
28
+ iterations = options[:iterations] || Float::INFINITY
29
+ code = 1
30
+ (1..iterations).each do
31
+ begin
32
+ code = run_once(client, benchmarker, reporter)
33
+ rescue Interrupt
34
+ break
35
+ end
36
+ end
37
+ reporter.report_quit(code)
38
+ end
39
+
40
+ private
41
+
42
+ def run_once(client, benchmarker, reporter)
43
+ begin
44
+ attrs = client.get
45
+ reporter.report_progress
46
+ device = Device.new(attrs)
47
+ benchmark = benchmarker.benchmark
48
+ rescue Client::ConnectionError, Benchmarker::ConnectionError
49
+ reporter.report_error
50
+ end
28
51
  reporter.report_on(device, benchmark)
29
- rescue Client::ConnectionError => e
30
- reporter.report_connectivity_failure e.message
31
- rescue Benchmarker::ConnectionError
32
- reporter.report_benchmark_failure_on(device)
33
52
  end
34
53
 
35
54
  class Reporter
@@ -42,34 +61,108 @@ module YourKarma
42
61
  self.options = DEFAULT_OPTIONS.merge(options)
43
62
  end
44
63
 
64
+ def report_header
65
+ write "| Connect | Speed | Battery | Charging | Bandwidth |\n"
66
+ write "+---------+-------+---------+----------+-----------+\n"
67
+ end
68
+
69
+ def report_progress
70
+ write '.' if reported?
71
+ end
72
+
73
+ def report_error
74
+ write '*' if reported?
75
+ end
76
+
45
77
  def report_on(device, benchmark)
46
- write "Connected to '#{device.ssid}' and online!"
47
- if options[:verbose]
48
- ceil = (benchmark * 10).ceil / 10.0
49
- write "Benchmark took less than #{ceil} seconds."
50
- end
51
- 0
78
+ write options[:tail] ? "\n" : "\r" if reported?
79
+ @reported = true
80
+ write [
81
+ '',
82
+ pad( 9, connect(device, benchmark)),
83
+ pad( 7, speed(device, benchmark)),
84
+ pad( 9, battery(device, benchmark)),
85
+ pad(10, charging(device, benchmark)),
86
+ pad(11, bandwidth(device, benchmark)),
87
+ " "
88
+ ].join "|"
89
+ status_code(device, benchmark)
52
90
  end
53
91
 
54
- def report_connectivity_failure(message)
55
- write "Not connected to a Karma hotspot."
56
- write message if options[:verbose]
57
- 1
92
+ def report_quit(code)
93
+ write "\n"
94
+ code || 1
58
95
  end
59
96
 
60
- def report_benchmark_failure_on(device)
61
- if device.valid_ipaddress?
62
- write "Connected to '#{device.ssid}' and online, but the tubes are slow!"
97
+ private
98
+
99
+ def reported?
100
+ !!@reported
101
+ end
102
+
103
+ def connect(device, benchmark)
104
+ return '' unless device
105
+ case
106
+ when benchmark
107
+ "-=≡"
108
+ when device.valid_ipaddress?
109
+ "-="
63
110
  else
64
- write "Connected to '#{device.ssid}' and acquiring IP address."
111
+ "-"
65
112
  end
66
- 1
67
113
  end
68
114
 
69
- private
115
+ def speed(device, benchmark)
116
+ unless benchmark
117
+ return device && device.valid_ipaddress? ? ":(" : ":X"
118
+ end
119
+ case benchmark * 100
120
+ when 0..20
121
+ "(⌐■_■)" # ":0"
122
+ when 20..40
123
+ ":)"
124
+ when 40..70
125
+ ":|"
126
+ else
127
+ "(ಠ_ಠ)" # ":["
128
+ end
129
+ end
130
+
131
+ def battery(device, benchmark)
132
+ return '[?????}' unless device && device.batterypower
133
+ percent = device.batterypower.to_f / 100.0
134
+ length = 5
135
+ tics = (length * percent).floor
136
+ "[#{ '#' * tics}#{ ' ' * (length - tics)}}"
137
+ end
138
+
139
+ def charging(device, benchmark)
140
+ return '?' unless device
141
+ device.charging ? "=D----" : "X"
142
+ end
143
+
144
+ def bandwidth(device, benchmark)
145
+ "1.3 GB"
146
+ end
147
+
148
+ def status_code(device, benchmark)
149
+ device && benchmark ? 0 : 3
150
+ end
151
+
152
+ def pad(size, meat)
153
+ meat ||= ''
154
+ space = size - meat.size
155
+ left = (space.to_f / 2).ceil
156
+ right = (space.to_f / 2).floor
157
+ [
158
+ ' ' * left,
159
+ meat,
160
+ ' ' * right
161
+ ].join
162
+ end
70
163
 
71
164
  def write(string)
72
- options[:io].puts string
165
+ options[:io].print string
73
166
  end
74
167
  end
75
168
 
@@ -78,7 +171,9 @@ module YourKarma
78
171
  end
79
172
 
80
173
  DEFAULT_OPTIONS = {
81
- verbose: false
174
+ verbose: false,
175
+ poll: true,
176
+ tail: false
82
177
  }
83
178
 
84
179
  def parse(arguments)
@@ -99,6 +194,16 @@ module YourKarma
99
194
  opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
100
195
  options[:verbose] = true
101
196
  end
197
+ opts.on('-c', '--count=COUNT', 'Poll COUNT times', Integer) do |c|
198
+ options[:iterations] = c
199
+ end
200
+ opts.on('-p', '--[no-]poll', 'Continually poll') do |p|
201
+ options[:poll] = p
202
+ options[:iterations] = 1 unless p
203
+ end
204
+ opts.on('--[no-]tail', 'Tail log') do |t|
205
+ options[:tail] = t
206
+ end
102
207
  opts.on('-h', '--help', 'Display this screen') do
103
208
  raise InvalidOption, opts
104
209
  end
@@ -113,83 +218,3 @@ module YourKarma
113
218
  end
114
219
  end
115
220
  end
116
-
117
- # require 'json'
118
- # require 'uri'
119
- # require 'net/http'
120
- # require 'timeout'
121
- # require 'benchmark'
122
- # require 'pp'
123
- #
124
- # uri = URI('http://hotspot.yourkarma.com/api/status.json')
125
- #
126
- # VERBOSE = true
127
- # VERY_VERBOSE = false
128
- # TIMEOUT = 10
129
- #
130
- # def failure(message, exception, context = nil)
131
- # if VERBOSE
132
- # puts exception.class if VERY_VERBOSE
133
- # puts exception
134
- # puts context if context && VERY_VERBOSE
135
- # end
136
- # puts message
137
- # exit 1
138
- # end
139
- #
140
- # HTTP_ERRORS = [Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
141
- # Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
142
- # SocketError]
143
- #
144
- # begin
145
- # response = nil
146
- # Timeout::timeout(TIMEOUT) do
147
- # response = Net::HTTP.get_response(uri)
148
- # end
149
- # parsed = JSON::load(response.body)
150
- # rescue Timeout::Error => e
151
- # failure "Request to Karma hotspot timed out.", e
152
- # rescue *HTTP_ERRORS => e
153
- # failure "Not connected to a Karma hotspot.", e
154
- # rescue JSON::ParserError
155
- # failure "Unexpected response from #{uri}.", e, parsed
156
- # end
157
- #
158
- # begin
159
- # message = "Network not connected."
160
- #
161
- # device = parsed.fetch "device"
162
- # wifi = device.fetch "wifiinterface"
163
- # ssid = wifi.fetch "ssid"
164
- #
165
- # message = "Unable to determine battery status."
166
- #
167
- # charging = device.fetch "charging"
168
- # battery = device.fetch "batterypower"
169
- # print "Battery #{battery}%. "
170
- # puts charging ? "Charging." : "Not charging."
171
- #
172
- # message = "Connected to '#{ssid}', but WAN IP address is not assigned."
173
- #
174
- # wan = device.fetch "waninterface"
175
- # ip_address = wan.fetch "ipaddress"
176
- # rescue KeyError => e
177
- # failure message, e, parsed
178
- # end
179
- #
180
- # begin
181
- # benchmark = nil
182
- # Timeout::timeout(TIMEOUT) do
183
- # benchmark = Benchmark.realtime do
184
- # Net::HTTP.get_response(URI('https://www.google.com'))
185
- # end
186
- # end
187
- # benchmark = (benchmark * 10).ceil / 10.0
188
- # rescue TimeoutError => e
189
- # failure "Connected to '#{ssid}' and online, but the tubes are slow!", e, parsed
190
- # rescue *HTTP_ERRORS => e
191
- # failure "Connected to '#{ssid}' and WAN IP address has be assigned, but request to Google failed.", e, parsed
192
- # end
193
- #
194
- # puts "Connected to '#{ssid}' and online!"
195
- # puts "Request to Google took less than #{benchmark} seconds." if VERBOSE
@@ -8,8 +8,9 @@ module YourKarma
8
8
  class BadResponseError < StandardError; end
9
9
 
10
10
  HTTP_ERRORS = [Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
11
- Errno::ETIMEDOUT, EOFError, Net::HTTPBadResponse,
12
- Net::HTTPHeaderSyntaxError, Net::ProtocolError, SocketError]
11
+ Errno::ENETUNREACH, Errno::ETIMEDOUT, EOFError,
12
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
13
+ Net::ProtocolError, SocketError]
13
14
 
14
15
  DEFAULT_OPTIONS = {
15
16
  timeout: 10,
@@ -28,6 +29,7 @@ module YourKarma
28
29
  Timeout::timeout(options[:timeout]) do
29
30
  response = Net::HTTP.get_response(uri)
30
31
  end
32
+ raise ConnectionError unless response.code == '200'
31
33
  JSON::load(response.body).fetch("device")
32
34
  rescue *HTTP_ERRORS => e
33
35
  raise ConnectionError, e.message
@@ -1,3 +1,3 @@
1
1
  module YourKarma
2
- VERSION = "0.0.2"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -33,15 +33,15 @@ http_interactions:
33
33
  Transfer-Encoding:
34
34
  - chunked
35
35
  Date:
36
- - Wed, 30 Apr 2014 22:02:23 GMT
36
+ - Wed, 30 Apr 2014 22:02:24 GMT
37
37
  Server:
38
38
  - lighttpd/1.4.30-devel-4855
39
39
  body:
40
40
  encoding: UTF-8
41
- string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H4M36S\",\"batterypower\":100,\"charging\":false,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"74.60.178.162\",\"bsid\":\"00:00:02:07:44:E9\",\"rssi\":-75,\"cinr\":20,\"connectionduration\":\"P0Y0M0DT0H0M17S\"},\"wifiinterface\":{\"ssid\":\"Karma
41
+ string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H4M37S\",\"batterypower\":30,\"charging\":true,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"74.60.178.162\",\"bsid\":\"00:00:02:07:44:E9\",\"rssi\":-75,\"cinr\":21,\"connectionduration\":\"P0Y0M0DT0H0M18S\"},\"wifiinterface\":{\"ssid\":\"Karma
42
42
  Wi-Fi\",\"users\":1}}}\r\n"
43
- http_version:
44
- recorded_at: Thu, 01 May 2014 12:49:45 GMT
43
+ http_version:
44
+ recorded_at: Thu, 01 May 2014 12:49:46 GMT
45
45
  - request:
46
46
  method: get
47
47
  uri: http://yourkarma.com/dashboard
@@ -65,7 +65,7 @@ http_interactions:
65
65
  Content-Type:
66
66
  - text/html
67
67
  Date:
68
- - Thu, 01 May 2014 12:49:45 GMT
68
+ - Thu, 01 May 2014 12:49:46 GMT
69
69
  Location:
70
70
  - https://yourkarma.com/dashboard
71
71
  Server:
@@ -81,6 +81,6 @@ http_interactions:
81
81
  body:
82
82
  encoding: UTF-8
83
83
  string: ''
84
- http_version:
85
- recorded_at: Thu, 01 May 2014 12:49:46 GMT
84
+ http_version:
85
+ recorded_at: Thu, 01 May 2014 12:49:47 GMT
86
86
  recorded_with: VCR 2.9.0
@@ -0,0 +1,86 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://hotspot.yourkarma.com/api/status.json
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Host:
17
+ - hotspot.yourkarma.com
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Cache-Control:
24
+ - no-cache
25
+ - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
26
+ Expires:
27
+ - "-1"
28
+ - "-1"
29
+ Content-Type:
30
+ - application/json; charset=utf-8
31
+ Access-Control-Allow-Origin:
32
+ - "*"
33
+ Transfer-Encoding:
34
+ - chunked
35
+ Date:
36
+ - Wed, 30 Apr 2014 22:02:24 GMT
37
+ Server:
38
+ - lighttpd/1.4.30-devel-4855
39
+ body:
40
+ encoding: UTF-8
41
+ string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H4M37S\",\"batterypower\":30,\"charging\":false,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"74.60.178.162\",\"bsid\":\"00:00:02:07:44:E9\",\"rssi\":-75,\"cinr\":21,\"connectionduration\":\"P0Y0M0DT0H0M18S\"},\"wifiinterface\":{\"ssid\":\"Karma
42
+ Wi-Fi\",\"users\":1}}}\r\n"
43
+ http_version:
44
+ recorded_at: Thu, 01 May 2014 12:49:46 GMT
45
+ - request:
46
+ method: get
47
+ uri: http://yourkarma.com/dashboard
48
+ body:
49
+ encoding: US-ASCII
50
+ string: ''
51
+ headers:
52
+ Accept-Encoding:
53
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
54
+ Accept:
55
+ - "*/*"
56
+ User-Agent:
57
+ - Ruby
58
+ Host:
59
+ - yourkarma.com
60
+ response:
61
+ status:
62
+ code: 301
63
+ message: Moved Permanently
64
+ headers:
65
+ Content-Type:
66
+ - text/html
67
+ Date:
68
+ - Thu, 01 May 2014 12:49:46 GMT
69
+ Location:
70
+ - https://yourkarma.com/dashboard
71
+ Server:
72
+ - nginx
73
+ Status:
74
+ - 301 Moved Permanently
75
+ X-Frame-Options:
76
+ - SAMEORIGIN
77
+ Content-Length:
78
+ - '0'
79
+ Connection:
80
+ - keep-alive
81
+ body:
82
+ encoding: UTF-8
83
+ string: ''
84
+ http_version:
85
+ recorded_at: Thu, 01 May 2014 12:49:47 GMT
86
+ recorded_with: VCR 2.9.0
@@ -42,4 +42,46 @@ http_interactions:
42
42
  Wi-Fi\",\"users\":1}}}\r\n"
43
43
  http_version:
44
44
  recorded_at: Thu, 01 May 2014 12:46:25 GMT
45
+ - request:
46
+ method: get
47
+ uri: http://hotspot.yourkarma.com/api/status.json
48
+ body:
49
+ encoding: US-ASCII
50
+ string: ''
51
+ headers:
52
+ Accept-Encoding:
53
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
54
+ Accept:
55
+ - "*/*"
56
+ User-Agent:
57
+ - Ruby
58
+ Host:
59
+ - hotspot.yourkarma.com
60
+ response:
61
+ status:
62
+ code: 404
63
+ message: Not Found
64
+ headers:
65
+ Content-Type:
66
+ - text/html
67
+ Cache-Control:
68
+ - public
69
+ Pragma:
70
+ - cache
71
+ Expires:
72
+ - Sat, 28 Jun 2014 00:07:42 GMT
73
+ Date:
74
+ - Fri, 27 Jun 2014 23:37:42 GMT
75
+ Last-Modified:
76
+ - Fri, 27 Jun 2014 23:37:42 GMT
77
+ Accept-Ranges:
78
+ - bytes
79
+ Connection:
80
+ - close
81
+ body:
82
+ encoding: UTF-8
83
+ string: "<html>\n<head>\n <title>404 Not Found</title>\n</head>\n<body bgcolor=\"ffffff\">\n
84
+ \ <h2>404 Not Found<h2>\n <p>\n \n</body>\n</html>\n"
85
+ http_version:
86
+ recorded_at: Fri, 27 Jun 2014 23:37:43 GMT
45
87
  recorded_with: VCR 2.9.0
@@ -33,15 +33,15 @@ http_interactions:
33
33
  Transfer-Encoding:
34
34
  - chunked
35
35
  Date:
36
- - Wed, 30 Apr 2014 22:02:23 GMT
36
+ - Wed, 30 Apr 2014 22:02:24 GMT
37
37
  Server:
38
38
  - lighttpd/1.4.30-devel-4855
39
39
  body:
40
40
  encoding: UTF-8
41
- string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H4M36S\",\"batterypower\":100,\"charging\":false,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"74.60.178.162\",\"bsid\":\"00:00:02:07:44:E9\",\"rssi\":-75,\"cinr\":20,\"connectionduration\":\"P0Y0M0DT0H0M17S\"},\"wifiinterface\":{\"ssid\":\"Karma
41
+ string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H4M37S\",\"batterypower\":100,\"charging\":false,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"74.60.178.162\",\"bsid\":\"00:00:02:07:44:E9\",\"rssi\":-75,\"cinr\":21,\"connectionduration\":\"P0Y0M0DT0H0M18S\"},\"wifiinterface\":{\"ssid\":\"Karma
42
42
  Wi-Fi\",\"users\":1}}}\r\n"
43
- http_version:
44
- recorded_at: Thu, 01 May 2014 12:49:45 GMT
43
+ http_version:
44
+ recorded_at: Thu, 01 May 2014 12:49:46 GMT
45
45
  - request:
46
46
  method: get
47
47
  uri: http://yourkarma.com/dashboard
@@ -65,7 +65,7 @@ http_interactions:
65
65
  Content-Type:
66
66
  - text/html
67
67
  Date:
68
- - Thu, 01 May 2014 12:49:45 GMT
68
+ - Thu, 01 May 2014 12:49:46 GMT
69
69
  Location:
70
70
  - https://yourkarma.com/dashboard
71
71
  Server:
@@ -81,6 +81,6 @@ http_interactions:
81
81
  body:
82
82
  encoding: UTF-8
83
83
  string: ''
84
- http_version:
85
- recorded_at: Thu, 01 May 2014 12:49:46 GMT
84
+ http_version:
85
+ recorded_at: Thu, 01 May 2014 12:49:47 GMT
86
86
  recorded_with: VCR 2.9.0
@@ -33,13 +33,13 @@ http_interactions:
33
33
  Transfer-Encoding:
34
34
  - chunked
35
35
  Date:
36
- - Wed, 30 Apr 2014 21:49:57 GMT
36
+ - Wed, 30 Apr 2014 22:02:24 GMT
37
37
  Server:
38
38
  - lighttpd/1.4.30-devel-4855
39
39
  body:
40
40
  encoding: UTF-8
41
41
  string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H4M37S\",\"batterypower\":100,\"charging\":false,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"74.60.178.162\",\"bsid\":\"00:00:02:07:44:E9\",\"rssi\":-75,\"cinr\":21,\"connectionduration\":\"P0Y0M0DT0H0M18S\"},\"wifiinterface\":{\"ssid\":\"Karma
42
42
  Wi-Fi\",\"users\":1}}}\r\n"
43
- http_version:
44
- recorded_at: Wed, 30 Apr 2014 21:49:58 GMT
43
+ http_version:
44
+ recorded_at: Thu, 01 May 2014 12:49:46 GMT
45
45
  recorded_with: VCR 2.9.0
@@ -3,75 +3,141 @@ require 'webmock/rspec'
3
3
 
4
4
  describe "CLI", :vcr do
5
5
  let(:io) { StringIO.new }
6
- let(:args) { ['--timeout', '10', '--verbose'] }
6
+ let(:timeout) { 0.01 }
7
+ let(:args) { ['--timeout', timeout.to_s, '--verbose', '--no-poll'] }
7
8
  let(:cli) { YourKarma::CLI.run(io, args) }
8
9
 
9
10
  describe "output" do
10
- subject do
11
+ # | Connect | Speed | Battery | Charging | Bandwidth |
12
+ # +---------+-------+---------+----------+-----------+
13
+ # | -=≡ | ==>-- | [### } | =D---- | 1.3 GB |
14
+ let(:string) do
11
15
  cli
12
16
  io.string
13
17
  end
14
-
15
- context "connected to a hotspot" do
16
- it { should match /connected/i }
18
+ let(:header) do
19
+ string.split("\n")
20
+ .first
21
+ .split(/\s*\|\s*/)[1..-1]
22
+ end
23
+ let(:rows) do
24
+ string.split("\n")[2..-1].map do |row|
25
+ Hash[
26
+ row
27
+ .split(/\s*\|\s*/)[1..-1]
28
+ .each_with_index
29
+ .map{|cell, i| [header[i], cell.strip] }
30
+ ]
31
+ end
17
32
  end
33
+ subject { rows.first }
34
+
35
+ context "connected to a hotspot and the internet", vcr: {cassette_name: "online"} do
36
+ its(["Connect"]) { should eq "-=≡" }
37
+
38
+ context "with a slow connection" do
39
+ before do
40
+ Benchmark.stub(:realtime) { timeout }
41
+ end
42
+ its(["Speed"]) { should eq "(ಠ_ಠ)" }
43
+ end
44
+
45
+ context "with a fast connection" do
46
+ before do
47
+ Benchmark.stub(:realtime) { timeout / 100.0 }
48
+ end
49
+ its(["Speed"]) { should eq "(⌐■_■)" }
50
+ end
51
+
52
+ context "full battery power", vcr: {cassette_name: "full_battery"} do
53
+ its(["Battery"]) { should eq "[#####}" }
54
+ end
55
+
56
+ context "low battery power", vcr: {cassette_name: "low_battery"} do
57
+ its(["Battery"]) { should eq "[# }" }
58
+ end
18
59
 
19
- context "connected to the internet" do
20
- it { should match "online" }
21
- it { should_not match /slow/i }
60
+ context "charging", vcr: {cassette_name: "charging"} do
61
+ its(["Charging"]) { should eq "=D----" }
62
+ end
63
+
64
+ context "not charging", vcr: {cassette_name: "not_charging"} do
65
+ its(["Charging"]) { should eq "X" }
66
+ end
22
67
  end
23
68
 
24
- context "connected to the internet with a slow connection" do
69
+ context "connected to a hotspot and the internet, but requests timeout", vcr: {cassette_name: "online_timeout"} do
25
70
  before do
26
71
  stub_request(:any, /.*yourkarma.com\/dashboard.*/).to_raise(Timeout::Error.new "Fail")
27
72
  end
28
- it { should match /slow/i }
73
+ its(["Connect"]) { should eq "-=" }
74
+ its(["Speed"]) { should eq ":(" }
29
75
  end
30
76
 
31
- context "connected to a hotspot without an assigned WAN IP address" do
77
+ context "connected to a hotspot, but not to the internet", vcr: {cassette_name: "no_wan"} do
32
78
  before do
33
79
  stub_request(:any, /.*yourkarma.com\/dashboard.*/).to_raise(Timeout::Error.new "Fail")
34
80
  end
35
- it { should match /acquiring IP address/i }
36
- it { should_not match "Fail" }
81
+
82
+ its(["Connect"]) { should eq "-" }
83
+ its(["Speed"]) { should eq ":X" }
37
84
  end
38
85
 
39
- context "not connected to a hotspot" do
86
+ context "not connected to a hotspot", vcr: {cassette_name: "offline"} do
40
87
  before do
41
88
  stub_request(:any, /.*yourkarma.com.*/).to_raise(Timeout::Error.new "Fail")
42
89
  end
43
- it { should match /Not connected/i }
44
- it { should match "Fail" }
90
+ its(["Connect"]) { should eq "" }
91
+ its(["Speed"]) { should eq ":X" }
92
+ its(["Battery"]) { should eq "[?????}" }
93
+ its(["Charging"]) { should eq "?" }
94
+ end
95
+
96
+ context "polling", vcr: { allow_playback_repeats: true, cassette_name: "online"} do
97
+ subject { rows }
98
+ let(:args) { ['--timeout', timeout.to_s, '--verbose', '--count', '2', '--no-tail'] }
99
+ it { should have(1).elements }
100
+
101
+ context "tailing" do
102
+ let(:args) { ['--timeout', timeout.to_s, '--verbose', '--count', '2', '--tail'] }
103
+ it { should have(2).elements }
104
+ end
45
105
  end
46
106
  end
47
107
 
48
108
  describe "status code" do
49
109
  subject { cli }
50
110
 
51
- context "connected to the internet" do
111
+ context "connected to a hotspot and the internet", vcr: {cassette_name: "online"} do
52
112
  it { should be 0 }
113
+
114
+ context "with a slow connection" do
115
+ before do
116
+ Benchmark.stub(:realtime) { timeout }
117
+ end
118
+ it { should be 0 }
119
+ end
53
120
  end
54
121
 
55
- context "connected to the internet with a slow connection" do
122
+ context "connected to a hotspot and the internet, but requests timeout", vcr: {cassette_name: "online_timeout"} do
56
123
  before do
57
124
  stub_request(:any, /.*yourkarma.com\/dashboard.*/).to_raise(Timeout::Error.new "Fail")
58
125
  end
59
- it { should be 1 }
126
+ it { should be 3 }
60
127
  end
61
128
 
62
- context "connected to a hotspot without an assigned WAN IP address" do
129
+ context "connected to a hotspot, but not to the internet", vcr: {cassette_name: "no_wan"} do
63
130
  before do
64
131
  stub_request(:any, /.*yourkarma.com\/dashboard.*/).to_raise(Timeout::Error.new "Fail")
65
132
  end
66
- it { should be 1 }
133
+ it { should be 3 }
67
134
  end
68
135
 
69
- context "not connected to a hotspot" do
136
+ context "not connected to a hotspot", vcr: {cassette_name: "offline"} do
70
137
  before do
71
138
  stub_request(:any, /.*yourkarma.com.*/).to_raise(Timeout::Error.new "Fail")
72
139
  end
73
- it { should be 1 }
140
+ it { should be 3 }
74
141
  end
75
142
  end
76
143
  end
77
-
data/spec/support/vcr.rb CHANGED
@@ -5,7 +5,8 @@ VCR.configure do |c|
5
5
  c.cassette_library_dir = 'spec/cassettes'
6
6
 
7
7
  c.default_cassette_options = {
8
- record: :new_episodes
8
+ record: :none,
9
+ allow_playback_repeats: true
9
10
  }
10
11
 
11
12
  c.configure_rspec_metadata!
@@ -23,8 +23,8 @@ describe YourKarma::Benchmarker do
23
23
  end
24
24
 
25
25
  it "returns execution time" do
26
- Benchmark.stub(:realtime) { 123.45 }
27
- subject.should eq 123.45
26
+ Benchmark.stub(:realtime) { 1.2345 }
27
+ subject.should eq 1.2345 / 10.0
28
28
  end
29
29
 
30
30
  context "timing out" do
@@ -14,48 +14,84 @@ end
14
14
 
15
15
  describe "CLI::Reporter", "#report_on" do
16
16
  let(:io) { StringIO.new }
17
- let(:device) { YourKarma::Device.new ssid: "My Karma" }
18
- let(:benchmark) { 123.45 }
17
+ let(:device) { YourKarma::Device.new batterypower: 30 }
18
+ let(:benchmark) { 0.123 }
19
19
  let(:reporter) { YourKarma::CLI::Reporter.new({ io: io, verbose: true }) }
20
- let!(:status) { reporter.report_on(device, benchmark) }
21
- subject { status }
20
+ let(:status) { reporter.report_on(device, benchmark) }
21
+ before do
22
+ status
23
+ end
22
24
 
23
- it { should be 0 }
25
+ describe "status" do
26
+ subject { status }
27
+ it { should be 0 }
28
+
29
+ context "without benchmark" do
30
+ let(:benchmark) { nil }
31
+ it { should be 3 }
32
+ end
33
+ end
24
34
 
25
35
  describe "io" do
26
36
  subject { io.string }
27
- it { should match "My Karma" }
28
- it { should match /123.5/ }
37
+ it { should include "-=≡" }
38
+ it { should include "(⌐■_■)" }
39
+ it { should include "[# }" }
40
+ it { should include "X" }
29
41
  end
30
42
  end
31
43
 
32
- describe "CLI::Reporter", "#report_connectivity_failure" do
44
+ describe "CLI::Reporter", "#report_progress" do
33
45
  let(:io) { StringIO.new }
34
46
  let(:reporter) { YourKarma::CLI::Reporter.new({ io: io }) }
35
- let(:message) { "Whoops" }
36
- let!(:status) { reporter.report_connectivity_failure(message) }
37
- subject { status }
47
+ subject { io.string }
38
48
 
39
- it { should be 1 }
49
+ before do
50
+ reporter.report_progress
51
+ end
40
52
 
41
- describe "io" do
42
- subject { io.string }
43
- it { should match "Not connected" }
53
+ it { should_not include "." }
54
+
55
+ context "after reporting on" do
56
+ before do
57
+ reporter.report_on(nil, nil)
58
+ reporter.report_progress
59
+ end
60
+ it { should include "." }
61
+ end
62
+ end
63
+
64
+ describe "CLI::Reporter", "#report_error" do
65
+ let(:io) { StringIO.new }
66
+ let(:reporter) { YourKarma::CLI::Reporter.new({ io: io }) }
67
+ subject { io.string }
68
+
69
+ before do
70
+ reporter.report_error
71
+ end
72
+
73
+ it { should_not include "*" }
74
+
75
+ context "after reporting on" do
76
+ before do
77
+ reporter.report_on(nil, nil)
78
+ reporter.report_error
79
+ end
80
+ it { should include "*" }
44
81
  end
45
82
  end
46
83
 
47
- describe "CLI::Reporter", "#report_benchmark_failure_on" do
84
+ describe "CLI::Reporter", "#report_quit" do
48
85
  let(:io) { StringIO.new }
49
- let(:device) { YourKarma::Device.new ssid: "My Karma", ipaddress: "192.168.1.1" }
50
86
  let(:reporter) { YourKarma::CLI::Reporter.new({ io: io }) }
51
- let!(:status) { reporter.report_benchmark_failure_on(device) }
87
+ let(:code) { 123 }
88
+ let(:status) { reporter.report_quit code }
52
89
  subject { status }
53
90
 
54
- it { should be 1 }
91
+ it { should eq code }
55
92
 
56
- describe "io" do
57
- subject { io.string }
58
- it { should match "My Karma" }
59
- it { should match "slow" }
93
+ context "nil code" do
94
+ let(:code) { nil }
95
+ it { should eq 1 }
60
96
  end
61
97
  end
@@ -23,19 +23,27 @@ end
23
23
 
24
24
  describe "CLI", "#run" do
25
25
  it "should fetch status from device, benchmark speed and report" do
26
+ iterations = 3
26
27
  client = double(:client, get: {})
27
28
  device = double(:device)
28
29
  benchmark = double(:benchmark)
29
30
  benchmarker = double(:benchmarker, benchmark: benchmark)
30
31
  exit_code = double(:exit_code)
31
- reporter = double(:reporter, report_on: exit_code)
32
+ reporter = double(:reporter,
33
+ report_header: nil,
34
+ report_progress: nil,
35
+ report_on: exit_code,
36
+ report_quit: exit_code)
32
37
  YourKarma::Client.stub(:new) { client }
33
38
  YourKarma::Device.stub(:new) { device }
34
39
  YourKarma::Benchmarker.stub(:new) { benchmarker }
35
40
  YourKarma::CLI::Reporter.stub(:new) { reporter }
36
- cli = YourKarma::CLI.new
41
+ cli = YourKarma::CLI.new iterations: iterations
37
42
  response = cli.run
38
- expect(reporter).to have_received(:report_on).with(device, benchmark)
43
+ expect(reporter).to have_received(:report_header).once
44
+ expect(reporter).to have_received(:report_progress).exactly(iterations).times
45
+ expect(reporter).to have_received(:report_on).with(device, benchmark).exactly(iterations).times
46
+ expect(reporter).to have_received(:report_quit).with(exit_code).once
39
47
  expect(response).to eq(exit_code)
40
48
  end
41
49
  end
@@ -3,14 +3,16 @@ require 'spec_helper'
3
3
  describe YourKarma::Client do
4
4
  describe "#options" do
5
5
  let(:client) { YourKarma::Client.new }
6
- subject { client.options }
6
+ subject { client.options }
7
7
  its([:url]) { should match "yourkarma.com" }
8
8
  end
9
9
 
10
10
  describe "#get" do
11
- let(:client) { YourKarma::Client.new(url: "example.com") }
12
- let(:response) { double :response, body: '{"device": {"foo": "bar"}}' }
13
- subject { client.get }
11
+ let(:client) { YourKarma::Client.new(url: "example.com") }
12
+ let(:status_code) { '200' }
13
+ let(:body) { '{"device": {"foo": "bar"}}' }
14
+ let(:response) { double :response, body: body, code: status_code }
15
+ subject { client.get }
14
16
  before do
15
17
  Net::HTTP.stub(:get_response) { response }
16
18
  end
@@ -33,6 +35,13 @@ describe YourKarma::Client do
33
35
  end
34
36
  end
35
37
 
38
+ context "with an unsuccessfull HTTP status code" do
39
+ let(:status_code) { '500' }
40
+ it "raises ConnectionError" do
41
+ expect(-> { subject }).to raise_error YourKarma::Client::ConnectionError
42
+ end
43
+ end
44
+
36
45
  context "with an HTTP error" do
37
46
  before do
38
47
  Net::HTTP.stub(:get_response) { raise SocketError }
@@ -44,8 +53,7 @@ describe YourKarma::Client do
44
53
  end
45
54
 
46
55
  context "with bad JSON" do
47
- let(:response) { double :response, body: '{ WRONG }' }
48
-
56
+ let(:body) { '{ WRONG }' }
49
57
  it "raises BadResponseError" do
50
58
  expect(-> { subject }).to raise_error YourKarma::Client::BadResponseError
51
59
  end
data/yourkarma.gemspec CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rake"
24
24
  spec.add_development_dependency "rspec", "~> 2.1"
25
25
  spec.add_development_dependency "webmock", "~> 1.15"
26
- spec.add_development_dependency "vcr", "~> 2.6"
26
+ spec.add_development_dependency "vcr", "~> 2.9"
27
27
 
28
28
  # Release every merge to master as a prerelease
29
29
  spec.version = "#{spec.version}.pre#{ENV['TRAVIS_BUILD_NUMBER']}" if ENV['TRAVIS']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yourkarma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Sterndale
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-08 00:00:00.000000000 Z
11
+ date: 2014-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '2.6'
75
+ version: '2.9'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '2.6'
82
+ version: '2.9'
83
83
  description: Determine connectivity, battery and connection speed for your device.
84
84
  email:
85
85
  - gsterndale@gmail.com
@@ -102,14 +102,13 @@ files:
102
102
  - lib/yourkarma/device.rb
103
103
  - lib/yourkarma/version.rb
104
104
  - spec/cassettes/.keep
105
- - spec/cassettes/CLI/output/connected_to_a_hotspot/.yml
106
- - spec/cassettes/CLI/output/connected_to_a_hotspot_without_an_assigned_WAN_IP_address/.yml
107
- - spec/cassettes/CLI/output/connected_to_the_internet/.yml
108
- - spec/cassettes/CLI/output/connected_to_the_internet_with_a_slow_connection/.yml
109
- - spec/cassettes/CLI/status_code/connected_to_a_hotspot/.yml
110
- - spec/cassettes/CLI/status_code/connected_to_a_hotspot_without_an_assigned_WAN_IP_address/.yml
111
- - spec/cassettes/CLI/status_code/connected_to_the_internet/.yml
112
- - spec/cassettes/CLI/status_code/connected_to_the_internet_with_a_slow_connection/.yml
105
+ - spec/cassettes/charging.yml
106
+ - spec/cassettes/full_battery.yml
107
+ - spec/cassettes/low_battery.yml
108
+ - spec/cassettes/no_wan.yml
109
+ - spec/cassettes/not_charging.yml
110
+ - spec/cassettes/online.yml
111
+ - spec/cassettes/online_timeout.yml
113
112
  - spec/features/cli_spec.rb
114
113
  - spec/spec_helper.rb
115
114
  - spec/support/have_line_matching_matcher.rb
@@ -147,14 +146,13 @@ specification_version: 4
147
146
  summary: Karma hotspot status client & CLI
148
147
  test_files:
149
148
  - spec/cassettes/.keep
150
- - spec/cassettes/CLI/output/connected_to_a_hotspot/.yml
151
- - spec/cassettes/CLI/output/connected_to_a_hotspot_without_an_assigned_WAN_IP_address/.yml
152
- - spec/cassettes/CLI/output/connected_to_the_internet/.yml
153
- - spec/cassettes/CLI/output/connected_to_the_internet_with_a_slow_connection/.yml
154
- - spec/cassettes/CLI/status_code/connected_to_a_hotspot/.yml
155
- - spec/cassettes/CLI/status_code/connected_to_a_hotspot_without_an_assigned_WAN_IP_address/.yml
156
- - spec/cassettes/CLI/status_code/connected_to_the_internet/.yml
157
- - spec/cassettes/CLI/status_code/connected_to_the_internet_with_a_slow_connection/.yml
149
+ - spec/cassettes/charging.yml
150
+ - spec/cassettes/full_battery.yml
151
+ - spec/cassettes/low_battery.yml
152
+ - spec/cassettes/no_wan.yml
153
+ - spec/cassettes/not_charging.yml
154
+ - spec/cassettes/online.yml
155
+ - spec/cassettes/online_timeout.yml
158
156
  - spec/features/cli_spec.rb
159
157
  - spec/spec_helper.rb
160
158
  - spec/support/have_line_matching_matcher.rb
@@ -165,3 +163,4 @@ test_files:
165
163
  - spec/units/cli_spec.rb
166
164
  - spec/units/client_spec.rb
167
165
  - spec/units/device_spec.rb
166
+ has_rdoc:
@@ -1,45 +0,0 @@
1
- ---
2
- http_interactions:
3
- - request:
4
- method: get
5
- uri: http://hotspot.yourkarma.com/api/status.json
6
- body:
7
- encoding: US-ASCII
8
- string: ''
9
- headers:
10
- Accept-Encoding:
11
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
- Accept:
13
- - "*/*"
14
- User-Agent:
15
- - Ruby
16
- Host:
17
- - hotspot.yourkarma.com
18
- response:
19
- status:
20
- code: 200
21
- message: OK
22
- headers:
23
- Cache-Control:
24
- - no-cache
25
- - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
26
- Expires:
27
- - "-1"
28
- - "-1"
29
- Content-Type:
30
- - application/json; charset=utf-8
31
- Access-Control-Allow-Origin:
32
- - "*"
33
- Transfer-Encoding:
34
- - chunked
35
- Date:
36
- - Wed, 30 Apr 2014 21:49:57 GMT
37
- Server:
38
- - lighttpd/1.4.30-devel-4855
39
- body:
40
- encoding: UTF-8
41
- string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H4M37S\",\"batterypower\":100,\"charging\":false,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"74.60.178.162\",\"bsid\":\"00:00:02:07:44:E9\",\"rssi\":-75,\"cinr\":21,\"connectionduration\":\"P0Y0M0DT0H0M18S\"},\"wifiinterface\":{\"ssid\":\"Karma
42
- Wi-Fi\",\"users\":1}}}\r\n"
43
- http_version:
44
- recorded_at: Wed, 30 Apr 2014 21:49:58 GMT
45
- recorded_with: VCR 2.9.0
@@ -1,45 +0,0 @@
1
- ---
2
- http_interactions:
3
- - request:
4
- method: get
5
- uri: http://hotspot.yourkarma.com/api/status.json
6
- body:
7
- encoding: US-ASCII
8
- string: ''
9
- headers:
10
- Accept-Encoding:
11
- - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
- Accept:
13
- - "*/*"
14
- User-Agent:
15
- - Ruby
16
- Host:
17
- - hotspot.yourkarma.com
18
- response:
19
- status:
20
- code: 200
21
- message: OK
22
- headers:
23
- Cache-Control:
24
- - no-cache
25
- - no-store, no-cache, must-revalidate, post-check=0, pre-check=0
26
- Expires:
27
- - "-1"
28
- - "-1"
29
- Content-Type:
30
- - application/json; charset=utf-8
31
- Access-Control-Allow-Origin:
32
- - "*"
33
- Transfer-Encoding:
34
- - chunked
35
- Date:
36
- - Wed, 30 Apr 2014 21:59:03 GMT
37
- Server:
38
- - lighttpd/1.4.30-devel-4855
39
- body:
40
- encoding: UTF-8
41
- string: "{\"device\":{\"name\":\"IMW-C918W\",\"swversion\":\"R4855\",\"hwversion\":\"R06\",\"uptime\":\"P0Y0M0DT0H25M15S\",\"batterypower\":100,\"charging\":false,\"waninterface\":{\"macaddress\":\"001E312C42D0\",\"ipaddress\":\"N/A\",\"bsid\":\"N/A\",\"rssi\":\"N/A\",\"cinr\":\"N/A\",\"connectionduration\":\"P0Y0M0DT0H0M0S\"},\"wifiinterface\":{\"ssid\":\"Karma
42
- Wi-Fi\",\"users\":1}}}\r\n"
43
- http_version:
44
- recorded_at: Thu, 01 May 2014 12:46:25 GMT
45
- recorded_with: VCR 2.9.0