thrillcall-api 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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"># =&gt; [ {"id" =&gt; ... }, {...}, ...]</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"># =&gt; {"id" =&gt; 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">=&gt;</span> <span class="mi">5</span><span class="p">)</span>
105
+ <span class="c1"># =&gt; [ {"id" =&gt; ... }, {...}, ...]</span>
106
+ <span class="n">events</span><span class="o">.</span><span class="n">length</span>
107
+ <span class="c1"># =&gt; 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&amp;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">=&gt;</span> <span class="s2">"94101"</span><span class="p">,</span> <span class="ss">:radius</span> <span class="o">=&gt;</span> <span class="mi">20</span><span class="p">)</span>
114
+ <span class="c1"># =&gt; [{"name" =&gt; "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">=&gt;</span> <span class="s2">"https://api.thrillcall.com/custom/"</span><span class="p">,</span>
133
+ <span class="ss">:version</span> <span class="o">=&gt;</span> <span class="mi">3</span><span class="p">,</span>
134
+ <span class="ss">:logger</span> <span class="o">=&gt;</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">=&gt;</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"># =&gt; 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">=&gt;</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">=&gt;</span> <span class="no">BASE_URL</span><span class="p">,</span> <span class="ss">:headers</span> <span class="o">=&gt;</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">=&gt;</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"># =&gt; "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,7 @@
1
+ module ThrillcallAPI
2
+ class Error < StandardError
3
+ def initialize(details = {})
4
+ super("#{details[:type]}: #{details[:message]}")
5
+ end
6
+ end
7
+ 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