rectify inline yaml sequence format
rectify inline yaml sequence format

require 'rubygems' require 'rubygems'
require 'nokogiri' require 'nokogiri'
require 'open-uri' require 'open-uri'
require 'pp' require 'pp'
  require 'yaml'
  class Array
  def to_yaml_style
  :inline
  end
  end
   
   
def makeTimetable(table, period, short_name) def makeTimetable(table, period, short_name)
timetable = {"stop_times" => [], "between_stops" => [], "short_name" => short_name} timetable = {"stop_times" => [], "between_stops" => [], "short_name" => short_name}
time_points = table.xpath('tr[1]//th').map do |tp| time_points = table.xpath('tr[1]//th').map do |tp|
if tp.content != "\302\240" && tp.content != "" && tp.content != "<br/>" if tp.content != "\302\240" && tp.content != "" && tp.content != "<br/>"
timing_point = tp.content.squeeze(" ").gsub("\r\n Platform"," - Platform").gsub(" - "," - ").gsub("\n","").gsub("\r","").gsub("\\"," / ").strip timing_point = tp.content.squeeze(" ").gsub("\r\n Platform"," - Platform").gsub(" - "," - ").gsub("\n","").gsub("\r","").gsub("\\"," / ").strip
end end
end end
time_points.delete(nil) time_points.delete(nil)
timetable["time_points"] = time_points timetable["time_points"] = time_points.to_a
timetable["long_name"] = "To " + time_points.last timetable["long_name"] = "To " + time_points.last
periodtimes = [] periodtimes = []
table.css('tr').each do |row| table.css('tr').each do |row|
times = row.css('td').map do |cell| times = row.css('td').map do |cell|
#TODO convert to GTFS time ie. replace " AM" with a #TODO convert to GTFS time ie. replace " AM" with a
time = cell.content.squeeze(" ").strip time = cell.content.squeeze(" ").strip
end end
if not times.empty? if not times.empty?
if not (route = times.shift) if not (route = times.shift)
raise("TODO: account for shifting route numbers eg. intertown/redex 62/162") raise("TODO: account for shifting route numbers eg. intertown/redex 62/162")
end end
periodtimes << times periodtimes << times.to_a
end end
end end
if periodtimes.size < 1 if periodtimes.size < 1
raise "No times for route " + short_name + " in period " + period raise "No times for route " + short_name + " in period " + period
end end
timetable["stop_times"] = { period => periodtimes } timetable["stop_times"] = { period => periodtimes.to_a }
# pp timetable # pp timetable
filename = timetable["short_name"] + "-" + timetable["long_name"].downcase.gsub(" ","-").gsub("/","") + "." + period + ".yml" filename = timetable["short_name"] + "-" + timetable["long_name"].downcase.gsub(" ","-").gsub("/","") + "." + period + ".yml"
puts "Saving " + filename puts "Saving " + filename
File.open("#{File.dirname(__FILE__)}/output/"+filename, "w") do |f| File.open("#{File.dirname(__FILE__)}/output/"+filename, "w") do |f|
f.write timetable.to_yaml f.write timetable.to_yaml
end end
timetable timetable
end end
   
