Class: MetraSchedule::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/metra/parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(html_doc) ⇒ Parser

Returns a new instance of Parser.



11
12
13
# File 'lib/metra/parser.rb', line 11

def initialize(html_doc)
  @html_doc = html_doc
end

Instance Attribute Details

#html_docObject (readonly)

Returns the value of attribute html_doc.



8
9
10
# File 'lib/metra/parser.rb', line 8

def html_doc
  @html_doc
end

#lineObject

Returns the value of attribute line.



9
10
11
# File 'lib/metra/parser.rb', line 9

def line
  @line
end

#tablesObject (readonly)

Returns the value of attribute tables.



8
9
10
# File 'lib/metra/parser.rb', line 8

def tables
  @tables
end

#trainsObject (readonly)

Returns the value of attribute trains.



8
9
10
# File 'lib/metra/parser.rb', line 8

def trains
  @trains
end

Instance Method Details

#am_or_pm(node) ⇒ Object



80
81
82
83
84
# File 'lib/metra/parser.rb', line 80

def am_or_pm(node)
  klass = node.attributes["class"].value
  return 'AM' if klass == 'am'
  return 'PM' if klass == 'pm'
end

#find_bike_count(table, count) ⇒ Object



91
92
93
94
95
96
97
98
# File 'lib/metra/parser.rb', line 91

def find_bike_count(table, count)
  num = table.xpath("thead/tr[3]/td[#{count}]").text.to_i
  if num == 0
    nil
  else
    num
  end
end

#find_stops(table, count, direction) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/metra/parser.rb', line 100

def find_stops(table, count, direction)
  stops = []
  1.upto(stop_count(table)).each do |stop_count|
    stop = make_stop(table.xpath("tbody[#{stop_count}]/tr/td[#{count}]")[0], stop_count - 1, direction)
    stops.push stop if stop
  end
  stops
end

#find_train_num(table, count) ⇒ Object



86
87
88
89
# File 'lib/metra/parser.rb', line 86

def find_train_num(table, count)
  text = table.xpath("thead/tr/th[#{count+1}]").text
  text.slice(0..-3).to_i #Chop off the AM/PM in the table
end

#make_stop(node, station_num, direction) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/metra/parser.rb', line 67

def make_stop(node, station_num, direction)
  node_text = node.text
  node_text = node_text[0..-2] if node_text[-1] == "x"
  return nil if node_text == "– "
  time = Time.parse(node_text + am_or_pm(node))
  if direction == :inbound
    station = @line[:stations].reverse[station_num]
  else
    station = @line[:stations][station_num]
  end
  MetraSchedule::Stop.new :station => station, :time => time
end

#make_trainsObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/metra/parser.rb', line 44

def make_trains
  @trains = []
  @tables.each do |t|
    t[:tables].each do |table|
      1.upto(train_count(table)).each do |count|
        new_train = MetraSchedule::Train.new :direction => t[:direction], \
          :schedule => t[:schedule], :stops => find_stops(table, count, t[:direction]), \
          :train_num => find_train_num(table, count), :bike_limit => find_bike_count(table, count)
        @trains.push(new_train)
      end
    end
  end
  @trains
end

#parse_nokogiriObject



21
22
23
24
25
# File 'lib/metra/parser.rb', line 21

def parse_nokogiri
  html_doc = open(@html_doc) if @html_doc.is_a?(String)
  html_doc = @html_doc if @html_doc.is_a?(File)
  @html_doc = Nokogiri::HTML(html_doc)
end

#sanitize(input) ⇒ Object



109
110
111
112
# File 'lib/metra/parser.rb', line 109

def sanitize(input)
  input.delete_at(0) if input.is_a?(Array)
  input
end

#scrapeObject



15
16
17
18
19
# File 'lib/metra/parser.rb', line 15

def scrape
  parse_nokogiri
  seperate_tables
  make_trains
end

#seperate_tablesObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/metra/parser.rb', line 27

def seperate_tables
  tables = @html_doc.css('table.schedule')
  @tables = []
  @tables.push ({:schedule => :weekday, :direction => :inbound, :tables => [tables[@line[:tables][:weekday_inbound]]].flatten}) \
    if @line[:tables].has_key?(:weekday_inbound)
  @tables.push ({:schedule => :saturday, :direction => :inbound, :tables => [tables[@line[:tables][:saturday_inbound]]].flatten}) \
    if @line[:tables].has_key?(:saturday_inbound)
  @tables.push ({:schedule => :sunday, :direction => :inbound, :tables => [tables[@line[:tables][:sunday_inbound]]].flatten}) \
    if @line[:tables].has_key?(:sunday_inbound)
  @tables.push ({:schedule => :weekday, :direction => :outbound, :tables => [tables[@line[:tables][:weekday_outbound]]].flatten}) \
    if @line[:tables].has_key?(:weekday_outbound)
  @tables.push ({:schedule => :saturday, :direction => :outbound, :tables => [tables[@line[:tables][:saturday_outbound]]].flatten}) \
    if @line[:tables].has_key?(:saturday_outbound)
  @tables.push ({:schedule => :sunday, :direction => :outbound, :tables => [tables[@line[:tables][:sunday_outbound]]].flatten}) \
    if @line[:tables].has_key?(:sunday_outbound)
end

#stop_count(table) ⇒ Object



63
64
65
# File 'lib/metra/parser.rb', line 63

def stop_count(table)
  table.xpath('tbody').count
end

#train_count(table) ⇒ Object



59
60
61
# File 'lib/metra/parser.rb', line 59

def train_count(table)
  table.xpath('thead/tr[1]/th').count - 1
end