ticketevolution-ruby 0.6.6 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  source :gemcutter
2
2
 
3
3
  gem 'activesupport', '3.0.0'
4
- gem 'curb', '0.7.8'
4
+ gem 'faraday', '0.7.3'
5
5
  gem 'yajl-ruby', '0.7.7'
6
6
  gem 'multi_json', '0.0.4'
7
7
  gem 'nokogiri', '1.4.3'
data/README.markdown CHANGED
@@ -58,7 +58,7 @@ Each set of API credentials can be combined with a mode and api version to creat
58
58
  :version => 8 # => (optional) API version to use - the only available
59
59
  version at the time of this writing is 8
60
60
  :logger => nil # => (optional) Object to use for logging requests and
61
- # responses. Any object which responds to '<<'
61
+ # responses. Any 'Logger' instance object
62
62
  # is valid. EX: Logger.new('log/te_api.log')
63
63
  })
64
64
 
@@ -256,7 +256,7 @@ Click on the links next to each endpoint for more detail.
256
256
  @venue = @connection.venues.show(id)
257
257
 
258
258
 
259
- ######ticketevolution-ruby v0.6.2
259
+ ######ticketevolution-ruby v0.7.0
260
260
 
261
261
  License
262
262
  -------
data/Rakefile CHANGED
@@ -32,9 +32,8 @@ namespace :documentation do
32
32
  # Endpoints
33
33
  contents << load_doc('endpoints')
34
34
 
35
- endpoints_connection = Curl::Easy.new('http://developer.ticketevolution.com/endpoints.xml')
36
- endpoints_connection.http_get
37
- endpoints_xml = Nokogiri::XML(endpoints_connection.body_str)
35
+ endpoints_connection = Faraday.new('http://developer.ticketevolution.com/endpoints.xml').get
36
+ endpoints_xml = Nokogiri::XML(endpoints_connection.body)
38
37
 
39
38
  endpoints_xml.xpath('//endpoint').sort_by{|x| x.xpath('name').children.to_s}.each do |xml|
40
39
  presenter = ThisTask::EndpointPresenter.new(xml)
@@ -16,7 +16,7 @@ Each set of API credentials can be combined with a mode and api version to creat
16
16
  :version => 8 # => (optional) API version to use - the only available
17
17
  version at the time of this writing is 8
18
18
  :logger => nil # => (optional) Object to use for logging requests and
19
- # responses. Any object which responds to '<<'
19
+ # responses. Any 'Logger' instance object
20
20
  # is valid. EX: Logger.new('log/te_api.log')
21
21
  })
22
22
 
@@ -0,0 +1,34 @@
1
+ require 'forwardable'
2
+
3
+ module Faraday
4
+ class Response::VerboseLogger < Response::Middleware
5
+ extend Forwardable
6
+
7
+ def initialize(app, logger)
8
+ super(app)
9
+ @logger = logger
10
+ end
11
+
12
+ def_delegators :@logger, :debug, :info, :warn, :error, :fatal
13
+
14
+ def call(env)
15
+ info "#{env[:method]} #{env[:url].to_s}"
16
+ debug('request headers') { dump_headers env[:request_headers] }
17
+ debug('request body') { env[:body] }
18
+ super
19
+ end
20
+
21
+ def on_complete(env)
22
+ info('Status') { env[:status].to_s }
23
+ debug('response headers') { dump_headers env[:response_headers] }
24
+ debug('response body') { env[:body] }
25
+ end
26
+
27
+ private
28
+
29
+ def dump_headers(headers)
30
+ headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
31
+ end
32
+ end
33
+ end
34
+
@@ -1,6 +1,6 @@
1
1
  module TicketEvolution
2
2
  class Connection < Base
3
- cattr_reader :default_options, :expected_options, :oldest_version_in_service
3
+ cattr_reader :default_options, :expected_options, :oldest_version_in_service, :adapter
4
4
  cattr_accessor :protocol, :url_base
5
5
 
6
6
  @@oldest_version_in_service = 8
@@ -24,7 +24,10 @@ module TicketEvolution
24
24
  @@url_base = "ticketevolution.com"
25
25
  @@protocol = "https"
26
26
 
27
+ @@adapter = :net_http
28
+
27
29
  def initialize(opts = {})
30
+ @adapter = self.class.adapter
28
31
  @config = self.class.default_options.merge(opts)
