Module: Suitcase::Hotel::Helpers

Included in:
Suitcase::Hotel, Location, PaymentOption, Room, Room
Defined in:
lib/suitcase/hotel/helpers.rb

Constant Summary collapse

URL_DEFAULTS =

Internal: Defaults for the builder options to Helpers#url.

{
  include_key: true,
  include_cid: true,
  secure: false,
  as_form: false,
  session: Session.new
}

Instance Method Summary collapse

Instance Method Details

#base_url(info) ⇒ Object

Internal: Get the base URL based on a Hash of info.

info - A Hash with only one required key:

:booking - Whether or not it is a booking request.

Returns the base URL.



157
158
159
# File 'lib/suitcase/hotel/helpers.rb', line 157

def base_url(info)
  main_url(info[:booking])
end

#build_session_params(session) ⇒ Object

Internal: Build a Hash of params from a Session.

session - The Session to generate params from.

Returns the Hash of params.



166
167
168
169
170
171
172
173
174
# File 'lib/suitcase/hotel/helpers.rb', line 166

def build_session_params(session)
  session_info = {}
  session_info["customerSessionId"] = session.id if session.id
  session_info["customerIpAddress"] = session.ip_address if session.ip_address
  session_info["locale"] = session.locale if session.locale
  session_info["currencyCode"] = session.currency_code if session.currency_code
  session_info["customerUserAgent"] = session.user_agent if session.user_agent
  session_info
end

#generate_signatureObject

Internal: Generate a digital signature to authenticate with.

Returns the generated signature.



190
191
192
193
194
# File 'lib/suitcase/hotel/helpers.rb', line 190

def generate_signature
  Digest::MD5.hexdigest(Configuration.hotel_api_key + 
                        Configuration.hotel_shared_secret + 
                        Time.now.to_i.to_s)
end

#handle_errors(info) ⇒ Object

Internal: Raise the errors returned from the response.

info - The parsed JSON to get the errors from.

Returns nothing.



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/suitcase/hotel/helpers.rb', line 126

def handle_errors(info)
  key = info.keys.first
  if info[key] && info[key]["EanWsError"]
    message = info[key]["EanWsError"]["presentationMessage"]
    exception = EANException.new(message)
    if message =~ /Multiple locations/ && (info = info[key]["LocationInfos"])
      exception.type = :multiple_locations
      exception.recovery = {
        alternate_locations: info["LocationInfo"].map do |info|
        Location.new(
          destination_id: info["destinationId"],
          type: info["type"],
          city: info["city"],
          province: info["stateProvinceCode"]
        )
        end
      }
    elsif message =~ /Data in this request could not be validated/
      exception.type = :invalid_data
    end

    raise exception
  end
end

#main_url(secure) ⇒ Object

Internal: Get the root URL for the Hotels API.

secure - Whether or not the URL should be HTTPS or not.

Returns the URL.



74
75
76
77
78
# File 'lib/suitcase/hotel/helpers.rb', line 74

def main_url(secure)
  url = "http#{secure ? "s" : ""}://#{secure ? "book." : ""}"
  url += "api.ean.com/ean-services/rs/hotel/v3/"
  url
end

#parameterize(hash) ⇒ Object

Internal: Parameterize a Hash.

hash - The Hash to be parameterized.

Examples

parameterize(something: "else", another: "thing")
# => "something=else&another=thing"

Returns a parameterized String.



30
31
32
# File 'lib/suitcase/hotel/helpers.rb', line 30

def parameterize(hash)
  hash.map { |key, value| "#{key}=#{value}" }.join "&"
end

#parse_response(uri) ⇒ Object

Internal: Parse the JSON response at the given URL and handle errors.

uri - The URI to parse the JSON from.

Returns the parsed JSON.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/suitcase/hotel/helpers.rb', line 85

def parse_response(uri)
  response = Net::HTTP.get_response(uri)

  if response.code.to_i == 403
    if response.body.include?("Forbidden")
      e = EANException.new("You have not been granted permission to access the requested method or object.")
      e.type = :forbidden
    elsif response.body.include?("Not Authorized")
      e = EANException.new("The API key associated with your request was not recognized, or the digital signature was incorrect.")
      e.type = :not_authorized
    elsif response.body.include?("Developer Inactive")
      e = EANException.new("The API key you are using to access the API has not been approved, is not correct, or has been disabled. If using SIG Authentication, your digital signature is incorrect and does not match the one generated when receiving your request.")
      e.type = :developer_inactive
    elsif response.body.include?("Queries Per Second Limit")
      e = EANException.new("The API key you are using has attempted to access the API too many times in one second.")
      e.type = :query_limit
    elsif response.body.include?("Account Over Rate Limit")
      e = EANException.new("The API key you are using has attempted to access the API too many times in the rate limiting period.")
      e.type = :rate_limit
    elsif response.body.include?("Rate Limit Exceeded")
      e = EANException.new("The service you have requested is over capacity.")
      e.type = :over_capacity
    elsif response.body.include?("Authentication Failure")
      e = EANException.new("The combination of authentication checks failed.")
      e.type = :authentication_failure
    else
      e = EANException.new("An unknown error occured: #{response.body}.")
      e.type = :unknown
    end

    raise e
  end

  JSON.parse(Net::HTTP.get_response(uri).body)
end

#update_session(parsed, session) ⇒ Object

Internal: Update the Session’s ID with the parsed JSON.

parsed - The parsed JSON to fetch the ID from. session - The Session to update.

Returns nothing.



182
183
184
185
# File 'lib/suitcase/hotel/helpers.rb', line 182

def update_session(parsed, session)
  session ||= Session.new
  session.id = parsed[parsed.keys.first]["customerSessionId"] if parsed[parsed.keys.first]
end

#url(builder) ⇒ Object

Internal: Build an API URL.

builder - A Hash with the following required keys:

:method       - The API method to be put in the URL.
:params       - The params to be put in the URL.
And the following optional ones:
:include_key  - Whether to include the API key or not.
:include_cid  - Whether to include the API cid or not.
:secure       - Whether or not for the request to be sent over
                HTTPS.
:as_form      - Whether or not to include the parameters in the
                URL.
:session      - The Session associated with the request.

Examples

url(secure: true, as_form: true, method: "myMethod", params: {})
# => #<URI::HTTPS URL:https://book.api.ean.com/.../rs/hotel/v3/myMethod>

Returns the URI with the builder’s information.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/suitcase/hotel/helpers.rb', line 54

def url(builder)
  builder = URL_DEFAULTS.merge(builder)
  builder[:session] ||= URL_DEFAULTS[:session]
  method, params = builder[:method], builder[:params]
  params["apiKey"] = Configuration.hotel_api_key if builder[:include_key]
  params["cid"] = (Configuration.hotel_cid ||= 55505) if builder[:include_cid]
  params["sig"] = generate_signature if Configuration.use_signature_auth?

  url = main_url(builder[:secure]) + method.to_s + (builder[:as_form] ? "" : "?")

  params.merge!(build_session_params(builder[:session]))
  url += parameterize(params) unless builder[:as_form]
  URI.parse(URI.escape(url))
end