#TODO fix route 934 #TODO fix route 934
Dir.glob("source-html/Route*.htm*") { |file| Dir.glob("source-html/Route*.htm*") { |file|
puts "Opened " + file puts "Opened " + file
doc = Nokogiri::HTML(open(file)) doc = Nokogiri::HTML(open(file))
# Search for nodes by css # Search for nodes by css
timetables = [] timetables = []
short_name = ""; short_name = "";
doc.xpath('//title').each do |title| doc.xpath('//title').each do |title|
short_name = title.content.gsub("Route_","").gsub("Route ","").squeeze(" ").strip short_name = title.content.gsub("Route_","").gsub("Route ","").squeeze(" ").strip
end end
if short_name == "" if short_name == ""
raise "Route number(s) not found in <title> tag" raise "Route number(s) not found in <title> tag"
end end
   
doc.xpath('//table[preceding::text()="Weekdays"]').each do |table| doc.xpath('//table[preceding::text()="Weekdays"]').each do |table|
timetables << makeTimetable(table, "weekday", short_name) timetables << makeTimetable(table, "weekday", short_name)
end end
   
#weekends #weekends
doc.xpath('//table[preceding::text()="Saturdays" and following::a]').each do |table| doc.xpath('//table[preceding::text()="Saturdays" and following::a]').each do |table|
timetables << makeTimetable(table, "saturday", short_name) timetables << makeTimetable(table, "saturday", short_name)
end end
doc.xpath('//table[preceding::text()="Sundays"]').each do |table| doc.xpath('//table[preceding::text()="Sundays"]').each do |table|
timetables << makeTimetable(table, "sunday", short_name) timetables << makeTimetable(table, "sunday", short_name)
end end
#930/934 special cases #930/934 special cases
doc.xpath('//table[preceding::text()="Saturday" and following::h2]').each do |table| doc.xpath('//table[preceding::text()="Saturday" and following::h2]').each do |table|
timetables << makeTimetable(table, "saturday", short_name) timetables << makeTimetable(table, "saturday", short_name)
end end
doc.xpath('//table[preceding::text()="Sunday"]').each do |table| doc.xpath('//table[preceding::text()="Sunday"]').each do |table|
timetables << makeTimetable(table, "sunday", short_name) timetables << makeTimetable(table, "sunday", short_name)
end end
#route 81 = Weekdays - School Holidays Only #route 81 = Weekdays - School Holidays Only
doc.xpath('//table[preceding::text()="Weekdays - School Holidays Only "]').each do |table| doc.xpath('//table[preceding::text()="Weekdays - School Holidays Only "]').each do |table|
timetable = makeTimetable(table, "weekday", short_name) timetable = makeTimetable(table, "weekday", short_name)
#TODO set active date range to only be holidays #TODO set active date range to only be holidays
timetables << timetable; timetables << timetable;
end end
   
if timetables.size > 2 if timetables.size > 2
puts "WARNING: " + file + " more than 2 timetables (weekend split?):" + timetables.size.to_s puts "WARNING: " + file + " more than 2 timetables (weekend split?):" + timetables.size.to_s
end end
if timetables.size < 2 if timetables.size < 2
puts "WARNING: " + file + " less than 2 timetables (weekday loop service?):" + timetables.size.to_s puts "WARNING: " + file + " less than 2 timetables (weekday loop service?):" + timetables.size.to_s
elsif not (timetables[0]["time_points"] - timetables[1]["time_points"].reverse).empty? elsif not (timetables[0]["time_points"] - timetables[1]["time_points"].reverse).empty?
puts "WARNING: first pair of timetable timing points are not complementary for "+ file puts "WARNING: first pair of timetable timing points are not complementary for "+ file
pp(timetables[0]["time_points"] - timetables[1]["time_points"].reverse) pp(timetables[0]["time_points"] - timetables[1]["time_points"].reverse)
end end
if timetables.size < 1 if timetables.size < 1
raise "No timetables extracted from " + file raise "No timetables extracted from " + file
end end
} }
   
require 'rubygems' require 'rubygems'
require 'pp' require 'pp'
require 'yaml' require 'yaml'
Dir.chdir("output") Dir.chdir("output")
   
def getTimePoints() def getTimePoints()
$time_points = [] $time_points = []
$time_points_sources = Hash.new([]) $time_points_sources = Hash.new([])
Dir.glob("*.yml") { |file| Dir.glob("*.yml") { |file|
timetable = YAML::load_file(file) timetable = YAML::load_file(file)
$time_points = $time_points | timetable["time_points"] $time_points = $time_points | timetable["time_points"]
timetable["time_points"].each do |timepoint| timetable["time_points"].each do |timepoint|
$time_points_sources[timepoint] = $time_points_sources[timepoint] | [ file ] $time_points_sources[timepoint] = $time_points_sources[timepoint] | [ file ]
end end
} }
end end
   
getTimePoints() getTimePoints()
pp $time_points.sort! pp $time_points.sort!
#pp $time_points_sources.sort #pp $time_points_sources.sort
   