29
32
  @config.delete_if{|k, v| ! TicketEvolution::Connection.expected_options.include?(k)}
30
33
 
@@ -56,27 +59,31 @@ module TicketEvolution
56
59
  end
57
60
 
58
61
  def sign(method, path, content = nil)
62
+ d = "#{method} #{process_params(method, path, content).gsub(TicketEvolution::Connection.protocol+'://', '').gsub(/\:\d{2,5}\//, '/')}"
59
63
  Base64.encode64(
60
64
  OpenSSL::HMAC.digest(
61
65
  OpenSSL::Digest::Digest.new('sha256'),
62
66
  @config[:secret],
63
- "#{method} #{process_params(method, path, content).gsub(TicketEvolution::Connection.protocol+'://', '').gsub(/\:\d{2,5}\//, '/')}"
67
+ d
64
68
  )).chomp
65
69
  end
66
70
 
67
71
  def build_request(method, path, params = nil)
68
- Curl::Easy.new(generate_url(method, self.uri(path), params)) do |request|
69
- if @config.has_key?(:ssl_verify)
70
- request.ssl_verify_host = @config[:ssl_verify]
71
- request.ssl_verify_peer = @config[:ssl_verify]
72
- end
73
- if self.logger.present?
74
- request.on_debug { |type, data| self.logger << data }
75
- end
76
- request.post_body = post_body(params) unless method == :GET
77
- request.headers["Accept"] = "application/vnd.ticketevolution.api+json; version=#{@config[:version]}" unless @config[:version] > 8
78
- request.headers["X-Signature"] = sign(method, self.uri(path), params)
79
- request.headers["X-Token"] = @config[:token]
72
+ options = {
73
+ :headers => {
74
+ "X-Signature" => sign(method, self.uri(path), params),
75
+ "X-Token" => @config[:token]
76
+ },
77
+ :ssl => {
78
+ :verify => @config[:ssl_verify]
79
+ }
80
+ }
81
+ options[:ssl][:verify] = false unless @config[:mode].to_s == 'production' ## REMOVE ME WHEN SANDBOX SSL IS FIXED
82
+ options[:params] = params if method == :GET
83
+ options[:headers]["Accept"] = "application/vnd.ticketevolution.api+json; version=#{@config[:version]}" unless @config[:version] > 8
84
+ Faraday.new(self.uri(path), options) do |builder|
85
+ builder.use Faraday::Response::VerboseLogger, self.logger if self.logger.present?
86
+ builder.adapter @adapter
80
87
  end
81
88
  end
82
89
 
@@ -90,15 +97,6 @@ module TicketEvolution
90
97
  MultiJson.encode(params)
91
98
  end
92
99
 
93
- def generate_url(method, uri, params)
94
- case method
95
- when :GET
96
- process_params(method, uri, params)
97
- else
98
- uri
99
- end
100
- end
101
-
102
100
  def process_params(method, uri, params)
103
101
  "#{uri}?#{if params.present?
104
102
  case method
@@ -20,11 +20,20 @@ module TicketEvolution
20
20
 
21
21
  def request(method, path, params = nil, &response_handler)
22
22
  redirecting = caller.first =~ /request_handler/ ? false : true
23
- response = self.build_request(method, path, params, redirecting)
24
- response.http(method)
25
- response = self.naturalize_response(response)
23
+ request = self.build_request(method, path, params, redirecting)
24
+
25
+ response = self.naturalize_response do
26
+ method = method.to_s.downcase.to_sym
27
+ if method == :get
28
+ request.send(method)
29
+ else
30
+ request.send(method) do |req|
31
+ req.body = MultiJson.encode(params)
32
+ end
33
+ end
34
+ end
26
35
  if [301, 302].include?(response.response_code)
27
- new_path = response.header.match(/Location: ([\w\.:\/]*)/).to_a[1].to_s.match(/^https?:\/\/[a-zA-Z_]+[\.a-zA-Z_]+(\/[\w\/]+)[\?]*/).to_a[1]
36
+ new_path = response.header['location'].match(/^https?:\/\/[a-zA-Z_]+[\.a-zA-Z_]+(\/[\w\/]+)[\?]*/).to_a[1]
28
37
  self.request(method, new_path, params, &response_handler)
29
38
  elsif response.response_code >= 300
30
39
  TicketEvolution::ApiError.new(response)
