Class: NationalRail::JourneyPlanner
- Inherits:
-
Object
- Object
- NationalRail::JourneyPlanner
- Defined in:
- lib/national-rail/journey_planner.rb,
lib/national-rail/journey_planner/details_page_parser.rb
Defined Under Namespace
Classes: DetailsPageParser, NokogiriParser, SummaryRow, TimeParser
Constant Summary collapse
- OPERATORS =
{ "Arriva Trains Wales" => "AW", "c2c" => "CC", "Chiltern Railways" => "CH", "CrossCountry" => "XC", "East Coast" => "GR", "East Midlands Trains" => "EM", "First Capital Connect" => "FC", "First Great Western" => "GW", "First ScotRail" => "SR", "Gatwick Express" => "GX", "Grand Central Railway" => "GC", "Heathrow Connect" => "HC", "Heathrow Express" => "HX", "Hull Trains" => "HT", "Island Line" => "IL", "London Midland" => "LM", "London Overground" => "LO", "London Underground" => "LT", "Merseyrail" => "ME", "Northern Rail" => "NT", "NXEA" => "LE", "South West Trains" => "SW", "Southeastern" => "SE", "Southern" => "SN", "Transpennine Express" => "TP", "Virgin Trains" => "VT", "Wrexham and Shropshire Railway" => "WS" }
Class Attribute Summary collapse
-
.capture_path ⇒ Object
Returns the value of attribute capture_path.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize ⇒ JourneyPlanner
constructor
A new instance of JourneyPlanner.
- #plan(options = {}) ⇒ Object
Constructor Details
#initialize ⇒ JourneyPlanner
Returns a new instance of JourneyPlanner.
129 130 131 132 133 134 135 |
# File 'lib/national-rail/journey_planner.rb', line 129 def initialize Time.zone ||= 'London' @agent = Mechanize.new @agent.pluggable_parser.html = NokogiriParser aliases = Mechanize::AGENT_ALIASES.keys - %w(Mechanize) @agent.user_agent_alias = aliases[rand(aliases.length)] end |
Class Attribute Details
.capture_path ⇒ Object
Returns the value of attribute capture_path.
57 58 59 |
# File 'lib/national-rail/journey_planner.rb', line 57 def capture_path @capture_path end |
Class Method Details
.capture(page, filename) ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'lib/national-rail/journey_planner.rb', line 58 def capture(page, filename) if capture_path.present? FileUtils.mkdir_p(capture_path) path = File.join(capture_path, filename) File.open(path, "w") { |f| f.write(TidyFFI::Tidy.new(page.parser.to_html).clean) } end rescue => e puts e end |
Instance Method Details
#plan(options = {}) ⇒ Object
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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/national-rail/journey_planner.rb', line 137 def plan( = {}) summary_rows = [] @agent.get("http://www.nationalrail.co.uk/") do |home_page| JourneyPlanner.capture(home_page, "index.html") = nil times_page = home_page.form_with(:action => "http://ojp.nationalrail.co.uk/en/s/planjourney/plan") do |form| = form..last form["jpState"] = "single" form["commandName"] = "journeyPlannerCommand" form["from.searchTerm"] = [:from] form["to.searchTerm"] = [:to] form["timeOfOutwardJourney.arrivalOrDeparture"] = "DEPART" form["timeOfOutwardJourney.monthDay"] = [:time].strftime("%d/%m/%Y") form["timeOfOutwardJourney.hour"] = [:time].strftime("%H") form["timeOfOutwardJourney.minute"] = [:time].strftime("%M") # form["timeOfReturnJourney.arrivalOrDeparture"] = "DEPART" # form["timeOfReturnJourney.monthDay"] = "Today" # form["timeOfReturnJourney.hour"] = "15" # form["timeOfReturnJourney.minute"] = "0" form["viaMode"] = "VIA" form["via.searchTerm"] = "" form["offSetOption"] = "0" form["reduceTransfers"] = "true" form["_reduceTransfers"] = "on" # hidden (duplicate of reduceTransfers?) form["operatorMode"] = "SHOW" # alternative is "DONT_SHOW" form["operator.code"] = "" form["lookForSleeper"] = "true" form["_lookForSleeper"] = "on" # hidden (duplicate of lookForSleeper?) form["directTrains"] = "true" form["_directTrains"] = "on" # hidden (duplicate of directTrains?) form["includeOvertakenTrains"] = "true" form["_includeOvertakenTrains"] = "on" # hidden (duplicate of includeOvertakenTrains?) end.() JourneyPlanner.capture(times_page, "summary.html") if (times_page.doc/".error-message").any? raise InputError.new((times_page.doc/".error-message").first.inner_text.gsub(/\s+/, " ").strip) end year = [:time].year date_as_string = (times_page.doc/".journey-details span").first.children.first.inner_text.gsub(/\s+/, " ").gsub(/\+ 1 day/, '').strip date = Date.parse("#{date_as_string} #{year}") (times_page.doc/"table#outboundJourneyTable > tbody > tr").reject { |tr| %w(status changes).include?(tr.attributes["class"].value) }.each do |tr| if (tr.attributes["class"].value == "day-heading") date_as_string = (tr/"th > p > span").first.inner_text.strip date = Date.parse("#{date_as_string} #{year}") next end departure_time = TimeParser.new(date).time((tr/"td:nth-child(1)").inner_text.strip) number_of_changes = (tr/"td:nth-child(6)").inner_text.strip status = (tr/"td:nth-child(10) .status").inner_text.strip anchor = (tr/"a[@id^=journeyOption]").first next unless anchor link = times_page.links.detect { |l| l.attributes["id"] == anchor.attributes["id"].value } summary_rows << SummaryRow.new(@agent, date, departure_time, number_of_changes, link, status) end end summary_rows rescue => e page = @agent.current_page JourneyPlanner.capture(page, "summary-error.html") page_html = TidyFFI::Tidy.new(page.parser.to_html).clean raise ParseError.new(e, page_html) end |