yourkarma 0.0.2 → 1.0.0

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: 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