suitcase 1.0.1 → 1.1.0
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.
- data/README.md +4 -4
- data/features/hotels.feature +28 -0
- data/features/step_definitions/hotels_steps.rb +21 -0
- data/lib/suitcase/hotel.rb +151 -0
- data/lib/suitcase/version.rb +1 -1
- data/lib/suitcase.rb +3 -6
- data/spec/api_key.rb +1 -0
- data/spec/data_helpers_spec.rb +14 -0
- data/spec/hotels_spec.rb +7 -0
- data/spec/spec_helper.rb +0 -2
- data/suitcase.gemspec +2 -0
- metadata +50 -13
- data/lib/suitcase/air/air.rb +0 -86
- data/lib/suitcase/hotel/hotel.rb +0 -49
- data/spec/hotel_spec.rb +0 -23
data/README.md
CHANGED
@@ -21,14 +21,14 @@ First, include the module in your code:
|
|
21
21
|
Find nearby hotels:
|
22
22
|
|
23
23
|
Hotel::API_KEY = "your_api_key_here"
|
24
|
-
Hotel.near('Boston, MA', 10) # Returns 10 closest hotels to Boston, MA
|
25
|
-
Hotel.near('Metropoliton Museum of Art') # Returns 50 closest hotels to the Met Museum in New York
|
24
|
+
Hotel.near(:location => 'Boston, MA', :results => 10) # Returns 10 closest hotels to Boston, MA
|
25
|
+
Hotel.near(:location => 'Metropoliton Museum of Art') # Returns 50 closest hotels to the Met Museum in New York
|
26
26
|
|
27
27
|
Find available airline flights (not yet implemented):
|
28
28
|
|
29
29
|
Flight:API_KEY = "your_api_key_here"
|
30
|
-
Flight.available('June 23 2012', :
|
30
|
+
Flight.available(:date => 'June 23 2012', :departs => "BOS", :arrives => "LHR") # Return all flights flying from Boston to London (Heathrow) on June 23, 2012
|
31
31
|
|
32
32
|
Contributing
|
33
33
|
------------
|
34
|
-
Please submit any useful pull requests through GitHub. If you find any bugs, please report them! Thanks.
|
34
|
+
Please submit any useful pull requests through GitHub. If you find any bugs, please report them with the issue tracker! Thanks.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Hotels
|
2
|
+
As a developer
|
3
|
+
In order to use the EAN API in my application
|
4
|
+
I need to be able to manipulate hotel information
|
5
|
+
|
6
|
+
Scenario Outline: Listing available hotels
|
7
|
+
Given I have an API key
|
8
|
+
When I submit a request to find <number_of_results> hotels in <location>
|
9
|
+
Then I want to receive <number_of_results> hotels with their respective information
|
10
|
+
|
11
|
+
Examples:
|
12
|
+
|
13
|
+
| number_of_results | location |
|
14
|
+
| 10 | Boston, USA |
|
15
|
+
| 8 | Dublin, Ireland |
|
16
|
+
| 1 | London, UK |
|
17
|
+
|
18
|
+
Scenario Outline: Requesting more information about a given hotel
|
19
|
+
Given I have an API key
|
20
|
+
When I submit a request to find more information about a hotel with id <id>
|
21
|
+
Then I want to receive more information about that hotel
|
22
|
+
|
23
|
+
Examples:
|
24
|
+
|
25
|
+
| id |
|
26
|
+
| 252897 |
|
27
|
+
| 273655 |
|
28
|
+
| 174272 |
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'suitcase'
|
2
|
+
|
3
|
+
Given /^I have an API key$/ do
|
4
|
+
Suitcase::Hotel::API_KEY = "3kx2vhr7sjrgmsyddb2cg47j"
|
5
|
+
end
|
6
|
+
|
7
|
+
When /^I submit a request to find (\d+) hotels in (.+)$/ do |results, location|
|
8
|
+
@hotels = Suitcase::Hotel.find(:near => location, :results => results.to_i)
|
9
|
+
end
|
10
|
+
|
11
|
+
Then /^I want to receive (\d+) hotels with their respective information$/ do |results|
|
12
|
+
@hotels.count.should eq(results.to_i)
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I submit a request to find more information about a hotel with id (\d+)$/ do |id|
|
16
|
+
@hotel = Suitcase::Hotel.find_by_id(id)
|
17
|
+
end
|
18
|
+
|
19
|
+
Then /^I want to receive more information about that hotel$/ do
|
20
|
+
@hotel.should_not be_nil
|
21
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module Suitcase
|
2
|
+
class PaymentOption
|
3
|
+
attr_accessor :code, :name
|
4
|
+
|
5
|
+
def initialize(code, name)
|
6
|
+
@code = code
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Room
|
12
|
+
attr_accessor :rate_key, :hotel_id, :supplier_type
|
13
|
+
|
14
|
+
def initialize(rate_key, hotel_id, supplier_type)
|
15
|
+
@rate_key = rate_key
|
16
|
+
@hotel_id = hotel_id
|
17
|
+
@supplier_type = supplier_type
|
18
|
+
end
|
19
|
+
|
20
|
+
def reserve!(info)
|
21
|
+
params = info
|
22
|
+
params["hotelId"] = @id
|
23
|
+
params["arrivalDate"] = info[:arrival]
|
24
|
+
params["departureDate"] = info[:departure]
|
25
|
+
params.delete(:arrival)
|
26
|
+
params.delete(:departure)
|
27
|
+
params["supplierType"] = supplier_type
|
28
|
+
params["rateKey"] = @rate_key
|
29
|
+
params["rateTypeCode"] = info[:room_type_code]
|
30
|
+
params["rateCode"] = info[:rate_code]
|
31
|
+
params.delete(:rate_code)
|
32
|
+
p Hotel.hit(Hotel.url(:res, true, true, params))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Hotel
|
37
|
+
AMENITIES = { pool: 1,
|
38
|
+
fitness_center: 2,
|
39
|
+
restaurant: 3,
|
40
|
+
children_activities: 4,
|
41
|
+
breakfast: 5,
|
42
|
+
meeting_facilities: 6,
|
43
|
+
pets: 7,
|
44
|
+
wheelchair_accessible: 8,
|
45
|
+
kitchen: 9 }
|
46
|
+
|
47
|
+
attr_accessor :id, :name, :address, :city, :min_rate, :max_rate, :amenities, :country_code, :high_rate, :low_rate, :longitude, :latitude, :rating, :postal_code, :supplier_type
|
48
|
+
|
49
|
+
def initialize(info)
|
50
|
+
info.each do |k, v|
|
51
|
+
send (k.to_s + "=").to_sym, v
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.url(action, include_key, include_cid, params)
|
56
|
+
url = "http://api.ean.com/ean-services/rs/hotel/v3/" + action.to_s + "?"
|
57
|
+
include_key ? params["apiKey"] = Suitcase::Hotel::API_KEY : nil
|
58
|
+
include_cid ? params["cid"] = "55505" : nil
|
59
|
+
params.each do |k, v|
|
60
|
+
url += k.to_s + "=" + v.to_s + "&"
|
61
|
+
end
|
62
|
+
if url =~ /^(.+)&$/
|
63
|
+
url = $1
|
64
|
+
end
|
65
|
+
URI.parse URI.escape(url)
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.find(info)
|
69
|
+
if info[:id]
|
70
|
+
find_by_id(info[:id])
|
71
|
+
else
|
72
|
+
find_by_info(info)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.find_by_id(id)
|
77
|
+
Hotel.new(parse_hotel_information(hit(url(:info, true, true, { hotelId: id }))))
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.find_by_info(info)
|
81
|
+
params = info
|
82
|
+
params["numberOfResults"] = params[:results] ? params[:results] : 10
|
83
|
+
params.delete(:results)
|
84
|
+
params["destinationString"] = params[:location]
|
85
|
+
params.delete(:location)
|
86
|
+
if params[:amenities]
|
87
|
+
amenities = ""
|
88
|
+
params[:amenities].each do |amenity|
|
89
|
+
amenities += AMENITIES[amenity].to_s + ","
|
90
|
+
end
|
91
|
+
if amenities =~ /^(.+),$/
|
92
|
+
amenities = $1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
params["minRate"] = params[:min_rate] if params[:min_rate]
|
96
|
+
params["maxRate"] = params[:max_rate] if params[:max_rate]
|
97
|
+
params[:amenities] = amenities
|
98
|
+
hotels = []
|
99
|
+
split(hit(url(:list, true, true, params))).each do |hotel_data|
|
100
|
+
hotels.push Hotel.new(parse_hotel_information(hotel_data.to_json))
|
101
|
+
end
|
102
|
+
hotels
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.hit(url)
|
106
|
+
Net::HTTP.get_response(url).body
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.parse_hotel_information(json)
|
110
|
+
parsed = JSON.parse json
|
111
|
+
summary = parsed["hotelId"] ? parsed : parsed["HotelInformationResponse"]["HotelSummary"]
|
112
|
+
{ id: summary["hotelId"], name: summary["name"], address: summary["address1"], city: summary["city"], postal_code: summary["postalCode"], country_code: summary["countryCode"], rating: summary["hotelRating"], high_rate: summary["highRate"], low_rate: summary["lowRate"], latitude: summary["latitude"].to_f, longitude: summary["longitude"].to_f }
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.split(data)
|
116
|
+
parsed = JSON.parse(data)
|
117
|
+
hotels = parsed["HotelListResponse"]["HotelList"]
|
118
|
+
hotels["HotelSummary"]
|
119
|
+
end
|
120
|
+
|
121
|
+
def rooms(info)
|
122
|
+
params = info
|
123
|
+
params[:rooms].each_with_index do |room, n|
|
124
|
+
params["room#{n+1}"] = (room[:children] == 0 ? "" : room[:children].to_s + ",").to_s + room[:ages].join(",").to_s
|
125
|
+
end
|
126
|
+
params["arrivalDate"] = info[:arrival]
|
127
|
+
params["departureDate"] = info[:departure]
|
128
|
+
params.delete(:arrival)
|
129
|
+
params.delete(:departure)
|
130
|
+
params["hotelId"] = @id
|
131
|
+
parsed = JSON.parse(Hotel.hit(Hotel.url(:avail, true, true, params)))
|
132
|
+
hotel_id = parsed["HotelRoomAvailabilityResponse"]["hotelId"]
|
133
|
+
rate_key = parsed["HotelRoomAvailabilityResponse"]["rateKey"]
|
134
|
+
supplier_type = parsed["HotelRoomAvailabilityResponse"]["supplierType"]
|
135
|
+
Room.new(rate_key, hotel_id, supplier_type)
|
136
|
+
end
|
137
|
+
|
138
|
+
def payment_options
|
139
|
+
options = []
|
140
|
+
types_raw = JSON.parse Hotel.hit(Hotel.url(:paymentInfo, true, true, {}))
|
141
|
+
types_raw["HotelPaymentResponse"].each do |raw|
|
142
|
+
p raw
|
143
|
+
types = raw[0] != "PaymentType" ? [] : raw[1]
|
144
|
+
types.each do |type|
|
145
|
+
options.push PaymentOption.new(type["code"], type["name"])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
options
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/lib/suitcase/version.rb
CHANGED
data/lib/suitcase.rb
CHANGED
data/spec/api_key.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
HOTEL_API_KEY = "88m3ugkarmfzcq3z4syayymt"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Suitcase::DataHelpers do
|
4
|
+
before :each do
|
5
|
+
class Hotel
|
6
|
+
API_KEY = HOTEL_API_KEY
|
7
|
+
extend Suitcase::DataHelpers
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "#url should return a valid url" do
|
12
|
+
URI.parse(Hotel.url(:hotel, :list, true, { location: "London, UK" })).should be_a(URI)
|
13
|
+
end
|
14
|
+
end
|
data/spec/hotels_spec.rb
ADDED
data/spec/spec_helper.rb
CHANGED
data/suitcase.gemspec
CHANGED
@@ -19,6 +19,8 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.add_development_dependency "rspec"
|
22
|
+
s.add_development_dependency "cucumber"
|
23
|
+
s.add_development_dependency "rake"
|
22
24
|
s.add_runtime_dependency "json"
|
23
25
|
s.add_runtime_dependency "nokogiri"
|
24
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: suitcase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-12-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &20325340 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,32 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *20325340
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: cucumber
|
27
|
+
requirement: &20324640 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *20324640
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &20324160 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *20324160
|
25
47
|
- !ruby/object:Gem::Dependency
|
26
48
|
name: json
|
27
|
-
requirement: &
|
49
|
+
requirement: &20323700 !ruby/object:Gem::Requirement
|
28
50
|
none: false
|
29
51
|
requirements:
|
30
52
|
- - ! '>='
|
@@ -32,10 +54,10 @@ dependencies:
|
|
32
54
|
version: '0'
|
33
55
|
type: :runtime
|
34
56
|
prerelease: false
|
35
|
-
version_requirements: *
|
57
|
+
version_requirements: *20323700
|
36
58
|
- !ruby/object:Gem::Dependency
|
37
59
|
name: nokogiri
|
38
|
-
requirement: &
|
60
|
+
requirement: &20323260 !ruby/object:Gem::Requirement
|
39
61
|
none: false
|
40
62
|
requirements:
|
41
63
|
- - ! '>='
|
@@ -43,7 +65,7 @@ dependencies:
|
|
43
65
|
version: '0'
|
44
66
|
type: :runtime
|
45
67
|
prerelease: false
|
46
|
-
version_requirements: *
|
68
|
+
version_requirements: *20323260
|
47
69
|
description: Suitcase utilizes the EAN API for locating available hotels, rental cars,
|
48
70
|
and flights.
|
49
71
|
email:
|
@@ -56,13 +78,16 @@ files:
|
|
56
78
|
- Gemfile
|
57
79
|
- README.md
|
58
80
|
- Rakefile
|
81
|
+
- features/hotels.feature
|
82
|
+
- features/step_definitions/hotels_steps.rb
|
59
83
|
- lib/suitcase.rb
|
60
|
-
- lib/suitcase/air/air.rb
|
61
84
|
- lib/suitcase/airport_codes.rb
|
62
85
|
- lib/suitcase/country_codes.rb
|
63
|
-
- lib/suitcase/hotel
|
86
|
+
- lib/suitcase/hotel.rb
|
64
87
|
- lib/suitcase/version.rb
|
65
|
-
- spec/
|
88
|
+
- spec/api_key.rb
|
89
|
+
- spec/data_helpers_spec.rb
|
90
|
+
- spec/hotels_spec.rb
|
66
91
|
- spec/spec_helper.rb
|
67
92
|
- suitcase.gemspec
|
68
93
|
homepage: http://github.com/thoughtfusion/suitcase
|
@@ -77,16 +102,28 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
102
|
- - ! '>='
|
78
103
|
- !ruby/object:Gem::Version
|
79
104
|
version: '0'
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
hash: -1859999531224729447
|
80
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
109
|
none: false
|
82
110
|
requirements:
|
83
111
|
- - ! '>='
|
84
112
|
- !ruby/object:Gem::Version
|
85
113
|
version: '0'
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
hash: -1859999531224729447
|
86
117
|
requirements: []
|
87
118
|
rubyforge_project: suitcase
|
88
|
-
rubygems_version: 1.8.
|
119
|
+
rubygems_version: 1.8.10
|
89
120
|
signing_key:
|
90
121
|
specification_version: 3
|
91
122
|
summary: Locates available hotels, rental cars, and flights
|
92
|
-
test_files:
|
123
|
+
test_files:
|
124
|
+
- features/hotels.feature
|
125
|
+
- features/step_definitions/hotels_steps.rb
|
126
|
+
- spec/api_key.rb
|
127
|
+
- spec/data_helpers_spec.rb
|
128
|
+
- spec/hotels_spec.rb
|
129
|
+
- spec/spec_helper.rb
|
data/lib/suitcase/air/air.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'json'
|
3
|
-
require 'nokogiri'
|
4
|
-
require File.dirname(__FILE__) + '/../airport_codes'
|
5
|
-
|
6
|
-
module Suitcase
|
7
|
-
class Flight
|
8
|
-
attr_accessor :flights, :key, :origin, :destination, :departure, :arrival, :adults, :children, :seniors, :fare, :direct, :round_trip, :currency, :search_window, :results, :airline, :airline_code, :price, :segments, :outgoing
|
9
|
-
|
10
|
-
def to_s
|
11
|
-
puts <<EOS
|
12
|
-
----------
|
13
|
-
FLIGHT:
|
14
|
-
airline: #{airline} (#{airline_code})
|
15
|
-
origin: #{origin}
|
16
|
-
destination: #{destination}
|
17
|
-
departure: #{departure}
|
18
|
-
arrival: #{arrival}
|
19
|
-
price: #{price} (#{currency})
|
20
|
-
key: #{key}
|
21
|
-
----------
|
22
|
-
EOS
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.available(data)
|
26
|
-
origin_city = data[:from]
|
27
|
-
destination_city = data[:to]
|
28
|
-
departure_date_time = data[:departs]
|
29
|
-
arrival_date_time = data[:arrives]
|
30
|
-
adult_passengers = data[:adults] ? data[:adults] : 0
|
31
|
-
child_passengers = data[:children] ? data[:children].inject("") { |result, element| result + "C" + (element < 10 ? "0" : "") + element.to_s + (data[:children].last == element ? "" : ",") } : "" # :children => [2, 9, 11] (ages of children) should yield "C02,C09,C11"
|
32
|
-
senior_passengers = data[:seniors] ? data[:seniors] : 0
|
33
|
-
fare_class = data[:fare] ? data[:fare] : "Y" # F: first class; Y: coach; B: business
|
34
|
-
direct_flight = data[:direct_only] ? data[:direct_only] : false
|
35
|
-
round_trip = data[:round_trip] ? data[:round_trip] : "O"
|
36
|
-
currency = data[:currency] ? data[:currency] : "USD"
|
37
|
-
search_window = data[:search_window] ? data[:search_window] : 2
|
38
|
-
number_of_results = data[:results] ? data[:results] : 50
|
39
|
-
xml_format = <<EOS
|
40
|
-
<AirSessionRequest method="getAirAvailability">
|
41
|
-
<AirAvailabilityQuery>
|
42
|
-
<originCityCode>#{origin_city}</originCityCode>
|
43
|
-
<destinationCityCode>#{destination_city}</destinationCityCode>
|
44
|
-
<departureDateTime>#{departure_date_time}</departureDateTime>
|
45
|
-
<returnDateTime>#{arrival_date_time}</returnDateTime>
|
46
|
-
<fareClass>#{fare_class}</fareClass>
|
47
|
-
<tripType>#{round_trip}</tripType>
|
48
|
-
<Passengers>
|
49
|
-
<adultPassengers>#{adult_passengers}</adultPassengers>
|
50
|
-
<seniorPassengers>#{senior_passengers}</seniorPassengers>
|
51
|
-
<childCodes>#{child_passengers}</childCodes>
|
52
|
-
</Passengers>
|
53
|
-
</AirAvailabilityQuery>
|
54
|
-
</AirSessionRequest>
|
55
|
-
EOS
|
56
|
-
uri = URI.escape("http://api.ean.com/ean-services/rs/air/200919/xmlinterface.jsp?cid=#{CID}&resType=air&intfc=ws&apiKey=#{API_KEY}&xml=#{xml_format}")
|
57
|
-
xml = Nokogiri::XML(open(uri))
|
58
|
-
segments = []
|
59
|
-
xml.xpath('//Segment').each do |segment|
|
60
|
-
f = Flight.new
|
61
|
-
f.key = segment.xpath("@key")
|
62
|
-
f.origin = segment.xpath("//originCity") + segment.xpath("//originStateProvince") + segment.xpath("//originCountry")
|
63
|
-
f.destination = segment.xpath("//destinationCity")
|
64
|
-
f.airline = segment.xpath("//airline")
|
65
|
-
f.airline_code = segment.xpath("//airlineCode")
|
66
|
-
f.departure = segment.xpath("//departureDateTime")
|
67
|
-
f.arrival = segment.xpath("//arrivalDateTime")
|
68
|
-
segments.push(f)
|
69
|
-
end
|
70
|
-
flights = []
|
71
|
-
xml.xpath("//AirAvailabilityReply").each do |aar|
|
72
|
-
f = Flight.new
|
73
|
-
f.segments = []
|
74
|
-
f.price = aar.xpath("//nativeTotalPrice")
|
75
|
-
f.currency = aar.xpath("//displayCurrencyCode")
|
76
|
-
aar.xpath("//FlightSegment").each do |subseg|
|
77
|
-
fn = segments.find { |x| x.key == subseg.xpath("//segmentKey") }
|
78
|
-
f.segments.push(fn)
|
79
|
-
f.segments.compact!
|
80
|
-
end
|
81
|
-
flights.push(f)
|
82
|
-
end
|
83
|
-
flights
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/lib/suitcase/hotel/hotel.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'uri'
|
3
|
-
require 'json'
|
4
|
-
require File.dirname(__FILE__) + '/../country_codes'
|
5
|
-
|
6
|
-
module Suitcase
|
7
|
-
class Hotel
|
8
|
-
attr_accessor :id, :name, :address, :city, :postal_code, :country, :airport_code, :rating, :confidence_rating, :description, :high_rate, :low_rate, :tripadvisor_rating, :currency_code, :latitude, :longitude
|
9
|
-
|
10
|
-
def self.find(hash)
|
11
|
-
hotels = []
|
12
|
-
json = JSON.parse Net::HTTP.get_response(URI.parse(URI.escape("http://api.ean.com/ean-services/rs/hotel/v3/list?apiKey=#{Suitcase::Hotel::API_KEY}&city=#{hash[:near]}&numberOfResults=#{hash[:results]}"))).body
|
13
|
-
if json["HotelListResponse"]["HotelList"]
|
14
|
-
json["HotelListResponse"]["HotelList"]["HotelSummary"].each do |hotel_data|
|
15
|
-
h = Hotel.new
|
16
|
-
h.id = hotel_data["hotelId"]
|
17
|
-
h.name = hotel_data["name"]
|
18
|
-
h.address = hotel_data["address1"]
|
19
|
-
h.city = hotel_data["city"]
|
20
|
-
h.postal_code = hotel_data["postalCode"]
|
21
|
-
h.country = COUNTRY_CODES[hotel_data["countryCode"]]
|
22
|
-
h.airport_code = hotel_data["airportCode"]
|
23
|
-
h.rating = hotel_data["hotelRating"]
|
24
|
-
h.confidence_rating = hotel_data["confidenceRating"]
|
25
|
-
h.tripadvisor_rating = hotel_data["tripAdvisorRating"]
|
26
|
-
h.currency_code = hotel_data["rateCurrencyCode"]
|
27
|
-
h.latitude = hotel_data["latitude"]
|
28
|
-
h.longitude = hotel_data["longitude"]
|
29
|
-
h.high_rate = hotel_data["highRate"]
|
30
|
-
h.low_rate = hotel_data["lowRate"]
|
31
|
-
hotels.push(h)
|
32
|
-
end
|
33
|
-
hotels[0..hash[:results]-1]
|
34
|
-
else
|
35
|
-
if json["HotelListResponse"]["EanWsError"]
|
36
|
-
raise "An error occured. Check data."
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def geolocation
|
42
|
-
latitude + ", " + longitude
|
43
|
-
end
|
44
|
-
|
45
|
-
def complete_address
|
46
|
-
address + " " + city + ", " + country + " " + postal_code
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
data/spec/hotel_spec.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
include Suitcase
|
4
|
-
|
5
|
-
describe Hotel do
|
6
|
-
before(:each) do
|
7
|
-
@attr = { :near => "Boston", :results => 50 }
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "find method" do
|
11
|
-
it "should return the correct number of results" do
|
12
|
-
Hotel.find(@attr).count.should eq(50)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should return an array of hotels" do
|
16
|
-
Hotel.find(@attr).class.should eq(Array)
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should return all hotels" do
|
20
|
-
Hotel.find(@attr).map { |x| x.class }.should eq([Hotel] * 50)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|