@@ -38,12 +47,13 @@ module TicketEvolution
38
47
  self.connection.build_request(method, "#{build_path ? self.base_path : ''}#{path}", params)
39
48
  end
40
49
 
41
- def naturalize_response(response)
50
+ def naturalize_response(response = nil)
51
+ response = yield if block_given?
42
52
  OpenStruct.new.tap do |resp|
43
- resp.header = response.header_str
44
- resp.response_code = response.response_code
45
- resp.body = MultiJson.decode(response.body_str).merge({:connection => self.connection})
46
- resp.server_message = (CODES[response.response_code] || ['Unknown Error']).last
53
+ resp.header = response.headers
54
+ resp.response_code = response.status
55
+ resp.body = MultiJson.decode(response.body).merge({:connection => self.connection})
56
+ resp.server_message = (CODES[resp.response_code] || ['Unknown Error']).last
47
57
  end
48
58
  end
49
59
  end
@@ -48,10 +48,12 @@ module TicketEvolution
48
48
  define_method(name) do
49
49
  begin
50
50
  obj = @table[name]
51
- def obj.endpoint=(e); @endpoint = e; end
52
- def obj.method_missing(method, *args); @endpoint.send(method, *args); end
53
- named_endpoint = "#{self.plural_class_name}::#{name.to_s.camelize}".constantize
54
- obj.endpoint = named_endpoint.new(:parent => self.plural_class.new(:id => self.id, :parent => @connection))
51
+ unless obj.nil?
52
+ def obj.endpoint=(e); @endpoint = e; end
53
+ def obj.method_missing(method, *args); @endpoint.send(method, *args); end
54
+ named_endpoint = "#{self.plural_class_name}::#{name.to_s.camelize}".constantize
55
+ obj.endpoint = named_endpoint.new(:parent => self.plural_class.new(:id => self.id, :parent => @connection))
56
+ end
55
57
  obj
56
58
  rescue
57
59
  @table[name]
@@ -4,20 +4,33 @@ module TicketEvolution
4
4
  def self.included(klass)
5
5
  Class.new{extend SingularClass}.singular_class(klass.name).send(:include, Module.new{
6
6
  def update_attributes(params)
7
- params.each{|k, v| send("#{k}=", process_datum(v))}
8
- plural_class.new({:parent => @connection, :id => params.delete(:id)}).update(params)
7
+ atts = self.attributes.merge(params)
8
+ id = atts.delete(:id)
9
+ response = plural_class.new({:parent => @connection, :id => id}).update(atts)
10
+ if response.is_a?(TicketEvolution::ApiError)
11
+ response
12
+ else
13
+ self.attributes = response.attributes
14
+ self
15
+ end
9
16
  end
10
17
 
11
18
  def save
12
- atts = self.attributes
13
- plural_class.new({:parent => @connection, :id => atts.delete(:id)}).update(atts)
19
+ update_attributes({})
14
20
  end
15
21
  })
16
22
  end
17
23
 
18
24
  def update(params = nil)
19
25
  ensure_id
20
- request(:PUT, "/#{self.id}", params)
26
+ request(:PUT, nil, params, &method(:build_for_update))
27
+ end
28
+
29
+ def build_for_update(response)
30
+ singular_class.new(response.body.merge({
31
+ :status_code => response.response_code,
32
+ :server_message => response.server_message
33
+ }))
21
34
  end
22
35
  end
23
36
  end
@@ -1,3 +1,3 @@
1
1
  module TicketEvolution
2
- VERSION = '0.6.6'
2
+ VERSION = '0.7.0'
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'yajl'
3
3
  require 'multi_json'
4
- require 'curb'
4
+ require 'faraday'
5
5
 
6
6
  require 'ostruct'
7
7
  require 'base64'
@@ -18,6 +18,8 @@ require 'active_support/core_ext/module'
18
18
  require 'active_support/core_ext/object'
19
19
  require 'active_support/inflector'
20
20
 
21
+ require 'faraday/response/verbose_logger'
22
+
21
23
  if ActiveSupport::VERSION::STRING < "3.1.0"
22
24
  class Hash
23
25
  def to_param(namespace = nil)
@@ -26,7 +26,7 @@ class Fake
26
26
 
27
27
  def self.redirect_response
28
28
  r = self.response
