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.
- checksums.yaml +7 -0
- data/Rakefile +37 -0
- data/app/controllers/gtfs_engine/agencies_controller.rb +24 -0
- data/app/controllers/gtfs_engine/application_controller.rb +21 -0
- data/app/controllers/gtfs_engine/calendar_dates_controller.rb +22 -0
- data/app/controllers/gtfs_engine/calendars_controller.rb +51 -0
- data/app/controllers/gtfs_engine/data_sets_controller.rb +47 -0
- data/app/controllers/gtfs_engine/fare_attributes_controller.rb +27 -0
- data/app/controllers/gtfs_engine/fare_rules_controller.rb +26 -0
- data/app/controllers/gtfs_engine/feed_infos_controller.rb +26 -0
- data/app/controllers/gtfs_engine/frequencies_controller.rb +26 -0
- data/app/controllers/gtfs_engine/routes_controller.rb +25 -0
- data/app/controllers/gtfs_engine/shapes_controller.rb +23 -0
- data/app/controllers/gtfs_engine/stop_times_controller.rb +28 -0
- data/app/controllers/gtfs_engine/stops_controller.rb +30 -0
- data/app/controllers/gtfs_engine/transfers_controller.rb +38 -0
- data/app/controllers/gtfs_engine/trips_controller.rb +34 -0
- data/app/helpers/gtfs_engine/default_views_helper.rb +42 -0
- data/app/helpers/gtfs_engine/fields_helper.rb +32 -0
- data/app/models/gtfs_engine/agency.rb +19 -0
- data/app/models/gtfs_engine/calendar.rb +78 -0
- data/app/models/gtfs_engine/calendar_date.rb +20 -0
- data/app/models/gtfs_engine/data_set.rb +73 -0
- data/app/models/gtfs_engine/fare_attribute.rb +19 -0
- data/app/models/gtfs_engine/fare_rule.rb +28 -0
- data/app/models/gtfs_engine/feed_info.rb +19 -0
- data/app/models/gtfs_engine/frequency.rb +20 -0
- data/app/models/gtfs_engine/route.rb +24 -0
- data/app/models/gtfs_engine/shape.rb +20 -0
- data/app/models/gtfs_engine/stop.rb +26 -0
- data/app/models/gtfs_engine/stop_time.rb +21 -0
- data/app/models/gtfs_engine/transfer.rb +23 -0
- data/app/models/gtfs_engine/trip.rb +27 -0
- data/app/views/gtfs_engine/calendars/dates.json.jbuilder +18 -0
- data/app/views/gtfs_engine/data_sets/index.json.jbuilder +28 -0
- data/app/views/gtfs_engine/data_sets/show.json.jbuilder +21 -0
- data/app/views/gtfs_engine/gtfs/index.json.jbuilder +15 -0
- data/app/views/gtfs_engine/gtfs/show.json.jbuilder +15 -0
- data/app/views/gtfs_engine/transfers/from.json.jbuilder +15 -0
- data/app/views/gtfs_engine/transfers/from_to.json.jbuilder +15 -0
- data/app/views/gtfs_engine/transfers/to.json.jbuilder +15 -0
- data/app/views/gtfs_engine/trips/block.json.jbuilder +15 -0
- data/bin/rails +8 -0
- data/config/initializers/extensions_loader.rb +15 -0
- data/config/routes.rb +45 -0
- data/db/migrate/20140320045108_create_gtfs_engine_data_sets.rb +17 -0
- data/db/migrate/20140320045232_create_gtfs_engine_calendars.rb +24 -0
- data/db/migrate/20140320045751_create_gtfs_engine_calendar_dates.rb +16 -0
- data/db/migrate/20140320050100_create_gtfs_engine_shapes.rb +20 -0
- data/db/migrate/20140320051140_create_gtfs_engine_routes.rb +22 -0
- data/db/migrate/20140320052005_create_gtfs_engine_stops.rb +28 -0
- data/db/migrate/20140320052508_create_gtfs_engine_trips.rb +26 -0
- data/db/migrate/20140320052907_create_gtfs_engine_stop_times.rb +24 -0
- data/db/migrate/20140401032609_create_gtfs_engine_agencies.rb +19 -0
- data/db/migrate/20140405235947_create_gtfs_engine_fare_attributes.rb +18 -0
- data/db/migrate/20140406063500_create_gtfs_engine_fare_rules.rb +17 -0
- data/db/migrate/20140406071922_create_gtfs_engine_frequencies.rb +17 -0
- data/db/migrate/20140406072309_create_gtfs_engine_transfers.rb +17 -0
- data/db/migrate/20140406073548_create_gtfs_engine_feed_infos.rb +16 -0
- data/lib/ext.rb +19 -0
- data/lib/ext/active_record/associations/association.rb +41 -0
- data/lib/gtfs_engine.rb +33 -0
- data/lib/gtfs_engine/concerns.rb +19 -0
- data/lib/gtfs_engine/concerns/controllers.rb +20 -0
- data/lib/gtfs_engine/concerns/controllers/data_access.rb +31 -0
- data/lib/gtfs_engine/concerns/controllers/gtfs.rb +158 -0
- data/lib/gtfs_engine/engine.rb +28 -0
- data/lib/gtfs_engine/exceptions.rb +35 -0
- data/lib/gtfs_engine/json_responder.rb +31 -0
- data/lib/gtfs_engine/sources.rb +86 -0
- data/lib/gtfs_engine/version.rb +84 -0
- data/lib/tasks/gtfs_engine_tasks.rake +89 -0
- 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
|
data/lib/gtfs_engine.rb
ADDED
@@ -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
|