time_point_corrections = {"North Lynehamham" => "North Lyneham", time_point_corrections = {"North Lynehamham" => "North Lyneham",
"Lathlain St Platform 2" => "Lathlain St Bus Station - Platform 2", "Lathlain St Platform 2" => "Lathlain St Bus Station - Platform 2",
"Lathlain St Sation - Platform 5" => "Lathlain St Bus Station - Platform 5", "Lathlain St Sation - Platform 5" => "Lathlain St Bus Station - Platform 5",
"Lathlain Steet Station" => "Lathlain St Bus Station", "Lathlain Steet Station" => "Lathlain St Bus Station",
"Lathlain St - Platform 3" => "Lathlain St Bus Station - Platform 3", "Lathlain St - Platform 3" => "Lathlain St Bus Station - Platform 3",
"Lathlain Steet Station - Platform 3" => "Lathlain St Bus Station - Platform 3", "Lathlain Steet Station - Platform 3" => "Lathlain St Bus Station - Platform 3",
"Lathlain St Station" => "Lathlain St Bus Station", "Lathlain St Station" => "Lathlain St Bus Station",
"Lathlain St Station - Platform 1" => "Lathlain St Bus Station - Platform 1", "Lathlain St Station - Platform 1" => "Lathlain St Bus Station - Platform 1",
"Lathlain St Station - Platform 2" => "Lathlain St Bus Station - Platform 2", "Lathlain St Station - Platform 2" => "Lathlain St Bus Station - Platform 2",
"Lathlain St Station - Platform 3" => "Lathlain St Bus Station - Platform 3", "Lathlain St Station - Platform 3" => "Lathlain St Bus Station - Platform 3",
"Lathlain St Station - Platform 4" => "Lathlain St Bus Station - Platform 4", "Lathlain St Station - Platform 4" => "Lathlain St Bus Station - Platform 4",
"Lathlain St Station - Platform 5" => "Lathlain St Bus Station - Platform 5", "Lathlain St Station - Platform 5" => "Lathlain St Bus Station - Platform 5",
"Lathlain St Station - Platform 6" => "Lathlain St Bus Station - Platform 6", "Lathlain St Station - Platform 6" => "Lathlain St Bus Station - Platform 6",
"Manuka Captain Cook" => "Manuka, Captain Cook", "Manuka Captain Cook" => "Manuka, Captain Cook",
"Flemington Rd, Sandford St" => "Flemington Rd/Sandford St", "Flemington Rd, Sandford St" => "Flemington Rd/Sandford St",
"Erindale Centre / - Sternberg Crescent" => "Erindale Drive/Sternberg", "Erindale Centre / - Sternberg Crescent" => "Erindale Drive/Sternberg",
"Canberra Hospita" => "Canberra Hospital", "Canberra Hospita" => "Canberra Hospital",
"Cohen Str Station - Platform 1" => "Cohen St Bus Station - Platform 1", "Cohen Str Station - Platform 1" => "Cohen St Bus Station - Platform 1",
"Cohen Street Station" => "Cohen St Bus Station", "Cohen Street Station" => "Cohen St Bus Station",
"Cohen Street Station - Platform 2" => "Cohen St Bus Station - Platform 2", "Cohen Street Station - Platform 2" => "Cohen St Bus Station - Platform 2",
"Cohn St Station - Platform 3" => "Cohen St Bus Station - Platform 3", "Cohn St Station - Platform 3" => "Cohen St Bus Station - Platform 3",
"Cohen St Station" => "Cohen St Bus Station", "Cohen St Station" => "Cohen St Bus Station",
"Cohen St Station - Platform 1" => "Cohen St Bus Station - Platform 1", "Cohen St Station - Platform 1" => "Cohen St Bus Station - Platform 1",
"Cohen St Station - Platform 2" => "Cohen St Bus Station - Platform 2", "Cohen St Station - Platform 2" => "Cohen St Bus Station - Platform 2",
"Cohen St Station - Platform 3" => "Cohen St Bus Station - Platform 3", "Cohen St Station - Platform 3" => "Cohen St Bus Station - Platform 3",
"Cohen St Station - Platform 4" => "Cohen St Bus Station - Platform 4", "Cohen St Station - Platform 4" => "Cohen St Bus Station - Platform 4",
"Cohen St Station - Platform 5" => "Cohen St Bus Station - Platform 5", "Cohen St Station - Platform 5" => "Cohen St Bus Station - Platform 5",
"Cohen St Station - Platform 6" => "Cohen St Bus Station - Platform 6", "Cohen St Station - Platform 6" => "Cohen St Bus Station - Platform 6",
"City - Platform 7" => "City Interchange - Platform 7", "City - Platform 7" => "City Interchange - Platform 7",
"Cameron Avenue Station" => "Cameron Ave Bus Station", "Cameron Avenue Station" => "Cameron Ave Bus Station",
"Cameron Avenue Station - Platform 1" => "Cameron Ave Bus Station - Platform 1", "Cameron Avenue Station - Platform 1" => "Cameron Ave Bus Station - Platform 1",
"Cameron Avenue Station - Platform 2" => "Cameron Ave Bus Station - Platform 2", "Cameron Avenue Station - Platform 2" => "Cameron Ave Bus Station - Platform 2",
"Cameron Avenue Station - Platform 3" => "Cameron Ave Bus Station - Platform 3", "Cameron Avenue Station - Platform 3" => "Cameron Ave Bus Station - Platform 3",
"Cameron Avenue Station - Platform 4" => "Cameron Ave Bus Station - Platform 4", "Cameron Avenue Station - Platform 4" => "Cameron Ave Bus Station - Platform 4",
"Cameron Avenue Station - Platform 5" => "Cameron Ave Bus Station - Platform 5", "Cameron Avenue Station - Platform 5" => "Cameron Ave Bus Station - Platform 5",
"Cameron Ave Station" => "Cameron Ave Bus Station", "Cameron Ave Station" => "Cameron Ave Bus Station",
"Cameron Ave Station - Platform 1" => "Cameron Ave Bus Station - Platform 1", "Cameron Ave Station - Platform 1" => "Cameron Ave Bus Station - Platform 1",
"Cameron Ave Station - Platform 2" => "Cameron Ave Bus Station - Platform 2", "Cameron Ave Station - Platform 2" => "Cameron Ave Bus Station - Platform 2",
"Cameron Ave Station - Platform 3" => "Cameron Ave Bus Station - Platform 3", "Cameron Ave Station - Platform 3" => "Cameron Ave Bus Station - Platform 3",
"Cameron Ave Station - Platform 4" => "Cameron Ave Bus Station - Platform 4", "Cameron Ave Station - Platform 4" => "Cameron Ave Bus Station - Platform 4",
"Cameron Ave Station - Platform 5" => "Cameron Ave Bus Station - Platform 5", "Cameron Ave Station - Platform 5" => "Cameron Ave Bus Station - Platform 5",
"Burton & Garranan Hall, Daley Road ANU" => "Burton & Garran Hall, Daley Road ANU", "Burton & Garranan Hall, Daley Road ANU" => "Burton & Garran Hall, Daley Road ANU",
"Burton & Garranan Hall,Daley Road ANU" => "Burton & Garran Hall, Daley Road ANU", "Burton & Garranan Hall,Daley Road ANU" => "Burton & Garran Hall, Daley Road ANU",
"Garran/Daley Rd" => "Burton & Garran Hall, Daley Road ANU", "Garran/Daley Rd" => "Burton & Garran Hall, Daley Road ANU",
"Kingstons Ave/National Crt" => "Kings Ave/National Crt", "Kingstons Ave/National Crt" => "Kings Ave/National Crt",
"Newcastle Street after Isa St" => "Newcastle / Isa Street Fyshwick", "Newcastle Street after Isa St" => "Newcastle / Isa Street Fyshwick",
"National Circ/Canberra Ave" => "National Circuit / Canberra Ave", "National Circ/Canberra Ave" => "National Circuit / Canberra Ave",
"St Clare of Conder" => "St Clare of Assisi Primary", "St Clare of Conder" => "St Clare of Assisi Primary",
"McKillop College Isabella Campus" => "MacKillop College Isabella Campus", "McKillop College Isabella Campus" => "MacKillop College Isabella Campus",
  "Outrim / Duggan" => "Outtrim / Duggan",
} }
time_point_corrections.each do |wrong, right| time_point_corrections.each do |wrong, right|
$time_points_sources[wrong].each do |wrongfile| $time_points_sources[wrong].each do |wrongfile|
badtimetable = YAML::load_file(wrongfile) badtimetable = YAML::load_file(wrongfile)
badentrynumber = badtimetable["time_points"].index wrong badentrynumber = badtimetable["time_points"].index wrong
badtimetable["time_points"][badentrynumber] = right badtimetable["time_points"][badentrynumber] = right
puts "Corrected '" + wrong + "' to '" + right + "' in " + wrongfile puts "Corrected '" + wrong + "' to '" + right + "' in " + wrongfile
File.open(wrongfile, "w") do |f| File.open(wrongfile, "w") do |f|
f.write badtimetable.to_yaml f.write badtimetable.to_yaml
end end
end end
end end
   
