suitcase 1.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.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/lib/suitcase/air/air.rb +86 -0
- data/lib/suitcase/airport_codes.rb +3 -0
- data/lib/suitcase/country_codes.rb +3 -0
- data/lib/suitcase/hotel/hotel.rb +49 -0
- data/lib/suitcase/version.rb +3 -0
- data/lib/suitcase.rb +7 -0
- data/spec/hotel_spec.rb +23 -0
- data/spec/spec_helper.rb +4 -0
- data/suitcase.gemspec +24 -0
- metadata +92 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
Suitcase
|
2
|
+
========
|
3
|
+
|
4
|
+
Suitcase is a Ruby library that utilizes the EAN (Expedia.com) API for locating available hotels, rental cars, and flights.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
Add the following line to your Gemfile:
|
10
|
+
|
11
|
+
`gem 'suitcase', :git => "http://github.com/thoughtfusion/suitcase.git"` then run `bundle install`. Or install the gem: `gem install suitcase`.
|
12
|
+
|
13
|
+
|
14
|
+
Usage
|
15
|
+
-----
|
16
|
+
|
17
|
+
First, include the module in your code:
|
18
|
+
|
19
|
+
include Suitcase
|
20
|
+
|
21
|
+
Find nearby hotels:
|
22
|
+
|
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
|
26
|
+
|
27
|
+
Find available airline flights (not yet implemented):
|
28
|
+
|
29
|
+
Flight:API_KEY = "your_api_key_here"
|
30
|
+
Flight.available('June 23 2012', :from => "BOS", :to => "LHR") # Return all flights flying from Boston to London (Heathrow) on June 23, 2012
|
31
|
+
|
32
|
+
Contributing
|
33
|
+
------------
|
34
|
+
Please submit any useful pull requests through GitHub. If you find any bugs, please report them! Thanks.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,86 @@
|
|
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
|