ticketevolution-ruby 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/.rdebugrc +1 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +7 -0
- data/LICENSE +23 -0
- data/README.markdown +237 -0
- data/Rakefile +124 -0
- data/examples/events.rb +64 -0
- data/lib/docs/endpoints.markdown +47 -0
- data/lib/docs/installation.markdown +5 -0
- data/lib/docs/introduction.markdown +16 -0
- data/lib/docs/objects.markdown +40 -0
- data/lib/ticket_evolution/account.rb +4 -0
- data/lib/ticket_evolution/accounts.rb +6 -0
- data/lib/ticket_evolution/address.rb +4 -0
- data/lib/ticket_evolution/brokerage.rb +4 -0
- data/lib/ticket_evolution/brokerages.rb +7 -0
- data/lib/ticket_evolution/categories.rb +7 -0
- data/lib/ticket_evolution/category.rb +4 -0
- data/lib/ticket_evolution/client.rb +4 -0
- data/lib/ticket_evolution/clients/addresses.rb +10 -0
- data/lib/ticket_evolution/clients/credit_cards.rb +8 -0
- data/lib/ticket_evolution/clients/email_addresses.rb +10 -0
- data/lib/ticket_evolution/clients/phone_numbers.rb +10 -0
- data/lib/ticket_evolution/clients.rb +8 -0
- data/lib/ticket_evolution/configuration.rb +4 -0
- data/lib/ticket_evolution/configurations.rb +6 -0
- data/lib/ticket_evolution/core/api_error.rb +11 -0
- data/lib/ticket_evolution/core/base.rb +12 -0
- data/lib/ticket_evolution/core/builder.rb +74 -0
- data/lib/ticket_evolution/core/collection.rb +32 -0
- data/lib/ticket_evolution/core/connection.rb +99 -0
- data/lib/ticket_evolution/core/datum.rb +7 -0
- data/lib/ticket_evolution/core/endpoint/request_handler.rb +46 -0
- data/lib/ticket_evolution/core/endpoint.rb +51 -0
- data/lib/ticket_evolution/core/model.rb +64 -0
- data/lib/ticket_evolution/core/models/samples.rb +8 -0
- data/lib/ticket_evolution/core/samples.rb +6 -0
- data/lib/ticket_evolution/core/singular_class.rb +7 -0
- data/lib/ticket_evolution/core/time.rb +19 -0
- data/lib/ticket_evolution/credit_card.rb +4 -0
- data/lib/ticket_evolution/email_address.rb +4 -0
- data/lib/ticket_evolution/errors/connection_not_found.rb +4 -0
- data/lib/ticket_evolution/errors/endpoint_configuration_error.rb +5 -0
- data/lib/ticket_evolution/errors/invalid_configuration.rb +4 -0
- data/lib/ticket_evolution/errors/method_unavailable_error.rb +4 -0
- data/lib/ticket_evolution/event.rb +4 -0
- data/lib/ticket_evolution/events.rb +7 -0
- data/lib/ticket_evolution/modules/create.rb +18 -0
- data/lib/ticket_evolution/modules/deleted.rb +13 -0
- data/lib/ticket_evolution/modules/list.rb +15 -0
- data/lib/ticket_evolution/modules/search.rb +13 -0
- data/lib/ticket_evolution/modules/show.rb +20 -0
- data/lib/ticket_evolution/modules/update.rb +24 -0
- data/lib/ticket_evolution/office.rb +4 -0
- data/lib/ticket_evolution/offices.rb +7 -0
- data/lib/ticket_evolution/order.rb +15 -0
- data/lib/ticket_evolution/orders.rb +30 -0
- data/lib/ticket_evolution/performer.rb +4 -0
- data/lib/ticket_evolution/performers.rb +8 -0
- data/lib/ticket_evolution/phone_number.rb +4 -0
- data/lib/ticket_evolution/quote.rb +4 -0
- data/lib/ticket_evolution/quotes.rb +7 -0
- data/lib/ticket_evolution/search.rb +22 -0
- data/lib/ticket_evolution/shipment.rb +4 -0
- data/lib/ticket_evolution/shipments.rb +8 -0
- data/lib/ticket_evolution/ticket_group.rb +4 -0
- data/lib/ticket_evolution/ticket_groups.rb +6 -0
- data/lib/ticket_evolution/user.rb +4 -0
- data/lib/ticket_evolution/users.rb +7 -0
- data/lib/ticket_evolution/venue.rb +4 -0
- data/lib/ticket_evolution/venues.rb +8 -0
- data/lib/ticket_evolution/version.rb +3 -0
- data/lib/ticket_evolution.rb +108 -0
- data/spec/fixtures/fake.rb +97 -0
- data/spec/fixtures/net/endpoints/accounts.yml +175 -0
- data/spec/fixtures/net/endpoints/brokerages.yml +257 -0
- data/spec/fixtures/net/endpoints/categories.yml +85 -0
- data/spec/fixtures/net/endpoints/clients.yml +243 -0
- data/spec/fixtures/net/endpoints/search.yml +93 -0
- data/spec/lib/ticket_evolution/account_spec.rb +7 -0
- data/spec/lib/ticket_evolution/accounts_spec.rb +45 -0
- data/spec/lib/ticket_evolution/address_spec.rb +7 -0
- data/spec/lib/ticket_evolution/brokerage_spec.rb +7 -0
- data/spec/lib/ticket_evolution/brokerages_spec.rb +50 -0
- data/spec/lib/ticket_evolution/categories_spec.rb +27 -0
- data/spec/lib/ticket_evolution/category_spec.rb +7 -0
- data/spec/lib/ticket_evolution/client_spec.rb +7 -0
- data/spec/lib/ticket_evolution/clients/addresses_spec.rb +13 -0
- data/spec/lib/ticket_evolution/clients/credit_cards_spec.rb +11 -0
- data/spec/lib/ticket_evolution/clients/email_addresses_spec.rb +13 -0
- data/spec/lib/ticket_evolution/clients/phone_numbers_spec.rb +13 -0
- data/spec/lib/ticket_evolution/clients_spec.rb +37 -0
- data/spec/lib/ticket_evolution/configuration_spec.rb +7 -0
- data/spec/lib/ticket_evolution/configurations_spec.rb +10 -0
- data/spec/lib/ticket_evolution/core/api_error_spec.rb +13 -0
- data/spec/lib/ticket_evolution/core/base_spec.rb +29 -0
- data/spec/lib/ticket_evolution/core/builder_spec.rb +95 -0
- data/spec/lib/ticket_evolution/core/collection_spec.rb +23 -0
- data/spec/lib/ticket_evolution/core/connection_spec.rb +220 -0
- data/spec/lib/ticket_evolution/core/datum_spec.rb +15 -0
- data/spec/lib/ticket_evolution/core/endpoint_spec.rb +12 -0
- data/spec/lib/ticket_evolution/core/model_spec.rb +167 -0
- data/spec/lib/ticket_evolution/core/time_spec.rb +28 -0
- data/spec/lib/ticket_evolution/credit_card_spec.rb +7 -0
- data/spec/lib/ticket_evolution/email_address_spec.rb +7 -0
- data/spec/lib/ticket_evolution/errors/connection_not_found_spec.rb +7 -0
- data/spec/lib/ticket_evolution/errors/endpoint_configuration_error_spec.rb +8 -0
- data/spec/lib/ticket_evolution/errors/invalid_configuration_spec.rb +8 -0
- data/spec/lib/ticket_evolution/errors/method_unavailable_error_spec.rb +7 -0
- data/spec/lib/ticket_evolution/event_spec.rb +7 -0
- data/spec/lib/ticket_evolution/events_spec.rb +11 -0
- data/spec/lib/ticket_evolution/office_spec.rb +7 -0
- data/spec/lib/ticket_evolution/offices_spec.rb +11 -0
- data/spec/lib/ticket_evolution/order_spec.rb +44 -0
- data/spec/lib/ticket_evolution/orders_spec.rb +123 -0
- data/spec/lib/ticket_evolution/performer_spec.rb +7 -0
- data/spec/lib/ticket_evolution/performers_spec.rb +12 -0
- data/spec/lib/ticket_evolution/phone_number_spec.rb +7 -0
- data/spec/lib/ticket_evolution/quote_spec.rb +7 -0
- data/spec/lib/ticket_evolution/quotes_spec.rb +11 -0
- data/spec/lib/ticket_evolution/search_spec.rb +31 -0
- data/spec/lib/ticket_evolution/shipment_spec.rb +7 -0
- data/spec/lib/ticket_evolution/shipments_spec.rb +13 -0
- data/spec/lib/ticket_evolution/ticket_group_spec.rb +7 -0
- data/spec/lib/ticket_evolution/ticket_groups_spec.rb +14 -0
- data/spec/lib/ticket_evolution/user_spec.rb +7 -0
- data/spec/lib/ticket_evolution/users_spec.rb +15 -0
- data/spec/lib/ticket_evolution/venue_spec.rb +7 -0
- data/spec/lib/ticket_evolution/venues_spec.rb +12 -0
- data/spec/lib/ticket_evolution_spec.rb +20 -0
- data/spec/shared_examples/endpoints/class.rb +241 -0
- data/spec/shared_examples/endpoints/create.rb +41 -0
- data/spec/shared_examples/endpoints/deleted.rb +41 -0
- data/spec/shared_examples/endpoints/list.rb +41 -0
- data/spec/shared_examples/endpoints/search.rb +42 -0
- data/spec/shared_examples/endpoints/show.rb +38 -0
- data/spec/shared_examples/endpoints/update.rb +59 -0
- data/spec/shared_examples/errors.rb +5 -0
- data/spec/shared_examples/models.rb +29 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/connection.rb +10 -0
- data/spec/support/vcr.rb +12 -0
- data/ticketevolution-ruby.gemspec +33 -0
- metadata +384 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Clients
|
3
|
+
class EmailAddresses < TicketEvolution::Endpoint
|
4
|
+
include TicketEvolution::Modules::Create
|
5
|
+
include TicketEvolution::Modules::List
|
6
|
+
include TicketEvolution::Modules::Show
|
7
|
+
include TicketEvolution::Modules::Update
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Clients
|
3
|
+
class PhoneNumbers < TicketEvolution::Endpoint
|
4
|
+
include TicketEvolution::Modules::Create
|
5
|
+
include TicketEvolution::Modules::List
|
6
|
+
include TicketEvolution::Modules::Show
|
7
|
+
include TicketEvolution::Modules::Update
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Builder < OpenStruct
|
3
|
+
include SingularClass
|
4
|
+
|
5
|
+
def initialize(*stuff)
|
6
|
+
super
|
7
|
+
@table.each do |k, v|
|
8
|
+
send("#{k}=", process_datum(v))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash
|
13
|
+
hash = {}
|
14
|
+
@table.each do |k, v|
|
15
|
+
hash[k] = from_ostruct(v)
|
16
|
+
end
|
17
|
+
hash
|
18
|
+
end
|
19
|
+
|
20
|
+
# Ruby 1.8.7 / REE compatibility
|
21
|
+
def id=(id)
|
22
|
+
@table[:id] = id
|
23
|
+
end
|
24
|
+
|
25
|
+
def id
|
26
|
+
@table[:id]
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def process_datum(v)
|
32
|
+
case v.class.to_s.to_sym
|
33
|
+
when :Hash
|
34
|
+
Datum.new(v)
|
35
|
+
when :Array
|
36
|
+
v.map{|x| process_datum(x)}
|
37
|
+
when :String
|
38
|
+
Time.parse(v)
|
39
|
+
else
|
40
|
+
v
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def from_ostruct(v)
|
45
|
+
if v.kind_of? OpenStruct
|
46
|
+
v.to_hash
|
47
|
+
elsif v.class.to_s == "Array"
|
48
|
+
v.map{|x| from_ostruct(v)}
|
49
|
+
else
|
50
|
+
v
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def method_missing(meth, *args)
|
55
|
+
if args.size == 1
|
56
|
+
super(meth, process_datum(args.first))
|
57
|
+
elsif args.size == 0
|
58
|
+
super(meth)
|
59
|
+
else
|
60
|
+
super(meth, process_datum(args))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def datum_exists?(name)
|
65
|
+
defined?(name.constantize) and defined?(singular_class(name.constantize))
|
66
|
+
end
|
67
|
+
|
68
|
+
def class_name_from_url(url)
|
69
|
+
url.split('/').reverse.each do |segment|
|
70
|
+
return "TicketEvolution::#{segment.capitalize}" if segment.split('')[-1] == 's'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Collection
|
3
|
+
attr_accessor :total_entries, :per_page, :current_page, :entries
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
options.each {|k,v| send("#{k}=", v)}
|
9
|
+
@entries ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.build_from_response(response, entries_key, singular_class)
|
13
|
+
entries = response.body[entries_key] || []
|
14
|
+
new(
|
15
|
+
:total_entries => response.body['total_entries'],
|
16
|
+
:per_page => response.body['per_page'],
|
17
|
+
:current_page => response.body['current_page'],
|
18
|
+
:entries => entries.collect do |entry|
|
19
|
+
singular_class.new(entry.merge({:connection => response.body[:connection]}))
|
20
|
+
end
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def size
|
25
|
+
@entries.size
|
26
|
+
end
|
27
|
+
|
28
|
+
def each(&block)
|
29
|
+
@entries.each(&block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Connection < Base
|
3
|
+
cattr_reader :default_options, :expected_options, :oldest_version_in_service
|
4
|
+
cattr_accessor :protocol, :url_base
|
5
|
+
|
6
|
+
@@oldest_version_in_service = 8
|
7
|
+
|
8
|
+
@@default_options = HashWithIndifferentAccess.new({
|
9
|
+
:version => @@oldest_version_in_service,
|
10
|
+
:mode => :sandbox,
|
11
|
+
:ssl_verify => true
|
12
|
+
})
|
13
|
+
|
14
|
+
@@expected_options = [
|
15
|
+
'version',
|
16
|
+
'mode',
|
17
|
+
'token',
|
18
|
+
'secret',
|
19
|
+
'ssl_verify'
|
20
|
+
]
|
21
|
+
|
22
|
+
@@url_base = "ticketevolution.com"
|
23
|
+
@@protocol = "https"
|
24
|
+
|
25
|
+
def initialize(opts = {})
|
26
|
+
@config = self.class.default_options.merge(opts)
|
27
|
+
@config.delete_if{|k, v| ! TicketEvolution::Connection.expected_options.include?(k)}
|
28
|
+
|
29
|
+
# Error Notification
|
30
|
+
if @config.keys.sort_by{|x|x} == TicketEvolution::Connection.expected_options.sort_by{|x|x}
|
31
|
+
raise InvalidConfiguration.new("Invalid Token Format") unless @config[:token] =~ /^[a-zA-Z0-9]{32}$/
|
32
|
+
raise InvalidConfiguration.new("Invalid Secret Format") unless @config[:secret] =~ /^\S{40}$/
|
33
|
+
raise InvalidConfiguration.new("Please Use API Version #{TicketEvolution::Connection.oldest_version_in_service} or Above") unless @config[:version] >= TicketEvolution::Connection.oldest_version_in_service
|
34
|
+
else
|
35
|
+
raise InvalidConfiguration.new("Missing: #{(self.class.expected_options - @config.keys).join(', ')}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def url
|
40
|
+
@url ||= [].tap do |parts|
|
41
|
+
parts << TicketEvolution::Connection.protocol
|
42
|
+
parts << "://api."
|
43
|
+
parts << "#{@config[:mode]}." unless @config[:mode] == :production
|
44
|
+
parts << TicketEvolution::Connection.url_base
|
45
|
+
end.join
|
46
|
+
end
|
47
|
+
|
48
|
+
def sign(method, path, content = nil)
|
49
|
+
Base64.encode64(
|
50
|
+
OpenSSL::HMAC.digest(
|
51
|
+
OpenSSL::Digest::Digest.new('sha256'),
|
52
|
+
@config[:secret],
|
53
|
+
"#{method} #{process_params(method, path, content).gsub(TicketEvolution::Connection.protocol+'://', '')}"
|
54
|
+
)).chomp
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_request(method, path, params = nil)
|
58
|
+
uri = URI.join(self.url, path).to_s
|
59
|
+
Curl::Easy.new(generate_url(method, uri, params)) do |request|
|
60
|
+
if @config.has_key?(:ssl_verify)
|
61
|
+
request.ssl_verify_host = @config[:ssl_verify]
|
62
|
+
request.ssl_verify_peer = @config[:ssl_verify]
|
63
|
+
end
|
64
|
+
request.post_body = post_body(params) unless method == :GET
|
65
|
+
request.headers["Accept"] = "application/vnd.ticketevolution.api+json; version=#{@config[:version]}"
|
66
|
+
request.headers["X-Signature"] = sign(method, uri, params)
|
67
|
+
request.headers["X-Token"] = @config[:token]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def post_body(params)
|
74
|
+
MultiJson.encode(params)
|
75
|
+
end
|
76
|
+
|
77
|
+
def generate_url(method, uri, params)
|
78
|
+
case method
|
79
|
+
when :GET
|
80
|
+
process_params(method, uri, params)
|
81
|
+
else
|
82
|
+
uri
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def process_params(method, path, params)
|
87
|
+
suffix = if params.present?
|
88
|
+
case method
|
89
|
+
when :GET
|
90
|
+
params.to_query
|
91
|
+
else
|
92
|
+
post_body(params)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
"#{URI.join(url, path).to_s}?" + suffix.to_s
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Endpoint < Base
|
3
|
+
module RequestHandler
|
4
|
+
|
5
|
+
# Response Code Mappings From TicketEvolution API
|
6
|
+
CODES = {
|
7
|
+
200 => ["OK","Generally returned by successful GET requests. "],
|
8
|
+
201 => ["Created","Generally returned by successful POST requests. "],
|
9
|
+
202 => ["Accepted","Generally returned when a request has succeeded, but has been scheduled processing at a later time. "],
|
10
|
+
301 => ["Moved Permanently","Used when a resource's URL has changed."],
|
11
|
+
302 => ["Found","Returned when there's a redirect that should be followed."],
|
12
|
+
400 => ["Bad Request","Generally returned on POST and PUT requests when validation fails for the given input. "],
|
13
|
+
401 => ["Unauthorized","Returned when the authentication credentials are invalid."],
|
14
|
+
404 => ["Not Found","The requested resource could not be located."],
|
15
|
+
406 => ["Not Acceptable","The requested content type or version is invalid."],
|
16
|
+
500 => ["Internal Server Error","Used a general error response for processing errors or other issues with the web service. "],
|
17
|
+
503 => ["Service Unavailable","Returned when the API service is temporarily unavailable. This could also indicate that the rate limit for the given token has been reached. If this status is received, the request should be retried."]
|
18
|
+
}
|
19
|
+
|
20
|
+
def request(method, path, params = nil, &response_handler)
|
21
|
+
response = self.build_request(method, path, params)
|
22
|
+
response.http(method)
|
23
|
+
response = self.naturalize_response(response)
|
24
|
+
if response.response_code >= 400
|
25
|
+
TicketEvolution::ApiError.new(response)
|
26
|
+
else
|
27
|
+
response_handler.call(response)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_request(method, path, params = nil)
|
32
|
+
raise EndpointConfigurationError, "#{self.class.to_s}#request requires it's first parameter to be a valid HTTP method" unless [:GET, :POST, :PUT, :DELETE].include? method.to_sym
|
33
|
+
self.connection.build_request(method, "#{self.base_path}#{path}", params)
|
34
|
+
end
|
35
|
+
|
36
|
+
def naturalize_response(response)
|
37
|
+
OpenStruct.new.tap do |resp|
|
38
|
+
resp.header = response.header_str
|
39
|
+
resp.response_code = response.response_code
|
40
|
+
resp.body = MultiJson.decode(response.body_str).merge({:connection => self.connection})
|
41
|
+
resp.server_message = CODES[response.response_code].last
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Endpoint < Base
|
3
|
+
include RequestHandler
|
4
|
+
include SingularClass
|
5
|
+
|
6
|
+
def initialize(options = nil)
|
7
|
+
raise EndpointConfigurationError, "#{self.class.to_s} instances require a hash as their first parameter" unless options.is_a? Hash
|
8
|
+
raise EndpointConfigurationError, "The options hash must include a parent key / value pair" unless options[:parent].present?
|
9
|
+
raise EndpointConfigurationError, "#{self.class.to_s} instances require a parent which inherits from TicketEvolution::Base" unless options[:parent].kind_of? TicketEvolution::Base
|
10
|
+
options.each do |k, v|
|
11
|
+
self.singleton_class.send(:attr_accessor, k)
|
12
|
+
send("#{k}=", v)
|
13
|
+
end
|
14
|
+
raise EndpointConfigurationError, "The parent passed in the options hash must be a TicketEvolution::Connection object or have one in it's parent chain" unless has_connection?
|
15
|
+
end
|
16
|
+
|
17
|
+
def base_path
|
18
|
+
[].tap do |parts|
|
19
|
+
parts << parent.base_path if parent.kind_of? TicketEvolution::Endpoint
|
20
|
+
parts << "/"+endpoint_name
|
21
|
+
parts << "/#{self.id}" if self.respond_to?("id=") and self.id.present?
|
22
|
+
end.join
|
23
|
+
end
|
24
|
+
|
25
|
+
def connection
|
26
|
+
if self.parent.is_a? TicketEvolution::Connection
|
27
|
+
self.parent
|
28
|
+
elsif self.parent.respond_to? :parent
|
29
|
+
self.parent.connection
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_connection?
|
36
|
+
connection.present?
|
37
|
+
end
|
38
|
+
|
39
|
+
def endpoint_name
|
40
|
+
self.class.name.demodulize.underscore
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def ensure_id
|
46
|
+
raise TicketEvolution::MethodUnavailableError.new \
|
47
|
+
"#{self.class.to_s}##{caller.first.split('`').last.split("'").first} can only be called if there is an id present on this #{self.class.to_s} instance" \
|
48
|
+
unless self.respond_to?("id=") and self.id.present?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Model < Builder
|
3
|
+
def initialize(params = {})
|
4
|
+
@connection = params.delete(:connection)
|
5
|
+
raise TicketEvolution::ConnectionNotFound.new \
|
6
|
+
"#{self.class.name} must receive a TicketEvolution::Connection object on initialize" \
|
7
|
+
unless @connection.is_a? TicketEvolution::Connection
|
8
|
+
@scope = params['url'].split('/')[0..2].join('/') if params['url'] =~ /^(\/[a-z_]+s\/\d){2}$/
|
9
|
+
super(params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def plural_class_name
|
13
|
+
parts = ["TicketEvolution", self.class.name.demodulize.pluralize.camelize]
|
14
|
+
parts[0] = self.scope[:class] if @scope.present?
|
15
|
+
parts.join('::')
|
16
|
+
end
|
17
|
+
|
18
|
+
def plural_class
|
19
|
+
self.plural_class_name.constantize
|
20
|
+
end
|
21
|
+
|
22
|
+
def attributes
|
23
|
+
HashWithIndifferentAccess.new(to_hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
def attributes=(params)
|
27
|
+
params.each do |k, v|
|
28
|
+
send("#{k}=", v)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def scope
|
33
|
+
if @scope.present?
|
34
|
+
{}.tap do |scope|
|
35
|
+
parts = @scope.split('/')
|
36
|
+
scope[:class] = "TicketEvolution::#{parts[1].camelize}"
|
37
|
+
scope[:id] = parts[2].to_i
|
38
|
+
end
|
39
|
+
else
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def process_datum(v)
|
47
|
+
if v.is_a? Hash and v['url'].present?
|
48
|
+
name = class_name_from_url(v['url'])
|
49
|
+
datum_exists?(name) ? singular_class(class_name_from_url(name)).new(v.merge({:connection => @connection})) : Datum.new(v)
|
50
|
+
else
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_missing(method, *args)
|
56
|
+
seek = method.to_s.camelize
|
57
|
+
if seek !~ /=/ and plural_class.const_defined?(seek.to_sym)
|
58
|
+
"#{plural_class_name}::#{seek}".constantize.new(:parent => plural_class.new(:connection => @connection, :id => self.id))
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
class Time < ::Time
|
3
|
+
def self.parse(str)
|
4
|
+
if str =~ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/
|
5
|
+
parts = str.split(/[-T:Z]/).collect(&:to_i)
|
6
|
+
Time.gm(
|
7
|
+
parts[0],
|
8
|
+
parts[1],
|
9
|
+
parts[2],
|
10
|
+
parts[3],
|
11
|
+
parts[4],
|
12
|
+
parts[5]
|
13
|
+
)
|
14
|
+
else
|
15
|
+
str
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
module Modules
|
3
|
+
module Create
|
4
|
+
def create(params = nil)
|
5
|
+
params = { endpoint_name.to_sym => [params] } if params.present?
|
6
|
+
request(:POST, nil, params, &method(:build_for_create))
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_for_create(response)
|
10
|
+
singular_class.new(response.body[endpoint_name].first.merge({
|
11
|
+
:status_code => response.response_code,
|
12
|
+
:server_message => response.server_message,
|
13
|
+
:connection => response.body[:connection]
|
14
|
+
}))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
module Modules
|
3
|
+
module Deleted
|
4
|
+
def deleted(params = nil)
|
5
|
+
request(:GET, '/deleted', params, &method(:build_for_deleted))
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_for_deleted(response)
|
9
|
+
TicketEvolution::Collection.build_from_response(response, self.class.name.demodulize.underscore, singular_class)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
module Modules
|
3
|
+
module List
|
4
|
+
def list(params = nil)
|
5
|
+
request(:GET, nil, params, &method(:build_for_list))
|
6
|
+
end
|
7
|
+
|
8
|
+
alias :all :list
|
9
|
+
|
10
|
+
def build_for_list(response)
|
11
|
+
TicketEvolution::Collection.build_from_response(response, self.class.name.demodulize.underscore, singular_class)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
module Modules
|
3
|
+
module Search
|
4
|
+
def search(params = nil)
|
5
|
+
request(:GET, '/search', params, &method(:build_for_search))
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_for_search(response)
|
9
|
+
TicketEvolution::Collection.build_from_response(response, self.class.name.demodulize.underscore, singular_class)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
module Modules
|
3
|
+
module Show
|
4
|
+
def show(id)
|
5
|
+
request(:GET, "/#{id}", &method(:build_for_show))
|
6
|
+
end
|
7
|
+
|
8
|
+
alias :find :show
|
9
|
+
|
10
|
+
def build_for_show(response)
|
11
|
+
singular_class.new(
|
12
|
+
response.body.merge({
|
13
|
+
:status_code => response.response_code,
|
14
|
+
:server_message => response.server_message
|
15
|
+
})
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TicketEvolution
|
2
|
+
module Modules
|
3
|
+
module Update
|
4
|
+
def self.included(klass)
|
5
|
+
Class.new{extend SingularClass}.singular_class(klass.name).send(:include, Module.new{
|
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)
|
9
|
+
end
|
10
|
+
|
11
|
+
def save
|
12
|
+
atts = self.attributes
|
13
|
+
plural_class.new({:parent => @connection, :id => atts.delete(:id)}).update(atts)
|
14
|
+
end
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
def update(params = nil)
|
19
|
+
ensure_id
|
20
|
+
request(:PUT, "/#{self.id}", params)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|