mudbug 0.6.0.1 → 0.7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MANIFEST.txt +1 -0
- data/README.md +65 -47
- data/VERSION +1 -1
- data/bin/mb +42 -61
- data/lib/mb_config.rb +9 -4
- data/lib/mudbug.rb +10 -4
- metadata +27 -15
- checksums.yaml +0 -15
data/MANIFEST.txt
CHANGED
data/README.md
CHANGED
@@ -19,82 +19,105 @@ Install the gem:
|
|
19
19
|
|
20
20
|
Or, if using bundler, add to your Gemfile:
|
21
21
|
|
22
|
-
gem 'mudbug', '~> 0'
|
22
|
+
gem 'mudbug', '~> 0.6'
|
23
23
|
|
24
24
|
Quick Start
|
25
25
|
-----------
|
26
26
|
Initialize it with a host:
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
```ruby
|
29
|
+
require 'mudbug'
|
30
|
+
mb = Mudbug.new 'ip.jsontest.com'
|
31
|
+
```
|
30
32
|
|
31
33
|
The convenience methods *#get*, *#post*, *#put*, or *#delete* return the response body. If the response has a *Content-type:* **application/json** header, then JSON parsing will be automatically performed on the response body, with the resulting object returned.
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
+
```ruby
|
36
|
+
response = mb.get '/'
|
37
|
+
# => {"ip"=>"12.34.56.78"}
|
35
38
|
|
36
|
-
|
37
|
-
|
39
|
+
response.class
|
40
|
+
# => Hash
|
41
|
+
```
|
38
42
|
|
39
43
|
Usage
|
40
44
|
-----
|
41
45
|
You can pass through persistent [options to rest-client](https://github.com/rest-client/rest-client/blob/master/lib/restclient/request.rb):
|
42
46
|
|
43
|
-
|
44
|
-
|
47
|
+
```ruby
|
48
|
+
require 'mudbug'
|
49
|
+
mb = Mudbug.new 'google.com', max_redirects: 3
|
50
|
+
```
|
45
51
|
|
46
52
|
Declare what you accept: (optional, default shown)
|
47
53
|
|
48
|
-
|
54
|
+
```ruby
|
55
|
+
mb.accept :json, :html, :text
|
56
|
+
```
|
49
57
|
|
50
58
|
You can pass through per-request [options to rest-client](https://github.com/rest-client/rest-client/blob/master/lib/restclient/request.rb)
|
51
59
|
|
52
|
-
|
53
|
-
|
60
|
+
```ruby
|
61
|
+
mb.get '/', max_redirects: 3
|
62
|
+
# => "<!doctype html><html ... <head><meta content=\"Search the world's information ... "
|
63
|
+
```
|
54
64
|
|
55
65
|
[RestClient exceptions](https://github.com/rest-client/rest-client/blob/master/lib/restclient/exceptions.rb) will be passed through. POST and PUT payloads will be sent as strings. Non-string payloads will be converted to JSON by calling #to_json.
|
56
66
|
|
57
|
-
|
58
|
-
|
67
|
+
```ruby
|
68
|
+
mb = Mudbug.new 'plus.google.com'
|
69
|
+
mb.post '/', { 'hi' => 'mom' }, max_redirects: 3
|
59
70
|
|
60
|
-
|
71
|
+
# /path/to/lib/restclient/abstract_response.rb:48:in `return!': 405 Method Not Allowed (RestClient::MethodNotAllowed)
|
61
72
|
|
62
|
-
|
63
|
-
|
64
|
-
|
73
|
+
# lawyer up
|
74
|
+
# hit gym
|
75
|
+
Mudbug.new('facebook.com').delete '/'
|
65
76
|
|
66
|
-
|
77
|
+
# /path/to/lib/restclient/abstract_response.rb:39:in `return!': 301 Moved Permanently (RestClient::MovedPermanently)
|
78
|
+
```
|
67
79
|
|
68
80
|
Digging Deeper
|
69
81
|
--------------
|
70
82
|
Call Mudbug#resource directly for finer-grained response handling:
|
71
83
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
84
|
+
```ruby
|
85
|
+
resp = Mudbug.new('google.com').resource('/').get
|
86
|
+
# check resp.code
|
87
|
+
# check resp.headers
|
88
|
+
# process resp.body
|
89
|
+
# etc.
|
90
|
+
```
|
77
91
|
|
78
92
|
Here is the heart of Mudbug's [response processing](https://github.com/rickhull/mudbug/blob/master/lib/mudbug.rb#L45):
|
79
93
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
94
|
+
```ruby
|
95
|
+
# this structure declares what we support in the request Accept: header
|
96
|
+
# and defines automatic processing of the response based on the
|
97
|
+
# response Content-type: header
|
98
|
+
#
|
99
|
+
CONTENT = {
|
100
|
+
json: {
|
101
|
+
type: 'application/json',
|
102
|
+
proc: proc { |text| JSON.parse(text, symobolize_names: true) },
|
103
|
+
},
|
104
|
+
html: {
|
105
|
+
type: 'text/html',
|
106
|
+
proc: proc { |text| text },
|
107
|
+
},
|
108
|
+
text: {
|
109
|
+
type: 'text/plain',
|
110
|
+
proc: proc { |text| text },
|
111
|
+
},
|
112
|
+
}
|
113
|
+
```
|
114
|
+
|
115
|
+
Careful with that axe, Eugene.
|
116
|
+
|
117
|
+
Examples
|
118
|
+
--------
|
119
|
+
* accepts_and_methods [sample script](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.rb)
|
120
|
+
* accepts_and_methods [sample output](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.txt)
|
98
121
|
|
99
122
|
Funny, that
|
100
123
|
-----------
|
@@ -103,8 +126,3 @@ Mudbug works best with webservers that respect the *Accept:* request header and
|
|
103
126
|
[RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)
|
104
127
|
|
105
128
|
> If no Accept header field is present, then it is assumed that the client accepts all media types. If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.
|
106
|
-
|
107
|
-
Examples
|
108
|
-
--------
|
109
|
-
* accepts_and_methods [sample script](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.rb)
|
110
|
-
* accepts_and_methods [sample output](https://github.com/rickhull/mudbug/blob/master/examples/accepts_and_methods.txt)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0.1
|
data/bin/mb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'mb_config'
|
4
|
+
|
3
5
|
def usage(msg = nil)
|
4
6
|
puts "ERROR: #{msg}" if msg
|
5
|
-
puts <<
|
7
|
+
puts <<EOF
|
6
8
|
USAGE:
|
7
9
|
mb [get|delete] [PATH] - GET or DELETE PATH
|
8
10
|
mb [post|put] [PATH] - - POST or PUT payload (STDIN) to PATH
|
@@ -12,10 +14,11 @@ USAGE:
|
|
12
14
|
mb payload [-] - Set (from STDIN) or display payload config
|
13
15
|
mb config - Display current config
|
14
16
|
|
15
|
-
* A host must be configured for mb to operate
|
16
|
-
* method
|
17
|
-
*
|
18
|
-
|
17
|
+
* A `host` must be configured for mb to operate
|
18
|
+
* `method`, `path`, and `payload`, if configured, are not required arguments
|
19
|
+
* Set a config item to nil in order to remove it
|
20
|
+
* `accept` is optional; valid values include json, html, text
|
21
|
+
EOF
|
19
22
|
puts
|
20
23
|
puts "CONFIG: #{MbConfig.dump}"
|
21
24
|
|
@@ -27,8 +30,6 @@ def conclude(msg)
|
|
27
30
|
exit 0
|
28
31
|
end
|
29
32
|
|
30
|
-
require 'mb_config'
|
31
|
-
|
32
33
|
#
|
33
34
|
# Config section: handle commands that manipulate MbConfig
|
34
35
|
# Should exit in all cases with conclude()
|
@@ -96,9 +97,7 @@ if cfg_cmd
|
|
96
97
|
end
|
97
98
|
when 1
|
98
99
|
# did they provide a quoted or CSV list? or pseudo-symbols with colons?
|
99
|
-
accepts = accepts.first.split(/[ ,:]+/).
|
100
|
-
s.empty? ? nil : s
|
101
|
-
}.compact
|
100
|
+
accepts = accepts.first.split(/[ ,:]+/).select { |s| !s.empty? }
|
102
101
|
else
|
103
102
|
accepts.map! { |s| s.gsub %r{[ ,:]+}, '' }
|
104
103
|
end
|
@@ -112,87 +111,69 @@ if cfg_cmd
|
|
112
111
|
end
|
113
112
|
|
114
113
|
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
|
118
|
-
#
|
119
|
-
# Stage 2: create Mudbug based on MbConfig and command line options
|
114
|
+
# OK, we're not manipulating MbConfig
|
115
|
+
# Create Mudbug, determine method and path - from MbConfig and cmd line args
|
120
116
|
#
|
121
117
|
|
122
118
|
# set the host, always from MbConfig
|
119
|
+
#
|
123
120
|
usage "no host is set" unless MbConfig['host']
|
124
121
|
mb = Mudbug.new MbConfig['host']
|
125
122
|
|
126
123
|
mb.accept MbConfig['accept'].map(&:to_sym) if MbConfig['accept']
|
127
124
|
|
128
125
|
# set the method, possibly from CLI args
|
129
|
-
|
130
|
-
case
|
131
|
-
when 'get', 'post', 'put', 'delete', '
|
132
|
-
ARGV.shift
|
133
|
-
method = meth_cmd
|
126
|
+
#
|
127
|
+
case ARGV.first
|
128
|
+
when 'get', 'post', 'put', 'delete'# , 'patch' # Soon(tm)
|
129
|
+
method = ARGV.shift
|
134
130
|
else
|
135
131
|
method = MbConfig['method'] or usage "no method provided"
|
136
132
|
end
|
137
133
|
|
138
134
|
# set the path, possibly from CLI args
|
139
|
-
|
140
|
-
case
|
135
|
+
#
|
136
|
+
case ARGV.first
|
141
137
|
when %r{^\/} # starts with a slash
|
142
|
-
ARGV.shift
|
143
|
-
path = path_cmd
|
138
|
+
path = ARGV.shift
|
144
139
|
else
|
145
140
|
path = MbConfig['path'] or usage "no path provided"
|
146
141
|
end
|
147
142
|
|
143
|
+
# determine method
|
144
|
+
# gather payload as required
|
145
|
+
# create args for sending the request
|
148
146
|
#
|
149
|
-
# no payload yet; run GET and DELETE
|
150
|
-
#
|
151
|
-
|
152
147
|
case method
|
153
|
-
when 'get'
|
154
|
-
|
155
|
-
data = mb.get path
|
156
|
-
rescue RuntimeError => e
|
157
|
-
puts "#{e} - #{e.class}"
|
158
|
-
exit 1
|
159
|
-
end
|
160
|
-
conclude JSON.pretty_generate data
|
161
|
-
when 'del', 'delete'
|
162
|
-
begin
|
163
|
-
data = mb.delete path
|
164
|
-
rescue RuntimeError => e
|
165
|
-
puts "#{e} - #{e.class}"
|
166
|
-
exit 1
|
167
|
-
end
|
168
|
-
conclude JSON.pretty_generate data
|
148
|
+
when 'get', 'delete'
|
149
|
+
args = [method, path]
|
169
150
|
when 'post', 'put', 'patch'
|
170
|
-
#
|
151
|
+
# get payload
|
152
|
+
case ARGV.first
|
153
|
+
when nil
|
154
|
+
payload = MbConfig['payload'] or usage "no payload provided"
|
155
|
+
when '-'
|
156
|
+
begin
|
157
|
+
payload = JSON.parse $stdin.read
|
158
|
+
rescue
|
159
|
+
usage "could not parse payload:\n#{payload.inspect}"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
args = [method, path, payload]
|
171
163
|
else
|
172
164
|
usage "Bad HTTP method #{method}"
|
173
165
|
end
|
174
166
|
|
175
|
-
#
|
176
|
-
#
|
177
|
-
|
178
|
-
payload = ARGV.first
|
179
|
-
case payload
|
180
|
-
when nil
|
181
|
-
payload = MbConfig['payload'] or usage "no payload provided"
|
182
|
-
when '-'
|
183
|
-
payload = $stdin.read
|
184
|
-
begin
|
185
|
-
JSON.parse payload
|
186
|
-
rescue
|
187
|
-
usage "could not parse payload:\n#{payload.inspect}"
|
188
|
-
end
|
189
|
-
end
|
167
|
+
#
|
168
|
+
# finally!
|
169
|
+
#
|
190
170
|
|
191
171
|
begin
|
192
|
-
data = mb.send(
|
172
|
+
data = mb.send(*args)
|
193
173
|
rescue RuntimeError => e
|
194
174
|
puts "#{e} - #{e.class}"
|
195
175
|
exit 1
|
196
176
|
end
|
197
177
|
|
198
|
-
|
178
|
+
data = JSON.pretty_generate data unless data.is_a? String
|
179
|
+
conclude data
|
data/lib/mb_config.rb
CHANGED
@@ -26,16 +26,21 @@ module MbConfig
|
|
26
26
|
#
|
27
27
|
def self.load
|
28
28
|
reset unless File.exists?(FILE)
|
29
|
+
rescues = 0
|
29
30
|
begin
|
30
31
|
File.open(FILE, 'r') { |f|
|
31
32
|
CFG.merge! JSON.parse f.read
|
32
33
|
}
|
33
34
|
rescue JSON::ParserError => e
|
35
|
+
rescues += 1
|
34
36
|
puts "#{e} (#{e.class})"
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
if rescues < 2
|
38
|
+
puts "Resetting #{FILE}"
|
39
|
+
reset
|
40
|
+
retry
|
41
|
+
end
|
42
|
+
Mudbug.lager.fatal { "MbConfig.load failed!" }
|
43
|
+
raise e
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
data/lib/mudbug.rb
CHANGED
@@ -84,8 +84,6 @@ class Mudbug
|
|
84
84
|
attr_accessor :host
|
85
85
|
|
86
86
|
def initialize(host, options = {})
|
87
|
-
# note, not yet logging at instance layer
|
88
|
-
# @lager = self.class.lager
|
89
87
|
@host = host
|
90
88
|
@options = options
|
91
89
|
accept :json, :html, :text
|
@@ -107,10 +105,18 @@ class Mudbug
|
|
107
105
|
|
108
106
|
# use this method directly if you want finer-grained request and response
|
109
107
|
# handling
|
108
|
+
# supports /path/to/res, path/to/res, http://host.com/path/to/res
|
110
109
|
#
|
111
110
|
def resource(path, options = {})
|
112
|
-
|
113
|
-
|
111
|
+
uri = URI.parse(path)
|
112
|
+
if uri.host # a full URL was passed in
|
113
|
+
@host = uri.host
|
114
|
+
url = uri.to_s
|
115
|
+
else
|
116
|
+
path = "/#{path}" unless path[0,1] == '/'
|
117
|
+
url = "http://#{@host}#{path}"
|
118
|
+
end
|
119
|
+
RestClient::Resource.new url, @options.merge(options)
|
114
120
|
end
|
115
121
|
|
116
122
|
# no payload
|
metadata
CHANGED
@@ -1,85 +1,96 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mudbug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0.1
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Rick Hull
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-19 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rest-client
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '1'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
20
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
21
26
|
requirements:
|
22
27
|
- - ~>
|
23
28
|
- !ruby/object:Gem::Version
|
24
29
|
version: '1'
|
25
|
-
type: :runtime
|
26
|
-
prerelease: false
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: json
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
33
37
|
version: '1'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
34
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
35
42
|
requirements:
|
36
43
|
- - ~>
|
37
44
|
- !ruby/object:Gem::Version
|
38
45
|
version: '1'
|
39
|
-
type: :runtime
|
40
|
-
prerelease: false
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: lager
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ! '>='
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: '0.2'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
48
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
49
58
|
requirements:
|
50
59
|
- - ! '>='
|
51
60
|
- !ruby/object:Gem::Version
|
52
61
|
version: '0.2'
|
53
|
-
type: :runtime
|
54
|
-
prerelease: false
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: minitest
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
67
|
- - ! '>='
|
60
68
|
- !ruby/object:Gem::Version
|
61
69
|
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
62
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
63
74
|
requirements:
|
64
75
|
- - ! '>='
|
65
76
|
- !ruby/object:Gem::Version
|
66
77
|
version: '0'
|
67
|
-
type: :development
|
68
|
-
prerelease: false
|
69
78
|
- !ruby/object:Gem::Dependency
|
70
79
|
name: buildar
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
72
82
|
requirements:
|
73
83
|
- - ~>
|
74
84
|
- !ruby/object:Gem::Version
|
75
85
|
version: '1.4'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
76
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
77
90
|
requirements:
|
78
91
|
- - ~>
|
79
92
|
- !ruby/object:Gem::Version
|
80
93
|
version: '1.4'
|
81
|
-
type: :development
|
82
|
-
prerelease: false
|
83
94
|
description: GET, POST, PUT, and DELETE JSON payloads. Easy Accept headers. Fine-grained
|
84
95
|
response handling using Mudbug#resource.
|
85
96
|
email:
|
@@ -102,25 +113,26 @@ files:
|
|
102
113
|
homepage: http://github.com/rickhull/mudbug
|
103
114
|
licenses:
|
104
115
|
- LGPL
|
105
|
-
metadata: {}
|
106
116
|
post_install_message:
|
107
117
|
rdoc_options: []
|
108
118
|
require_paths:
|
109
119
|
- lib
|
110
120
|
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
111
122
|
requirements:
|
112
123
|
- - ! '>='
|
113
124
|
- !ruby/object:Gem::Version
|
114
125
|
version: '0'
|
115
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
116
128
|
requirements:
|
117
129
|
- - ! '>='
|
118
130
|
- !ruby/object:Gem::Version
|
119
131
|
version: '0'
|
120
132
|
requirements: []
|
121
133
|
rubyforge_project:
|
122
|
-
rubygems_version:
|
134
|
+
rubygems_version: 1.8.23
|
123
135
|
signing_key:
|
124
|
-
specification_version:
|
136
|
+
specification_version: 3
|
125
137
|
summary: This hardy creature consumes JSON / REST APIs
|
126
138
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
YmI3NzE0NGE5MmVjZGQ5NDgwNzRmZmZjOTdkNjVmMGQ1NGJjYmRkZQ==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MDQ5NGFhZTVkZTEyMzU4NjVjY2Y3NjI0YjAyNjEzNDEyNDdhNzdhMw==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
MTAwMzFjZThlNWFkMTczNzM5YTFhMDQ2M2UxNzg3ZGU3OGE5MjYxMjYyYTNl
|
10
|
-
ZDIwMGU3MmNhMGQzOWFlNWY4NzdmMDBmZTFhNWZiZjM2YmRiNDk3NWI2OTI1
|
11
|
-
OWFhNDJlNWQwNGQwYjAyNTdhMDJmN2E1NjdiMTkzMmIwNDgzODc=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MjMyZTljZTNjMzMzM2M3YzhhNThiYjhmNDM1MTM0NTY2ZWMzZGY2N2NjMWVh
|
14
|
-
YjM3N2QyYjYxOTMyNDcyY2JiMTBhYTY5MTlmOWE3NDBmMGE1OTUzZjM5ZjMx
|
15
|
-
ZTJmMzMyMTI3MGYwMDc3NzlhMTczM2Y0ZDhlOTI2YzYxYWFkNDc=
|