teecket 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2188b057b1c90ca438cd0a9c8d1800fdddd05c2f
4
+ data.tar.gz: 385db9dad3eccd44072b238b35404303595e64e3
5
+ SHA512:
6
+ metadata.gz: 83801f55ee2aa27350e4da061cffd2398681c56e4f473865c50f83ea903fcb9342e623506c49e8d6394c6941f759ac4ec162e76a0293145e8a66cdb8057092dc
7
+ data.tar.gz: 03c6c00aa42395bd1cd9f99261675094f3cf5f9e50b9b298c11563c244ae4ecb03259705f228a8f052b06a9d0556bdfbf19382395a13a960a2342fecccc2e381
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'teecket'
4
+
5
+ if ARGV.count == 3
6
+ Teecket.search({ from: ARGV[0], to: ARGV[1], date: ARGV[2]})
7
+ else
8
+ puts 'Example: teecket KBR KUL 30-07-2015'
9
+ end
10
+
@@ -0,0 +1,28 @@
1
+ require 'teecket/flight'
2
+ require 'teecket/air_asia'
3
+ require 'teecket/malaysia_airlines'
4
+ require 'teecket/malindo_air'
5
+ require 'teecket/printer'
6
+ require 'teecket/firefly'
7
+
8
+ require 'byebug'
9
+
10
+ class Teecket
11
+ def self.search(params)
12
+ airasia = AirAsia.new({ from: params[:from], to: params[:to], date: params[:date] })
13
+ airasia.get
14
+
15
+ firefly = Firefly.new({ from: params[:from], to: params[:to], date: params[:date] })
16
+ firefly.get
17
+
18
+ mas = MalaysiaAirlines.new({ from: params[:from], to: params[:to], date: params[:date] })
19
+ mas.get
20
+
21
+ malindo = MalindoAir.new({ from: params[:from], to: params[:to], date: params[:date] })
22
+ malindo.get
23
+
24
+ output = airasia.fares + mas.fares + malindo.fares + firefly.fares
25
+
26
+ puts Printer.table(output)
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ class AirAsia < Flight
2
+ def get
3
+ uri = URI('https://argon.airasia.com/api/7.0/search')
4
+
5
+ http = Net::HTTP.new(uri.host, uri.port)
6
+ http.use_ssl = true
7
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
8
+
9
+ req = Net::HTTP::Post.new(uri.path)
10
+ req.body = "type=classic&origin=#{from}&destination=#{to}&depart=#{date}&return=&passenger-count=1&child-count=0&infant-count=0&currency=MYR&days=1"
11
+
12
+ res = http.request(req)
13
+
14
+ result = JSON.parse(res.body)
15
+
16
+ if result['session-id']
17
+ begin
18
+ result['depart'][date]['details']['low-fare'].each do |rs|
19
+ depart_at = DateTime.parse(rs['segments'][0]['departure-datetime'])
20
+ arrive_at = DateTime.parse(rs['segments'][0]['arrival-datetime'])
21
+ fare = rs['total']['adult']
22
+ flight_number = rs['segments'][0]['flight-number']
23
+ origin = rs['segments'][0]['origincode']
24
+ destination = rs['segments'][0]['destinationcode']
25
+
26
+ depart_at = depart_at.strftime('%I:%M %p')
27
+ arrive_at = arrive_at.strftime('%I:%M %p')
28
+ fare = sprintf("%.2f", fare)
29
+ flight_number = flight_number.gsub(/ /, '')
30
+
31
+ fares << { flight_name: 'AirAsia',
32
+ flight_number: flight_number,
33
+ origin: origin,
34
+ destination: destination,
35
+ depart_at: depart_at,
36
+ arrive_at: arrive_at,
37
+ fare: fare }
38
+ end
39
+ rescue StandardError
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,75 @@
1
+ require 'nokogiri'
2
+
3
+ class Firefly < Flight
4
+ def get
5
+
6
+ uri = URI('https://m.fireflyz.com.my/')
7
+
8
+ http = Net::HTTP.new(uri.host, uri.port)
9
+ http.use_ssl = true
10
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
11
+
12
+ req = Net::HTTP::Get.new(uri.path)
13
+
14
+ res = http.request(req)
15
+
16
+ cookie = res['Set-Cookie']
17
+
18
+ uri = URI('https://m.fireflyz.com.my/Search')
19
+
20
+ http = Net::HTTP.new(uri.host, uri.port)
21
+ http.use_ssl = true
22
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
23
+
24
+ req = Net::HTTP::Get.new(uri.path, initheader = { 'Cookie' => cookie})
25
+
26
+ cookie = res['Set-Cookie']
27
+
28
+ uri = URI('https://m.fireflyz.com.my/Search')
29
+
30
+ http = Net::HTTP.new(uri.host, uri.port)
31
+ http.use_ssl = true
32
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
33
+
34
+ req = Net::HTTP::Post.new(uri.path, initheader = { 'Cookie' => cookie})
35
+ req.body = 'type=2&departure_station=KBR&arrival_station=SZB&departure_date=30%2F06%2F2015&return_date=30%2F06%2F2015&adult=1&infant=0'
36
+
37
+ res = http.request(req)
38
+
39
+ if res['location']
40
+ uri = URI(res['location'])
41
+
42
+ http = Net::HTTP.new(uri.host, uri.port)
43
+ http.use_ssl = true
44
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
45
+
46
+ req = Net::HTTP::Get.new(uri.path, initheader = { 'Cookie' => cookie})
47
+
48
+ res = http.request(req)
49
+
50
+ doc = Nokogiri::HTML(res.body)
51
+
52
+ doc.css('div.market1').each_with_index do |elem, i|
53
+ depart_at = doc.css('div.market1')[i].css('div.visible-xs').css('table')[1].css('td')[0].text.strip
54
+ arrive_at = doc.css('div.market1')[i].css('div.visible-xs').css('table')[1].css('td')[1].text.strip
55
+ fare = doc.css('div.market1')[i].css('div.visible-xs > div').text.strip
56
+ flight_number = doc.css('div.market1')[i].css('div.visible-xs').css('table')[0].text.strip
57
+ origin = doc.css('div.market1')[i]['onclick'].scan(/~[A-Z]{3}~/)[0].gsub('~', '')
58
+ destination = doc.css('div.market1')[i]['onclick'].scan(/~[A-Z]{3}~/)[1].gsub('~', '')
59
+
60
+ depart_at = DateTime.parse("#{date} #{depart_at.gsub(/\t/, '').match(/^(.*?)(AM|PM)/).to_s}").strftime('%I:%M %p')
61
+ arrive_at = DateTime.parse("#{date} #{arrive_at.gsub(/\t/, '').match(/^(.*?)(AM|PM)/).to_s}").strftime('%I:%M %p')
62
+ fare = fare.gsub(/ MYR/, '')
63
+ flight_number = flight_number.gsub(/ /, '').gsub(/FLIGHTNO\./, '')
64
+
65
+ fares << { flight_name: 'Firefly',
66
+ flight_number: flight_number,
67
+ origin: origin,
68
+ destination: destination,
69
+ depart_at: depart_at,
70
+ arrive_at: arrive_at,
71
+ fare: fare }
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,15 @@
1
+ require 'net/http'
2
+ require 'openssl'
3
+ require 'json'
4
+
5
+ class Flight
6
+ attr_reader :from, :to, :date, :fares
7
+
8
+ def initialize(params)
9
+ @from = params[:from]
10
+ @to = params[:to]
11
+ @date = params[:date]
12
+
13
+ @fares = []
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ class MalaysiaAirlines < Flight
2
+ def get
3
+ new_date = DateTime.parse(date)
4
+ new_date = new_date.strftime('%Y-%m-%d')
5
+
6
+ uri = URI("https://flymh.mobi/TravelAPI/travelapi/shop/1/mh/#{from}/#{to}/1/0/0/Economy/#{new_date}/")
7
+
8
+ http = Net::HTTP.new(uri.host, uri.port)
9
+ http.use_ssl = true
10
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
11
+
12
+ req = Net::HTTP::Get.new(uri.path, initHeader = { 'X-apiKey' => '52e6d6d613d3a3e825ac02253fe6b5a4'})
13
+
14
+ res = http.request(req)
15
+ res.body.gsub!(/^fn\(/, '')
16
+ res.body.gsub!(/\)/, '')
17
+
18
+ result = JSON.parse(res.body)
19
+
20
+ if result['success']
21
+ result['outboundOptions'].each do |rs|
22
+ depart_at = DateTime.parse(rs['flights'][0]['depScheduled'])
23
+ arrive_at = DateTime.parse(rs['flights'][0]['arrScheduled'])
24
+ fare = rs['fareDetails']['totalTripFare']
25
+ flight_number = rs['flights'][0]['marketingAirline'] + rs['flights'][0]['flightNumber']
26
+ origin = rs['flights'][0]['departureAirport']['code']
27
+ destination = rs['flights'][0]['arrivalAirport']['code']
28
+
29
+ depart_at = depart_at.strftime('%I:%M %p')
30
+ arrive_at = arrive_at.strftime('%I:%M %p')
31
+ fare = sprintf("%.2f", fare)
32
+
33
+ fares << { flight_name: 'Malaysia Airlines',
34
+ flight_number: flight_number,
35
+ origin: origin,
36
+ destination: destination,
37
+ depart_at: depart_at,
38
+ arrive_at: arrive_at,
39
+ fare: fare }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,60 @@
1
+ class MalindoAir < Flight
2
+ def get
3
+ new_date = DateTime.parse(date)
4
+ new_date = new_date.strftime('%Q')
5
+
6
+ uri = URI('https://mobileapi.malindoair.com/GQWCF_FlightEngine/GQDPMobileBookingService.svc/InitializeGQService')
7
+
8
+ http = Net::HTTP.new(uri.host, uri.port)
9
+ http.use_ssl = true
10
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
11
+
12
+ req = Net::HTTP::Post.new(uri.path, initheader = { 'Content-Type' => 'application/json' })
13
+ req.body = '{"B2BID":"0","UserLoginId":"0","CustomerUserID":91,"Language":"en-GB","isearchType":"15"}'
14
+
15
+ res = http.request(req)
16
+ key = res['wscContext']
17
+
18
+ if key
19
+ uri = URI('https://mobileapi.malindoair.com/GQWCF_FlightEngine/GQDPMobileBookingService.svc/SearchAirlineFlights')
20
+
21
+ http = Net::HTTP.new(uri.host, uri.port)
22
+ http.use_ssl = true
23
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
24
+
25
+ req = Net::HTTP::Post.new(uri.path, initheader = { 'Content-Type' => 'application/json',
26
+ 'WscContext' => key })
27
+
28
+ payload = "{\"sd\":{\"Adults\":1,\"AirlineCode\":\"\",\"ArrivalCity\":\"#{to}\",\"ArrivalCityName\":null,\"BookingClass\":null,\"CabinClass\":0,\"ChildAge\":[],\"Children\":0,\"CustomerId\":0,\"CustomerType\":0,\"CustomerUserId\":91,\"DepartureCity\":\"#{from}\",\"DepartureCityName\":null,\"DepartureDate\":\"/Date(#{new_date})/\",\"DepartureDateGap\":0,\"DirectFlightsOnly\":false,\"Infants\":0,\"IsPackageUpsell\":false,\"JourneyType\":1,\"ReturnDate\":\"/Date(-2208988800000)/\",\"ReturnDateGap\":0,\"SearchOption\":1},\"fsc\":\"0\"}"
29
+
30
+ req.body = payload
31
+
32
+ res = http.request(req)
33
+
34
+ result = JSON.parse(res.body)
35
+
36
+ if result['SearchAirlineFlightsResult']
37
+ result['SearchAirlineFlightsResult'].each do |rs|
38
+ depart_at = rs['DepartureDate']
39
+ arrive_at = rs['ArrivalDate']
40
+ fare = rs['FlightAmount']
41
+ flight_number = rs['MACode'] + rs['FlightNo']
42
+ origin = rs['DepCity']
43
+ destination = rs['ArrCity']
44
+
45
+ depart_at = DateTime.strptime(depart_at.gsub(/^\/Date\(|\)\//, ''), '%Q').strftime('%I:%M %p')
46
+ arrive_at = DateTime.strptime(arrive_at.gsub(/^\/Date\(|\)\//, ''), '%Q').strftime('%I:%M %p')
47
+ fare = sprintf("%.2f", fare)
48
+
49
+ fares << { flight_name: 'Malindo Air',
50
+ flight_number: flight_number,
51
+ origin: origin,
52
+ destination: destination,
53
+ depart_at: depart_at,
54
+ arrive_at: arrive_at,
55
+ fare: fare }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ require 'terminal-table'
2
+
3
+ class Printer
4
+ def self.table(rows = [])
5
+ headings = ['Flight', 'Flight #', 'Origin', 'Destination', 'Depart', 'Arrive', 'Fare (RM)']
6
+
7
+ new_rows = rows.map { |row| row.values }
8
+
9
+ Terminal::Table.new(headings: headings, rows: new_rows)
10
+ end
11
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: teecket
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Amree Zaid
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: terminal-table
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.5
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.4'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.4.5
33
+ - !ruby/object:Gem::Dependency
34
+ name: nokogiri
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.6'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.6.6.2
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.6'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.6.6.2
53
+ - !ruby/object:Gem::Dependency
54
+ name: byebug
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '5.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 5.0.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '5.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 5.0.0
73
+ description: Search ticket's fare for all major airlines in Malaysia at once
74
+ email: mohd.amree@gmail.com
75
+ executables:
76
+ - teecket
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - bin/teecket
81
+ - lib/teecket.rb
82
+ - lib/teecket/air_asia.rb
83
+ - lib/teecket/firefly.rb
84
+ - lib/teecket/flight.rb
85
+ - lib/teecket/malaysia_airlines.rb
86
+ - lib/teecket/malindo_air.rb
87
+ - lib/teecket/printer.rb
88
+ homepage: https://github.com/amree/teecket
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.2.2
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Search for flights fare in Malaysia
112
+ test_files: []