gillbus 0.11.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.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +10 -0
  5. data/Guardfile +29 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +140 -0
  8. data/Rakefile +9 -0
  9. data/gillbus.gemspec +31 -0
  10. data/lib/gillbus/base_request.rb +99 -0
  11. data/lib/gillbus/base_response.rb +43 -0
  12. data/lib/gillbus/buy_booking.rb +74 -0
  13. data/lib/gillbus/buy_tickets.rb +36 -0
  14. data/lib/gillbus/cancel_order.rb +55 -0
  15. data/lib/gillbus/drivers/faraday_response_file_logger.rb +19 -0
  16. data/lib/gillbus/find_order.rb +37 -0
  17. data/lib/gillbus/get_all_cities.rb +24 -0
  18. data/lib/gillbus/get_cities.rb +34 -0
  19. data/lib/gillbus/get_countries.rb +24 -0
  20. data/lib/gillbus/get_dates_new.rb +35 -0
  21. data/lib/gillbus/get_order_status.rb +28 -0
  22. data/lib/gillbus/get_order_ticket.rb +62 -0
  23. data/lib/gillbus/get_required_fields.rb +32 -0
  24. data/lib/gillbus/get_time_table.rb +33 -0
  25. data/lib/gillbus/get_trip_seats.rb +61 -0
  26. data/lib/gillbus/get_trips.rb +13 -0
  27. data/lib/gillbus/helpers/fields.rb +47 -0
  28. data/lib/gillbus/helpers/parser.rb +100 -0
  29. data/lib/gillbus/helpers/update_attrs.rb +15 -0
  30. data/lib/gillbus/lock_seats.rb +82 -0
  31. data/lib/gillbus/logout.rb +19 -0
  32. data/lib/gillbus/parse_error.rb +11 -0
  33. data/lib/gillbus/reserve_tickets.rb +13 -0
  34. data/lib/gillbus/search_trips.rb +96 -0
  35. data/lib/gillbus/session_login.rb +32 -0
  36. data/lib/gillbus/structs/commission.rb +54 -0
  37. data/lib/gillbus/structs/item.rb +14 -0
  38. data/lib/gillbus/structs/passenger_discount.rb +37 -0
  39. data/lib/gillbus/structs/point.rb +38 -0
  40. data/lib/gillbus/structs/return_cause.rb +23 -0
  41. data/lib/gillbus/structs/seat.rb +38 -0
  42. data/lib/gillbus/structs/segment.rb +161 -0
  43. data/lib/gillbus/structs/tariff.rb +59 -0
  44. data/lib/gillbus/structs/ticket.rb +285 -0
  45. data/lib/gillbus/structs/timetable_segment.rb +51 -0
  46. data/lib/gillbus/structs/timetable_trip.rb +77 -0
  47. data/lib/gillbus/structs/trip.rb +164 -0
  48. data/lib/gillbus/tickets_booking.rb +182 -0
  49. data/lib/gillbus/unlock_seats.rb +15 -0
  50. data/lib/gillbus/version.rb +3 -0
  51. data/lib/gillbus.rb +86 -0
  52. data/script/example_booking.rb +82 -0
  53. data/script/example_booking_with_segments.rb +90 -0
  54. data/script/example_canceling_booking.rb +67 -0
  55. data/script/example_canceling_reservation.rb +69 -0
  56. data/script/example_reservation.rb +88 -0
  57. data/test/buy_booking_test.rb +32 -0
  58. data/test/buy_tickets_test.rb +12 -0
  59. data/test/cancel_order_test.rb +12 -0
  60. data/test/error_test.rb +31 -0
  61. data/test/find_order_test.rb +24 -0
  62. data/test/get_cities_test.rb +12 -0
  63. data/test/get_countries_test.rb +12 -0
  64. data/test/get_dates_new_test.rb +12 -0
  65. data/test/get_order_ticket_test.rb +12 -0
  66. data/test/get_time_table_test.rb +21 -0
  67. data/test/get_trip_seats_test.rb +40 -0
  68. data/test/lock_seats_test.rb +70 -0
  69. data/test/reserve_tickets_test.rb +22 -0
  70. data/test/responses/buyBooking.xml +9 -0
  71. data/test/responses/buyTickets.xml +7 -0
  72. data/test/responses/cancelOrder.xml +8 -0
  73. data/test/responses/error.xml +1 -0
  74. data/test/responses/findOrder.xml +296 -0
  75. data/test/responses/getCities.xml +266 -0
  76. data/test/responses/getCountries.xml +90 -0
  77. data/test/responses/getOrderTicket.xml +3 -0
  78. data/test/responses/getTimeTable.xml +81 -0
  79. data/test/responses/getTripSeats-one-empty-segment.xml +562 -0
  80. data/test/responses/getTripSeats-segments.xml +1052 -0
  81. data/test/responses/getTripSeats.xml +492 -0
  82. data/test/responses/lockSeats.xml +23 -0
  83. data/test/responses/reserveTickets.xml +76 -0
  84. data/test/responses/searchTrips-empty.xml +3 -0
  85. data/test/responses/searchTrips-prod.xml +193 -0
  86. data/test/responses/searchTrips-segments-roundtrip.xml +15812 -0
  87. data/test/responses/searchTrips-segments.xml +808 -0
  88. data/test/responses/sessionLogin.xml +3 -0
  89. data/test/responses/ticketsBooking.xml +75 -0
  90. data/test/responses/very_empty.xml +1 -0
  91. data/test/search_trips_test.rb +71 -0
  92. data/test/session_login_test.rb +12 -0
  93. data/test/test_helper.rb +3 -0
  94. data/test/tickets_booking_test.rb +16 -0
  95. metadata +303 -0