getTimePoints() getTimePoints()
pp $time_points.sort! pp $time_points.sort!
   
  #!/usr/bin/ruby
  require 'postgres'
 
  require 'highline.rb'
  include HighLine
 
  require 'rubygems'
  require 'json'
  require 'yaml'
  require 'pp'
  # make - { name: Civic Interchange Platform 1,stop_code: civic_platform_1, lat: -35.2794347, lng: 149.130588}
  connbus = PGconn.connect("localhost", 5432, '', '', "bus", "postgres", "snmc")
 
  f = File.open('cbrtable.yml.in.in')
  header = f.readlines
  f.close
 
  File.open('cbrtable.yml.in', 'w') do |f2|
  f2.puts header
  f2.puts "stops:\n";
  begin
  time_points = connbus.exec("SELECT * from timing_point")
  rescue PGError => e
  puts "Error reading from DB #{e}"
  #conn.close() if conn
  end
  time_points.each do |time_point|
  #pp time_point
  # 0 = name
 
  # 1 = lat*100000
  # 2 = lng*100000
  f2.puts " - { name: #{time_point[0]},stop_code: #{time_point[0]}, lat: #{Float(time_point[1])/10000000}, lng: #{Float(time_point[2])/10000000}}"
  end
  f2.puts "routes:\n";
  end
 
 