29
- r.header = "HTTP/1.1 301 Moved Permanently\r\nContent-Type: text/html\r\nConnection: keep-alive\r\nStatus: 301\r\nX-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.11\r\nX-UA-Compatible: IE=Edge,chrome=1\r\nLocation: http://api.ticketevolution.com/something_else/1\r\nX-Runtime: 0.001401\r\nContent-Length: 102\r\nServer: nginx/1.0.11 + Phusion Passenger 3.0.11 (mod_rails/mod_rack)\r\n\r\n"
29
+ r.header = {'location' => 'http://api.ticketevolution.com/something_else/1'}
30
30
  r.response_code = 302
31
31
  r.server_message = TicketEvolution::Endpoint::RequestHandler::CODES[302].last
32
32
  r
@@ -86,7 +86,7 @@
86
86
  accept:
87
87
  - application/vnd.ticketevolution.api+json; version=8
88
88
  x-signature:
89
- - F/qzyf3TZi71VSZ7GtP9yfgdfB/LFGKIqup6s5GoQ8E=
89
+ - 6tWs3CIO4szKWCKxo8OkrtPCxTsdgjAT32LrpgZvr4M=
90
90
  x-token:
91
91
  - 621e8a816a4e31a4dcf9f450e6de150f
92
92
  response: !ruby/struct:VCR::Response
@@ -107,7 +107,7 @@
107
107
  location:
108
108
  - http://developer.ticketevolution.com
109
109
  x-runtime:
110
- - '0.001958'
110
+ - '0.001729'
111
111
  content-length:
112
112
  - '102'
113
113
  server:
@@ -123,7 +123,7 @@
123
123
  accept:
124
124
  - application/vnd.ticketevolution.api+json; version=8
125
125
  x-signature:
126
- - F/qzyf3TZi71VSZ7GtP9yfgdfB/LFGKIqup6s5GoQ8E=
126
+ - 6tWs3CIO4szKWCKxo8OkrtPCxTsdgjAT32LrpgZvr4M=
127
127
  x-token:
128
128
  - 621e8a816a4e31a4dcf9f450e6de150f
129
129
  response: !ruby/struct:VCR::Response
@@ -144,7 +144,46 @@
144
144
  location:
145
145
  - http://developer.ticketevolution.com
146
146
  x-runtime:
147
- - '0.001958'
147
+ - '0.001729'
148
+ content-length:
149
+ - '102'
150
+ server:
151
+ - nginx/1.0.11 + Phusion Passenger 3.0.11 (mod_rails/mod_rack)
152
+ body: <html><body>You are being <a href="http://developer.ticketevolution.com">redirected</a>.</body></html>
153
+ http_version: '1.1'
154
+ - !ruby/struct:VCR::HTTPInteraction
155
+ request: !ruby/struct:VCR::Request
156
+ method: :get
157
+ uri: https://api.sandbox.ticketevolution.com:443/
158
+ body: !!null
159
+ headers:
160
+ x-signature:
161
+ - EHMCoxW80aA60GAi04x5zWHsthNwAijm8tu85Dw9mw0=
162
+ x-token:
163
+ - 621e8a816a4e31a4dcf9f450e6de150f
164
+ accept:
165
+ - application/vnd.ticketevolution.api+json; version=8
166
+ accept-encoding:
167
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
168
+ response: !ruby/struct:VCR::Response
169
+ status: !ruby/struct:VCR::ResponseStatus
170
+ code: 301
171
+ message: Moved Permanently
172
+ headers:
173
+ content-type:
174
+ - text/html
175
+ connection:
176
+ - keep-alive
177
+ status:
178
+ - '301'
179
+ x-powered-by:
180
+ - Phusion Passenger (mod_rails/mod_rack) 3.0.11
181
+ x-ua-compatible:
182
+ - IE=Edge,chrome=1
183
+ location:
184
+ - http://developer.ticketevolution.com
185
+ x-runtime:
186
+ - '0.002040'
148
187
  content-length:
149
188
  - '102'
150
189
  server:
@@ -327,3 +327,47 @@
327
327
  - nginx/1.0.11 + Phusion Passenger 3.0.11 (mod_rails/mod_rack)
328
328
  body: <html><body>You are being <a href="http://developer.ticketevolution.com">redirected</a>.</body></html>
329
329
  http_version: '1.1'
