Class: NSClient

Inherits:
Object
  • Object
show all
Defined in:
lib/ns_client.rb

Defined Under Namespace

Classes: InvalidStationNameError, MissingParameter, PlannedDisruption, PricesResponse, ProductPrice, SameDestinationError, Station, UnparseableXMLError, UnplannedDisruption

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(username, password) ⇒ NSClient

Returns a new instance of NSClient.



45
46
47
48
49
50
51
# File 'lib/ns_client.rb', line 45

def initialize(username, password)
  @client = HTTPClient.new
  @client.set_auth("http://webservices.ns.nl", username, password)
  @prices_url = PricesUrl.new("http://webservices.ns.nl/ns-api-prijzen-v3")
  @last_received_raw_xml = ""
  @last_received_corrected_xml = ""
end

Instance Attribute Details

#last_received_corrected_xmlObject

Returns the value of attribute last_received_corrected_xml.



43
44
45
# File 'lib/ns_client.rb', line 43

def last_received_corrected_xml
  @last_received_corrected_xml
end

#last_received_raw_xmlObject

Returns the value of attribute last_received_raw_xml.



43
44
45
# File 'lib/ns_client.rb', line 43

def last_received_raw_xml
  @last_received_raw_xml
end

Instance Method Details

#disruption_url(query) ⇒ Object



186
187
188
189
# File 'lib/ns_client.rb', line 186

def disruption_url(query)
  return "http://webservices.ns.nl/ns-api-storingen?station=#{query}" if query
  "http://webservices.ns.nl/ns-api-storingen?actual=true"
end

#disruptions(query = nil) ⇒ Object



61
62
63
64
65
# File 'lib/ns_client.rb', line 61

def disruptions (query = nil)
  response_xml = get_xml(disruption_url(query))
  raise_error_when_response_is_error(response_xml)
  parse_disruptions(response_xml)
end

#get_xml(url) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/ns_client.rb', line 168

def get_xml(url)
  response = @client.get url
  @last_received_raw_xml = response.content
  @last_received_corrected_xml = remove_unwanted_whitespace(@last_received_raw_xml)
  begin
    Nokogiri.XML(@last_received_corrected_xml) do |config|
      config.options = Nokogiri::XML::ParseOptions::STRICT
    end
  rescue Nokogiri::XML::SyntaxError => e
    raise UnparseableXMLError.new e
  end

end

#parse_disruptions(response_xml) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/ns_client.rb', line 133

def parse_disruptions(response_xml)
  result = {planned: [], unplanned: []}
  (response_xml/'/Storingen').each do |disruption|
    (disruption/'Ongepland/Storing').each do |unplanned|
      unplanned_disruption = UnplannedDisruption.new
      unplanned_disruption.id = (unplanned/'./id').text
      unplanned_disruption.trip = (unplanned/'./Traject').text
      unplanned_disruption.reason = (unplanned/'./Reden').text
      unplanned_disruption.message = (unplanned/'./Bericht').text
      unplanned_disruption.datetime_string = (unplanned/'./Datum').text
      unplanned_disruption.cause = (unplanned/'./Oorzaak').text
      result[:unplanned] << unplanned_disruption
    end

    (disruption/'Gepland/Storing').each do |planned|
      planned_disruption = PlannedDisruption.new
      planned_disruption.id = (planned/'./id').text
      planned_disruption.trip = (planned/'./Traject').text
      planned_disruption.reason = (planned/'./Reden').text
      planned_disruption.advice = (planned/'./Advies').text
      planned_disruption.message = (planned/'./Bericht').text
      planned_disruption.cause = (planned/'./Oorzaak').text
      result[:planned] << planned_disruption
    end
  end
  result
end

#parse_prices(response_xml) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ns_client.rb', line 78

def parse_prices(response_xml)
  prices_response = PricesResponse.new
  (response_xml/'/VervoerderKeuzes/VervoerderKeuze').each do |transporter|
    prices_response.tariff_units = (transporter/'./Tariefeenheden').text.to_i

    (transporter/'ReisType').each do |travel_type|
      prices = []

      (travel_type/'ReisKlasse').each do |travel_class|
        (travel_class/'Korting/Kortingsprijs').each do |price_element|
          product_price = ProductPrice.new
          product_price.discount = price_element.attr("name")
          product_price.train_class = travel_class.attr("klasse")
          product_price.amount = price_element.attr("prijs").gsub(",", ".").to_f
          prices << product_price
        end
      end

      name = travel_type.attr('name')
      prices_response.products[name] = prices
    end

  end
  prices_response
end

#parse_stations(response_xml) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/ns_client.rb', line 104

def parse_stations(response_xml)
  result = []
  (response_xml/'/Stations/Station').each do |station|
    s = Station.new
    s.code = (station/'./Code').text
    s.type = (station/'./Type').text
    s.country = (station/'./Land').text
    s.short_name = (station/'./Namen/Kort').text
    s.name = (station/'./Namen/Middel').text
    s.long_name = (station/'./Namen/Lang').text
    s.lat = (station/'./Lat').text
    s.long = (station/'./Lon').text
    s.uiccode = (station/'./UICCode').text
    result << s
  end
  result
end

#parse_stations_as_map(response_xml) ⇒ Object



122
123
124
125
126
127
128
129
130
131
# File 'lib/ns_client.rb', line 122

def parse_stations_as_map(response_xml)
  result = {}
  (response_xml/'/Stations/Station').each do |station|
    code = (station/'./Code').text
    name = (station/'./Namen/Middel').text
    country = (station/'./Land').text
    result[code] = [name, country]
  end
  result
end

#prices(opts = {from: nil, to: nil, via: nil, date: nil}) ⇒ Object

Raises:



67
68
69
70
71
72
73
74
75
76
# File 'lib/ns_client.rb', line 67

def prices (opts = {from: nil, to: nil, via: nil, date: nil})
  raise MissingParameter, "from and to station is required" if (opts[:from] == nil && opts[:to] == nil)
  raise MissingParameter, "from station is required" unless opts[:from]
  raise MissingParameter, "to station is required" unless opts[:to]
  raise SameDestinationError,
    "from (#{opts[:from]}) and to (#{opts[:to]}) parameters should not be equal" if opts[:from] == opts[:to]
  response_xml = get_xml(@prices_url.url(opts))
  raise_error_when_response_is_error(response_xml)
  parse_prices(response_xml)
end

#raise_error_when_response_is_error(xdoc) ⇒ Object



161
162
163
164
165
166
# File 'lib/ns_client.rb', line 161

def raise_error_when_response_is_error(xdoc)
  (xdoc/'/error').each do |error|
    message = (error/'./message').text
    raise InvalidStationNameError, message
  end
end

#remove_unwanted_whitespace(content) ⇒ Object



182
183
184
# File 'lib/ns_client.rb', line 182

def remove_unwanted_whitespace content
  content.gsub /<\s*(\/?)\s*?([a-zA-Z0-9]*)\s*([a-zA-Z0-9]*)\s*>/, '<\1\2\3>'
end

#stationsObject



53
54
55
# File 'lib/ns_client.rb', line 53

def stations
  parse_stations(get_xml("http://webservices.ns.nl/ns-api-stations-v2"))
end

#stations_shortObject



57
58
59
# File 'lib/ns_client.rb', line 57

def stations_short
  parse_stations_as_map(get_xml("http://webservices.ns.nl/ns-api-stations-v2"))
end