tickethub 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/lib/tickethub/address.rb +5 -0
  5. data/lib/tickethub/app/package.rb +9 -0
  6. data/lib/tickethub/app/subscription.rb +11 -0
  7. data/lib/tickethub/app.rb +36 -0
  8. data/lib/tickethub/category.rb +7 -0
  9. data/lib/tickethub/collection.rb +150 -0
  10. data/lib/tickethub/connection.rb +140 -0
  11. data/lib/tickethub/contact.rb +5 -0
  12. data/lib/tickethub/endpoint.rb +36 -0
  13. data/lib/tickethub/errors.rb +34 -0
  14. data/lib/tickethub/exceptions.rb +73 -0
  15. data/lib/tickethub/formats/form_format.rb +17 -0
  16. data/lib/tickethub/formats/json_format.rb +25 -0
  17. data/lib/tickethub/formats.rb +35 -0
  18. data/lib/tickethub/helpers.rb +108 -0
  19. data/lib/tickethub/request.rb +130 -0
  20. data/lib/tickethub/resource.rb +279 -0
  21. data/lib/tickethub/response/headers.rb +31 -0
  22. data/lib/tickethub/response.rb +49 -0
  23. data/lib/tickethub/supplier/answer.rb +11 -0
  24. data/lib/tickethub/supplier/app.rb +9 -0
  25. data/lib/tickethub/supplier/bill.rb +11 -0
  26. data/lib/tickethub/supplier/booking.rb +39 -0
  27. data/lib/tickethub/supplier/card.rb +11 -0
  28. data/lib/tickethub/supplier/coupon.rb +14 -0
  29. data/lib/tickethub/supplier/customer.rb +15 -0
  30. data/lib/tickethub/supplier/element.rb +11 -0
  31. data/lib/tickethub/supplier/fee.rb +15 -0
  32. data/lib/tickethub/supplier/gateway/handpoint.rb +8 -0
  33. data/lib/tickethub/supplier/gateway/ideal.rb +8 -0
  34. data/lib/tickethub/supplier/gateway/paypal.rb +8 -0
  35. data/lib/tickethub/supplier/gateway/stripe.rb +8 -0
  36. data/lib/tickethub/supplier/gateway.rb +16 -0
  37. data/lib/tickethub/supplier/invoice.rb +7 -0
  38. data/lib/tickethub/supplier/message/email.rb +8 -0
  39. data/lib/tickethub/supplier/message/sms.rb +8 -0
  40. data/lib/tickethub/supplier/message.rb +20 -0
  41. data/lib/tickethub/supplier/option.rb +18 -0
  42. data/lib/tickethub/supplier/order.rb +51 -0
  43. data/lib/tickethub/supplier/package.rb +9 -0
  44. data/lib/tickethub/supplier/payment/card.rb +18 -0
  45. data/lib/tickethub/supplier/payment/cash.rb +8 -0
  46. data/lib/tickethub/supplier/payment/credit.rb +8 -0
  47. data/lib/tickethub/supplier/payment/direct.rb +8 -0
  48. data/lib/tickethub/supplier/payment/gratuity.rb +8 -0
  49. data/lib/tickethub/supplier/payment.rb +34 -0
  50. data/lib/tickethub/supplier/product.rb +54 -0
  51. data/lib/tickethub/supplier/question.rb +11 -0
  52. data/lib/tickethub/supplier/rate.rb +16 -0
  53. data/lib/tickethub/supplier/receipt.rb +11 -0
  54. data/lib/tickethub/supplier/reseller.rb +36 -0
  55. data/lib/tickethub/supplier/scan.rb +17 -0
  56. data/lib/tickethub/supplier/season.rb +16 -0
  57. data/lib/tickethub/supplier/subscription.rb +11 -0
  58. data/lib/tickethub/supplier/tax.rb +16 -0
  59. data/lib/tickethub/supplier/template.rb +11 -0
  60. data/lib/tickethub/supplier/ticket.rb +25 -0
  61. data/lib/tickethub/supplier/tier.rb +20 -0
  62. data/lib/tickethub/supplier/user.rb +9 -0
  63. data/lib/tickethub/supplier/variant.rb +10 -0
  64. data/lib/tickethub/supplier/voucher.rb +23 -0
  65. data/lib/tickethub/supplier.rb +86 -0
  66. data/lib/tickethub/token.rb +9 -0
  67. data/lib/tickethub/user/app.rb +5 -0
  68. data/lib/tickethub/user/supplier.rb +5 -0
  69. data/lib/tickethub/user.rb +38 -0
  70. data/lib/tickethub/version.rb +3 -0
  71. data/lib/tickethub.rb +26 -0
  72. data/tickethub.gemspec +25 -0
  73. metadata +209 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8d3318c8a3beae9788a9da8e2b31ef7f013f70ec
