thrillcall-api 0.0.3
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/.autotest +10 -0
- data/.gitignore +10 -0
- data/.rspec +4 -0
- data/.rvmrc +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +58 -0
- data/README.md +1141 -0
- data/Rakefile +2 -0
- data/autotest/discover.rb +1 -0
- data/docs/API.html +1262 -0
- data/docs/API.md +1024 -0
- data/docs/README.html +1382 -0
- data/docs/WRAPPER.html +182 -0
- data/docs/WRAPPER.md +115 -0
- data/lib/thrillcall-api.rb +76 -0
- data/lib/thrillcall-api/exceptions.rb +7 -0
- data/lib/thrillcall-api/result.rb +142 -0
- data/lib/thrillcall-api/version.rb +3 -0
- data/script/convert_readme.rb +119 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/thrillcall-api/thrillcall-api_spec.rb +477 -0
- data/thrillcall-api.gemspec +34 -0
- metadata +201 -0
data/docs/WRAPPER.html
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
|
2
|
+
<style type="text/css">
|
3
|
+
.highlight .hll { background-color: #ffffcc }
|
4
|
+
.highlight { background: #dddddd; }
|
5
|
+
.highlight .c { color: #408080; font-style: italic } /* Comment */
|
6
|
+
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
7
|
+
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
8
|
+
.highlight .o { color: #666666 } /* Operator */
|
9
|
+
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
10
|
+
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
|
11
|
+
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
12
|
+
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
|
13
|
+
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
14
|
+
.highlight .ge { font-style: italic } /* Generic.Emph */
|
15
|
+
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
16
|
+
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
17
|
+
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
18
|
+
.highlight .go { color: #808080 } /* Generic.Output */
|
19
|
+
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
20
|
+
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
21
|
+
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
22
|
+
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
|
23
|
+
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
24
|
+
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
25
|
+
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
26
|
+
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
27
|
+
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
28
|
+
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
29
|
+
.highlight .m { color: #666666 } /* Literal.Number */
|
30
|
+
.highlight .s { color: #BA2121 } /* Literal.String */
|
31
|
+
.highlight .na { color: #7D9029 } /* Name.Attribute */
|
32
|
+
.highlight .nb { color: #008000 } /* Name.Builtin */
|
33
|
+
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
34
|
+
.highlight .no { color: #880000 } /* Name.Constant */
|
35
|
+
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
36
|
+
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
37
|
+
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
38
|
+
.highlight .nf { color: #0000FF } /* Name.Function */
|
39
|
+
.highlight .nl { color: #A0A000 } /* Name.Label */
|
40
|
+
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
41
|
+
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
42
|
+
.highlight .nv { color: #19177C } /* Name.Variable */
|
43
|
+
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
44
|
+
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
45
|
+
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
46
|
+
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
47
|
+
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
48
|
+
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
49
|
+
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
50
|
+
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
51
|
+
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
52
|
+
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
53
|
+
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
54
|
+
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
55
|
+
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
56
|
+
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
57
|
+
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
|
58
|
+
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
59
|
+
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
60
|
+
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
61
|
+
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
62
|
+
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
63
|
+
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
64
|
+
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
65
|
+
</style><h1>Thrillcall API</h1>
|
66
|
+
|
67
|
+
<p>This document describes the Thrillcall API v2, and usage for the provided Ruby API wrapper gem.</p>
|
68
|
+
|
69
|
+
<h1>Ruby API Wrapper</h1>
|
70
|
+
|
71
|
+
<h3>Usage:</h3>
|
72
|
+
|
73
|
+
<div class="highlight">
|
74
|
+
<pre> <span class="c1">#---------------------------------------------------------------#</span>
|
75
|
+
<span class="c1"># First, require the gem:</span>
|
76
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
77
|
+
<span class="nb">require</span> <span class="s1">'rubygems'</span>
|
78
|
+
<span class="nb">require</span> <span class="s1">'thrillcall-api'</span>
|
79
|
+
|
80
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
81
|
+
<span class="c1"># Instantiate with your Thrillcall API key:</span>
|
82
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
83
|
+
<span class="no">MY_API_KEY</span> <span class="o">=</span> <span class="s2">"1234567890abcdef"</span>
|
84
|
+
<span class="n">tc</span> <span class="o">=</span> <span class="no">ThrillcallAPI</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">MY_API_KEY</span><span class="p">)</span>
|
85
|
+
|
86
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
87
|
+
<span class="c1"># Access any endpoint directly from the instance</span>
|
88
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
89
|
+
<span class="c1"># This is like calling GET "/events"</span>
|
90
|
+
<span class="n">tc</span><span class="o">.</span><span class="n">events</span>
|
91
|
+
<span class="c1"># => [ {"id" => ... }, {...}, ...]</span>
|
92
|
+
|
93
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
94
|
+
<span class="c1"># Provide IDs as arguments</span>
|
95
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
96
|
+
<span class="c1"># GET "/event/1"</span>
|
97
|
+
<span class="n">tc</span><span class="o">.</span><span class="n">event</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
98
|
+
<span class="c1"># => {"id" => 1, ...}</span>
|
99
|
+
|
100
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
101
|
+
<span class="c1"># Provide parameters as arguments</span>
|
102
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
103
|
+
<span class="c1"># GET "/events?limit=5"</span>
|
104
|
+
<span class="n">events</span> <span class="o">=</span> <span class="n">tc</span><span class="o">.</span><span class="n">events</span><span class="p">(</span><span class="ss">:limit</span> <span class="o">=></span> <span class="mi">5</span><span class="p">)</span>
|
105
|
+
<span class="c1"># => [ {"id" => ... }, {...}, ...]</span>
|
106
|
+
<span class="n">events</span><span class="o">.</span><span class="n">length</span>
|
107
|
+
<span class="c1"># => 5</span>
|
108
|
+
|
109
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
110
|
+
<span class="c1"># Chain methods together for nested routes</span>
|
111
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
112
|
+
<span class="c1"># GET "/search/venues/warfield?postalcode=94101&radius=20"</span>
|
113
|
+
<span class="n">venues</span> <span class="o">=</span> <span class="n">tc</span><span class="o">.</span><span class="n">search</span><span class="o">.</span><span class="n">venues</span><span class="p">(</span><span class="s2">"warfield"</span><span class="p">,</span> <span class="ss">:postalcode</span> <span class="o">=></span> <span class="s2">"94101"</span><span class="p">,</span> <span class="ss">:radius</span> <span class="o">=></span> <span class="mi">20</span><span class="p">)</span>
|
114
|
+
<span class="c1"># => [{"name" => "The Warfield", ...}]</span>
|
115
|
+
</pre>
|
116
|
+
</div>
|
117
|
+
|
118
|
+
|
119
|
+
<h3>Advanced Usage:</h3>
|
120
|
+
|
121
|
+
<p>Provide additional instantiation options:</p>
|
122
|
+
|
123
|
+
<div class="highlight">
|
124
|
+
<pre> <span class="c1">#---------------------------------------------------------------#</span>
|
125
|
+
<span class="c1"># The default SSL endpoint is "https://api.thrillcall.com/api/".</span>
|
126
|
+
<span class="c1"># The default API version is 2.</span>
|
127
|
+
<span class="c1"># By default, Faraday access logging is turned off.</span>
|
128
|
+
<span class="c1"># Override if necessary:</span>
|
129
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
130
|
+
<span class="n">tc</span> <span class="o">=</span> <span class="no">ThrillcallAPI</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
|
131
|
+
<span class="no">MY_API_KEY</span><span class="p">,</span>
|
132
|
+
<span class="ss">:base_url</span> <span class="o">=></span> <span class="s2">"https://api.thrillcall.com/custom/"</span><span class="p">,</span>
|
133
|
+
<span class="ss">:version</span> <span class="o">=></span> <span class="mi">3</span><span class="p">,</span>
|
134
|
+
<span class="ss">:logger</span> <span class="o">=></span> <span class="kp">true</span>
|
135
|
+
<span class="p">)</span>
|
136
|
+
</pre>
|
137
|
+
</div>
|
138
|
+
|
139
|
+
|
140
|
+
<p>Internally, the wrapper returns a ThrillcallAPI::Result class for any call. Data for the request is fetched only when used. This allows you to build requests piecemeal before executing them.</p>
|
141
|
+
|
142
|
+
<div class="highlight">
|
143
|
+
<pre> <span class="c1">#---------------------------------------------------------------#</span>
|
144
|
+
<span class="c1"># Build a partial request, add on to it later</span>
|
145
|
+
<span class="c1">#---------------------------------------------------------------#</span>
|
146
|
+
<span class="n">request</span> <span class="o">=</span> <span class="n">tc</span><span class="o">.</span><span class="n">artist</span><span class="p">(</span><span class="mi">22210</span><span class="p">)</span> <span class="c1"># Lady Gaga</span>
|
147
|
+
|
148
|
+
<span class="c1"># GET "/artist/22210/events?limit=2"</span>
|
149
|
+
<span class="n">artist_events</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">events</span><span class="p">(</span><span class="ss">:limit</span> <span class="o">=></span> <span class="mi">2</span><span class="p">)</span>
|
150
|
+
|
151
|
+
<span class="n">artist_events</span><span class="o">.</span><span class="n">length</span>
|
152
|
+
<span class="c1"># => 2</span>
|
153
|
+
</pre>
|
154
|
+
</div>
|
155
|
+
|
156
|
+
|
157
|
+
<p>This gem is a convenience wrapper around the excellent Faraday project. If more complicated use cases are necessary, consider using Faraday directly.</p>
|
158
|
+
|
159
|
+
<div class="highlight">
|
160
|
+
<pre> <span class="nb">require</span> <span class="s1">'faraday'</span>
|
161
|
+
<span class="nb">require</span> <span class="s1">'json'</span>
|
162
|
+
|
163
|
+
<span class="no">MY_API_KEY</span> <span class="o">=</span> <span class="s2">"1234567890abcdef"</span>
|
164
|
+
<span class="no">BASE_URL</span> <span class="o">=</span> <span class="s2">"https://api.thrillcall.com/api/v2/"</span>
|
165
|
+
<span class="no">HEADERS</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">:accept</span> <span class="o">=></span> <span class="s1">'application/json'</span> <span class="p">}</span>
|
166
|
+
|
167
|
+
<span class="n">connection</span> <span class="o">=</span> <span class="no">Faraday</span><span class="o">.</span><span class="n">new</span><span class="p">(</span> <span class="ss">:url</span> <span class="o">=></span> <span class="no">BASE_URL</span><span class="p">,</span> <span class="ss">:headers</span> <span class="o">=></span> <span class="no">HEADERS</span> <span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">builder</span><span class="o">|</span>
|
168
|
+
<span class="n">builder</span><span class="o">.</span><span class="n">adapter</span> <span class="no">Faraday</span><span class="o">.</span><span class="n">default_adapter</span>
|
169
|
+
<span class="n">builder</span><span class="o">.</span><span class="n">response</span> <span class="ss">:logger</span>
|
170
|
+
<span class="n">builder</span><span class="o">.</span><span class="n">response</span> <span class="ss">:raise_error</span>
|
171
|
+
<span class="k">end</span>
|
172
|
+
|
173
|
+
<span class="n">request</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">get</span> <span class="k">do</span> <span class="o">|</span><span class="n">req</span><span class="o">|</span>
|
174
|
+
<span class="n">req</span><span class="o">.</span><span class="n">url</span> <span class="s2">"artist/22210"</span><span class="p">,</span> <span class="p">{</span> <span class="ss">:api_key</span> <span class="o">=></span> <span class="no">MY_API_KEY</span> <span class="p">}</span>
|
175
|
+
<span class="k">end</span>
|
176
|
+
|
177
|
+
<span class="n">artist</span> <span class="o">=</span> <span class="no">JSON</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">body</span><span class="p">)</span>
|
178
|
+
|
179
|
+
<span class="n">artist</span><span class="o">[</span><span class="s2">"name"</span><span class="o">]</span>
|
180
|
+
<span class="c1"># => "Lady Gaga"</span>
|
181
|
+
</pre>
|
182
|
+
</div>
|
data/docs/WRAPPER.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# Thrillcall API
|
2
|
+
This document describes the Thrillcall API v2, and usage for the provided Ruby API wrapper gem.
|
3
|
+
|
4
|
+
# Ruby API Wrapper
|
5
|
+
### Usage:
|
6
|
+
|
7
|
+
``` ruby
|
8
|
+
#---------------------------------------------------------------#
|
9
|
+
# First, require the gem:
|
10
|
+
#---------------------------------------------------------------#
|
11
|
+
require 'rubygems'
|
12
|
+
require 'thrillcall-api'
|
13
|
+
|
14
|
+
#---------------------------------------------------------------#
|
15
|
+
# Instantiate with your Thrillcall API key:
|
16
|
+
#---------------------------------------------------------------#
|
17
|
+
MY_API_KEY = "1234567890abcdef"
|
18
|
+
tc = ThrillcallAPI.new(MY_API_KEY)
|
19
|
+
|
20
|
+
#---------------------------------------------------------------#
|
21
|
+
# Access any endpoint directly from the instance
|
22
|
+
#---------------------------------------------------------------#
|
23
|
+
# This is like calling GET "/events"
|
24
|
+
tc.events
|
25
|
+
# => [ {"id" => ... }, {...}, ...]
|
26
|
+
|
27
|
+
#---------------------------------------------------------------#
|
28
|
+
# Provide IDs as arguments
|
29
|
+
#---------------------------------------------------------------#
|
30
|
+
# GET "/event/1"
|
31
|
+
tc.event(1)
|
32
|
+
# => {"id" => 1, ...}
|
33
|
+
|
34
|
+
#---------------------------------------------------------------#
|
35
|
+
# Provide parameters as arguments
|
36
|
+
#---------------------------------------------------------------#
|
37
|
+
# GET "/events?limit=5"
|
38
|
+
events = tc.events(:limit => 5)
|
39
|
+
# => [ {"id" => ... }, {...}, ...]
|
40
|
+
events.length
|
41
|
+
# => 5
|
42
|
+
|
43
|
+
#---------------------------------------------------------------#
|
44
|
+
# Chain methods together for nested routes
|
45
|
+
#---------------------------------------------------------------#
|
46
|
+
# GET "/search/venues/warfield?postalcode=94101&radius=20"
|
47
|
+
venues = tc.search.venues("warfield", :postalcode => "94101", :radius => 20)
|
48
|
+
# => [{"name" => "The Warfield", ...}]
|
49
|
+
```
|
50
|
+
|
51
|
+
### Advanced Usage:
|
52
|
+
|
53
|
+
Provide additional instantiation options:
|
54
|
+
|
55
|
+
``` ruby
|
56
|
+
|
57
|
+
#---------------------------------------------------------------#
|
58
|
+
# The default SSL endpoint is "https://api.thrillcall.com/api/".
|
59
|
+
# The default API version is 2.
|
60
|
+
# By default, Faraday access logging is turned off.
|
61
|
+
# Override if necessary:
|
62
|
+
#---------------------------------------------------------------#
|
63
|
+
tc = ThrillcallAPI.new(
|
64
|
+
MY_API_KEY,
|
65
|
+
:base_url => "https://api.thrillcall.com/custom/",
|
66
|
+
:version => 3,
|
67
|
+
:logger => true
|
68
|
+
)
|
69
|
+
|
70
|
+
```
|
71
|
+
|
72
|
+
Internally, the wrapper returns a ThrillcallAPI::Result class for any call. Data for the request is fetched only when used. This allows you to build requests piecemeal before executing them.
|
73
|
+
|
74
|
+
``` ruby
|
75
|
+
|
76
|
+
#---------------------------------------------------------------#
|
77
|
+
# Build a partial request, add on to it later
|
78
|
+
#---------------------------------------------------------------#
|
79
|
+
request = tc.artist(22210) # Lady Gaga
|
80
|
+
|
81
|
+
# GET "/artist/22210/events?limit=2"
|
82
|
+
artist_events = request.events(:limit => 2)
|
83
|
+
|
84
|
+
artist_events.length
|
85
|
+
# => 2
|
86
|
+
|
87
|
+
```
|
88
|
+
|
89
|
+
This gem is a convenience wrapper around the excellent Faraday project. If more complicated use cases are necessary, consider using Faraday directly.
|
90
|
+
|
91
|
+
``` ruby
|
92
|
+
|
93
|
+
require 'faraday'
|
94
|
+
require 'json'
|
95
|
+
|
96
|
+
MY_API_KEY = "1234567890abcdef"
|
97
|
+
BASE_URL = "https://api.thrillcall.com/api/v2/"
|
98
|
+
HEADERS = { :accept => 'application/json' }
|
99
|
+
|
100
|
+
connection = Faraday.new( :url => BASE_URL, :headers => HEADERS ) do |builder|
|
101
|
+
builder.adapter Faraday.default_adapter
|
102
|
+
builder.response :logger
|
103
|
+
builder.response :raise_error
|
104
|
+
end
|
105
|
+
|
106
|
+
request = connection.get do |req|
|
107
|
+
req.url "artist/22210", { :api_key => MY_API_KEY }
|
108
|
+
end
|
109
|
+
|
110
|
+
artist = JSON.parse(request.body)
|
111
|
+
|
112
|
+
artist["name"]
|
113
|
+
# => "Lady Gaga"
|
114
|
+
|
115
|
+
```
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
require "#{File.expand_path("../thrillcall-api/exceptions", __FILE__)}"
|
4
|
+
require "#{File.expand_path("../thrillcall-api/result", __FILE__)}"
|
5
|
+
require "#{File.expand_path("../thrillcall-api/version", __FILE__)}"
|
6
|
+
|
7
|
+
module ThrillcallAPI
|
8
|
+
class << self
|
9
|
+
attr_accessor :cur_api_key, :base, :result, :conn
|
10
|
+
|
11
|
+
# Set up the Faraday connection based on configuration
|
12
|
+
def new(cur_api_key, options = {})
|
13
|
+
default_options = {
|
14
|
+
:base_url => "https://api.thrillcall.com/api/",
|
15
|
+
:version => 2,
|
16
|
+
:logger => false
|
17
|
+
}
|
18
|
+
|
19
|
+
opts = default_options.merge(options)
|
20
|
+
|
21
|
+
@cur_api_key = cur_api_key
|
22
|
+
base_url = opts[:base_url]
|
23
|
+
version = opts[:version]
|
24
|
+
logger = opts[:logger]
|
25
|
+
|
26
|
+
# Make sure the base_url is in the form https://.../
|
27
|
+
unless base_url.match /^(http|https):\/\//
|
28
|
+
base_url = "https://" + base_url
|
29
|
+
end
|
30
|
+
|
31
|
+
unless base_url.match /\/$/
|
32
|
+
base_url = base_url + "/"
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set JSON accept header and custom user agent
|
36
|
+
@headers = {
|
37
|
+
:accept => 'application/json',
|
38
|
+
:user_agent => "Thrillcall API Wrapper version #{ThrillcallAPI::VERSION}"
|
39
|
+
}
|
40
|
+
|
41
|
+
@base = "#{base_url}v#{version}/"
|
42
|
+
@conn = Faraday.new( :url => @base, :headers => @headers ) do |builder|
|
43
|
+
builder.adapter Faraday.default_adapter
|
44
|
+
if logger
|
45
|
+
builder.response :logger
|
46
|
+
end
|
47
|
+
# This will raise an exception if an error occurs during a request
|
48
|
+
builder.response :raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
@result = Result.new
|
52
|
+
|
53
|
+
return self
|
54
|
+
end
|
55
|
+
|
56
|
+
def get(endpoint, params)
|
57
|
+
r = @conn.get do |req|
|
58
|
+
req.url endpoint, params.merge(:api_key => @cur_api_key)
|
59
|
+
end
|
60
|
+
JSON.parse(r.body)
|
61
|
+
end
|
62
|
+
|
63
|
+
def post(endpoint, params)
|
64
|
+
r = @conn.post do |req|
|
65
|
+
req.url endpoint, params.merge(:api_key => @cur_api_key)
|
66
|
+
end
|
67
|
+
JSON.parse(r.body)
|
68
|
+
end
|
69
|
+
|
70
|
+
def method_missing(method, *args, &block)
|
71
|
+
r = Result.new
|
72
|
+
r.send(method, args, block)
|
73
|
+
return r
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# Adapted from
|
2
|
+
# http://stackoverflow.com/questions/1332404/how-to-detect-the-end-of-a-method-chain-in-ruby
|
3
|
+
# and
|
4
|
+
# http://blog.jayfields.com/2008/02/ruby-replace-methodmissing-with-dynamic.html
|
5
|
+
|
6
|
+
module ThrillcallAPI
|
7
|
+
class Result
|
8
|
+
attr_accessor :ran, :request_keys, :options, :set_methods, :http_method
|
9
|
+
attr_reader :data
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
reset
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset
|
16
|
+
if @set_methods
|
17
|
+
unset_methods
|
18
|
+
end
|
19
|
+
@ran = false
|
20
|
+
@data = {} # could be an array after fetch
|
21
|
+
@end_of_chain_is_singular = false
|
22
|
+
@options = {}
|
23
|
+
@request_keys = []
|
24
|
+
@set_methods = []
|
25
|
+
@http_method = :get
|
26
|
+
end
|
27
|
+
|
28
|
+
# Removes any dynamically defined methods
|
29
|
+
def unset_methods
|
30
|
+
@set_methods.each do |s|
|
31
|
+
(class << self; self; end).class_eval do
|
32
|
+
undef_method s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
@set_methods = []
|
37
|
+
end
|
38
|
+
|
39
|
+
# Dynamically defines any methods available to data.
|
40
|
+
# i.e. it puts on a "#{data.class}" costume
|
41
|
+
def reassign(data)
|
42
|
+
unset_methods
|
43
|
+
|
44
|
+
data.public_methods(false).each do |meth|
|
45
|
+
@set_methods << meth
|
46
|
+
(class << self; self; end).class_eval do
|
47
|
+
define_method meth do |*args, &block|
|
48
|
+
data.send meth, *args, &block
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Append the name of the method and any args to the current
|
55
|
+
# request being built
|
56
|
+
def append(key, *args)
|
57
|
+
|
58
|
+
# If this is called but we've already fetched data, reset
|
59
|
+
if @ran
|
60
|
+
reset
|
61
|
+
end
|
62
|
+
|
63
|
+
@request_keys << key
|
64
|
+
|
65
|
+
if args
|
66
|
+
if args.is_a? Array
|
67
|
+
args = args.flatten
|
68
|
+
end
|
69
|
+
args.each do |arg|
|
70
|
+
if arg
|
71
|
+
a = arg
|
72
|
+
if a.is_a? Hash
|
73
|
+
# Merge this hash on top of the existing options
|
74
|
+
@options.merge!(a)
|
75
|
+
else
|
76
|
+
# This is an ID or search term, add it directly to the
|
77
|
+
# list of keys
|
78
|
+
@request_keys << a.to_s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def run(method, *args, &block)
|
86
|
+
# Fetch data if necessary. This will also "put on the
|
87
|
+
# data.class costume" and allow the method to respond to a
|
88
|
+
# subsequent send()
|
89
|
+
if !@ran
|
90
|
+
fetch_data
|
91
|
+
end
|
92
|
+
|
93
|
+
# Send the requested method out to the newly defined method
|
94
|
+
self.send(method, *args, &block)
|
95
|
+
end
|
96
|
+
|
97
|
+
def fetch_data
|
98
|
+
url = URI.escape(@request_keys.join("/"))
|
99
|
+
|
100
|
+
@data = ThrillcallAPI.send(@http_method, url, @options)
|
101
|
+
|
102
|
+
# Now we define the instance methods present in the data object
|
103
|
+
# so that we can use this object *as if* we are using the data
|
104
|
+
# object directly and we don't encounter method_missing
|
105
|
+
reassign(@data)
|
106
|
+
|
107
|
+
@ran = true
|
108
|
+
end
|
109
|
+
|
110
|
+
def post(args = {})
|
111
|
+
if @ran
|
112
|
+
raise ArgumentError, "This request has already been made!"
|
113
|
+
else
|
114
|
+
@http_method = :post
|
115
|
+
@options.merge!(args)
|
116
|
+
fetch_data
|
117
|
+
end
|
118
|
+
@data
|
119
|
+
end
|
120
|
+
|
121
|
+
def method_missing(method, *args, &block)
|
122
|
+
|
123
|
+
if @ran
|
124
|
+
# NoMethodError
|
125
|
+
super
|
126
|
+
else
|
127
|
+
# We haven't fetched the data yet, but if this method is for
|
128
|
+
# a hash or an array, we'd better.
|
129
|
+
# The bad news about this technique is that we can't have any
|
130
|
+
# endpoints that map to array or hash methods
|
131
|
+
if {}.respond_to?(method) || [].respond_to?(method)
|
132
|
+
r = run(method, *args, &block)
|
133
|
+
return r
|
134
|
+
else # Keep building the request
|
135
|
+
append(method, *args)
|
136
|
+
return self
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|