tickethub 0.0.1

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.
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