@@ -0,0 +1,34 @@
1
+ class Gillbus
2
+ module GetCities
3
+
4
+ Gillbus.register self, :get_cities
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/getCities' end
9
+
10
+ attr_accessor :start_city_id
11
+
12
+ def params
13
+ {
14
+ startCityId: start_city_id,
15
+ }
16
+ end
17
+
18
+ end
19
+
20
+ class City
21
+ extend Fields
22
+ include UpdateAttrs
23
+ field :id
24
+ field :name
25
+ field :country_id
26
+ field :country_name
27
+ end
28
+
29
+ class Response < BaseResponse
30
+ field :cities, [City], key: 'CITY'
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ class Gillbus
2
+ module GetCountries
3
+
4
+ Gillbus.register self, :get_countries
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/getCountries' end
9
+
10
+ end
11
+
12
+ class Country
13
+ extend Fields
14
+ include UpdateAttrs
15
+ field :id
16
+ field :name
17
+ end
18
+
19
+ class Response < BaseResponse
20
+ field :countries, [Country], key: 'COUNTRY'
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ class Gillbus
2
+ module GetDatesNew
3
+
4
+ Gillbus.register self, :get_dates_new
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/getDatesNew' end
9
+
10
+ attr_accessor :start_city_id
11
+ attr_accessor :end_city_id
12
+ attr_accessor :start_date_search
13
+ attr_accessor :end_date_search
14
+ attr_accessor :oneway_trip_date
15
+ attr_accessor :selected_modes
16
+
17
+ def params
18
+ compact(
19
+ startCityId: start_city_id,
20
+ endCityId: end_city_id,
21
+ startDateSearch: date(start_date_search),
22
+ endDateSearch: date(end_date_search),
23
+ onewayTripDate: date(oneway_trip_date),
24
+ selectedModes: modes(selected_modes),
25
+ )
26
+ end
27
+
28
+ end
29
+
30
+ class Response < BaseResponse
31
+ field :items, [Item], key: 'ITEM'
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ class Gillbus
2
+ module GetOrderStatus
3
+
4
+ Gillbus.register self, :get_order_status
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/getOrderStatus' end
9
+
10
+ # orderNumber
11
+ # Номер заказа или массив заказов, полученных при создании отложенной продажи.
12
+ attr_accessor :order_number
13
+
14
+ def params
15
+ compact(
16
+ orderNumber: order_number.is_a?(Array) ? order_number.join(";") : order_number,
17
+ )
18
+ end
19
+
20
+ end
21
+
22
+ class Response < BaseResponse
23
+ field :tickets, [Ticket], key: 'TICKET'
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,62 @@
1
+ require 'base64'
2
+ class Gillbus
3
+ module GetOrderTicket
4
+
5
+ Gillbus.register self, :get_order_ticket
6
+
7
+ class Request < BaseRequest
8
+
9
+ def path; '/online2/getOrderTicket' end
10
+
11
+ # orderId
12
+ # Уникальный ИД заказа, переданный при отложенной продаже.
13
+ attr_accessor :order_id
14
+
15
+ # removeAd
16
+ # Признак удаления логотипа Gillbus из билета. true – удалить логотип.
17
+ # По умолчанию false.
18
+ attr_accessor :remove_ad
19
+
20
+ # orderNumber
21
+ # Номер заказа полученный при создании отложенной продажи.
22
+ attr_accessor :order_number
23
+
24
+ # base64 (не обязательный)
25
+ # Признак получения билета заказа в виде строки Base64. true – билет заказа будет возвращен как строка Base64. По умолчанию false.
26
+ # Важно: надо передать true, парсер ответа ожидает этого.
27
+ # Иначе можно получить невалидный xml
28
+ attr_accessor :base64
29
+
30
+ # Тип возвращаемого документа. Например, "ticket"
31
+ attr_accessor :as
32
+
33
+ # locale (не обязательный)
34
+ # Язык формирования данных.
35
+ attr_accessor :locale
36
+
37
+ def params
38
+ compact(
39
+ orderId: order_id,
40
+ removeAd: remove_ad,
41
+ orderNumber: order_number,
42
+ base64: base64,
43
+ as: as,
44
+ locale: translated_locale(locale)
45
+ )
46
+ end
47
+ end
48
+
49
+ class Response < BaseResponse
50
+
51
+ field :ticket, :ticket
52
+
53
+ parser do
54
+ def ticket(val)
55
+ Base64.decode64(val)
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,32 @@
1
+ class Gillbus
2
+ module GetRequiredFields
3
+ Gillbus.register self, :get_required_fields
4
+
5
+ class Request < BaseRequest
6
+ def path; '/online2/getRequiredFields' end
7
+
8
+ attr_accessor :trip_id
9
+
10
+ def params
11
+ compact(
12
+ tripId: trip_id,
13
+ )
14
+ end
15
+ end
16
+
17
+ class Response < BaseResponse
18
+ field :dictionary, :bool_dict
19
+
20
+ parser do
21
+ def bool_dict(val)
22
+ return unless val
23
+ result = {}
24
+ val.each do |k, v|
25
+ result[k.downcase.to_sym] = bool(v)
26
+ end
27
+ result
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ class Gillbus
2
+ module GetTimeTable
3
+
4
+ Gillbus.register self, :get_time_table
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/getTimeTable' end
9
+
10
+ attr_accessor :locale
11
+ attr_accessor :start_city_id
12
+ attr_accessor :end_city_id
13
+ attr_accessor :start_date_search
14
+ attr_accessor :end_date_search
15
+
16
+ def params
17
+ compact(
18
+ locale: translated_locale(locale),
19
+ startCityId: start_city_id,
20
+ endCityId: end_city_id,
21
+ startDateSearch: date(start_date_search),
22
+ endDateSearch: date(end_date_search),
23
+ )
24
+ end
25
+
26
+ end
27
+
28
+ class Response < BaseResponse
29
+ field :trips, [TimetableTrip], key: 'TRIP'
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,61 @@
1
+ class Gillbus
2
+ module GetTripSeats
3
+
4
+ Gillbus.register self, :get_trip_seats
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/getTripSeats' end
9
+
10
+ # tripId
11
+ # ИД рейса, для которого нужно получить карту мест
12
+ attr_accessor :trip_id
13
+
14
+ # carriageId (не обязательный)
15
+ # ИД вагона, для которого нужно получить карту мест. По- умолчанию первый попавшийся. Только для железнодорожных рейсов.
16
+ attr_accessor :carriage_id
17
+
18
+ # backCarriageId (не обязательный)
19
+ # ИД вагона обратного рейса, для которого нужно получить карту мест. По-умолчанию первый попавшийся. Только для железнодорожных рейсов.
20
+ attr_accessor :back_carriage_id
21
+
22
+ # segment0carriageId...segmentNcarriageId (не обязательный)
23
+ # ИД вагона сегмента рейса с порядковым нормеом 0...N, для которого нужно получить карту мест.
24
+ # По-умолчанию первый попавшийся. Только для железнодорожных рейсов.
25
+
26
+ def params
27
+ compact(
28
+ tripId: trip_id,
29
+ carriageId: carriage_id,
30
+ backCarriageId: back_carriage_id
31
+ )
32
+ end
33
+
34
+ end
35
+
36
+ class Response < BaseResponse
37
+
38
+ SEGMENT_REGEX = /SEGMENT_(?<number>\d+)_SEAT/
39
+
40
+ field :seats, [Seat], key: 'SEAT'
41
+
42
+ field :segments, :segments, key: SEGMENT_REGEX
43
+
44
+ parser do
45
+ def segments(val)
46
+ return {} unless val.present?
47
+
48
+ max_segment_number = val.keys.max.match(SEGMENT_REGEX)[:number].to_i
49
+
50
+ [*0..max_segment_number].inject({}) do |hash, segment|
51
+ seats = val["SEGMENT_#{segment}_SEAT"].to_a
52
+ hash[segment] = seats.map { |seat| Seat.parse(seat) }.presence || []
53
+ hash
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,13 @@
1
+ class Gillbus
2
+ module GetTrips
3
+
4
+ Gillbus.register self, :get_trips
5
+
6
+ class Request < BaseRequest
7
+ def path; '/online2/getTrips' end
8
+ end
9
+
10
+ Response = Gillbus::SearchTrips::Response
11
+
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ class Gillbus
2
+ # Gives a bunch of class methods
3
+ # to parse gillbus responses hash and define accessors
4
+ #
5
+ # Warning:
6
+ # resulting definitions won't work properly in subclass
7
+ #
8
+ # Usage:
9
+ # class MyClass
10
+ # extend Gillbus::Fields
11
+ # field :foo, :date
12
+ # end
13
+ #
14
+ # MyClass.parse(hash)
15
+ module Fields
16
+
17
+ def parser_class
18
+ @parser_class || Gillbus::Parser
19
+ end
20
+
21
+ def parse(doc, instance=new)
22
+ parser_class.new(
23
+ doc: doc,
24
+ instance: instance,
25
+ fields: field_definitions
26
+ ).parse
27
+ instance
28
+ end
29
+
30
+ def parser(&definition)
31
+ @parser_class = Class.new(parser_class, &definition)
32
+ end
33
+
34
+ private
35
+
36
+ def field_definitions
37
+ @fields ||= []
38
+ end
39
+
40
+ def field(name, type=:string, key: name.to_s.upcase)
41
+ field_definitions << {name: name, key: key, type: type}
42
+ attr_accessor name
43
+ end
44
+
45
+
46
+ end
47
+ end
@@ -0,0 +1,100 @@
1
+ require 'bigdecimal'
2
+ require 'active_support/time'
3
+
4
+ class Gillbus
5
+ class Parser
6
+
7
+ attr_accessor :doc
8
+ attr_accessor :instance
9
+ attr_accessor :fields
10
+
11
+ def initialize(instance:, doc:, fields:)
12
+ @instance = instance
13
+ @doc = doc
14
+ @fields = fields
15
+ end
16
+
17
+ def parse
18
+ fields.each do |name:, key:, type:|
19
+ raw_value =
20
+ if key.is_a?(Regexp)
21
+ doc.select { |k| k =~ key }
22
+ else
23
+ doc[key]
24
+ end
25
+ value = make_one_or_many(type, raw_value)
26
+ instance.send "#{name}=", value unless value.nil?
27
+ end
28
+ instance
29
+ end
30
+
31
+ private
32
+
33
+ def make_one_or_many(type, val)
34
+ # [:type]
35
+ if type.is_a? Array
36
+ array(val).map {|v| make_one type.first, v }
37
+ # :type
38
+ else
39
+ make_one type, val
40
+ end
41
+ end
42
+
43
+ def make_one(type, val)
44
+ return if val.nil?
45
+ if type.is_a? Class
46
+ type.parse(val)
47
+ else
48
+ send type, val
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ # nil => []
55
+ # [] => []
56
+ # {} => [{}]
57
+ def array(arg)
58
+ return [arg] if arg.is_a? Hash
59
+ Array(arg)
60
+ end
61
+
62
+ def string(val)
63
+ return if val == "null"
64
+ val
65
+ end
66
+
67
+ def bool(val)
68
+ val == "true"
69
+ end
70
+
71
+ def yesno_bool(val)
72
+ val == 'Y'
73
+ end
74
+
75
+ def int(val)
76
+ val.to_i
77
+ end
78
+
79
+ def date(val)
80
+ Date.strptime(val, '%d.%m.%Y')
81
+ end
82
+
83
+ def time(val)
84
+ if val =~ /^ ( \d\d:\d\d ) (?: :\d\d )? $/x
85
+ $1
86
+ else
87
+ nil
88
+ end
89
+ end
90
+
91
+ def datetime(val)
92
+ ActiveSupport::TimeZone["Europe/Kiev"].parse(val)
93
+ end
94
+
95
+ def decimal(val)
96
+ BigDecimal.new(val)
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,15 @@
1
+ class Gillbus
2
+ module UpdateAttrs
3
+
4
+ def initialize(attrs={})
5
+ update_attrs attrs if attrs
6
+ end
7
+
8
+ def update_attrs(attrs={})
9
+ attrs.each do |k, v|
10
+ public_send "#{k}=", v
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,82 @@
1
+ class Gillbus
2
+ module LockSeats
3
+
4
+ Gillbus.register self, :lock_seats
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/lockSeats' end
9
+
10
+ # tripId
11
+ # ИД рейса, для которого нужно получить карту мест
12
+ attr_accessor :trip_id
13
+
14
+ # carriageId (не обязательный)
15
+ # ИД вагона, для которого нужно получить карту мест. По- умолчанию первый попавшийся. Только для железнодорожных рейсов.
16
+ attr_accessor :carriage_id
17
+
18
+ # backCarriageId (не обязательный)
19
+ # ИД вагона обратного рейса, для которого нужно получить карту мест. По-умолчанию первый попавшийся. Только для железнодорожных рейсов.
20
+ attr_accessor :back_carriage_id
21
+
22
+ # segment0carriageId...segmentNcarriageId (не обязательный)
23
+ # ИД вагона сегмента рейса с порядковым нормеом 0...N, для которого нужно получить карту мест.
24
+ # По-умолчанию первый попавшийся. Только для железнодорожных рейсов.
25
+
26
+ # seatId0...seatIdN (не обязательный)
27
+ # ИД места с порядковым номером 0...N, которое нужно заблокировать.
28
+ attr_accessor :seat_ids
29
+
30
+ # backSeatId0...backSeatIdN (не обязательный)
31
+ # ИД места с порядковым номером 0...N, которое нужно заблокировать на обратный рейс.
32
+ attr_accessor :back_seat_ids
33
+
34
+ # segment0seatId0... segmentMseatIdN (не обязательный)
35
+ # ИД места с порядковым номером 0...N, которое нужно заблокировать на сегмент рейса с порядковым номером 0...M.
36
+ attr_accessor :segments_seat_ids
37
+
38
+ def params
39
+ seats = Array(seat_ids).map.with_index {|id, n| [:"seatId#{n}", id] }.to_h
40
+ back_seats = Array(back_seat_ids).map.with_index {|id, n| [:"backSeatId#{n}", id] }.to_h
41
+ segments_seats = Hash(segments_seat_ids).map do |segment, seat_ids|
42
+ Array(seat_ids).map.with_index {|id, n| [:"segment#{segment}seatId#{n}", id] }.to_h
43
+ end.reduce(&:merge).to_h
44
+
45
+ compact(
46
+ tripId: trip_id,
47
+ carriageId: carriage_id,
48
+ backCarriageId: back_carriage_id,
49
+ **seats,
50
+ **back_seats,
51
+ **segments_seats,
52
+ )
53
+ end
54
+ end
55
+
56
+ class Response < BaseResponse
57
+
58
+ # seat lock, time limit, in seconds
59
+ field :time_limit, :milliseconds
60
+ # [{Symbol => Boolean}] необходимые для ввода типы документов?
61
+ field :dictionary, :bool_dict
62
+
63
+ parser do
64
+ def milliseconds(val)
65
+ return unless val
66
+ val.to_i / 1000
67
+ end
68
+
69
+ def bool_dict(val)
70
+ return unless val
71
+ result = {}
72
+ val.each do |k, v|
73
+ result[k.downcase.to_sym] = bool(v)
74
+ end
75
+ result
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,19 @@
1
+ class Gillbus
2
+ module Logout
3
+
4
+ Gillbus.register self, :logout
5
+
6
+ class Request < BaseRequest
7
+
8
+ def path; '/online2/logout' end
9
+
10
+ end
11
+
12
+ class Response < BaseResponse
13
+
14
+ field :logout, :bool
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # I want it not to be an exception, for now
2
+ class Gillbus::ParseError
3
+ def initialize(response_string)
4
+ @response = response_string
5
+ end
6
+ attr_reader :response
7
+ attr_accessor :session_id
8
+ def error?; true; end
9
+ def error_code; 0; end
10
+ def error_message; "Malformed response"; end
11
+ end
@@ -0,0 +1,13 @@
1
+ class Gillbus
2
+ module ReserveTickets
3
+
4
+ Gillbus.register self, :reserve_tickets
5
+
6
+ class Request < Gillbus::TicketsBooking::Request
7
+ def path; '/online2/reserveTickets' end
8
+ end
9
+
10
+ Response = Gillbus::TicketsBooking::Response
11
+
12
+ end
13
+ end