Class: OrcaCard

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

Overview

Prints out information about your ORCA card.

Defined Under Namespace

Classes: Error

Constant Summary collapse

VERSION =

Version of OrcaCard you are using

'1.0'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ OrcaCard

Creates a new OrcaCard object from options



62
63
64
65
# File 'lib/orca_card.rb', line 62

def initialize(options)
  @username = options[:Username]
  @password = options[:Password]
end

Class Method Details

.process_args(args) ⇒ Object

Processes args and returns an options Hash.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/orca_card.rb', line 23

def self.process_args(args)
  options = {}

  opts = OptionParser.new do |opts|
    opts.program_name = File.basename $0
    opts.banner = "Usage: #{opts.program_name} [options]\n\n"

    opts.on('-u', '--username=USERNAME',
            'ORCA card username') do |username|
      options[:Username] = username
            end

    opts.on('-p', '--password=PASSWORD',
            'ORCA card account password') do |password|
      options[:Password] = password
            end
  end

  opts.parse! args

  if options[:Username].nil? or options[:Password].nil? then
    $stderr.puts opts
    $stderr.puts
    $stderr.puts "username or password not set"
    exit 1
  end

  options
end

.run(args = ARGV) ⇒ Object



53
54
55
56
57
# File 'lib/orca_card.rb', line 53

def self.run(args = ARGV)
  options = process_args args
  orca_card = new options
  orca_card.run
end

Instance Method Details

#cardsObject

Returns links to card pages owned by the current account

Raises:



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/orca_card.rb', line 70

def cards
  agent = WWW::Mechanize.new
   = agent.get "https://www.orcacard.com/ERG-Seattle/p7_002ad.do?m=52"

  cards = .form_with :name => 'loginform' do |form|
    form.j_username = @username
    form.j_password = @password
  end.submit

  raise Error, $& if cards.title =~ /Authorization failed/

  cards.links_with(:text => /\d{8}/)
end

#runObject

Logs in, finds cards for this account and prints them on the screen



87
88
89
90
91
# File 'lib/orca_card.rb', line 87

def run
  cards.each do |card|
    view_card card
  end
end

#view_card(card) ⇒ Object

Prints information about the card for link card



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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
# File 'lib/orca_card.rb', line 96

def view_card(card)
  card_id = card.text

  card = card.click

  passenger_type = nil
  vehicle_type = nil

  card.root.xpath('//p/strong[@class="important"]').each do |strong|
    text = strong.text.gsub(/[\r\n\t\302\240]+/u, ' ')
    next unless text =~ /Passenger Type: (.*?) Vehicle Type: (.*)/

    passenger_type = $1.downcase
    vehicle_type = $2.strip.downcase
  end

  balance = nil
  active = nil

  card.root.xpath('//table/tbody/tr/td').each do |td|
    if element = td.xpath('.//strong[text()="Amount:"]').first then
      td.text =~ /\$([\d.]+)/
      balance = $1.to_f
    elsif element = td.xpath('.//strong[text()="Status:"]').first then
      td.text =~ /Status: (.*)/
      active = $1.downcase
    end
  end

  if vehicle_type == 'none' then
    puts "Card %s for %s" % [card_id, passenger_type]
  else
    puts "Card %s for %s, vehicle %s" % [
      card_id, passenger_type, vehicle_type
    ]
  end
  puts "E-purse %s, balance $%0.2f" % [active, balance]
  puts

  history = card.links_with(:text => 'View Transaction History').first.click

  data = history.search '#resultTable'

  puts "History:"
  data.search('tr').each do |row|
    cells = row.search('td').map do |cell| cell.text.strip end

    next if cells.empty?

    time, desc, location, product, txn, balance, method = cells

    txn = txn.to_f.abs
    balance = balance.to_f.abs

    location = case location
               when /KCM-BUS-(\d+)/ then
                 bus = $1.to_i
             "KC Metro"
               when /ORCA Cardholder website/ then
             "ORCA website"
               else
                 raise "unknown location %p" % location
               end

    case desc
    when /Purse Use Journey, / then
      journey = $'

      journey = case journey
                when /Route (\d+)/ then
                  route = $1.to_i
              "Route %3d" % route
                else
                  raise "unknown journey %p" % journey
                end

      if txn.zero? then
        puts "%s %s %s transfer" % [time, location, journey]
      else
        puts "%s %s %s fare $%0.2f (balance $%0.2f)" % [
          time, location, journey, txn, balance
        ]
      end
    when /Enable Product / then
      puts "%s Enabled %s" % [time, $']
    when /Add Purse Value/ then
      puts "%s Added purse value %0.2f to card" % [time, balance]
    when /Purse Add Remote, / then
      puts "%s Added purse value %0.2f to account, %s" % [time, txn, $']
    else
      raise "unknown description %p" % desc
    end
  end
end