4
+ data.tar.gz: 566e852760436eea922e39ed659e71f91597da50
5
+ SHA512:
6
+ metadata.gz: 4fa2a0d645c5d6c8d167387289ca4d2294c38facd25d7a67c090a1c44cd1615ae8c5a2ae1d732b4b8826a9063085d406d5fc20886c1f04f308a2795e48fe1e2a
7
+ data.tar.gz: 2284002231679ecee50ae1a29ded39dfb589796d60d7f68f330589d75310ed7bf55f69a91e4e2c4ba843e4f91421ed6602763d3a7397a27983ec152c6a929504
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sourcing.gemspec
4
+ gemspec
@@ -0,0 +1,5 @@
1
+ module Tickethub
2
+ class Address < Resource
3
+ # read_only!
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ module Tickethub
2
+ class App::Package < Resource
3
+ path '/app/packages'
4
+
5
+ require_relative '../app'
6
+
7
+ association :app, Tickethub::App
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require_relative '../resource'
2
+
3
+ module Tickethub
4
+ class App::Subscription < Resource
5
+ path '/app/subscriptions'
6
+
7
+ require_relative 'package'
8
+
9
+ association :package, App::Package
10
+ end
11
+ end
@@ -0,0 +1,36 @@
1
+ module Tickethub
2
+ class App < Resource
3
+ path '/apps'
4
+
5
+ require_relative 'contact'
6
+ require_relative 'category'
7
+ require_relative 'app/package'
8
+ require_relative 'app/subscription'
9
+
10
+ association :contact, Tickethub::Contact
11
+ association :token, Tickethub::Token
12
+ association :category, Tickethub::Category
13
+
14
+ collection :packages, App::Package
15
+ collection :subscriptions, App::Subscription
16
+
17
+ attribute :currency, type: :currency
18
+
19
+ def self.[](attributes)
20
+ token = attributes[:token].is_a?(String) ? attributes[:token]
21
+ : attributes[:token][:access_token]
22
+ self.new Tickethub.endpoint['/app', auth_type: :bearer, password: token]
23
+ end
24
+
25
+ def initialize(endpoint, attributes = nil)
26
+ attributes ||= endpoint.get
27
+
28
+ if attributes['token']
29
+ endpoint = Tickethub.endpoint['/app', {
30
+ auth_type: :bearer, password: attributes['token']['access_token'] }]
31
+ end
32
+
33
+ super(endpoint, attributes)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module Tickethub
2
+ class Category < Resource
3
+ path '/categories'
4
+
5
+ collection :apps, Tickethub::App
6
+ end
7
+ end
@@ -0,0 +1,150 @@
1
+ require_relative 'helpers'
2
+
3
+ module Tickethub
4
+ class Collection < Enumerator
5
+ attr_accessor :cache
6
+ attr_reader :count, :endpoint
7
+
8
+ def initialize(endpoint, klass, params = {})
9
+ @params = params.dup
10
+ @endpoint = endpoint
11
+ @klass = klass
12
+
13
+ klass.registered_types.each do |type, options|
14
+ define_singleton_method type do
15
+ instance_variable_defined?("@#{type}") ? instance_variable_get("@#{type}") :
16
+ instance_variable_set("@#{type}", Tickethub::Collection.new(@endpoint[type], options[:klass]))
17
+ end
18
+ end
19
+
20
+ klass.scopes.each do |key, block|
21
+ define_singleton_method key, &block
22
+ end
23
+
24
+ super() do |yielder|
25
+ self.reload! if @cache.nil?
26
+
27
+ @cache.each do |row|
28
+ yielder << @klass.load(@endpoint, row)
29
+ end
30
+
31
+ while @cache.length < @count
32
+ offset = @offset + @cache.length
33
+ response = @endpoint.get @params.merge(offset: @cache.length)
34
+ response.decoded.each do |row| @cache << row
35
+ yielder << @klass.load(@endpoint, row)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def reload!
42
+ @cache = (response = @endpoint.get @params).decoded
43
+ @count, @offset, @limit =
44
+ response.status == 206 ?
45
+ response.headers.values_at(*%w(x-total-count x-offset x-limit))
46
+ .collect { |value| value[0].to_i } : [@cache.length, 0, @cache.length]
47
+ end
48
+
49
+ def limit(value = nil)
50
+ if value.nil?
51
+ reload! if @limit.nil?
52
+ return @limit
53
+ else
54
+ self.class.new @endpoint, @klass,
55
+ @params.merge(limit: value)
56
+ end
57
+ end
58
+
59
+ def offset(value = nil)
60
+ if value.nil?
61
+ reload! if @offset.nil?
62
+ return @offset
63
+ else
64
+ self.class.new @endpoint, @klass,
65
+ @params.merge(offset: value)
66
+ end
67
+ end
68
+
69
+ def filter(value)
70
+ self.class.new @endpoint, @klass,
71
+ @params.merge(filters: (@params[:filters] || {}).merge(value))
72
+ end
73
+
74
+ def filters
75
+ @params[:filters].dup
76
+ end
77
+
78
+ def order(value = nil)
79
+ return @params[:order].dup if value.nil?
80
+ order = (@params[:order] || []) + (case value
81
+ when Symbol, String then [value.to_s]
82
+ when Hash
83
+ value.collect do |key, direction|
84
+ direction.to_s == 'desc' ? "-#{key}" : key
85
+ end
86
+ end)
87
+
88
+ self.class.new @endpoint, @klass,
89
+ @params.merge(order: order)
90
+ end
91
+
92
+ [:get, :post, :patch, :delete].each do |key|
93
+ define_method key do |path, params = {}, options = {}|
94
+ endpoint = (if path.is_a? Hash
95
+ params, options = [path, params]
96
+ self.endpoint
97
+ else self.endpoint[path] end)
98
+
99
+ if (response = endpoint.send(key, @params.merge(params), options)).body.length > 2
100
+ return response.decoded
101
+ end
102
+ end
103
+ end
104
+
105
+ def empty?
106
+ count.zero?
107
+ end
108
+
109
+ def any?(&block)
110
+ block_given?? super : ! empty?
111
+ end
112
+
113
+ def limit
114
+ self.reload! if @limit.nil?
115
+ return @limit
116
+ end
117
+
118
+ def count
119
+ self.reload! if @count.nil?
120
+ return @count
121
+ end
122
+
123
+ def [](*args)
124
+ case (key = args[0])
125
+ when Fixnum
126
+ self.offset(key).first
127
+ when Hash
128
+ self.filter(key).first
129
+ when Range
130
+ self.offset(key.min).first(key.max)
131
+ when String
132
+ options = { params: args[1] || {} }.merge args[2] || {}
133
+ @klass.load(@endpoint[nil, options], 'id' => key).reload!
134
+ else
135
+ raise ArgumentError, 'invalid search value type'
136
+ end
137
+ end
138
+
139
+ def create(attributes = {})
140
+ @klass.new @endpoint, @endpoint.post(attributes).decoded
141
+ rescue Tickethub::ResourceInvalid => err
142
+ @klass.new @endpoint, Tickethub::Response.new(err.response).decoded
143
+ end
144
+
145
+ def scope(key, params = {}, options = {})
146
+ Tickethub::Collection.new @endpoint[key, options.merge(params: params)], @klass,
147
+ filters: @filters, order: @order
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,140 @@
1
+ require 'uri'
2
+ require 'net/https'
3
+
4
+ module Tickethub
5
+ class Connection
6
+ UriParser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
7
+
8
+ attr_accessor :timeout, :ssl_options
9
+ attr_reader :endpoint, :timeout, :proxy, :ssl_options
10
+
11
+ # The +endpoint+ parameter is required and will set the +endpoint+
12
+ # attribute to the URI for the remote resource service.
13
+ def initialize(endpoint, options = {})
14
+ self.endpoint = endpoint
15
+
16
+ options.each do |key, value|
17
+ self.send("#{key}=", value) unless value.nil?
18
+ end
19
+ end
20
+
21
+ # Set URI for remote service.
22
+ def endpoint=(endpoint)
23
+ @endpoint = endpoint.is_a?(URI) ? endpoint : UriParser.parse(endpoint)
24
+ end
25
+
26
+ # Set the proxy for remote service.
27
+ def proxy=(proxy)
28
+ @proxy = proxy.is_a?(URI) ? proxy : UriParser.parse(proxy)
29
+ end
30
+
31
+ def get(path, headers = {}, &block)
32
+ request(:get, path, headers, &block)
33
+ end
34
+
35
+ def delete(path, headers = {}, &block)
36
+ request(:delete, path, headers, &block)
37
+ end
38
+
39
+ def head(path, headers = {}, &block)
40
+ request(:head, path, headers, &block)
41
+ end
42
+
43
+ def patch(path, body = '', headers = {}, &block)
44
+ request(:patch, path, body, headers, &block)
45
+ end
46
+
47
+ def post(path, body = '', headers = {}, &block)
48
+ request(:post, path, body, headers, &block)
49
+ end
50
+
51
+ protected
52
+
53
+ # Makes a request to the remote service.
54
+ def request(method, path, *arguments)
55
+ response = http.send(method, path, *arguments)
56
+ handle_response(response)
57
+
58
+ rescue Timeout::Error => e
59
+ raise TimeoutError.new(e.message)
60
+ rescue OpenSSL::SSL::SSLError => e
61
+ raise SSLError.new(e.message)
62
+ end
63
+
64
+ # Handles response and error codes from the remote service.
65
+ def handle_response(response)
66
+ case response.code.to_i
67
+ when 301,302
68
+ raise Redirection.new(response)
69
+ when 200...400
70
+ response
71
+ when 400
72
+ raise BadRequest.new(response)
73
+ when 401
74
+ raise UnauthorizedAccess.new(response)
75
+ when 403
76
+ raise ForbiddenAccess.new(response)
77
+ when 404
78
+ raise ResourceNotFound.new(response)
79
+ when 405
80
+ raise MethodNotAllowed.new(response)
81
+ when 409
82
+ raise ResourceConflict.new(response)
83
+ when 410
84
+ raise ResourceGone.new(response)
85
+ when 422
86
+ raise ResourceInvalid.new(response)
87
+ when 401...500
88
+ raise ClientError.new(response)
89
+ when 500...600
90
+ raise ServerError.new(response)
91
+ else
92
+ raise ConnectionError.new(
93
+ response, "Unknown response code: #{response.code}"
94
+ )
95
+ end
96
+ end
97
+
98
+ # Creates new Net::HTTP instance for communication with the
99
+ # remote service and resources.
100
+ def http
101
+ configure_http(new_http)
102
+ end
103
+
104
+ def new_http
105
+ if proxy
106
+ Net::HTTP.new(endpoint.host, endpoint.port,
107
+ proxy.host, proxy.port,
108
+ proxy.user, proxy.password)
109
+ else
110
+ Net::HTTP.new(endpoint.host, endpoint.port)
111
+ end
112
+ end
113
+
114
+ def configure_http(http)
115
+ http = apply_ssl_options(http)
116
+
117
+ # Net::HTTP timeouts default to 60 seconds.
118
+ if timeout
119
+ http.open_timeout = timeout
120
+ http.read_timeout = timeout
121
+ end
122
+
123
+ http
124
+ end
125
+
126
+ def apply_ssl_options(http)
127
+ return http unless endpoint.is_a?(URI::HTTPS)
128
+
129
+ http.use_ssl = true
130
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
131
+ return http unless ssl_options
132
+
133
+ ssl_options.each do |key, value|
134
+ http.send("#{key}=", value)
135
+ end
136
+
137
+ http
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,5 @@
1
+ module Tickethub
2
+ class Contact < Resource
3
+ # read_only!
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'request'
2
+ require_relative 'response'
3
+ require_relative 'helpers'
4
+
5
+ module Tickethub
6
+ class Endpoint
7
+ attr_reader :options, :url
8
+
9
+ def initialize(url, options = {})
10
+ @url = url
11
+ @options = options
12
+ end
13
+
14
+ def [](suburl, options = {})
15
+ url = (if suburl.nil? then self.url
16
+ else
17
+ suburl = suburl.to_s
18
+ base = self.url
19
+ base += "/" unless base =~ /\/$/
20
+ URI.join(base, suburl).to_s
21
+ end)
22
+
23
+ self.class.new url, Tickethub::Helpers.deep_merge(@options, options)
24
+ end
25
+
26
+ [:get, :post, :delete, :patch].each do |method|
27
+ define_method method do |params = {}, options = {}|
28
+ request options.merge(method: method, params: params)
29
+ end
30
+ end
31
+
32
+ def request(options = {})
33
+ Tickethub::Request.new(url, Tickethub::Helpers.deep_merge(@options, options)).execute
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,34 @@
1
+ module Tickethub
2
+ class Errors
3
+
4
+ def initialize(errors)
5
+ @errors = errors || {}
6
+ end
7
+
8
+ def full_messages_for(attribute)
9
+ send attribute
10
+ end
11
+
12
+ def on(attribute)
13
+ @errors[attribute.to_s]
14
+ end
15
+
16
+ def valid?(attribute)
17
+ send(attribute).empty?
18
+ end
19
+
20
+ def invalid?(attribute)
21
+ send(attribute).any?
22
+ end
23
+
24
+ def [](key)
25
+ send key
26
+ end
27
+
28
+ protected
29
+
30
+ def method_missing(method, *arguments)
31
+ on(method) || []
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,73 @@
1
+ module Tickethub
2
+ class ConnectionError < StandardError # :nodoc:
3
+ attr_reader :response
4
+
5
+ def initialize(response, message = nil)
6
+ @response = response
7
+ @message = message
8
+ end
9
+
10
+ def to_s
11
+ message = "Failed."
12
+ message << " Response code = #{response.code}." if response.respond_to?(:code)
13
+ message << " Response message = #{response.message}." if response.respond_to?(:message)
14
+ message << " Response Body = #{response.body}." if response.respond_to?(:body)
15
+ message
16
+ end
17
+ end
18
+
19
+ # Raised when a Timeout::Error occurs.
20
+ class TimeoutError < ConnectionError
21
+ def initialize(message)
22
+ @message = message
23
+ end
24
+ def to_s; @message ;end
25
+ end
26
+
27
+ # Raised when a OpenSSL::SSL::SSLError occurs.
28
+ class SSLError < ConnectionError
29
+ def initialize(message)
30
+ @message = message
31
+ end
32
+ def to_s; @message ;end
33
+ end
34
+
35
+ # 3xx Redirection
36
+ class Redirection < ConnectionError # :nodoc:
37
+ def to_s; response['Location'] ? "#{super} => #{response['Location']}" : super; end
38
+ end
39
+
40
+ # 4xx Client Error
41
+ class ClientError < ConnectionError; end # :nodoc:
42
+
43
+ # 400 Bad Request
44
+ class BadRequest < ClientError; end # :nodoc
45
+
46
+ # 401 Unauthorized
47
+ class UnauthorizedAccess < ClientError; end # :nodoc
48
+
49
+ # 403 Forbidden
50
+ class ForbiddenAccess < ClientError; end # :nodoc
51
+
52
+ # 404 Not Found
53
+ class ResourceNotFound < ClientError; end # :nodoc:
54
+
55
+ # 409 Conflict
56
+ class ResourceConflict < ClientError; end # :nodoc:
57
+
58
+ # 410 Gone
59
+ class ResourceGone < ClientError; end # :nodoc:
60
+
61
+ # 422 Invalid
62
+ class ResourceInvalid < ClientError; end # :nodoc:
63
+
64
+ # 5xx Server Error
65
+ class ServerError < ConnectionError; end # :nodoc:
66
+
67
+ # 405 Method Not Allowed
68
+ class MethodNotAllowed < ClientError # :nodoc:
69
+ def allowed_methods
70
+ @response['Allow'].split(',').map { |verb| verb.strip.downcase.to_sym }
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,17 @@
1
+ module Tickethub
2
+ module Formats
3
+ class FormFormat < Format
4
+ def mime_type
5
+ 'application/x-www-form-urlencoded'
6
+ end
7
+
8
+ def encode(params, options = nil)
9
+ Helpers.to_param(params)
10
+ end
11
+
12
+ def decode(body)
13
+ body
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ begin
2
+ require 'json'
3
+ rescue LoadError => e
4
+ require 'json/pure'
5
+ end
6
+
7
+ module Tickethub
8
+ module Formats
9
+ class JSONFormat < Format
10
+ def mime_type
11
+ 'application/json'
12
+ end
13
+
14
+ def encode(hash, options = nil)
15
+ hash.to_json(options)
16
+ end
17
+
18
+ def decode(json)
19
+ JSON.parse(json)
20
+ end
21
+ end
22
+
23
+ JsonFormat = JSONFormat
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ module Tickethub
2
+ module Formats
3
+ class Format
4
+ def mime_type
5
+ end
6
+
7
+ def encode(*args)
8
+ end
9
+
10
+ def decode(*args)
11
+ end
12
+ end
13
+
14
+ MAPPING = {
15
+ 'application/json' => :json
16
+ }
17
+
18
+ def self.for(type)
19
+ format = MAPPING[type]
20
+ format && self[format]
21
+ end
22
+
23
+ # Lookup the format class from a mime type reference symbol. Example:
24
+ #
25
+ # Tickethub::Formats[:json] # => Tickethub::Formats::JsonFormat
26
+ def self.[](mime_type_reference)
27
+ Tickethub::Formats.const_get(Helpers.camelize(mime_type_reference.to_s) + 'Format')
28
+ end
29
+ end
30
+ end
31
+
32
+ Dir[File.dirname(__FILE__) + '/formats/*.rb'].sort.each do |path|
33
+ filename = File.basename(path)
34
+ require_relative "formats/#{filename}"
35
+ end