default: cbrfeed.zip default: cbrfeed.zip
   
cbrfeed.zip: cbrtable.yml createfeed.py cbrfeed.zip: cbrtable.yml createfeed.py
./createfeed.py --input=cbrtable.yml --output=cbrfeed.zip ./createfeed.py --input=cbrtable.yml --output=cbrfeed.zip
   
ROUTE_FILES=900-intertown.yml cbrtable.yml: cbrtable.yml.in indent-route.pl
   
cbrtable.yml: cbrtable.yml.in $(ROUTE_FILES) indent-route.pl  
cp cbrtable.yml.in cbrtable.yml cp cbrtable.yml.in cbrtable.yml
@$(foreach ROUTE_FILE, $(ROUTE_FILES), \ @$(foreach ROUTE_FILE, $(wildcard output/*), \
echo "Parsing $(ROUTE_FILE)"; \ echo "Parsing $(ROUTE_FILE)"; \
echo "TODO: replace friendly timing spot names with OSM node IDs or geohash in $(ROUTE_FILE)"; \ echo "TODO: replace friendly timing spot names with OSM node IDs or geohash in $(ROUTE_FILE)"; \
echo "TODO: add inbetween stops in $(ROUTE_FILE)"; \ echo "TODO: add inbetween stops in $(ROUTE_FILE)"; \
./indent-route.pl < $(ROUTE_FILE) >> cbrtable.yml;) ./indent-route.pl < $(ROUTE_FILE) >> cbrtable.yml;)
   
cbrtable.yml.in: cbrtable.yml.in.in cbrtable.yml.in: cbrtable.yml.in.in
@echo "TODO: autogenerate stops via database, convert to YAML" ruby 04-generateymlinclude.rb
cp cbrtable.yml.in.in cbrtable.yml.in  
   
   
clean: clean:
rm -f cbrtable.yml cbrtable.yml.in cbrfeed.zip *~ rm -f cbrtable.yml cbrtable.yml.in cbrfeed.zip *~
   
options: options:
start_date: 20090525 start_date: 20090525
end_date: 20100601 end_date: 20101001
remove_date: 2010601 remove_date: 20101001
agency_name: ACT Internal Omnibus Network (ACTION) agency_name: ACT Internal Omnibus Network (ACTION)
agency_url: http://www.action.act.gov.au/ agency_url: http://www.action.act.gov.au/
agency_timezone: Australia/Canberra agency_timezone: Australia/Canberra
   
   
stops: stops:
- { name: Civic Interchange Platform 1,stop_code: civic_platform_1, lat: -35.2794347, lng: 149.130588} - { name: ADFA,stop_code: ADFA, lat: -35.2937972, lng: 149.1643403}
- { name: Civic Interchange Platform 5,stop_code: civic_platform_5, lat: -35.2786, lng: 149.13033} - { name: Ainslie,stop_code: Ainslie, lat: -35.2620105, lng: 149.1443302}
- { name: Civic Interchange Platform 6,stop_code: civic_platform_6, lat: -35.27851, lng: 149.12979 } - { name: Aranda,stop_code: Aranda, lat: -35.257534, lng: 149.0762963}
- { name: Canberra House Northbound, stop_code: 3042, lat: -35.27833, - { name: Bonython,stop_code: Bonython, lat: -35.4297416, lng: 149.0814517}
lng: 149.12712 } - { name: Botanic Gardens,stop_code: Botanic Gardens, lat: -35.278643, lng: 149.1093237}
- { name: Canberra House Southbound, stop_code: 4531, - { name: Cameron Ave Bus Station,stop_code: Cameron Ave Bus Station, lat: -35.2410195, lng: 149.0722506}
lat: -35.2786, lng: 149.13033 } - { name: Cameron Ave Bus Station - Platform 1,stop_code: Cameron Ave Bus Station - Platform 1, lat: -35.2410195, lng: 149.0722506}
- { name: Marcus Clarke Street - Unilodge ANU, stop_code: 4929, lat: -35.2764151, lng: 149.1267199 } - { name: Cameron Ave Bus Station - Platform 2,stop_code: Cameron Ave Bus Station - Platform 2, lat: -35.2410108, lng: 149.0717142}
  - { name: Cameron Ave Bus Station - Platform 3,stop_code: Cameron Ave Bus Station - Platform 3, lat: -35.2410064, lng: 149.0710758}
  - { name: Cameron Ave Bus Station - Platform 4,stop_code: Cameron Ave Bus Station - Platform 4, lat: -35.2411773, lng: 149.0709793}
  - { name: Cameron Ave Bus Station - Platform 5,stop_code: Cameron Ave Bus Station - Platform 5, lat: -35.241186, lng: 149.0720789}
  - { name: Canberra College Weston,stop_code: Canberra College Weston, lat: -35.3490278, lng: 149.0486277}
  - { name: Canberra Hospital,stop_code: Canberra Hospital, lat: -35.3459462, lng: 149.1012001}
  - { name: Canberra Times,stop_code: Canberra Times, lat: -35.3245431, lng: 149.1705533}
  - { name: Chapman,stop_code: Chapman, lat: -35.3557877, lng: 149.0408111}
  - { name: Charnwood,stop_code: Charnwood, lat: -35.2052138, lng: 149.0337266}
  - { name: Chifley,stop_code: Chifley, lat: -35.350985, lng: 149.077319}
  - { name: Bonython Primary,stop_code: Bonython Primary, lat: -35.431019, lng: 149.0831217}
  - { name: Cohen St Bus Station - Platform 1,stop_code: Cohen St Bus Station - Platform 1, lat: -35.2394775, lng: 149.0602031}
  - { name: Conder Primary,stop_code: Conder Primary, lat: -35.4643475, lng: 149.0986908}
  - { name: Cook,stop_code: Cook, lat: -35.2646433, lng: 149.0631708}
  - { name: Copland College,stop_code: Copland College, lat: -35.2127018, lng: 149.0596387}
  - { name: Curtin,stop_code: Curtin, lat: -35.3248779, lng: 149.081441}
  - { name: Dickson,stop_code: Dickson, lat: -35.2498434, lng: 149.1391218}
  - { name: Duffy,stop_code: Duffy, lat: -35.3366908, lng: 149.0324311}
  - { name: Dunlop,stop_code: Dunlop, lat: -35.1942693, lng: 149.0206702}
  - { name: Belconnen Way,stop_code: Belconnen Way, lat: -35.24809, lng: 149.06765}