330
+ - !ruby/struct:VCR::HTTPInteraction
331
+ request: !ruby/struct:VCR::Request
332
+ method: :get
333
+ uri: https://api.sandbox.ticketevolution.com:443/accounts/62
334
+ body: !!null
335
+ headers:
336
+ x-signature:
337
+ - pJI/Zi+UHr/bfyNIT2P604nnFQdEoC6CyuasOGhKP68=
338
+ x-token:
339
+ - b2b5a7a33b1a78896ed1b53d81c5c9cc
340
+ accept:
341
+ - application/vnd.ticketevolution.api+json; version=8
342
+ accept-encoding:
343
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
344
+ response: !ruby/struct:VCR::Response
345
+ status: !ruby/struct:VCR::ResponseStatus
346
+ code: 200
347
+ message: OK
348
+ headers:
349
+ content-type:
350
+ - application/vnd.ticketevolution.api+json; version=8; charset=utf-8
351
+ transfer-encoding:
352
+ - chunked
353
+ connection:
354
+ - keep-alive
355
+ status:
356
+ - '200'
357
+ x-powered-by:
358
+ - Phusion Passenger (mod_rails/mod_rack) 3.0.11
359
+ etag:
360
+ - ! '"2aa05292e24fd9ebd325cc99027a64a1"'
361
+ x-ua-compatible:
362
+ - IE=Edge,chrome=1
363
+ x-runtime:
364
+ - '0.057554'
365
+ cache-control:
366
+ - max-age=0, private, must-revalidate
367
+ strict-transport-security:
368
+ - max-age=31536000
369
+ server:
370
+ - nginx/1.0.11 + Phusion Passenger 3.0.11 (mod_rails/mod_rack)
371
+ body: ! '{"balance":"8583.71","url":"/accounts/62","updated_at":"2012-02-13T18:47:04Z","currency":"USD","id":"62","client":{"url":"/clients/3","name":"Main
372
+ Office","id":"3"}}'
373
+ http_version: '1.1'
@@ -255,3 +255,47 @@
255
255
  - NY","_score":1.4142135,"name":"Totally New York","url":"/brokerages/725","id":"725","updated_at":"2011-02-10T13:44:47Z"},{"_type":"Brokerage","natb_member":false,"abbreviation":"At
256
256
  New York","_score":1.4142135,"name":"At New York & Company","url":"/brokerages/781","id":"781","updated_at":"2011-03-28T16:21:41Z"}]}'
257
257
  http_version: '1.1'
258
+ - !ruby/struct:VCR::HTTPInteraction
259
+ request: !ruby/struct:VCR::Request
260
+ method: :get
261
+ uri: https://api.sandbox.ticketevolution.com:443/brokerages/2
262
+ body: !!null
263
+ headers:
264
+ x-signature:
265
+ - 36B0ISsVd28X7Ml4r2v/QTYLf0q9lCnA0WFb98NZ004=
266
+ x-token:
267
+ - b2b5a7a33b1a78896ed1b53d81c5c9cc
268
+ accept:
269
+ - application/vnd.ticketevolution.api+json; version=8
270
+ accept-encoding:
271
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
272
+ response: !ruby/struct:VCR::Response
273
+ status: !ruby/struct:VCR::ResponseStatus
274
+ code: 200
275
+ message: OK
276
+ headers:
277
+ content-type:
278
+ - application/vnd.ticketevolution.api+json; version=8; charset=utf-8
279
+ transfer-encoding:
280
+ - chunked
281
+ connection:
282
+ - keep-alive
283
+ status:
284
+ - '200'
285
+ x-powered-by:
286
+ - Phusion Passenger (mod_rails/mod_rack) 3.0.11
287
+ etag:
288
+ - ! '"6d78396d1811212dc31c155b1b14a8a7"'
289
+ x-ua-compatible:
290
+ - IE=Edge,chrome=1
291
+ x-runtime:
292
+ - '0.447611'
293
+ cache-control:
294
+ - max-age=0, private, must-revalidate
295
+ strict-transport-security:
296
+ - max-age=31536000
297
+ server:
298
+ - nginx/1.0.11 + Phusion Passenger 3.0.11 (mod_rails/mod_rack)
299
+ body: ! '{"natb_member":true,"url":"/brokerages/2","updated_at":"2012-01-11T23:07:43Z","abbreviation":"Golden
300
+ Tickets","name":"Golden Tickets","id":"2"}'
301
+ http_version: '1.1'