national-rail 0.2.0 → 0.3.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.
@@ -43,6 +43,7 @@ module NationalRail
43
43
  end
44
44
 
45
45
  def details
46
+ return if number_of_changes.to_i > 0
46
47
  @agent.transact do
47
48
  parse_details(@link.click, @date)
48
49
  end
@@ -50,7 +51,7 @@ module NationalRail
50
51
 
51
52
  def parse_details(page, date)
52
53
  details = {}
53
- description = (page.doc/"table#journeyLegDetails tbody tr.lastRow td[@colspan=6] div").first.inner_text.gsub(/\s+/, " ").strip
54
+ description = (page.doc/"table#journeyLegDetails tbody tr.lastRow td[@colspan=6] div").last.inner_text.gsub(/\s+/, " ").strip
54
55
  origins, destinations = (/from (.*) to (.*)/.match(description)[1,2]).map{ |s| s.split(",").map(&:strip) }
55
56
  details[:origins], details[:destinations] = origins, destinations
56
57
  parser = TimeParser.new(date)
@@ -102,7 +103,9 @@ module NationalRail
102
103
  def plan(options = {})
103
104
  summary_rows = []
104
105
  @agent.get("http://www.nationalrail.co.uk/") do |home_page|
106
+ button = nil
105
107
  times_page = home_page.form_with(:action => "http://ojp.nationalrail.co.uk/en/s/planjourney/plan") do |form|
108
+ button = form.buttons.last
106
109
  form["jpState"] = "single"
107
110
  form["commandName"] = "journeyPlannerCommand"
108
111
  form["from.searchTerm"] = options[:from]
@@ -124,7 +127,7 @@ module NationalRail
124
127
  form["_lookForSleeper"] = "on"
125
128
  form["_directTrains"] = "on"
126
129
  form["_includeOvertakenTrains"] = "on"
127
- end.click_button
130
+ end.click_button(button)
128
131
 
129
132
  if (times_page.doc/"error-message").any?
130
133
  raise (times_page.doc/"error-message").first.inner_text.gsub(/\s+/, " ").strip
@@ -1,105 +1,66 @@
1
- require 'mechanize'
2
- require 'hpricot'
1
+ require "active_support"
2
+ require "active_support/core_ext"
3
3
 
4
4
  module NationalRail
5
5
 
6
6
  class LiveDepartureBoards
7
7
 
8
- class HpricotParser < Mechanize::Page
9
- attr_reader :doc
10
- def initialize(uri = nil, response = nil, body = nil, code = nil)
11
- @doc = Hpricot(body)
12
- super(uri, response, body, code)
13
- end
14
- end
15
-
16
8
  class SummaryRow
17
9
  attr_reader :attributes
18
- def initialize(agent, attributes)
19
- @agent, @attributes = agent, attributes
10
+ def initialize(attributes)
11
+ @attributes = attributes
20
12
  end
21
13
  def [](key)
22
14
  @attributes[key]
23
15
  end
24
16
  def details
25
- page = nil
26
- @agent.transact do
27
- page = @attributes[:details][:link].click
28
- station = nil
29
- (page.doc/"table.arrivaltable tbody tr").map do |tr|
30
- tds = (tr/"td")
31
- tds.unshift(station) if tds.length < 4
32
- station = tds[0]
33
- station_url = (station/"a").first.attributes["href"]
34
- station_code = /station_query\=(.*)$/.match(station_url)[1]
35
- deparr = (tds[1]/".deparr").remove
36
- direction = (deparr.inner_text.strip == "Dep") ? "departure" : "arrival"
37
- {
38
- :station => {
39
- :name => (station/"a").inner_text.strip,
40
- :url => station_url,
41
- :code => station_code
42
- },
43
- :timetabled => {
44
- :time => tds[1].inner_text.strip,
45
- :direction => direction
46
- },
47
- :expected => {
48
- :time => tds[2].inner_text.strip
49
- },
50
- :actual => {
51
- :time => tds[3].inner_text.strip
52
- }
53
- }
54
- end
17
+ url = "http://ojp.nationalrail.co.uk/en/s/ldbdetailsJson"
18
+ params = { "departing" => "false", "serviceId" => @attributes[:service_id] }
19
+ uri = URI.parse("#{url}?#{params.to_query}")
20
+ response = Net::HTTP.get_response(uri)
21
+ json = ActiveSupport::JSON.decode(response.body)
22
+ json["trains"].map do |row|
23
+ {
24
+ :departs => row[1],
25
+ :station => row[2],
26
+ :status => row[3..4],
27
+ :platform => row[5]
28
+ }
55
29
  end
