apify 0.3.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/.gitignore +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +25 -0
- data/Rakefile +40 -0
- data/VERSION +1 -0
- data/apify.gemspec +103 -0
- data/app/helpers/apify_helper.rb +14 -0
- data/app/views/apify/api/_actions.html.erb +38 -0
- data/app/views/apify/api/_client.html.erb +38 -0
- data/app/views/apify/api/_overview.html.erb +9 -0
- data/app/views/apify/api/_protocol.html.erb +38 -0
- data/app/views/apify/api/docs.html.erb +66 -0
- data/lib/apify.rb +7 -0
- data/lib/apify/action.rb +98 -0
- data/lib/apify/api.rb +65 -0
- data/lib/apify/api_controller.rb +99 -0
- data/lib/apify/client.rb +52 -0
- data/lib/apify/errors.rb +12 -0
- data/lib/apify/exchange.rb +53 -0
- data/lib/apify/schema_helper.rb +56 -0
- data/spec/apify/action_spec.rb +35 -0
- data/spec/apify/client_spec.rb +24 -0
- data/spec/app_root/app/controllers/api_controller.rb +8 -0
- data/spec/app_root/app/controllers/application_controller.rb +3 -0
- data/spec/app_root/app/models/api.rb +42 -0
- data/spec/app_root/config/boot.rb +114 -0
- data/spec/app_root/config/database.yml +21 -0
- data/spec/app_root/config/environment.rb +14 -0
- data/spec/app_root/config/environments/in_memory.rb +0 -0
- data/spec/app_root/config/environments/mysql.rb +0 -0
- data/spec/app_root/config/environments/postgresql.rb +0 -0
- data/spec/app_root/config/environments/sqlite.rb +0 -0
- data/spec/app_root/config/environments/sqlite3.rb +0 -0
- data/spec/app_root/config/routes.rb +12 -0
- data/spec/app_root/lib/console_with_fixtures.rb +4 -0
- data/spec/app_root/script/console +7 -0
- data/spec/controllers/api_controller_spec.rb +155 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +31 -0
- metadata +151 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Henning Koch
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
apify
|
2
|
+
=====
|
3
|
+
|
4
|
+
Installation
|
5
|
+
------------
|
6
|
+
|
7
|
+
Install the gem with
|
8
|
+
|
9
|
+
sudo gem install apify
|
10
|
+
|
11
|
+
...
|
12
|
+
|
13
|
+
Rails 3 compatibility
|
14
|
+
---------------------
|
15
|
+
|
16
|
+
We cannot guarantee Rails 3 compatibility at this point, but we will upgrade the gem when Rails 3 is released.
|
17
|
+
|
18
|
+
Credits
|
19
|
+
-------
|
20
|
+
|
21
|
+
Henning Koch
|
22
|
+
|
23
|
+
{makandra.com}[http://makandra.com/]
|
24
|
+
|
25
|
+
{gem-session.com}[http://gem-session.com/]
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
desc 'Default: Run all specs.'
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
desc "Run all specs"
|
9
|
+
Spec::Rake::SpecTask.new() do |t|
|
10
|
+
t.spec_opts = ['--options', "\"spec/spec.opts\""]
|
11
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Generate documentation for the apify gem.'
|
15
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'apify'
|
18
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
19
|
+
rdoc.rdoc_files.include('README')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'jeweler'
|
25
|
+
Jeweler::Tasks.new do |gemspec|
|
26
|
+
gemspec.name = "apify"
|
27
|
+
gemspec.summary = "Compact definition of JSON APIs for Rails applications. "
|
28
|
+
gemspec.email = "github@makandra.de"
|
29
|
+
gemspec.homepage = "http://github.com/makandra/apify"
|
30
|
+
gemspec.description = "Compact definition of JSON APIs for Rails applications. "
|
31
|
+
gemspec.authors = ["Henning Koch"]
|
32
|
+
gemspec.add_dependency 'json'
|
33
|
+
gemspec.add_dependency 'jsonschema'
|
34
|
+
gemspec.add_dependency 'rest-client'
|
35
|
+
end
|
36
|
+
Jeweler::GemcutterTasks.new
|
37
|
+
rescue LoadError
|
38
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
39
|
+
end
|
40
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/apify.gemspec
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{apify}
|
8
|
+
s.version = "0.3.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Henning Koch"]
|
12
|
+
s.date = %q{2010-08-28}
|
13
|
+
s.description = %q{Compact definition of JSON APIs for Rails applications. }
|
14
|
+
s.email = %q{github@makandra.de}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"MIT-LICENSE",
|
21
|
+
"README.md",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"apify.gemspec",
|
25
|
+
"app/helpers/apify_helper.rb",
|
26
|
+
"app/views/apify/api/_actions.html.erb",
|
27
|
+
"app/views/apify/api/_client.html.erb",
|
28
|
+
"app/views/apify/api/_overview.html.erb",
|
29
|
+
"app/views/apify/api/_protocol.html.erb",
|
30
|
+
"app/views/apify/api/docs.html.erb",
|
31
|
+
"lib/apify.rb",
|
32
|
+
"lib/apify/action.rb",
|
33
|
+
"lib/apify/api.rb",
|
34
|
+
"lib/apify/api_controller.rb",
|
35
|
+
"lib/apify/client.rb",
|
36
|
+
"lib/apify/errors.rb",
|
37
|
+
"lib/apify/exchange.rb",
|
38
|
+
"lib/apify/schema_helper.rb",
|
39
|
+
"spec/apify/action_spec.rb",
|
40
|
+
"spec/apify/client_spec.rb",
|
41
|
+
"spec/app_root/app/controllers/api_controller.rb",
|
42
|
+
"spec/app_root/app/controllers/application_controller.rb",
|
43
|
+
"spec/app_root/app/models/api.rb",
|
44
|
+
"spec/app_root/config/boot.rb",
|
45
|
+
"spec/app_root/config/database.yml",
|
46
|
+
"spec/app_root/config/environment.rb",
|
47
|
+
"spec/app_root/config/environments/in_memory.rb",
|
48
|
+
"spec/app_root/config/environments/mysql.rb",
|
49
|
+
"spec/app_root/config/environments/postgresql.rb",
|
50
|
+
"spec/app_root/config/environments/sqlite.rb",
|
51
|
+
"spec/app_root/config/environments/sqlite3.rb",
|
52
|
+
"spec/app_root/config/routes.rb",
|
53
|
+
"spec/app_root/lib/console_with_fixtures.rb",
|
54
|
+
"spec/app_root/script/console",
|
55
|
+
"spec/controllers/api_controller_spec.rb",
|
56
|
+
"spec/rcov.opts",
|
57
|
+
"spec/spec.opts",
|
58
|
+
"spec/spec_helper.rb"
|
59
|
+
]
|
60
|
+
s.homepage = %q{http://github.com/makandra/apify}
|
61
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
62
|
+
s.require_paths = ["lib"]
|
63
|
+
s.rubygems_version = %q{1.3.6}
|
64
|
+
s.summary = %q{Compact definition of JSON APIs for Rails applications.}
|
65
|
+
s.test_files = [
|
66
|
+
"spec/apify/action_spec.rb",
|
67
|
+
"spec/apify/client_spec.rb",
|
68
|
+
"spec/spec_helper.rb",
|
69
|
+
"spec/app_root/app/controllers/api_controller.rb",
|
70
|
+
"spec/app_root/app/controllers/application_controller.rb",
|
71
|
+
"spec/app_root/app/models/api.rb",
|
72
|
+
"spec/app_root/lib/console_with_fixtures.rb",
|
73
|
+
"spec/app_root/config/environments/in_memory.rb",
|
74
|
+
"spec/app_root/config/environments/mysql.rb",
|
75
|
+
"spec/app_root/config/environments/postgresql.rb",
|
76
|
+
"spec/app_root/config/environments/sqlite.rb",
|
77
|
+
"spec/app_root/config/environments/sqlite3.rb",
|
78
|
+
"spec/app_root/config/boot.rb",
|
79
|
+
"spec/app_root/config/environment.rb",
|
80
|
+
"spec/app_root/config/routes.rb",
|
81
|
+
"spec/controllers/api_controller_spec.rb"
|
82
|
+
]
|
83
|
+
|
84
|
+
if s.respond_to? :specification_version then
|
85
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
86
|
+
s.specification_version = 3
|
87
|
+
|
88
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
89
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
90
|
+
s.add_runtime_dependency(%q<jsonschema>, [">= 0"])
|
91
|
+
s.add_runtime_dependency(%q<rest-client>, [">= 0"])
|
92
|
+
else
|
93
|
+
s.add_dependency(%q<json>, [">= 0"])
|
94
|
+
s.add_dependency(%q<jsonschema>, [">= 0"])
|
95
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
96
|
+
end
|
97
|
+
else
|
98
|
+
s.add_dependency(%q<json>, [">= 0"])
|
99
|
+
s.add_dependency(%q<jsonschema>, [">= 0"])
|
100
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ApifyHelper
|
2
|
+
|
3
|
+
def api_docs_artifact(action, artifact, nature)
|
4
|
+
show_id = "#{nature}_#{artifact}_for_#{action.name}"
|
5
|
+
show_link = link_to_function('show', "document.getElementById('#{show_id}').style.display = 'block';")
|
6
|
+
download_url = url_for(:action => action.name, artifact.to_sym => nature.to_s)
|
7
|
+
download_tooltip = "#{action.method.to_s.upcase} #{download_url} to download"
|
8
|
+
download_link = link_to('download', download_url, :method => action.method, :title => download_tooltip)
|
9
|
+
json = JSON.pretty_generate(action.send(artifact, nature))
|
10
|
+
embedded = "<pre id='#{show_id}' style='display: none'>#{json}</pre>"
|
11
|
+
"#{artifact.to_s.humanize} (#{show_link}, #{download_link})#{embedded}".html_safe
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<h2 id="api_actions">Available actions</h2>
|
2
|
+
|
3
|
+
<% api.actions.each do |action| %>
|
4
|
+
|
5
|
+
<div class="action">
|
6
|
+
|
7
|
+
<h3><%= action.method.to_s.upcase %> <%= action.name %></h3>
|
8
|
+
|
9
|
+
<% if action.description %>
|
10
|
+
<p><%=h action.description %></p>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<dl>
|
14
|
+
<dt>Arguments</dt>
|
15
|
+
<dd>
|
16
|
+
<% if action.takes_args? %>
|
17
|
+
<%= api_docs_artifact(action, :schema, :args) %>
|
18
|
+
<br />
|
19
|
+
<%= api_docs_artifact(action, :example, :args) %>
|
20
|
+
<% else %>
|
21
|
+
none
|
22
|
+
<% end %>
|
23
|
+
</dd>
|
24
|
+
<dt>Return value</dt>
|
25
|
+
<dd>
|
26
|
+
<% if action.returns_value? %>
|
27
|
+
<%= api_docs_artifact(action, :schema, :value) %>
|
28
|
+
<br />
|
29
|
+
<%= api_docs_artifact(action, :example, :value) %>
|
30
|
+
<% else %>
|
31
|
+
none
|
32
|
+
<% end %>
|
33
|
+
</dd>
|
34
|
+
</dl>
|
35
|
+
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<% end %>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<h2 id="api_client">Using the Ruby client</h2>
|
2
|
+
|
3
|
+
<p>
|
4
|
+
An easy way to use the API is to use the <code>Apify::Client</code> class.
|
5
|
+
It takes care of the protocol details and lets you focus on exchanging data.
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<h3>Installation</h3>
|
9
|
+
|
10
|
+
First install the Apify gem:
|
11
|
+
|
12
|
+
<pre><code>sudo gem install apify</code></pre>
|
13
|
+
|
14
|
+
In Rails 2, add the following to your environment.rb:
|
15
|
+
|
16
|
+
<pre><code>config.gem 'aegis'</code></pre>
|
17
|
+
|
18
|
+
In Rails 3, add the following to your Gemfile:
|
19
|
+
|
20
|
+
<pre><code>gem 'aegis'</code></pre>
|
21
|
+
|
22
|
+
<h3>Usage</h3>
|
23
|
+
|
24
|
+
<pre><code>client = Apify::Client.new(:host => 'localhost:3000', :user => 'api', :password => 'secret')
|
25
|
+
client.post('/api/hello', :name => 'Jack') # { 'message' => 'Hello Jack' }</code></pre>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
Errors can be caught and inspected like this:
|
29
|
+
</p>
|
30
|
+
|
31
|
+
<pre><code>begin
|
32
|
+
client.get('/api/hello', :name => 'Jack') # { 'message' => 'Hello Jack' }
|
33
|
+
rescue Apify::RequestFailed => e
|
34
|
+
puts "Oh no! The API request failed."
|
35
|
+
puts "Message: #{e.message}"
|
36
|
+
puts "Response: #{e.response_body}"
|
37
|
+
end
|
38
|
+
</code></pre>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<h2>Overview</h2>
|
2
|
+
|
3
|
+
<ul>
|
4
|
+
<li>The API works by exchanging messages encoded in <a href="http://en.wikipedia.org/wiki/JSON">JSON</a>.</li>
|
5
|
+
<li>There are no fancy message formats, it's all just sending arbitrary JSON objects back and forth.</li>
|
6
|
+
<li>There are some optional features like validating requests with schemas, but you don't need to use them if you don't like.</li>
|
7
|
+
<li>Building a lient that consumes the API is very straightforward. Also if you use Ruby, there is a helpful <a href="#api_client">client class</a> available.</li>
|
8
|
+
</ul>
|
9
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<h2 id="api_protocol">Protocol</h2>
|
2
|
+
|
3
|
+
<h3>Requests</h3>
|
4
|
+
|
5
|
+
<ul>
|
6
|
+
<li>The API is accessed over plain HTTP.</li>
|
7
|
+
<% if authentication_configured? %>
|
8
|
+
<li>HTTP basic authentication is used.</li>
|
9
|
+
<% end %>
|
10
|
+
<li>Take care to use the correct HTTP method (<code>GET, POST, PUT, DELETE</code>) as documented for each action.</li>
|
11
|
+
<li>Some (but not all) actions take arguments.</li>
|
12
|
+
<li>Action arguments are serialized into a <strong>single</strong> HTTP parameter <code>args</code> as JSON.</li>
|
13
|
+
<li>You can download an example for a request's arguments by appending <code>?example=args</code> to the action URL.</li>
|
14
|
+
<li>You can download a <a href="http://json-schema.org/">JSON schema</a> for a valid request by appending <code>?schema=args</code> to the action URL. Using the schema and a library like <a href="http://github.com/Constellation/ruby-jsonchema">jasonschema</a> you can validate your requests before sending them. The API will only process requests that conform to this schema.</li>
|
15
|
+
</ul>
|
16
|
+
|
17
|
+
<h3>Responses</h3>
|
18
|
+
|
19
|
+
<ul>
|
20
|
+
<li>Successful requests are returned with a status of 200 (OK).</li>
|
21
|
+
<li>The body of a successful response is always a hash, serialized as JSON.</li>
|
22
|
+
<li>Requests that have errors are returned with a status of 500 (internal server error). The body of a error response is an error message in plain text (no JSON here).</li>
|
23
|
+
<li>You can download an example for a successful response value by appending <code>?example=value</code> to the action URL.</li>
|
24
|
+
<li>You can download a <a href="http://json-schema.org/">JSON schema</a> for a successful response by appending <code>?schema=value</code> to the URL. The API guarantees that all responses conform to this schema.</li>
|
25
|
+
</ul>
|
26
|
+
|
27
|
+
<h3>Example for a request/response exchange</h3>
|
28
|
+
|
29
|
+
<ol>
|
30
|
+
<li>
|
31
|
+
API client sends to API host: <code>POST http://api-host/api/hello?args=JSON</code>
|
32
|
+
<br />
|
33
|
+
where JSON is a serialized JSON object: <code>'{ "name": "Jack" }'</code>
|
34
|
+
</li>
|
35
|
+
<li>
|
36
|
+
API host returns a response with a status of 200 (OK) and a serialized JSON object as its body: <code>'{ "message": "Hello Jack" }'</code>
|
37
|
+
</li>
|
38
|
+
</ol>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
5
|
+
<title>API documentation</title>
|
6
|
+
<style type="text/css">
|
7
|
+
<!--
|
8
|
+
body {
|
9
|
+
font-family: arial, helvetica, sans-serif;
|
10
|
+
font-size: 15px;
|
11
|
+
line-height: 19px;
|
12
|
+
}
|
13
|
+
#container {
|
14
|
+
max-width: 80%;
|
15
|
+
margin: 40px auto;
|
16
|
+
}
|
17
|
+
dt, dd {
|
18
|
+
margin-left: 0;
|
19
|
+
padding-left: 0;
|
20
|
+
}
|
21
|
+
dt {
|
22
|
+
font-weight: bold;
|
23
|
+
}
|
24
|
+
dl {
|
25
|
+
margin-bottom: 0;
|
26
|
+
}
|
27
|
+
h1, h2, h3, p, dd, ol, ul {
|
28
|
+
margin-bottom: 0.6em;
|
29
|
+
margin-top: 0;
|
30
|
+
}
|
31
|
+
h2 {
|
32
|
+
margin-top: 1em;
|
33
|
+
}
|
34
|
+
code {
|
35
|
+
font-family: courier new, monospace;
|
36
|
+
font-size: 15px;
|
37
|
+
background-color: #eee;
|
38
|
+
padding: 0 2px
|
39
|
+
}
|
40
|
+
pre {
|
41
|
+
background-color: #eee;
|
42
|
+
padding: 5px;
|
43
|
+
}
|
44
|
+
.action {
|
45
|
+
border: 1px dotted #777;
|
46
|
+
padding: 10px;
|
47
|
+
margin-bottom: 0.8em;
|
48
|
+
background-color: #f4f4f4;
|
49
|
+
}
|
50
|
+
.action dl dd:last-child {
|
51
|
+
margin-bottom: 0;
|
52
|
+
}
|
53
|
+
|
54
|
+
-->
|
55
|
+
</style>
|
56
|
+
</head>
|
57
|
+
<body>
|
58
|
+
<div id="container">
|
59
|
+
<h1>API documentation</h1>
|
60
|
+
<%= render :partial => 'apify/api/overview' %>
|
61
|
+
<%= render :partial => 'apify/api/protocol' %>
|
62
|
+
<%= render :partial => 'apify/api/client' %>
|
63
|
+
<%= render :partial => 'apify/api/actions' %>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
data/lib/apify.rb
ADDED
data/lib/apify/action.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
module Apify
|
2
|
+
class Action
|
3
|
+
|
4
|
+
attr_reader :name, :description, :method
|
5
|
+
|
6
|
+
def initialize(method, name, &block)
|
7
|
+
@method = method
|
8
|
+
@name = name
|
9
|
+
@schemas = Hash.new({}.freeze)
|
10
|
+
instance_eval(&block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def schema(nature, &block)
|
14
|
+
nature = nature.to_sym
|
15
|
+
if block
|
16
|
+
@schemas[nature] = eval_schema(block)
|
17
|
+
else
|
18
|
+
@schemas[nature]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond(args = nil, &block)
|
23
|
+
if block
|
24
|
+
@responder = block
|
25
|
+
else
|
26
|
+
Apify::Exchange.new.tap do |exchange|
|
27
|
+
exchange.respond(args, self)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def description(description = nil, &block)
|
33
|
+
if description || block
|
34
|
+
@description = description ? description : block.call
|
35
|
+
else
|
36
|
+
@description
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def takes_args?
|
41
|
+
schema(:args) != {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def returns_value?
|
45
|
+
schema(:value) != {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def responder
|
49
|
+
@responder || lambda {}
|
50
|
+
end
|
51
|
+
|
52
|
+
def example(schema_nature)
|
53
|
+
example_for_schema(schema(schema_nature))
|
54
|
+
end
|
55
|
+
|
56
|
+
def uid
|
57
|
+
"#{method}_#{name}"
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def example_for_schema(schema)
|
63
|
+
case schema['type']
|
64
|
+
when 'object'
|
65
|
+
{}.tap do |object|
|
66
|
+
if properties = schema['properties']
|
67
|
+
properties.each do |key, value|
|
68
|
+
object[key] = example_for_schema(value)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
when 'array'
|
73
|
+
[].tap do |array|
|
74
|
+
if items = schema['items']
|
75
|
+
array.concat [example_for_schema(items)] * 2
|
76
|
+
end
|
77
|
+
end
|
78
|
+
when 'boolean'
|
79
|
+
true
|
80
|
+
when 'number'
|
81
|
+
2.5
|
82
|
+
when 'integer'
|
83
|
+
123
|
84
|
+
when 'string'
|
85
|
+
'string'
|
86
|
+
else
|
87
|
+
raise "Unknown schema type: #{schema['type']}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def eval_schema(schema)
|
92
|
+
lathe = Object.new
|
93
|
+
lathe.extend Apify::SchemaHelper
|
94
|
+
lathe.instance_eval(&schema)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|