UNPKG

node-skyscanner-live

Version:
173 lines (144 loc) 7.05 kB
var promise = require('bluebird'); var request = require('request-promise'); var util = require('util'); var _ = require('lodash'); module.exports = { setApiKey: function (apiKey) { this.apiKey = apiKey; }, getLocation: function (searchLocation) { var url = util.format( 'http://partners.api.skyscanner.net/apiservices/autosuggest/v1.0/HK/HKD/en-US/?query=%s&apiKey=%s', encodeURIComponent(searchLocation), this.apiKey); return request(url).then(function (body) { var data = JSON.parse(body); return data.Places.map(function (loc) { return { id: loc.PlaceId, name: loc.PlaceName }; }); }); }, searchCache: function (fromLocation, toLocation, fromDate, toDate) { var url = util.format( 'http://partners.api.skyscanner.net/apiservices/browsequotes/v1.0/HK/HKD/en-US/%s/%s/%s/%s?apiKey=%s', encodeURIComponent(fromLocation), encodeURIComponent(toLocation), encodeURIComponent(fromDate), encodeURIComponent(toDate), this.apiKey); return request(url).then(function (body) { var data = JSON.parse(body); var toReturn = data.Quotes.map(function (quote) { var segments = [quote.OutboundLeg, quote.InboundLeg].map(function (segment, index) { var departPlace = _.filter(data.Places, { PlaceId: segment.OriginId })[0]; var arrivePlace = _.filter(data.Places, { PlaceId: segment.DestinationId })[0]; var carriers = segment.CarrierIds.map(c => _.filter(data.Carriers, { CarrierId: c })[0].Name); return { group: index + 1, departAirport: { code: departPlace.IataCode, name: departPlace.Name }, arriveAirport: { code: arrivePlace.IataCode, name: arrivePlace.Name }, departCity: { code: departPlace.CityId, name: departPlace.CityName }, arriveCity: { code: arrivePlace.CityId, name: arrivePlace.CityName }, departTime: segment.DepartureDate, carriers: carriers }; }); return { segments: segments, price: quote.MinPrice, } }); return toReturn; }); }, search: function (fromLocation, toLocation, fromDate, toDate, adults, children, infants, fastMode) { var apiKey = this.apiKey; var delay = 1000; var pull = this.pull; var options = { method: 'POST', uri: 'http://partners.api.skyscanner.net/apiservices/pricing/v1.0', form: { cabinclass: 'Economy', country: 'HK', currency: 'HKD', locale: 'en-US', locationSchema: 'iata', originplace: fromLocation, destinationplace: toLocation, outbounddate: fromDate, inbounddate: toDate, adults: adults || 1, children: children || 0, infants: infants || 0, apikey: apiKey, GroupPricing: false }, transform: function (body, response) { return { url: util.format('%s?apiKey=%s&pageIndex=0&pageSize=10', response.headers['location'], apiKey) }; }, json: false }; return request(options).then(function (session) { return pull(session.url, pull, delay, fastMode).then(function (body) { var data = JSON.parse(body); var toReturn = data.Itineraries.map(function (itin) { var outboundLeg = _.filter(data.Legs, { Id: itin.OutboundLegId })[0]; var inboundLeg = _.filter(data.Legs, { Id: itin.InboundLegId })[0]; var segments = outboundLeg.SegmentIds.concat(inboundLeg.SegmentIds).map(function (segmentId, index) { var segment = _.filter(data.Segments, { Id: segmentId })[0]; var departAirport = _.filter(data.Places, { Id: segment.OriginStation })[0]; var arriveAirport = _.filter(data.Places, { Id: segment.DestinationStation })[0]; var departCity = !departAirport.ParentId ? departAirport : _.filter(data.Places, { Id: departAirport.ParentId })[0]; var arriveCity = !arriveAirport.ParentId ? arriveAirport : _.filter(data.Places, { Id: arriveAirport.ParentId })[0]; var carriers = _.union(_.filter(data.Carriers, { Id: segment.OperatingCarrier }), _.filter(data.Carriers, { Id: segment.Carrier })); return { group: index < outboundLeg.SegmentIds.length ? 1 : 2, departAirport: { code: departAirport.Code, name: departAirport.Name }, arriveAirport: { code: arriveAirport.Code, name: arriveAirport.Name }, departCity: { code: departCity.Code, name: departCity.Name }, arriveCity: { code: arriveCity.Code, name: arriveCity.Name }, departTime: segment.DepartureDateTime, arriveTime: segment.ArrivalDateTime, carrier: carriers.map(c => c.Name) }; }); return { segments: segments, price: itin.PricingOptions[0].Price, url: itin.PricingOptions[0].DeeplinkUrl }; }); return toReturn; }); }); }, pull: function (url, self, delay, fastMode) { var pullinner = function () { var currentRequest = request(url); return currentRequest.then(function (body) { var data = JSON.parse(body); if (fastMode && data.Itineraries.length) { return currentRequest; } else if (data.Status === "UpdatesPending") { return self(url, self, delay); } else if (data.Status === "UpdatesComplete") { return currentRequest; } else { return null; } }, function (error) { if (error.statusCode === 304) { return self(url, self, delay); } else if (error.statusCode === 429) { return self(url, self, 60000); } else { return null; } }); }; return promise.delay(delay).then(pullinner); }, };