Class: Bahn::Service

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

Overview

Represents a scheduled train (or other transportation) service. This is not specific to a particular day’s train, but encompasses all trains taking this route at this time of day. When services are subject to daily or seasonal variations, each such variation is considered a Service of its own, even if they share the same service name.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Service

 :nodoc:



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/bahn.rb', line 203

def initialize(opts) # :nodoc:
  @path = opts[:path]
  @name = opts[:name]
  if opts[:origin_info]
    @origin = Stop.new(opts[:origin_info].merge(
      :service => self,
      :arrival_time => :none,
      :arrival_time_from_origin => :none,
      :arrival_time_to_destination => :none,
      :departure_time_from_origin => 0
    ))
  end
  if opts[:destination_info]
    @destination = Stop.new(opts[:destination_info].merge(
      :service => self,
      :arrival_time_to_destination => 0,
      :departure_time => :none,
      :departure_time_from_origin => :none,
      :departure_time_to_destination => :none
    ))
  end
end

Instance Attribute Details

#nameObject (readonly)

The designated name for this service, if any - e.g. “ICE 692”.



227
228
229
# File 'lib/bahn.rb', line 227

def name
  @name
end

Instance Method Details

#destinationObject

Returns the Stop object for the destination station of this service.



286
287
288
# File 'lib/bahn.rb', line 286

def destination
  @destination ||= stops.last
end

#featuresObject

Returns an array of strings indicating the features of this train, as listed as ‘Comments:’ on the Deutsche Bahn website; e.g. “Subject to compulsory reservation”, “Sleeping-car”. There doesn’t seem to be a consistent format for these.



311
312
313
314
315
316
317
318
319
320
321
# File 'lib/bahn.rb', line 311

def features
  if @features.nil?
    tr = (traininfo_response_doc / 'table.remarks tr').find {|tr| (tr % 'th').inner_text == 'Comments:'}
    if tr
      @features = (tr / 'td strong').collect {|elem| elem.inner_text}.uniq
    else
      @features = []
    end
  end
  @features
end

#hashObject

Returns a hash code which will match for any two Service objects that stop at the same list of stations at the same times.



296
297
298
# File 'lib/bahn.rb', line 296

def hash
  stops.collect{|stop| stop.subhash}.hash
end

#inspectObject

:nodoc:



290
291
292
# File 'lib/bahn.rb', line 290

def inspect # :nodoc:
  "#<#{self.class} @name=#{@name.inspect} @origin=#{@origin.inspect} @destination=#{@destination.inspect}>"
end

#long_hashObject

Returns a hash code which will match for any two Service objects that stop at the same list of stations at the same times; like hash, but using SHA1 to make it more collision-resistant. (This is the nearest thing we have to a unique ID, as Deutsche Bahn do not expose unique IDs for services)



304
305
306
# File 'lib/bahn.rb', line 304

def long_hash
  Digest::SHA1.hexdigest(stops.collect{|stop| stop.long_hash_element}.join)
end

#originObject

Returns the Stop object for the departure station of this service.



281
282
283
# File 'lib/bahn.rb', line 281

def origin
  @origin ||= stops.first
end

#stopsObject

Returns an array of Stop objects for all the stops that this service makes.



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/bahn.rb', line 230

def stops
  if !@stops
    stop_docs = traininfo_response_doc / "table.result tr[td.station]"
    last_time = nil
    days_passed = 0
    
    origin_departure_time = nil
    
    @stops = stop_docs.collect {|stop_doc|
      station_link = stop_doc % 'td.station a'
      
      arrival_time = ClockTime.parse((stop_doc % 'td.arrival').inner_text)
      departure_time = ClockTime.parse((stop_doc % 'td.departure').inner_text)
      origin_departure_time ||= departure_time
      
      if arrival_time.nil?
        arrival_time_from_origin = :none
      else
        days_passed += 1 if (!last_time.nil? && arrival_time < last_time)
        arrival_time_from_origin = days_passed * 24*60*60 + (arrival_time - origin_departure_time)
        last_time = arrival_time
      end
      
      if departure_time.nil?
        departure_time_from_origin = :none
      else
        days_passed += 1 if (!last_time.nil? && departure_time < last_time)
        departure_time_from_origin = days_passed * 24*60*60 + (departure_time - origin_departure_time)
        last_time = departure_time
      end
  
      platform = (stop_doc % 'td.platform').inner_text.strip

      Stop.new(
        :station => Station.new(
          :id => station_link['href'].scan(/&input=[^&]*%23(\d+)&/).first.first,
          :name => station_link.inner_text
        ),
        :service => self,
        :arrival_time => arrival_time || :none,
        :departure_time => departure_time || :none,
        :platform => (platform == '' ? :none : platform),
        :arrival_time_from_origin => arrival_time_from_origin,
        :departure_time_from_origin => departure_time_from_origin
      )
    }
  end
  @stops
end