56
- rescue => e
57
- File.open("error.html", "w") { |f| f.write(page.parser.to_html) } if page
58
- raise e
59
30
  end
60
31
  end
61
32
 
62
- def initialize
63
- @agent = Mechanize.new
64
- @agent.pluggable_parser.html = HpricotParser
65
- end
66
-
67
33
  def summary(options = {})
68
- summary_url = "http://realtime.nationalrail.co.uk/ldb/sumdep.aspx"
69
- page = @agent.get(summary_url, "T" => options[:from], "S" => options[:to])
70
- (page.doc/"table.arrivaltable tbody tr").map do |tr|
71
- destination = (tr/"td:nth-child(1)")
72
- destination_url = (destination/"a").first.attributes["href"]
73
- destination_code = /station_query\=(.*)$/.match(destination_url)[1]
74
- operator = (tr/"td:nth-child(5)")
75
- operator_url = (operator/"a").first.attributes["href"]
76
- operator_code = /atocCode\=(.*)$/.match(operator_url)[1]
77
- details = (tr/"td:nth-child(6)")
78
- details_url = (details/"a").first.attributes["href"]
79
- details_link = page.links.detect { |l| l.attributes["href"] == details_url }
80
- SummaryRow.new(@agent,
81
- :destination => {
82
- :name => destination.inner_text,
83
- :url => destination_url,
84
- :code => destination_code
85
- },
86
- :platform => (tr/"td:nth-child(2)").inner_text,
87
- :timetabled_at => (tr/"td:nth-child(3)").inner_text,
88
- :expected_at => (tr/"td:nth-child(4)").inner_text,
89
- :operator => {
90
- :name => operator.inner_text,
91
- :url => operator_url,
92
- :code => operator_code
93
- },
94
- :details => {
95
- :url => details_url,
96
- :link => details_link
97
- }
34
+ departing = case options[:type]
35
+ when :departures
36
+ true
37
+ when :arrivals
38
+ false
39
+ else
40
+ true
41
+ end
42
+ if departing
43
+ liveTrainsFrom, liveTrainsTo = options[:from], options[:to]
44
+ origin_or_destination = :destination
45
+ else
46
+ liveTrainsFrom, liveTrainsTo = options[:to], options[:from]
47
+ origin_or_destination = :origin
48
+ end
49
+ url = "http://ojp.nationalrail.co.uk/en/s/ldb/liveTrainsJson"
50
+ params = { "departing" => departing.to_s, "liveTrainsFrom" => liveTrainsFrom, "liveTrainsTo" => liveTrainsTo }
51
+ uri = URI.parse("#{url}?#{params.to_query}")
52
+ response = Net::HTTP.get_response(uri)
53
+ json = ActiveSupport::JSON.decode(response.body)
54
+ trains = json["trains"].map do |row|
55
+ service_id = CGI.unescape(%r{/en/s/ldbdetails/([^\?]+)}.match(row[5])[1])
56
+ SummaryRow.new(
57
+ :service_id => service_id,
58
+ :due => row[1],
59
+ origin_or_destination => row[2],
60
+ :status => CGI.unescapeHTML(row[3]).split("<br/>").map(&:strip),
61
+ :platform => row[4]
98
62
  )
99
63
  end
100
- rescue => e
101
- File.open("error.html", "w") { |f| f.write(@agent.current_page.parser.to_html) }
102
- raise e
103
64
  end
104
65
 
105
66
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
7
+ - 3
8
8
  - 0
9
- version: 0.2.0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - James Mead
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-23 00:00:00 +01:00
17
+ date: 2010-11-04 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -53,10 +53,10 @@ dependencies:
53
53
  - - ~>
54
54
  - !ruby/object:Gem::Version
55
55
  segments:
56
- - 2
57
56
  - 3
58
- - 5
59
- version: 2.3.5
57
+ - 0
58
+ - 0
59
+ version: 3.0.0
60
60
  type: :runtime
61
61
  version_requirements: *id003
62
62
  description: