gtfs-engine 1.0.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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +37 -0
  3. data/app/controllers/gtfs_engine/agencies_controller.rb +24 -0
  4. data/app/controllers/gtfs_engine/application_controller.rb +21 -0
  5. data/app/controllers/gtfs_engine/calendar_dates_controller.rb +22 -0
  6. data/app/controllers/gtfs_engine/calendars_controller.rb +51 -0
  7. data/app/controllers/gtfs_engine/data_sets_controller.rb +47 -0
  8. data/app/controllers/gtfs_engine/fare_attributes_controller.rb +27 -0
  9. data/app/controllers/gtfs_engine/fare_rules_controller.rb +26 -0
  10. data/app/controllers/gtfs_engine/feed_infos_controller.rb +26 -0
  11. data/app/controllers/gtfs_engine/frequencies_controller.rb +26 -0
  12. data/app/controllers/gtfs_engine/routes_controller.rb +25 -0
  13. data/app/controllers/gtfs_engine/shapes_controller.rb +23 -0
  14. data/app/controllers/gtfs_engine/stop_times_controller.rb +28 -0
  15. data/app/controllers/gtfs_engine/stops_controller.rb +30 -0
  16. data/app/controllers/gtfs_engine/transfers_controller.rb +38 -0
  17. data/app/controllers/gtfs_engine/trips_controller.rb +34 -0
  18. data/app/helpers/gtfs_engine/default_views_helper.rb +42 -0
  19. data/app/helpers/gtfs_engine/fields_helper.rb +32 -0
  20. data/app/models/gtfs_engine/agency.rb +19 -0
  21. data/app/models/gtfs_engine/calendar.rb +78 -0
  22. data/app/models/gtfs_engine/calendar_date.rb +20 -0
  23. data/app/models/gtfs_engine/data_set.rb +73 -0
  24. data/app/models/gtfs_engine/fare_attribute.rb +19 -0
  25. data/app/models/gtfs_engine/fare_rule.rb +28 -0
  26. data/app/models/gtfs_engine/feed_info.rb +19 -0
  27. data/app/models/gtfs_engine/frequency.rb +20 -0
  28. data/app/models/gtfs_engine/route.rb +24 -0
  29. data/app/models/gtfs_engine/shape.rb +20 -0
  30. data/app/models/gtfs_engine/stop.rb +26 -0
  31. data/app/models/gtfs_engine/stop_time.rb +21 -0
  32. data/app/models/gtfs_engine/transfer.rb +23 -0
  33. data/app/models/gtfs_engine/trip.rb +27 -0
  34. data/app/views/gtfs_engine/calendars/dates.json.jbuilder +18 -0
  35. data/app/views/gtfs_engine/data_sets/index.json.jbuilder +28 -0
  36. data/app/views/gtfs_engine/data_sets/show.json.jbuilder +21 -0
  37. data/app/views/gtfs_engine/gtfs/index.json.jbuilder +15 -0
  38. data/app/views/gtfs_engine/gtfs/show.json.jbuilder +15 -0
  39. data/app/views/gtfs_engine/transfers/from.json.jbuilder +15 -0
  40. data/app/views/gtfs_engine/transfers/from_to.json.jbuilder +15 -0
  41. data/app/views/gtfs_engine/transfers/to.json.jbuilder +15 -0
  42. data/app/views/gtfs_engine/trips/block.json.jbuilder +15 -0
  43. data/bin/rails +8 -0
  44. data/config/initializers/extensions_loader.rb +15 -0
  45. data/config/routes.rb +45 -0
  46. data/db/migrate/20140320045108_create_gtfs_engine_data_sets.rb +17 -0
  47. data/db/migrate/20140320045232_create_gtfs_engine_calendars.rb +24 -0
  48. data/db/migrate/20140320045751_create_gtfs_engine_calendar_dates.rb +16 -0
  49. data/db/migrate/20140320050100_create_gtfs_engine_shapes.rb +20 -0
  50. data/db/migrate/20140320051140_create_gtfs_engine_routes.rb +22 -0
  51. data/db/migrate/20140320052005_create_gtfs_engine_stops.rb +28 -0
  52. data/db/migrate/20140320052508_create_gtfs_engine_trips.rb +26 -0
  53. data/db/migrate/20140320052907_create_gtfs_engine_stop_times.rb +24 -0
  54. data/db/migrate/20140401032609_create_gtfs_engine_agencies.rb +19 -0
  55. data/db/migrate/20140405235947_create_gtfs_engine_fare_attributes.rb +18 -0
  56. data/db/migrate/20140406063500_create_gtfs_engine_fare_rules.rb +17 -0
  57. data/db/migrate/20140406071922_create_gtfs_engine_frequencies.rb +17 -0
  58. data/db/migrate/20140406072309_create_gtfs_engine_transfers.rb +17 -0
  59. data/db/migrate/20140406073548_create_gtfs_engine_feed_infos.rb +16 -0
  60. data/lib/ext.rb +19 -0
  61. data/lib/ext/active_record/associations/association.rb +41 -0
  62. data/lib/gtfs_engine.rb +33 -0
  63. data/lib/gtfs_engine/concerns.rb +19 -0
  64. data/lib/gtfs_engine/concerns/controllers.rb +20 -0
  65. data/lib/gtfs_engine/concerns/controllers/data_access.rb +31 -0
  66. data/lib/gtfs_engine/concerns/controllers/gtfs.rb +158 -0
  67. data/lib/gtfs_engine/engine.rb +28 -0
  68. data/lib/gtfs_engine/exceptions.rb +35 -0
  69. data/lib/gtfs_engine/json_responder.rb +31 -0
  70. data/lib/gtfs_engine/sources.rb +86 -0
  71. data/lib/gtfs_engine/version.rb +84 -0
  72. data/lib/tasks/gtfs_engine_tasks.rake +89 -0
  73. metadata +242 -0
@@ -0,0 +1,22 @@
1
+ class CreateGtfsEngineRoutes < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_routes
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :route_id, null: false
7
+ t.string :agency_id
8
+ t.string :route_short_name, null: false
9
+ t.string :route_long_name, null: false
10
+ t.string :route_desc
11
+ t.integer :route_type, null: false
12
+ t.integer :route_url
13
+ t.string :route_color
14
+ t.string :route_text_color
15
+
16
+ t.references :data_set, null: false, index: true
17
+ end
18
+
19
+ add_index TABLE, :route_id
20
+ add_index TABLE, :route_short_name
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ class CreateGtfsEngineStops < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_stops
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :stop_id, null: false
7
+ t.string :stop_code
8
+ t.string :stop_name, null: false
9
+ t.string :stop_desc
10
+ t.float :stop_lat, null: false
11
+ t.float :stop_lon, null: false
12
+ t.string :zone_id
13
+ t.string :stop_url
14
+ t.integer :location_type
15
+ t.integer :parent_station
16
+ t.string :stop_timezone
17
+ t.integer :wheelchair_boarding
18
+
19
+ t.references :data_set, null: false, index: true
20
+ end
21
+
22
+ add_index TABLE, :stop_id
23
+ add_index TABLE, :stop_code
24
+ add_index TABLE, :stop_lat
25
+ add_index TABLE, :stop_lon
26
+ add_index TABLE, :zone_id
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ class CreateGtfsEngineTrips < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_trips
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :trip_id, null: false
7
+ t.string :service_id, null: false
8
+ t.string :trip_headsign
9
+ t.string :trip_short_name
10
+ t.integer :direction_id
11
+ t.string :block_id
12
+ t.string :route_id, null: false
13
+ t.string :shape_id
14
+ t.integer :wheelchair_accessible
15
+ t.integer :bikes_allowed
16
+
17
+ t.references :data_set, null: false, index: true
18
+ end
19
+
20
+ add_index TABLE, :trip_id
21
+ add_index TABLE, :service_id
22
+ add_index TABLE, :block_id
23
+ add_index TABLE, :route_id
24
+ add_index TABLE, :shape_id
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ class CreateGtfsEngineStopTimes < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_stop_times
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :stop_id, null: false
7
+ t.string :trip_id, null: false
8
+ t.string :arrival_time, null: false
9
+ t.string :departure_time, null: false
10
+ t.integer :stop_sequence, null: false
11
+ t.string :stop_headsign
12
+ t.integer :pickup_type
13
+ t.integer :drop_off_type
14
+ t.float :shape_dist_traveled
15
+
16
+ t.references :data_set, null: false, index: true
17
+ end
18
+
19
+ add_index TABLE, :stop_id
20
+ add_index TABLE, :trip_id
21
+ add_index TABLE, :arrival_time
22
+ add_index TABLE, :departure_time
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ class CreateGtfsEngineAgencies < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_agencies
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :agency_id
7
+ t.string :agency_name, null: false
8
+ t.string :agency_url, null: false
9
+ t.string :agency_timezone, null: false
10
+ t.string :agency_lang
11
+ t.string :agency_fare_url
12
+ t.string :agency_phone
13
+
14
+ t.references :data_set, null: false, index: true
15
+ end
16
+
17
+ add_index TABLE, :agency_id
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ class CreateGtfsEngineFareAttributes < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_fare_attributes
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :fare_id, null: false
7
+ t.float :price, null: false
8
+ t.string :currency_type, null: false
9
+ t.integer :payment_method, null: false
10
+ t.integer :transfers
11
+ t.integer :transfer_duration
12
+
13
+ t.references :data_set, null: false, index: true
14
+ end
15
+
16
+ add_index TABLE, :fare_id
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ class CreateGtfsEngineFareRules < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_fare_rules
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :fare_id, null: false
7
+ t.string :route_id
8
+ t.string :origin_id
9
+ t.string :destination_id
10
+ t.string :contains_id
11
+
12
+ t.references :data_set, null: false, index: true
13
+ end
14
+
15
+ add_index TABLE, :fare_id
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ class CreateGtfsEngineFrequencies < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_frequencies
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :trip_id, null: false
7
+ t.integer :start_time, null: false
8
+ t.integer :end_time, null: false
9
+ t.integer :headway_secs, null: false
10
+ t.boolean :exact_times
11
+
12
+ t.references :data_set, null: false, index: true
13
+ end
14
+
15
+ add_index TABLE, :trip_id
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ class CreateGtfsEngineTransfers < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_transfers
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :from_stop_id, null: false
7
+ t.string :to_stop_id, null: false
8
+ t.integer :transfer_type, null: false
9
+ t.integer :min_transfer_time
10
+
11
+ t.references :data_set, null: false, index: true
12
+ end
13
+
14
+ add_index TABLE, :from_stop_id
15
+ add_index TABLE, :to_stop_id
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ class CreateGtfsEngineFeedInfos < ActiveRecord::Migration
2
+ TABLE = :gtfs_engine_feed_infos
3
+
4
+ def change
5
+ create_table TABLE do |t|
6
+ t.string :feed_publisher_name, null: false
7
+ t.string :feed_publisher_url, null: false
8
+ t.string :feed_lang, null: false
9
+ t.date :feed_start_date
10
+ t.date :feed_end_date
11
+ t.string :feed_version
12
+
13
+ t.references :data_set, null: false, index: true
14
+ end
15
+ end
16
+ end
data/lib/ext.rb ADDED
@@ -0,0 +1,19 @@
1
+ # This file is part of the KNOWtime server.
2
+ #
3
+ # The KNOWtime server is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU General Public License as published by the Free
5
+ # Software Foundation, either version 3 of the License, or (at your option) any
6
+ # later version.
7
+ #
8
+ # The KNOWtime server is distributed in the hope that it will be useful, but
9
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+ # details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with the KNOWtime server. If not, see <http://www.gnu.org/licenses/>.
15
+ dir = File.dirname(__FILE__) + '/'
16
+
17
+ Dir[dir + 'ext/**/*.rb'].each do |extension|
18
+ require extension[dir.length..-1]
19
+ end
@@ -0,0 +1,41 @@
1
+ # This file is part of the KNOWtime server.
2
+ #
3
+ # The KNOWtime server is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU General Public License as published by the Free
5
+ # Software Foundation, either version 3 of the License, or (at your option) any
6
+ # later version.
7
+ #
8
+ # The KNOWtime server is distributed in the hope that it will be useful, but
9
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+ # details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with the KNOWtime server. If not, see <http://www.gnu.org/licenses/>.
15
+ #
16
+ # Many GTFS associations reference arbitrary fields in the referenced table.
17
+ # This requires the use of the +primary_key:+ named parameter. Coincidentally,
18
+ # the name of the +foreign_key:+ is often the same as the referenced field. As
19
+ # a convenience, this file adds a +shared_key:+ named parameter which simply
20
+ # sets these two parameters to the same value.
21
+ module ActiveRecord
22
+ module Associations
23
+ class Association
24
+ def build_record_with_shared_key(attributes)
25
+ share_key attributes
26
+ build_record_without_shared_key attributes
27
+ end
28
+ alias_method_chain :build_record, :shared_key
29
+
30
+ private
31
+
32
+ def share_key(attributes)
33
+ h = attributes.last
34
+ if Hash === h and h.key? :shared_key
35
+ key = h.delete :shared_key
36
+ h.reverse_merge! foreign_key: key, primary_key: key
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ # This file is part of the KNOWtime server.
2
+ #
3
+ # The KNOWtime server is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU General Public License as published by the Free
5
+ # Software Foundation, either version 3 of the License, or (at your option) any
6
+ # later version.
7
+ #
8
+ # The KNOWtime server is distributed in the hope that it will be useful, but
9
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+ # details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with the KNOWtime server. If not, see <http://www.gnu.org/licenses/>.
15
+ require 'gtfs_reader'
16
+
17
+ require 'gtfs_engine/engine'
18
+ require 'gtfs_engine/exceptions'
19
+ require 'gtfs_engine/json_responder'
20
+ require 'gtfs_engine/sources'
21
+
22
+ module GtfsEngine
23
+ extend ActiveSupport::Autoload
24
+
25
+ autoload :Concerns
26
+
27
+ class << self
28
+ def sources(&block)
29
+ @sources ||= Sources.new GtfsReader.config
30
+ block.call @sources
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # This file is part of the KNOWtime server.
2
+ #
3
+ # The KNOWtime server is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU General Public License as published by the Free
5
+ # Software Foundation, either version 3 of the License, or (at your option) any
6
+ # later version.
7
+ #
8
+ # The KNOWtime server is distributed in the hope that it will be useful, but
9
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+ # details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with the KNOWtime server. If not, see <http://www.gnu.org/licenses/>.
15
+ module GtfsEngine::Concerns
16
+ extend ActiveSupport::Autoload
17
+
18
+ autoload :Controllers
19
+ end
@@ -0,0 +1,20 @@
1
+ # This file is part of the KNOWtime server.
2
+ #
3
+ # The KNOWtime server is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU General Public License as published by the Free
5
+ # Software Foundation, either version 3 of the License, or (at your option) any
6
+ # later version.
7
+ #
8
+ # The KNOWtime server is distributed in the hope that it will be useful, but
9
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+ # details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with the KNOWtime server. If not, see <http://www.gnu.org/licenses/>.
15
+ module GtfsEngine::Concerns::Controllers
16
+ extend ActiveSupport::Autoload
17
+
18
+ autoload :DataAccess
19
+ autoload :Gtfs
20
+ end
@@ -0,0 +1,31 @@
1
+ # A Controller +Concern+ for convenient access to the +DataSet+ specified in
2
+ # the URL.
3
+ module GtfsEngine::Concerns::Controllers::DataAccess
4
+ extend ActiveSupport::Concern
5
+
6
+ #@param param_key <Symbol> The key of the URL param to use as the feed's ID
7
+ #@return <DataSet>
8
+ def data(param_key=:data_set_id)
9
+ key = params[param_key]
10
+ (@data_sets ||= {})[key] =
11
+ Rails.cache.fetch "data_set_#{key}" do
12
+ if param_is_data_set_name? param_key
13
+ GtfsEngine::DataSet.where(name: key).newest
14
+ else
15
+ GtfsEngine::DataSet.find params[param_key]
16
+ end
17
+ end
18
+ end
19
+
20
+ def data_cache(key)
21
+ Rails.cache.fetch "#{data.id}::#{key}" do
22
+ yield
23
+ end
24
+ end
25
+
26
+ #@return <Bool> +true+ if the key is the name of the GTFS feed,
27
+ # instead of its ID
28
+ def param_is_data_set_name?(param_key)
29
+ not /[[:digit:]]/ === params[param_key].try(:first)
30
+ end
31
+ end
@@ -0,0 +1,158 @@
1
+ # This file is part of the KNOWtime server.
2
+ #
3
+ # The KNOWtime server is free software: you can redistribute it and/or modify it
4
+ # under the terms of the GNU General Public License as published by the Free
5
+ # Software Foundation, either version 3 of the License, or (at your option) any
6
+ # later version.
7
+ #
8
+ # The KNOWtime server is distributed in the hope that it will be useful, but
9
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11
+ # details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with the KNOWtime server. If not, see <http://www.gnu.org/licenses/>.
15
+ #
16
+ # This controller +Concern+ provides the functionality common among most of
17
+ # the GTFS controllers.
18
+ module GtfsEngine::Concerns::Controllers::Gtfs
19
+ extend ActiveSupport::Concern
20
+
21
+ included do
22
+ around_filter :gtfs_cache, only: [:index, :show]
23
+
24
+ rescue_from GtfsEngine::UnknownFilters, with: :unknown_filter
25
+ rescue_from ActiveRecord::StatementInvalid, with: :statement_invalid
26
+ rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
27
+ helper_method :filter
28
+ end
29
+
30
+
31
+ module ClassMethods
32
+ #@return [Symbol] the unique key for this GTFS association
33
+ def gtfs_id(id=nil)
34
+ @gtfs_id = id unless id.nil?
35
+ @gtfs_id or controller_name.singularize.foreign_key
36
+ end
37
+
38
+ def filters(*attrs)
39
+ attrs.flatten!
40
+ @filters = attrs unless attrs.empty?
41
+ @filters ||= []
42
+ end
43
+
44
+ #@return [Class] the +ActiveRecord::Base+ class associated with this
45
+ # controller
46
+ def record_class
47
+ @record_class ||= begin
48
+ "#{name.deconstantize}::#{controller_name.classify}".constantize
49
+ end
50
+ end
51
+ end
52
+
53
+
54
+ # GET / collection of elements for the given GTFS type
55
+ # The returned collection may be filtered with query parameters
56
+ def index
57
+ @records = query.empty? ? collection : filtered_collection
58
+ respond_with @records, template: 'gtfs_engine/gtfs/index'
59
+ end
60
+
61
+ # GET /:id for a specific element of the given GTFS type
62
+ def show
63
+ @record = record
64
+ respond_with @record, template: 'gtfs_engine/gtfs/show'
65
+ end
66
+
67
+ #@return <ActionController::Parameters> the map of fields to filter;
68
+ # derived from the query string
69
+ def filter
70
+ @filter ||= begin
71
+ query = self.query
72
+ unknown = query.map do |q, v|
73
+ query[q] = true if v.blank? # blank value indicates boolean filter
74
+ filters.include?(q.to_sym) ? nil : q
75
+ end.compact
76
+ require 'pry'
77
+ binding.pry
78
+ unless unknown.empty?
79
+ raise GtfsEngine::UnknownFilters.new(unknown), 'unknown filter'
80
+ end
81
+ query_params = ActionController::Parameters.new query
82
+ query_params.permit filters
83
+ end
84
+ end
85
+
86
+ protected
87
+
88
+ #@return [ActiveRecord::Relation] all the records in this GTFS association
89
+ def collection
90
+ data.send controller_name
91
+ end
92
+
93
+ #@return [ActiveRecord::Relation] all the records in this GTFS
94
+ # association that match the filter specified in the query string
95
+ def filtered_collection
96
+ collection.where filter
97
+ end
98
+
99
+ #@return [ActiveRecord::Base] the record identified by +params[:id]+ in this
100
+ # GTFS association
101
+ def record
102
+ collection.find_by! gtfs_id => params[:id]
103
+ end
104
+
105
+ def gtfs_id
106
+ self.class.gtfs_id
107
+ end
108
+
109
+ def filters
110
+ self.class.filters
111
+ end
112
+
113
+ def query
114
+ request.query_parameters
115
+ end
116
+
117
+ private
118
+
119
+ def format
120
+ request.format.to_sym
121
+ end
122
+
123
+ def gtfs_cache
124
+ options = {
125
+ etag: [controller_name, data, query],
126
+ last_modified: data.updated_at,
127
+ public: true
128
+ }
129
+
130
+ expires_in 3.hours
131
+ yield if stale? options
132
+ end
133
+
134
+ #@param ex [GtfsEngine::UnknownFilter]
135
+ def unknown_filter(ex)
136
+ json = {status: 'fail', data: ex.to_hash}
137
+ render status: :bad_request, format => json
138
+ end
139
+
140
+ def statement_invalid(ex)
141
+ inner = ex.original_exception
142
+ case inner
143
+ when PG::InvalidDatetimeFormat, PG::DatetimeFieldOverflow
144
+ lines = inner.message.split "\n"
145
+ /.*"([^"]+)"[^"]+/ === lines[1][0..lines[2].size] and begin
146
+ json = {status: 'fail', data: {$1 => 'invalid date'}}
147
+ render status: :bad_request, format => json
148
+ end
149
+ else
150
+ raise ex
151
+ end
152
+ end
153
+
154
+ def record_not_found(ex)
155
+ json = {status: 'fail', data: {gtfs_id => params[:id]}}
156
+ render status: :not_found, format => json
157
+ end
158
+ end