rest-core 1.0.3 → 2.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.
- data/.travis.yml +6 -7
- data/CHANGES.md +137 -0
- data/Gemfile +1 -1
- data/README.md +183 -191
- data/TODO.md +5 -8
- data/example/multi.rb +31 -24
- data/example/simple.rb +28 -0
- data/example/use-cases.rb +194 -0
- data/lib/rest-core.rb +26 -19
- data/lib/rest-core/builder.rb +2 -2
- data/lib/rest-core/client.rb +40 -27
- data/lib/rest-core/client/universal.rb +16 -13
- data/lib/rest-core/client_oauth1.rb +5 -5
- data/lib/rest-core/engine/auto.rb +25 -0
- data/lib/rest-core/{app → engine}/dry.rb +1 -2
- data/lib/rest-core/engine/em-http-request.rb +39 -0
- data/lib/rest-core/engine/future/future.rb +106 -0
- data/lib/rest-core/engine/future/future_fiber.rb +39 -0
- data/lib/rest-core/engine/future/future_thread.rb +29 -0
- data/lib/rest-core/engine/rest-client.rb +56 -0
- data/lib/rest-core/middleware.rb +27 -5
- data/lib/rest-core/middleware/auth_basic.rb +5 -5
- data/lib/rest-core/middleware/bypass.rb +2 -2
- data/lib/rest-core/middleware/cache.rb +67 -54
- data/lib/rest-core/middleware/common_logger.rb +5 -8
- data/lib/rest-core/middleware/default_headers.rb +2 -2
- data/lib/rest-core/middleware/default_payload.rb +26 -2
- data/lib/rest-core/middleware/default_query.rb +4 -2
- data/lib/rest-core/middleware/default_site.rb +8 -6
- data/lib/rest-core/middleware/error_detector.rb +9 -16
- data/lib/rest-core/middleware/error_handler.rb +25 -11
- data/lib/rest-core/middleware/follow_redirect.rb +11 -14
- data/lib/rest-core/middleware/json_request.rb +19 -0
- data/lib/rest-core/middleware/json_response.rb +28 -0
- data/lib/rest-core/middleware/oauth1_header.rb +2 -7
- data/lib/rest-core/middleware/oauth2_header.rb +4 -7
- data/lib/rest-core/middleware/oauth2_query.rb +2 -2
- data/lib/rest-core/middleware/timeout.rb +21 -65
- data/lib/rest-core/middleware/timeout/{eventmachine_timer.rb → timer_em.rb} +3 -1
- data/lib/rest-core/middleware/timeout/timer_thread.rb +36 -0
- data/lib/rest-core/patch/multi_json.rb +8 -0
- data/lib/rest-core/test.rb +3 -12
- data/lib/rest-core/util/json.rb +65 -0
- data/lib/rest-core/util/parse_query.rb +2 -2
- data/lib/rest-core/version.rb +1 -1
- data/lib/rest-core/wrapper.rb +16 -16
- data/rest-core.gemspec +28 -27
- data/test/test_auth_basic.rb +14 -10
- data/test/test_builder.rb +7 -7
- data/test/test_cache.rb +126 -37
- data/test/test_client.rb +3 -1
- data/test/test_client_oauth1.rb +2 -3
- data/test/test_default_query.rb +17 -23
- data/test/test_em_http_request.rb +146 -0
- data/test/test_error_detector.rb +0 -1
- data/test/test_error_handler.rb +44 -0
- data/test/test_follow_redirect.rb +17 -19
- data/test/test_json_request.rb +28 -0
- data/test/test_json_response.rb +51 -0
- data/test/test_oauth1_header.rb +4 -4
- data/test/test_payload.rb +20 -12
- data/test/test_simple.rb +14 -0
- data/test/test_timeout.rb +11 -19
- data/test/test_universal.rb +5 -5
- data/test/test_wrapper.rb +19 -13
- metadata +28 -29
- data/doc/ToC.md +0 -7
- data/doc/dependency.md +0 -4
- data/doc/design.md +0 -4
- data/example/auto.rb +0 -51
- data/example/coolio.rb +0 -21
- data/example/eventmachine.rb +0 -30
- data/example/rest-client.rb +0 -16
- data/lib/rest-core/app/abstract/async_fiber.rb +0 -13
- data/lib/rest-core/app/auto.rb +0 -23
- data/lib/rest-core/app/coolio-async.rb +0 -32
- data/lib/rest-core/app/coolio-fiber.rb +0 -30
- data/lib/rest-core/app/coolio.rb +0 -9
- data/lib/rest-core/app/em-http-request-async.rb +0 -37
- data/lib/rest-core/app/em-http-request-fiber.rb +0 -45
- data/lib/rest-core/app/em-http-request.rb +0 -9
- data/lib/rest-core/app/rest-client.rb +0 -41
- data/lib/rest-core/middleware/json_decode.rb +0 -93
- data/lib/rest-core/middleware/timeout/coolio_timer.rb +0 -10
- data/pending/test_multi.rb +0 -123
- data/pending/test_test_util.rb +0 -86
- data/test/test_json_decode.rb +0 -24
data/doc/ToC.md
DELETED
data/doc/dependency.md
DELETED
data/doc/design.md
DELETED
data/example/auto.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core'
|
3
|
-
require 'eventmachine'
|
4
|
-
require 'cool.io'
|
5
|
-
|
6
|
-
YourClient = RestCore::Builder.client do
|
7
|
-
s = RestCore
|
8
|
-
use s::DefaultSite , 'https://api.github.com/users/'
|
9
|
-
use s::JsonDecode , true
|
10
|
-
use s::CommonLogger, method(:puts)
|
11
|
-
use s::Cache , nil, 3600
|
12
|
-
run s::Auto
|
13
|
-
end
|
14
|
-
|
15
|
-
client = YourClient.new(:cache => {})
|
16
|
-
p client.get('cardinalblue') # cache miss
|
17
|
-
puts
|
18
|
-
p client.get('cardinalblue') # cache hit
|
19
|
-
|
20
|
-
puts
|
21
|
-
|
22
|
-
client = YourClient.new(:cache => {})
|
23
|
-
EM.run{
|
24
|
-
client.get('cardinalblue'){ |response|
|
25
|
-
p response
|
26
|
-
EM.stop
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
puts
|
31
|
-
|
32
|
-
EM.run{
|
33
|
-
Fiber.new{
|
34
|
-
p client.get('cardinalblue')
|
35
|
-
EM.stop
|
36
|
-
}.resume
|
37
|
-
}
|
38
|
-
|
39
|
-
puts
|
40
|
-
|
41
|
-
client = YourClient.new(:cache => {})
|
42
|
-
Coolio::TimerWatcher.new(1).attach(Coolio::Loop.default).on_timer{detach}
|
43
|
-
client.get('cardinalblue'){ |response|
|
44
|
-
p response
|
45
|
-
}
|
46
|
-
Coolio::Loop.default.run
|
47
|
-
|
48
|
-
puts
|
49
|
-
Coolio::TimerWatcher.new(1).attach(Coolio::Loop.default).on_timer{detach}
|
50
|
-
Fiber.new{ p client.get('cardinalblue') }.resume
|
51
|
-
Coolio::Loop.default.run
|
data/example/coolio.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core'
|
3
|
-
|
4
|
-
AsynchronousClient = RestCore::Builder.client do
|
5
|
-
s = RestCore
|
6
|
-
use s::DefaultSite , 'https://api.github.com/users/'
|
7
|
-
use s::JsonDecode , true
|
8
|
-
use s::CommonLogger, method(:puts)
|
9
|
-
use s::Cache , nil, 3600
|
10
|
-
run s::Coolio
|
11
|
-
end
|
12
|
-
|
13
|
-
AsynchronousClient.new.get('cardinalblue'){ |response|
|
14
|
-
p response
|
15
|
-
}
|
16
|
-
Coolio::Loop.default.run
|
17
|
-
|
18
|
-
puts
|
19
|
-
|
20
|
-
Fiber.new{ p AsynchronousClient.new.get('cardinalblue') }.resume
|
21
|
-
Coolio::Loop.default.run
|
data/example/eventmachine.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core'
|
3
|
-
|
4
|
-
AsynchronousClient = RestCore::Builder.client do
|
5
|
-
s = RestCore
|
6
|
-
use s::DefaultSite , 'https://api.github.com/users/'
|
7
|
-
use s::JsonDecode , true
|
8
|
-
use s::CommonLogger, method(:puts)
|
9
|
-
use s::Cache , nil, 3600
|
10
|
-
run s::EmHttpRequest
|
11
|
-
end
|
12
|
-
|
13
|
-
client = AsynchronousClient.new
|
14
|
-
EM.run{
|
15
|
-
client.get('cardinalblue'){ |response|
|
16
|
-
p response
|
17
|
-
EM.stop
|
18
|
-
}
|
19
|
-
puts "It's not blocking..."
|
20
|
-
}
|
21
|
-
|
22
|
-
puts
|
23
|
-
|
24
|
-
EM.run{
|
25
|
-
Fiber.new{
|
26
|
-
p client.get('cardinalblue')
|
27
|
-
EM.stop
|
28
|
-
}.resume
|
29
|
-
puts "It's not blocking..."
|
30
|
-
}
|
data/example/rest-client.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core'
|
3
|
-
|
4
|
-
YourClient = RestCore::Builder.client do
|
5
|
-
s = RestCore
|
6
|
-
use s::DefaultSite , 'https://api.github.com/users/'
|
7
|
-
use s::JsonDecode , true
|
8
|
-
use s::CommonLogger, method(:puts)
|
9
|
-
use s::Cache , nil, 3600
|
10
|
-
run s::RestClient
|
11
|
-
end
|
12
|
-
|
13
|
-
client = YourClient.new(:cache => {})
|
14
|
-
p client.get('cardinalblue') # cache miss
|
15
|
-
puts
|
16
|
-
p client.get('cardinalblue') # cache hit
|
data/lib/rest-core/app/auto.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/middleware'
|
3
|
-
|
4
|
-
class RestCore::Auto
|
5
|
-
include RestCore::Middleware
|
6
|
-
def call env
|
7
|
-
client = http_client
|
8
|
-
client.call(log(env, "Auto picked: #{client.class}"))
|
9
|
-
end
|
10
|
-
|
11
|
-
def http_client
|
12
|
-
if Object.const_defined?(:EventMachine) && ::EventMachine.reactor_running?
|
13
|
-
@emhttprequest ||= RestCore::EmHttpRequest.new
|
14
|
-
|
15
|
-
elsif Object.const_defined?(:Coolio) && ::Coolio::Loop.default.
|
16
|
-
has_active_watchers?
|
17
|
-
@coolio ||= RestCore::Coolio.new
|
18
|
-
|
19
|
-
else
|
20
|
-
@restclient ||= RestCore::RestClient.new
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/middleware'
|
3
|
-
|
4
|
-
require 'cool.io-http'
|
5
|
-
|
6
|
-
class RestCore::CoolioAsync
|
7
|
-
include RestCore::Middleware
|
8
|
-
def call env
|
9
|
-
client = ::Coolio::Http.request(:method => env[REQUEST_METHOD] ,
|
10
|
-
:url => request_uri(env) ,
|
11
|
-
:payload => env[REQUEST_PAYLOAD],
|
12
|
-
:headers => env[REQUEST_HEADERS]){ |res|
|
13
|
-
|
14
|
-
env[TIMER].detach if env[TIMER]
|
15
|
-
env[ASYNC].call(env.merge(RESPONSE_BODY => res.body ,
|
16
|
-
RESPONSE_STATUS => res.status,
|
17
|
-
RESPONSE_HEADERS => res.headers)) if
|
18
|
-
env[ASYNC]
|
19
|
-
}
|
20
|
-
|
21
|
-
env[TIMER].on_timer{
|
22
|
-
detach
|
23
|
-
client.detach
|
24
|
-
env[ASYNC].call(env.merge(RESPONSE_BODY => env[TIMER].error,
|
25
|
-
RESPONSE_STATUS => 0 ,
|
26
|
-
RESPONSE_HEADERS => {} )) if
|
27
|
-
env[ASYNC]
|
28
|
-
} if env[TIMER]
|
29
|
-
|
30
|
-
env
|
31
|
-
end
|
32
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/middleware'
|
3
|
-
|
4
|
-
require 'cool.io-http'
|
5
|
-
|
6
|
-
class RestCore::CoolioFiber
|
7
|
-
include RestCore::Middleware
|
8
|
-
def call env
|
9
|
-
process(env,
|
10
|
-
::Coolio::HttpFiber.request(:method => env[REQUEST_METHOD] ,
|
11
|
-
:url => request_uri(env) ,
|
12
|
-
:payload => env[REQUEST_PAYLOAD],
|
13
|
-
:headers => env[REQUEST_HEADERS]))
|
14
|
-
rescue FiberError
|
15
|
-
end
|
16
|
-
|
17
|
-
def process env, response
|
18
|
-
Thread.current[:coolio_http_client].detach if
|
19
|
-
Thread.current[:coolio_http_client].kind_of?(::Coolio::HttpFiber)
|
20
|
-
|
21
|
-
raise response if response.kind_of?(::Exception)
|
22
|
-
|
23
|
-
result = env.merge(RESPONSE_BODY => response.body ,
|
24
|
-
RESPONSE_STATUS => response.status,
|
25
|
-
RESPONSE_HEADERS => response.headers)
|
26
|
-
|
27
|
-
result[ASYNC].call(result) if result[ASYNC]
|
28
|
-
result
|
29
|
-
end
|
30
|
-
end
|
data/lib/rest-core/app/coolio.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/app/abstract/async_fiber'
|
3
|
-
require 'rest-core/app/coolio-async'
|
4
|
-
require 'rest-core/app/coolio-fiber'
|
5
|
-
|
6
|
-
class RestCore::Coolio < RestCore::AsyncFiber
|
7
|
-
def async; @async ||= CoolioAsync.new; end
|
8
|
-
def fiber; @fiber ||= CoolioFiber.new; end
|
9
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/middleware'
|
3
|
-
|
4
|
-
require 'restclient/payload'
|
5
|
-
require 'em-http-request'
|
6
|
-
|
7
|
-
class RestCore::EmHttpRequestAsync
|
8
|
-
include RestCore::Middleware
|
9
|
-
def call env
|
10
|
-
payload = ::RestClient::Payload.generate(env[REQUEST_PAYLOAD])
|
11
|
-
client = ::EventMachine::HttpRequest.new(request_uri(env)).send(
|
12
|
-
env[REQUEST_METHOD],
|
13
|
-
:body => payload.read,
|
14
|
-
:head => payload.headers.merge(env[REQUEST_HEADERS]))
|
15
|
-
|
16
|
-
client.callback{ respond(env, client) }
|
17
|
-
client. errback{ respond(env, client) }
|
18
|
-
|
19
|
-
env[TIMER].on_timeout{
|
20
|
-
client.close
|
21
|
-
env[ASYNC].call(env.merge(RESPONSE_BODY => env[TIMER].error,
|
22
|
-
RESPONSE_STATUS => 0 ,
|
23
|
-
RESPONSE_HEADERS => {} )) if
|
24
|
-
env[ASYNC]
|
25
|
-
} if env[TIMER]
|
26
|
-
|
27
|
-
env
|
28
|
-
end
|
29
|
-
|
30
|
-
def respond env, client
|
31
|
-
env[TIMER].cancel if env[TIMER] && !env[TIMER].canceled?
|
32
|
-
env[ASYNC].call(env.merge(
|
33
|
-
RESPONSE_BODY => client.response,
|
34
|
-
RESPONSE_STATUS => client.response_header.status,
|
35
|
-
RESPONSE_HEADERS => client.response_header)) if env[ASYNC]
|
36
|
-
end
|
37
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/middleware'
|
3
|
-
|
4
|
-
require 'restclient/payload'
|
5
|
-
require 'em-http-request'
|
6
|
-
require 'fiber'
|
7
|
-
|
8
|
-
class RestCore::EmHttpRequestFiber
|
9
|
-
include RestCore::Middleware
|
10
|
-
def call env
|
11
|
-
f = Fiber.current
|
12
|
-
|
13
|
-
payload = ::RestClient::Payload.generate(env[REQUEST_PAYLOAD])
|
14
|
-
client = ::EventMachine::HttpRequest.new(request_uri(env)).send(
|
15
|
-
env[REQUEST_METHOD],
|
16
|
-
:body => payload.read,
|
17
|
-
:head => payload.headers.merge(env[REQUEST_HEADERS]))
|
18
|
-
|
19
|
-
client.callback{ respond(f, env, client) }
|
20
|
-
client. errback{ respond(f, env, client) }
|
21
|
-
|
22
|
-
if (response = Fiber.yield).kind_of?(::Exception)
|
23
|
-
client.close
|
24
|
-
raise response
|
25
|
-
else
|
26
|
-
response
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def respond f, env, client
|
31
|
-
f.resume(process(env, client)) if f.alive?
|
32
|
-
rescue FiberError
|
33
|
-
# whenever timeout, client.close would be called,
|
34
|
-
# and then errback would be called. in this case,
|
35
|
-
# the fiber is already resumed by the timer
|
36
|
-
end
|
37
|
-
|
38
|
-
def process env, client
|
39
|
-
result = env.merge(RESPONSE_BODY => client.response,
|
40
|
-
RESPONSE_STATUS => client.response_header.status,
|
41
|
-
RESPONSE_HEADERS => client.response_header)
|
42
|
-
result[ASYNC].call(result) if result[ASYNC]
|
43
|
-
result
|
44
|
-
end
|
45
|
-
end
|
@@ -1,9 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/app/abstract/async_fiber'
|
3
|
-
require 'rest-core/app/em-http-request-async'
|
4
|
-
require 'rest-core/app/em-http-request-fiber'
|
5
|
-
|
6
|
-
class RestCore::EmHttpRequest < RestCore::AsyncFiber
|
7
|
-
def async; @async ||= EmHttpRequestAsync.new; end
|
8
|
-
def fiber; @fiber ||= EmHttpRequestFiber.new; end
|
9
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/middleware'
|
3
|
-
|
4
|
-
require 'restclient'
|
5
|
-
|
6
|
-
require 'rest-core/patch/rest-client'
|
7
|
-
|
8
|
-
class RestCore::RestClient
|
9
|
-
include RestCore::Middleware
|
10
|
-
def call env
|
11
|
-
process(env,
|
12
|
-
::RestClient::Request.execute(:method => env[REQUEST_METHOD ],
|
13
|
-
:url => request_uri(env) ,
|
14
|
-
:payload => env[REQUEST_PAYLOAD],
|
15
|
-
:headers => env[REQUEST_HEADERS],
|
16
|
-
:max_redirects => 0))
|
17
|
-
|
18
|
-
rescue ::RestClient::Exception => e
|
19
|
-
process(env, e.response)
|
20
|
-
end
|
21
|
-
|
22
|
-
def process env, response
|
23
|
-
result = env.merge(RESPONSE_BODY => response.body,
|
24
|
-
RESPONSE_STATUS => response.code,
|
25
|
-
RESPONSE_HEADERS => normalize_headers(
|
26
|
-
response.raw_headers))
|
27
|
-
result[ASYNC].call(result) if result[ASYNC]
|
28
|
-
result
|
29
|
-
end
|
30
|
-
|
31
|
-
def normalize_headers raw_headers
|
32
|
-
raw_headers.inject({}){ |r, (k, v)|
|
33
|
-
r[k.to_s.upcase.tr('-', '_')] = if v.kind_of?(Array) && v.size == 1
|
34
|
-
v.first
|
35
|
-
else
|
36
|
-
v
|
37
|
-
end
|
38
|
-
r
|
39
|
-
}
|
40
|
-
end
|
41
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'rest-core/middleware'
|
3
|
-
|
4
|
-
class RestCore::JsonDecode
|
5
|
-
def self.members; [:json_decode]; end
|
6
|
-
include RestCore::Middleware
|
7
|
-
|
8
|
-
def call env
|
9
|
-
return app.call(env) if env[DRY]
|
10
|
-
if env[ASYNC]
|
11
|
-
app.call(env.merge(ASYNC => lambda{ |response|
|
12
|
-
env[ASYNC].call(process(response))
|
13
|
-
}))
|
14
|
-
else
|
15
|
-
process(app.call(env))
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def process response
|
20
|
-
if json_decode(response)
|
21
|
-
response.merge(RESPONSE_BODY =>
|
22
|
-
self.class.json_decode("[#{response[RESPONSE_BODY]}]").first)
|
23
|
-
# [this].first is not needed for yajl-ruby
|
24
|
-
else
|
25
|
-
response
|
26
|
-
end
|
27
|
-
rescue self.class.const_get(:ParseError) => error
|
28
|
-
fail(response, error)
|
29
|
-
end
|
30
|
-
|
31
|
-
module YajlRuby
|
32
|
-
def self.extended mod
|
33
|
-
mod.const_set(:ParseError, Yajl::ParseError)
|
34
|
-
end
|
35
|
-
def json_encode hash
|
36
|
-
Yajl::Encoder.encode(hash)
|
37
|
-
end
|
38
|
-
def json_decode json
|
39
|
-
Yajl::Parser.parse(json)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
module Json
|
44
|
-
def self.extended mod
|
45
|
-
mod.const_set(:ParseError, JSON::ParserError)
|
46
|
-
end
|
47
|
-
def json_encode hash
|
48
|
-
JSON.dump(hash)
|
49
|
-
end
|
50
|
-
def json_decode json
|
51
|
-
JSON.parse(json)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
module Gsub
|
56
|
-
class ParseError < RuntimeError; end
|
57
|
-
def self.extended mod
|
58
|
-
mod.const_set(:ParseError, Gsub::ParseError)
|
59
|
-
end
|
60
|
-
# only works for flat hash
|
61
|
-
def json_encode hash
|
62
|
-
middle = hash.inject([]){ |r, (k, v)|
|
63
|
-
r << "\"#{k}\":\"#{v.gsub('"','\\"')}\""
|
64
|
-
}.join(',')
|
65
|
-
"{#{middle}}"
|
66
|
-
end
|
67
|
-
def json_decode json
|
68
|
-
raise NotImplementedError.new(
|
69
|
-
'You need to install either yajl-ruby, json, or json_pure gem')
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.select_json! mod, picked=false
|
74
|
-
if Object.const_defined?(:Yajl)
|
75
|
-
mod.send(:extend, YajlRuby)
|
76
|
-
elsif Object.const_defined?(:JSON)
|
77
|
-
mod.send(:extend, Json)
|
78
|
-
elsif picked
|
79
|
-
mod.send(:extend, Gsub)
|
80
|
-
else
|
81
|
-
# pick a json gem if available
|
82
|
-
%w[yajl json].each{ |json|
|
83
|
-
begin
|
84
|
-
require json
|
85
|
-
break
|
86
|
-
rescue LoadError
|
87
|
-
end
|
88
|
-
}
|
89
|
-
select_json!(mod, true)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
select_json!(self)
|
93
|
-
end
|