ns-yapi 0.5.0 → 0.6.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +19 -0
- data/.ruby-version +1 -1
- data/.travis.yml +5 -2
- data/Gemfile +13 -5
- data/Gemfile.lock +95 -44
- data/lib/model/prices_url.rb +7 -5
- data/lib/ns_client.rb +123 -97
- data/ns.gemspec +16 -14
- data/rakefile.rb +3 -1
- data/spec/model/prices_url_spec.rb +23 -23
- data/spec/ns_client_spec.rb +158 -173
- data/spec/nsyapi_spec.rb +17 -22
- data/spec/spec_helper.rb +13 -18
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 90e0e28a27c5819ad9ccab28567b1645e19995308e2da96345f0ef7dcb2fdff7
|
4
|
+
data.tar.gz: b815628df8eb973f22856ca0d95c9575e2bc02749225bb95685b622bdabe5c9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5da72d6d6be93450f0d7c84aae840719df990e26d9253250bf53fc564431f1127fb606292757fef8ef943650b5eb84834b30ca24222be6cbe5e72f83893676a6
|
7
|
+
data.tar.gz: 6bb0a08ac0d239b3fba39e62c094bc207f08c171b9ef3a83e739eefc91078e6fec1ff3045d7dfab95fdda435450f0399b70d102129f88044e288533f90c36b47
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require: rubocop-performance
|
2
|
+
|
3
|
+
Style/Documentation:
|
4
|
+
Enabled: false
|
5
|
+
|
6
|
+
Metrics/LineLength:
|
7
|
+
Max: 120
|
8
|
+
Exclude:
|
9
|
+
- spec/**/*
|
10
|
+
|
11
|
+
Metrics/BlockLength:
|
12
|
+
Exclude:
|
13
|
+
- spec/**/*
|
14
|
+
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Max: 20
|
17
|
+
|
18
|
+
Metrics/ClassLength:
|
19
|
+
Max: 200
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6.2
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,15 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'http://rubygems.org'
|
2
4
|
|
3
|
-
gem "httpclient", "~> 2.3.3"
|
4
5
|
gem 'rake'
|
6
|
+
gem 'rest-client'
|
5
7
|
|
6
8
|
gemspec
|
7
9
|
|
8
10
|
group :test do
|
11
|
+
gem 'coveralls', require: false
|
12
|
+
gem 'mocha', require: 'mocha/api'
|
13
|
+
gem 'pry'
|
9
14
|
gem 'rspec'
|
10
15
|
gem 'simplecov'
|
11
|
-
gem
|
12
|
-
gem
|
13
|
-
|
14
|
-
|
16
|
+
gem 'timecop'
|
17
|
+
gem 'webmock'
|
18
|
+
end
|
19
|
+
|
20
|
+
group :development do
|
21
|
+
gem 'rubocop', require: false
|
22
|
+
gem 'rubocop-performance', require: false
|
15
23
|
end
|
data/Gemfile.lock
CHANGED
@@ -3,69 +3,120 @@ PATH
|
|
3
3
|
specs:
|
4
4
|
ns-yapi (0.5.0)
|
5
5
|
addressable
|
6
|
-
httpclient
|
7
6
|
nokogiri
|
8
7
|
nori
|
8
|
+
rest-client
|
9
9
|
|
10
10
|
GEM
|
11
11
|
remote: http://rubygems.org/
|
12
12
|
specs:
|
13
|
-
addressable (2.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
simplecov (
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
13
|
+
addressable (2.6.0)
|
14
|
+
public_suffix (>= 2.0.2, < 4.0)
|
15
|
+
ast (2.4.0)
|
16
|
+
coderay (1.1.2)
|
17
|
+
coveralls (0.8.22)
|
18
|
+
json (>= 1.8, < 3)
|
19
|
+
simplecov (~> 0.16.1)
|
20
|
+
term-ansicolor (~> 1.3)
|
21
|
+
thor (~> 0.19.4)
|
22
|
+
tins (~> 1.6)
|
23
|
+
crack (0.4.3)
|
24
|
+
safe_yaml (~> 1.0.0)
|
25
|
+
diff-lcs (1.3)
|
26
|
+
docile (1.3.1)
|
27
|
+
domain_name (0.5.20180417)
|
28
|
+
unf (>= 0.0.5, < 1.0.0)
|
29
|
+
hashdiff (0.3.8)
|
30
|
+
http-cookie (1.0.3)
|
31
|
+
domain_name (~> 0.5)
|
32
|
+
jaro_winkler (1.5.2)
|
33
|
+
json (2.2.0)
|
34
|
+
metaclass (0.0.4)
|
35
|
+
method_source (0.9.2)
|
36
|
+
mime-types (3.2.2)
|
37
|
+
mime-types-data (~> 3.2015)
|
38
|
+
mime-types-data (3.2019.0331)
|
39
|
+
mini_portile2 (2.4.0)
|
40
|
+
mocha (1.8.0)
|
29
41
|
metaclass (~> 0.0.1)
|
30
|
-
|
31
|
-
nokogiri (1.
|
32
|
-
mini_portile2 (~> 2.
|
42
|
+
netrc (0.11.0)
|
43
|
+
nokogiri (1.10.2)
|
44
|
+
mini_portile2 (~> 2.4.0)
|
33
45
|
nori (2.6.0)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
parallel (1.17.0)
|
47
|
+
parser (2.6.2.1)
|
48
|
+
ast (~> 2.4.0)
|
49
|
+
pry (0.12.2)
|
50
|
+
coderay (~> 1.1.0)
|
51
|
+
method_source (~> 0.9.0)
|
52
|
+
psych (3.1.0)
|
53
|
+
public_suffix (3.0.3)
|
54
|
+
rainbow (3.0.0)
|
55
|
+
rake (12.3.2)
|
56
|
+
rest-client (2.0.2)
|
57
|
+
http-cookie (>= 1.0.2, < 2.0)
|
58
|
+
mime-types (>= 1.16, < 4.0)
|
59
|
+
netrc (~> 0.8)
|
60
|
+
rspec (3.8.0)
|
61
|
+
rspec-core (~> 3.8.0)
|
62
|
+
rspec-expectations (~> 3.8.0)
|
63
|
+
rspec-mocks (~> 3.8.0)
|
64
|
+
rspec-core (3.8.0)
|
65
|
+
rspec-support (~> 3.8.0)
|
66
|
+
rspec-expectations (3.8.2)
|
67
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
68
|
+
rspec-support (~> 3.8.0)
|
69
|
+
rspec-mocks (3.8.0)
|
70
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
71
|
+
rspec-support (~> 3.8.0)
|
72
|
+
rspec-support (3.8.0)
|
73
|
+
rubocop (0.67.2)
|
74
|
+
jaro_winkler (~> 1.5.1)
|
75
|
+
parallel (~> 1.10)
|
76
|
+
parser (>= 2.5, != 2.5.1.1)
|
77
|
+
psych (>= 3.1.0)
|
78
|
+
rainbow (>= 2.2.2, < 4.0)
|
79
|
+
ruby-progressbar (~> 1.7)
|
80
|
+
unicode-display_width (>= 1.4.0, < 1.6)
|
81
|
+
rubocop-performance (1.1.0)
|
82
|
+
rubocop (>= 0.67.0)
|
83
|
+
ruby-progressbar (1.10.0)
|
84
|
+
safe_yaml (1.0.5)
|
85
|
+
simplecov (0.16.1)
|
86
|
+
docile (~> 1.1)
|
87
|
+
json (>= 1.8, < 3)
|
88
|
+
simplecov-html (~> 0.10.0)
|
89
|
+
simplecov-html (0.10.2)
|
90
|
+
term-ansicolor (1.7.1)
|
91
|
+
tins (~> 1.0)
|
92
|
+
thor (0.19.4)
|
93
|
+
timecop (0.9.1)
|
94
|
+
tins (1.20.2)
|
95
|
+
unf (0.1.4)
|
96
|
+
unf_ext
|
97
|
+
unf_ext (0.0.7.5)
|
98
|
+
unicode-display_width (1.5.0)
|
99
|
+
webmock (3.5.1)
|
100
|
+
addressable (>= 2.3.6)
|
54
101
|
crack (>= 0.3.2)
|
102
|
+
hashdiff
|
55
103
|
|
56
104
|
PLATFORMS
|
57
105
|
ruby
|
58
106
|
|
59
107
|
DEPENDENCIES
|
60
108
|
coveralls
|
61
|
-
httpclient (~> 2.3.3)
|
62
109
|
mocha
|
63
110
|
ns-yapi!
|
111
|
+
pry
|
64
112
|
rake
|
113
|
+
rest-client
|
65
114
|
rspec
|
115
|
+
rubocop
|
116
|
+
rubocop-performance
|
66
117
|
simplecov
|
67
|
-
timecop
|
68
|
-
webmock
|
118
|
+
timecop
|
119
|
+
webmock
|
69
120
|
|
70
121
|
BUNDLED WITH
|
71
|
-
1.
|
122
|
+
1.17.2
|
data/lib/model/prices_url.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
class PricesUrl
|
3
4
|
def initialize(url)
|
4
|
-
raise InvalidURL,
|
5
|
+
raise InvalidURL, 'You must give an url, ie http://www.ns.nl/api' unless url
|
6
|
+
|
5
7
|
@url = url
|
6
8
|
end
|
7
9
|
|
8
|
-
def url
|
9
|
-
opts[:date] = opts[:date].strftime(
|
10
|
-
uri = URI.escape(opts.collect{|k,v| "#{k}=#{v}"}.join('&'))
|
10
|
+
def url(opts = { date: nil, from: '', to: '' })
|
11
|
+
opts[:date] = opts[:date].strftime('%d%m%Y') if opts[:date]
|
12
|
+
uri = Addressable::URI.escape(opts.collect { |k, v| "#{k}=#{v}" }.join('&'))
|
11
13
|
"#{@url}?#{uri}"
|
12
14
|
end
|
13
15
|
|
data/lib/ns_client.rb
CHANGED
@@ -1,191 +1,219 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'pathname'
|
3
4
|
require 'time'
|
4
5
|
require 'nori'
|
5
6
|
require 'nokogiri'
|
6
|
-
require '
|
7
|
-
require
|
7
|
+
require 'rest-client'
|
8
|
+
require 'addressable/uri'
|
8
9
|
|
9
10
|
this = Pathname.new(__FILE__).realpath
|
10
|
-
lib_path = File.expand_path(
|
11
|
-
|
12
|
-
|
13
|
-
$ROOT = File.expand_path("../", lib_path)
|
11
|
+
lib_path = File.expand_path('..', this)
|
12
|
+
$LOAD_PATH.unshift(lib_path)
|
14
13
|
|
15
14
|
Dir.glob(File.join(lib_path, '/**/*.rb')).each do |file|
|
16
15
|
require file
|
17
16
|
end
|
18
17
|
|
19
18
|
module NSYapi
|
20
|
-
|
21
19
|
class Configuration
|
22
|
-
attr_accessor :username, :password
|
20
|
+
attr_accessor :username, :password, :configuration
|
23
21
|
end
|
24
22
|
|
25
23
|
def self.configure(configuration = NSYapi::Configuration.new)
|
26
24
|
yield configuration if block_given?
|
27
|
-
|
25
|
+
@configuration = configuration
|
28
26
|
end
|
29
27
|
|
30
28
|
def self.configuration # :nodoc:
|
31
|
-
|
29
|
+
@configuration ||= NSYapi::Configuration.new
|
32
30
|
end
|
33
31
|
|
34
32
|
def self.client
|
35
|
-
@client_instance
|
33
|
+
@client_instance ||= NSClient.new(configuration.username, configuration.password)
|
36
34
|
@client_instance
|
37
35
|
end
|
38
|
-
|
39
36
|
end
|
40
37
|
|
41
38
|
class NSClient
|
42
|
-
|
43
|
-
attr_accessor :last_received_raw_xml, :last_received_corrected_xml
|
39
|
+
attr_accessor :last_received_raw_xml, :last_received_corrected_xml, :username, :password
|
44
40
|
|
45
41
|
def initialize(username, password)
|
46
|
-
@
|
47
|
-
@
|
48
|
-
@prices_url = PricesUrl.new(
|
49
|
-
@last_received_raw_xml =
|
50
|
-
@last_received_corrected_xml =
|
42
|
+
@username = username
|
43
|
+
@password = password
|
44
|
+
@prices_url = PricesUrl.new('https://webservices.ns.nl/ns-api-prijzen-v3')
|
45
|
+
@last_received_raw_xml = ''
|
46
|
+
@last_received_corrected_xml = ''
|
51
47
|
end
|
52
48
|
|
53
49
|
def stations
|
54
|
-
parse_stations(get_xml(
|
50
|
+
parse_stations(get_xml('https://webservices.ns.nl/ns-api-stations-v2'))
|
55
51
|
end
|
56
52
|
|
57
53
|
def stations_short
|
58
|
-
parse_stations_as_map(get_xml(
|
54
|
+
parse_stations_as_map(get_xml('https://webservices.ns.nl/ns-api-stations-v2'))
|
59
55
|
end
|
60
56
|
|
61
|
-
def disruptions
|
57
|
+
def disruptions(query = nil)
|
62
58
|
response_xml = get_xml(disruption_url(query))
|
63
59
|
raise_error_when_response_is_error(response_xml)
|
64
60
|
parse_disruptions(response_xml)
|
65
61
|
end
|
66
62
|
|
67
|
-
def prices
|
68
|
-
|
69
|
-
raise MissingParameter, "from station is required" unless opts[:from]
|
70
|
-
raise MissingParameter, "to station is required" unless opts[:to]
|
71
|
-
raise SameDestinationError,
|
72
|
-
"from (#{opts[:from]}) and to (#{opts[:to]}) parameters should not be equal" if opts[:from] == opts[:to]
|
63
|
+
def prices(opts = { from: nil, to: nil, via: nil, date: nil })
|
64
|
+
validate_prices(opts)
|
73
65
|
response_xml = get_xml(@prices_url.url(opts))
|
74
66
|
raise_error_when_response_is_error(response_xml)
|
75
67
|
parse_prices(response_xml)
|
76
68
|
end
|
77
69
|
|
70
|
+
def validate_price_parameters(opts)
|
71
|
+
raise MissingParameter, 'from and to station is required' if opts[:from].nil? && opts[:to].nil?
|
72
|
+
raise MissingParameter, 'from station is required' unless opts[:from]
|
73
|
+
raise MissingParameter, 'to station is required' unless opts[:to]
|
74
|
+
end
|
75
|
+
|
76
|
+
def validate_prices(opts)
|
77
|
+
validate_price_parameters(opts)
|
78
|
+
|
79
|
+
return unless opts[:from] == opts[:to]
|
80
|
+
|
81
|
+
raise SameDestinationError,
|
82
|
+
"from (#{opts[:from]}) and to (#{opts[:to]}) parameters should not be equal"
|
83
|
+
end
|
84
|
+
|
78
85
|
def parse_prices(response_xml)
|
79
86
|
prices_response = PricesResponse.new
|
80
|
-
(response_xml/'/VervoerderKeuzes/VervoerderKeuze').each do |transporter|
|
81
|
-
prices_response.tariff_units = (transporter/'./Tariefeenheden').text.to_i
|
82
|
-
|
83
|
-
(transporter/'ReisType').each do |travel_type|
|
84
|
-
prices =
|
85
|
-
|
86
|
-
(travel_type/'ReisKlasse').each do |travel_class|
|
87
|
-
(travel_class/'Korting/Kortingsprijs').each do |price_element|
|
88
|
-
product_price = ProductPrice.new
|
89
|
-
product_price.discount = price_element.attr("name")
|
90
|
-
product_price.train_class = travel_class.attr("klasse")
|
91
|
-
product_price.amount = price_element.attr("prijs").gsub(",", ".").to_f
|
92
|
-
prices << product_price
|
93
|
-
end
|
94
|
-
end
|
87
|
+
(response_xml / '/VervoerderKeuzes/VervoerderKeuze').each do |transporter|
|
88
|
+
prices_response.tariff_units = (transporter / './Tariefeenheden').text.to_i
|
89
|
+
|
90
|
+
(transporter / 'ReisType').each do |travel_type|
|
91
|
+
prices = parse_travel_type(travel_type)
|
95
92
|
|
96
93
|
name = travel_type.attr('name')
|
97
94
|
prices_response.products[name] = prices
|
98
95
|
end
|
99
|
-
|
100
96
|
end
|
101
97
|
prices_response
|
102
98
|
end
|
103
99
|
|
100
|
+
def parse_travel_type(travel_type)
|
101
|
+
prices = []
|
102
|
+
|
103
|
+
(travel_type / 'ReisKlasse').each do |travel_class|
|
104
|
+
(travel_class / 'Korting/Kortingsprijs').each do |price_element|
|
105
|
+
product_price = ProductPrice.new
|
106
|
+
product_price.discount = price_element.attr('name')
|
107
|
+
product_price.train_class = travel_class.attr('klasse')
|
108
|
+
product_price.amount = price_element.attr('prijs').tr(',', '.').to_f
|
109
|
+
prices << product_price
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
prices
|
114
|
+
end
|
115
|
+
|
104
116
|
def parse_stations(response_xml)
|
105
117
|
result = []
|
106
|
-
(response_xml/'/Stations/Station').each do |station|
|
107
|
-
|
108
|
-
s.code = (station/'./Code').text
|
109
|
-
s.type = (station/'./Type').text
|
110
|
-
s.country = (station/'./Land').text
|
111
|
-
s.short_name = (station/'./Namen/Kort').text
|
112
|
-
s.name = (station/'./Namen/Middel').text
|
113
|
-
s.long_name = (station/'./Namen/Lang').text
|
114
|
-
s.lat = (station/'./Lat').text
|
115
|
-
s.long = (station/'./Lon').text
|
116
|
-
s.uiccode = (station/'./UICCode').text
|
117
|
-
result << s
|
118
|
+
(response_xml / '/Stations/Station').each do |station|
|
119
|
+
result << parse_station(station)
|
118
120
|
end
|
119
121
|
result
|
120
122
|
end
|
121
123
|
|
124
|
+
def parse_station(station)
|
125
|
+
s = Station.new
|
126
|
+
s.code = parse_station_field(station, './Code')
|
127
|
+
s.type = parse_station_field(station, './Type')
|
128
|
+
s.country = parse_station_field(station, './Land')
|
129
|
+
s.short_name = parse_station_field(station, './Namen/Kort')
|
130
|
+
s.name = parse_station_field(station, './Namen/Middel')
|
131
|
+
s.long_name = parse_station_field(station, './Namen/Lang')
|
132
|
+
s.lat = parse_station_field(station, './Lat')
|
133
|
+
s.long = parse_station_field(station, './Lon')
|
134
|
+
s.uiccode = parse_station_field(station, './UICCode')
|
135
|
+
s
|
136
|
+
end
|
137
|
+
|
138
|
+
def parse_station_field(station, field)
|
139
|
+
(station / field).text
|
140
|
+
end
|
141
|
+
|
122
142
|
def parse_stations_as_map(response_xml)
|
123
143
|
result = {}
|
124
|
-
(response_xml/'/Stations/Station').each do |station|
|
125
|
-
code = (station/'./Code').text
|
126
|
-
name = (station/'./Namen/Middel').text
|
127
|
-
country = (station/'./Land').text
|
144
|
+
(response_xml / '/Stations/Station').each do |station|
|
145
|
+
code = (station / './Code').text
|
146
|
+
name = (station / './Namen/Middel').text
|
147
|
+
country = (station / './Land').text
|
128
148
|
result[code] = [name, country]
|
129
149
|
end
|
130
150
|
result
|
131
151
|
end
|
132
152
|
|
133
153
|
def parse_disruptions(response_xml)
|
134
|
-
result = {planned: [], unplanned: []}
|
135
|
-
(response_xml/'/Storingen').each do |disruption|
|
136
|
-
(disruption/'Ongepland/Storing').each do |unplanned|
|
137
|
-
|
138
|
-
unplanned_disruption.id = (unplanned/'./id').text
|
139
|
-
unplanned_disruption.trip = (unplanned/'./Traject').text
|
140
|
-
unplanned_disruption.reason = (unplanned/'./Reden').text
|
141
|
-
unplanned_disruption.message = (unplanned/'./Bericht').text
|
142
|
-
unplanned_disruption.datetime_string = (unplanned/'./Datum').text
|
143
|
-
unplanned_disruption.cause = (unplanned/'./Oorzaak').text
|
144
|
-
result[:unplanned] << unplanned_disruption
|
154
|
+
result = { planned: [], unplanned: [] }
|
155
|
+
(response_xml / '/Storingen').each do |disruption|
|
156
|
+
(disruption / 'Ongepland/Storing').each do |unplanned|
|
157
|
+
result[:unplanned] << parse_unplanned_disruption(unplanned)
|
145
158
|
end
|
146
159
|
|
147
|
-
(disruption/'Gepland/Storing').each do |planned|
|
148
|
-
|
149
|
-
planned_disruption.id = (planned/'./id').text
|
150
|
-
planned_disruption.trip = (planned/'./Traject').text
|
151
|
-
planned_disruption.reason = (planned/'./Reden').text
|
152
|
-
planned_disruption.advice = (planned/'./Advies').text
|
153
|
-
planned_disruption.message = (planned/'./Bericht').text
|
154
|
-
planned_disruption.cause = (planned/'./Oorzaak').text
|
155
|
-
result[:planned] << planned_disruption
|
160
|
+
(disruption / 'Gepland/Storing').each do |planned|
|
161
|
+
result[:planned] << parse_planned_disruption(planned)
|
156
162
|
end
|
157
163
|
end
|
158
164
|
result
|
159
165
|
end
|
160
166
|
|
167
|
+
def parse_unplanned_disruption(disruption)
|
168
|
+
result = UnplannedDisruption.new
|
169
|
+
result.id = (disruption / './id').text
|
170
|
+
result.trip = (disruption / './Traject').text
|
171
|
+
result.reason = (disruption / './Reden').text
|
172
|
+
result.message = (disruption / './Bericht').text
|
173
|
+
result.datetime_string = (disruption / './Datum').text
|
174
|
+
result.cause = (disruption / './Oorzaak').text
|
175
|
+
result
|
176
|
+
end
|
177
|
+
|
178
|
+
def parse_planned_disruption(disruption)
|
179
|
+
result = PlannedDisruption.new
|
180
|
+
result.id = (disruption / './id').text
|
181
|
+
result.trip = (disruption / './Traject').text
|
182
|
+
result.reason = (disruption / './Reden').text
|
183
|
+
result.advice = (disruption / './Advies').text
|
184
|
+
result.message = (disruption / './Bericht').text
|
185
|
+
result.cause = (disruption / './Oorzaak').text
|
186
|
+
result
|
187
|
+
end
|
188
|
+
|
161
189
|
def raise_error_when_response_is_error(xdoc)
|
162
|
-
(xdoc/'/error').each do |error|
|
163
|
-
message = (error/'./message').text
|
190
|
+
(xdoc / '/error').each do |error|
|
191
|
+
message = (error / './message').text
|
164
192
|
raise InvalidStationNameError, message
|
165
193
|
end
|
166
194
|
end
|
167
195
|
|
168
196
|
def get_xml(url)
|
169
|
-
response =
|
170
|
-
@last_received_raw_xml = response.
|
197
|
+
response = RestClient::Request.new(url: url, user: username, password: password, method: :get).execute
|
198
|
+
@last_received_raw_xml = response.body
|
171
199
|
@last_received_corrected_xml = remove_unwanted_whitespace(@last_received_raw_xml)
|
172
200
|
begin
|
173
201
|
Nokogiri.XML(@last_received_corrected_xml) do |config|
|
174
202
|
config.options = Nokogiri::XML::ParseOptions::STRICT
|
175
203
|
end
|
176
204
|
rescue Nokogiri::XML::SyntaxError => e
|
177
|
-
raise UnparseableXMLError
|
205
|
+
raise UnparseableXMLError, e
|
178
206
|
end
|
179
|
-
|
180
207
|
end
|
181
208
|
|
182
|
-
def remove_unwanted_whitespace
|
183
|
-
content.gsub
|
209
|
+
def remove_unwanted_whitespace(content)
|
210
|
+
content.gsub %r{<\s*(/?)\s*?([a-zA-Z0-9]*)\s*([a-zA-Z0-9]*)\s*>}, '<\1\2\3>'
|
184
211
|
end
|
185
212
|
|
186
213
|
def disruption_url(query)
|
187
|
-
return "
|
188
|
-
|
214
|
+
return "https://webservices.ns.nl/ns-api-storingen?station=#{query}" if query
|
215
|
+
|
216
|
+
'https://webservices.ns.nl/ns-api-storingen?actual=true'
|
189
217
|
end
|
190
218
|
|
191
219
|
class PricesResponse
|
@@ -197,20 +225,19 @@ class NSClient
|
|
197
225
|
end
|
198
226
|
|
199
227
|
def enkele_reis
|
200
|
-
products[
|
228
|
+
products['Enkele reis']
|
201
229
|
end
|
202
230
|
|
203
231
|
def dagretour
|
204
|
-
products[
|
232
|
+
products['Retour']
|
205
233
|
end
|
206
|
-
|
207
234
|
end
|
208
235
|
|
209
236
|
class ProductPrice
|
210
237
|
attr_accessor :discount, :train_class, :amount
|
211
238
|
DISCOUNT_MAP ||= {
|
212
|
-
|
213
|
-
|
239
|
+
'20% korting' => 'reductie_20',
|
240
|
+
'40% korting' => 'reductie_40'
|
214
241
|
}.freeze
|
215
242
|
|
216
243
|
def type
|
@@ -241,5 +268,4 @@ class NSClient
|
|
241
268
|
|
242
269
|
class SameDestinationError < StandardError
|
243
270
|
end
|
244
|
-
|
245
271
|
end
|