Class: OCTranspo
- Inherits:
-
Object
- Object
- OCTranspo
- Defined in:
- lib/octranspo_fetch.rb
Instance Method Summary collapse
- #cache_stats ⇒ Object
- #clear_cache ⇒ Object
-
#get_next_trips_for_stop(stop, route_no, options = {}) ⇒ Object
Get the next three trips for the given stop.
-
#get_route_summary_for_stop(stop, options = {}) ⇒ Object
Get a list of routes for a specific stop.
-
#initialize(options) ⇒ OCTranspo
constructor
Create a new OCTranspo.
-
#requests ⇒ Object
Returns the number of API calls made by this instance since it was created.
-
#simple_get_next_trips_for_stop(stop, route_nos = nil, route_label = nil) ⇒ Object
Returns an array of ‘stop_description, route_no, route_label, direction, arrival_in_minutes, …` objects.
Constructor Details
#initialize(options) ⇒ OCTranspo
Create a new OCTranspo
Arguments:
[:application_id]: (String) Your application ID, assigned by OC Transpo.
[:application_key]: (String) Your application key, assigned by OC Transpo.
15 16 17 18 19 20 21 22 23 |
# File 'lib/octranspo_fetch.rb', line 15 def initialize() @app_id = [:application_id] @app_key = [:application_key] @next_trips_cache = LruRedux::Cache.new(NEXT_TRIPS_CACHE_SIZE) @route_summary_cache = LruRedux::Cache.new(ROUTE_CACHE_SIZE) @api_calls = 0 @cache_hits = 0 @cache_misses = 0 end |
Instance Method Details
#cache_stats ⇒ Object
35 36 37 |
# File 'lib/octranspo_fetch.rb', line 35 def cache_stats() return {hits: @cache_hits, misses: @cache_misses} end |
#clear_cache ⇒ Object
25 26 27 28 |
# File 'lib/octranspo_fetch.rb', line 25 def clear_cache() @next_trips_cache.clear() @route_summary_cache.clear() end |
#get_next_trips_for_stop(stop, route_no, options = {}) ⇒ Object
Get the next three trips for the given stop. Note this may return data for the same route number in multiple headings.
Arguments:
stop: (String) The stop number.
route_no: (String) The route number.
[:max_cache_time]: (Integer) Maximum cache age, in seconds. If cached data is
available and is newer than this, then the cached value will be returned. Defaults
to five minutes.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 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 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/octranspo_fetch.rb', line 98 def get_next_trips_for_stop(stop, route_no, ={}) max_cache_time = ([:max_cache_time] or 60*5) # Return result from cache, if available cache_key = "#{stop}-#{route_no}" cached_result = @next_trips_cache[cache_key] if !cached_result.nil? and ((cached_result[:time] + max_cache_time) > Time.now.to_i) @cache_hits += 1 return adjust_cached_trip_times(cached_result[:next_trips]) end @cache_misses += 1 xresult = fetch "GetNextTripsForStop", "stopNo=#{stop}&routeNo=#{route_no}" result = { stop: get_value(xresult, "t:StopNo"), stop_description: get_value(xresult, "t:StopLabel"), time: Time.now, routes: [] } found_data = false xresult.xpath('t:Route/t:RouteDirection', OCT_NS).each do |route| get_error(route, "Error for route: #{route_no}") route_obj = { cached: false, route: get_value(route, "t:RouteNo"), route_label: get_value(route, "t:RouteLabel"), direction: get_value(route, "t:Direction"), request_processing_time: Time.parse(get_value(route, "t:RequestProcessingTime")), trips: [] } route.xpath('t:Trips/t:Trip', OCT_NS).each do |trip| route_obj[:trips].push({ destination: get_value(trip, "t:TripDestination"), # e.g. "Barhaven" start_time: get_value(trip, "t:TripStartTime"), # e.g. "14:25" TODO: parse to time adjusted_schedule_time: get_value(trip, "t:AdjustedScheduleTime").to_i, # Adjusted schedule time in minutes adjustment_age: get_value(trip, "t:AdjustmentAge").to_f, # Time since schedule was adjusted in minutes last_trip: (get_value(trip, "t:LastTripOfSchedule") == "true"), bus_type: get_value(trip, "t:BusType"), gps_speed: get_value(trip, "t:GPSSpeed").to_f, latitude: get_value(trip, "t:Latitude").to_f, longitude: get_value(trip, "t:Longitude").to_f }) end if route_obj[:trips].length != 0 # Assume that if any trips are filled in, then all the trips will be filled in? # Is this a safe assumption? found_data = true end result[:routes].push route_obj end # Sometimes OC Transpo doesn't return any data for a route, even though it should. When # this happens, if we have cached data, we use that, even if it's slightly stale. if !found_data and !cached_result.nil? and (get_trip_count(cached_result[:next_trips]) > 0) # Use the cached data, even if it's stale result = adjust_cached_trip_times(cached_result[:next_trips]) else @next_trips_cache[cache_key] = { next_trips: result, time: Time.now.to_i } end return result end |
#get_route_summary_for_stop(stop, options = {}) ⇒ Object
Get a list of routes for a specific stop.
Returns a stop_description, routes: [{route, direction_id, direction, heading]} object. Note that route data is cached.
Arguments:
stop: (String) The stop number.
[:max_cache_time]: (Integer) Maximum cache age, in seconds. If cached data is
available and is newer than this, then the cached value will be returned. Defaults to
one day.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/octranspo_fetch.rb', line 50 def get_route_summary_for_stop(stop, ={}) max_cache_time = ([:max_cache_time] or 60*60*24) cached_result = @route_summary_cache[stop] if !cached_result.nil? and ((cached_result[:time] + max_cache_time) > Time.now.to_i) @cache_hits += 1 return cached_result[:route_summary] end @cache_misses += 1 xresult = fetch "GetRouteSummaryForStop", "stopNo=#{stop}" result = { stop: get_value(xresult, "t:StopNo"), stop_description: get_value(xresult, "t:StopDescription"), routes: [] } xresult.xpath('t:Routes/t:Route', OCT_NS).each do |route| result[:routes].push({ route: get_value(route, "t:RouteNo"), direction_id: get_value(route, "t:DirectionID"), direction: get_value(route, "t:Direction"), heading: get_value(route, "t:RouteHeading") }) end if result[:routes].length == 0 raise "No routes found" end @route_summary_cache[stop] = { route_summary: result, time: Time.now.to_i } return result end |
#requests ⇒ Object
Returns the number of API calls made by this instance since it was created.
31 32 33 |
# File 'lib/octranspo_fetch.rb', line 31 def requests() return @api_calls end |
#simple_get_next_trips_for_stop(stop, route_nos = nil, route_label = nil) ⇒ Object
Returns an array of ‘stop_description, route_no, route_label, direction, arrival_in_minutes, …` objects.
... is any data that would be available from a trip object from ‘get_next_trips_for_stop()` (e.g. gps_speed, latitude, longitude, etc…) Returned results are sorted in ascending arrival time.
Arguments:
stop: (String) The stop number.
route_nos: ([String]) can be a single route number, or an array of route numbers, or nil.
If nil, then this method will call get_route_summary_for_stop to get a list of routes.
route_label: (String) If "route_label" is supplied, then only trips with a matching
route_label will be returned.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/octranspo_fetch.rb', line 185 def simple_get_next_trips_for_stop(stop, route_nos=nil, route_label=nil) answer = [] if route_nos.nil? route_summary = get_route_summary_for_stop(stop) route_nos = route_summary[:routes].map { |e| e[:route] } elsif !route_nos.kind_of?(Array) route_nos = [route_nos] end route_nos.uniq.each do |route_no| oct_result = get_next_trips_for_stop stop, route_no oct_result[:routes].each do |route| if route_label.nil? or (route[:route_label] == route_label) route[:trips].each do |trip| answer.push(trip.merge({ stop: oct_result[:stop], stop_description: oct_result[:stop_description], route_no: route[:route], route_label: route[:route_label], direction: route[:direction], arrival_in_minutes: trip[:adjusted_schedule_time], live: (trip[:adjustment_age] > 0) })) end end end end answer.sort! { |a,b| a[:arrival_in_minutes] <=> b[:arrival_in_minutes] } return answer end |