orca_card 1.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.
- data.tar.gz.sig +2 -0
- data/.autotest +23 -0
- data/History.txt +6 -0
- data/Manifest.txt +7 -0
- data/README.txt +65 -0
- data/Rakefile +15 -0
- data/bin/orca_card +6 -0
- data/lib/orca_card.rb +192 -0
- metadata +108 -0
- metadata.gz.sig +2 -0
data.tar.gz.sig
ADDED
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
= orca_card
|
2
|
+
|
3
|
+
* http://seattlerb.rubyforge.org/orca_card
|
4
|
+
* http://orcacard.com
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
Dumps information about your ORCA card. ORCA cards are Western Washington's
|
9
|
+
all-in-one transit smart card that allow travel via bus, train and ferry
|
10
|
+
throughout King, Kitsap, Snohomish and Pierce counties.
|
11
|
+
|
12
|
+
== FEATURES/PROBLEMS:
|
13
|
+
|
14
|
+
* Cheap hack
|
15
|
+
* No API
|
16
|
+
|
17
|
+
== SYNOPSIS:
|
18
|
+
|
19
|
+
$ orca_card -u username -p passwsord
|
20
|
+
Card 12345678 for adult
|
21
|
+
E-purse active, balance $XX.75
|
22
|
+
|
23
|
+
History:
|
24
|
+
mm/dd/2009 HH:MM PM KC Metro Route RRR fare $1.75 (balance $XX.75)
|
25
|
+
mm/dd/2009 HH:MM PM KC Metro Route RRR fare $1.75 (balance $XX.50)
|
26
|
+
mm/dd/2009 HH:MM PM KC Metro Route RRR fare $2.00 (balance $XX.25)
|
27
|
+
mm/dd/2009 HH:MM PM KC Metro Route RRR transfer
|
28
|
+
mm/dd/2009 HH:MM PM KC Metro Route RRR fare $1.75 (balance $XX.25)
|
29
|
+
mm/dd/2009 HH:MM PM Enabled Autoload, Receipt XXXXXXX
|
30
|
+
mm/dd/2009 HH:MM PM Added purse value XX.00 to card
|
31
|
+
mm/dd/2009 HH:MM PM Added purse value XX.00 to account, Receipt XXXXXXX
|
32
|
+
|
33
|
+
== REQUIREMENTS:
|
34
|
+
|
35
|
+
* An ORCA card tied to an account
|
36
|
+
* An internet connection
|
37
|
+
|
38
|
+
== INSTALL:
|
39
|
+
|
40
|
+
* gem install orca_card
|
41
|
+
|
42
|
+
== LICENSE:
|
43
|
+
|
44
|
+
(The MIT License)
|
45
|
+
|
46
|
+
Copyright (c) 2009 Eric Hodel
|
47
|
+
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
49
|
+
a copy of this software and associated documentation files (the
|
50
|
+
'Software'), to deal in the Software without restriction, including
|
51
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
52
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
53
|
+
permit persons to whom the Software is furnished to do so, subject to
|
54
|
+
the following conditions:
|
55
|
+
|
56
|
+
The above copyright notice and this permission notice shall be
|
57
|
+
included in all copies or substantial portions of the Software.
|
58
|
+
|
59
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
60
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
61
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
62
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
63
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
64
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
65
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
$:.unshift 'lib'
|
6
|
+
require 'orca_card'
|
7
|
+
|
8
|
+
Hoe.new('orca_card', OrcaCard::VERSION) do |oc|
|
9
|
+
oc.rubyforge_name = 'seattlerb'
|
10
|
+
oc.developer('Eric Hodel', 'drbrain@segment7.net')
|
11
|
+
|
12
|
+
oc.extra_deps << ['mechanize', '~> 0.9']
|
13
|
+
end
|
14
|
+
|
15
|
+
# vim: syntax=Ruby
|
data/bin/orca_card
ADDED
data/lib/orca_card.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mechanize'
|
3
|
+
|
4
|
+
##
|
5
|
+
# Prints out information about your {ORCA card}[http://orcacard.com].
|
6
|
+
|
7
|
+
class OrcaCard
|
8
|
+
|
9
|
+
##
|
10
|
+
# Version of OrcaCard you are using
|
11
|
+
|
12
|
+
VERSION = '1.0'
|
13
|
+
|
14
|
+
##
|
15
|
+
# OrcaCard Error class
|
16
|
+
|
17
|
+
class Error < RuntimeError
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Processes +args+ and returns an options Hash.
|
22
|
+
|
23
|
+
def self.process_args(args)
|
24
|
+
options = {}
|
25
|
+
|
26
|
+
opts = OptionParser.new do |opts|
|
27
|
+
opts.program_name = File.basename $0
|
28
|
+
opts.banner = "Usage: #{opts.program_name} [options]\n\n"
|
29
|
+
|
30
|
+
opts.on('-u', '--username=USERNAME',
|
31
|
+
'ORCA card username') do |username|
|
32
|
+
options[:Username] = username
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('-p', '--password=PASSWORD',
|
36
|
+
'ORCA card account password') do |password|
|
37
|
+
options[:Password] = password
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.parse! args
|
42
|
+
|
43
|
+
if options[:Username].nil? or options[:Password].nil? then
|
44
|
+
$stderr.puts opts
|
45
|
+
$stderr.puts
|
46
|
+
$stderr.puts "username or password not set"
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
|
50
|
+
options
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.run(args = ARGV)
|
54
|
+
options = process_args args
|
55
|
+
orca_card = new options
|
56
|
+
orca_card.run
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Creates a new OrcaCard object from +options+
|
61
|
+
|
62
|
+
def initialize(options)
|
63
|
+
@username = options[:Username]
|
64
|
+
@password = options[:Password]
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Returns links to card pages owned by the current account
|
69
|
+
|
70
|
+
def cards
|
71
|
+
agent = WWW::Mechanize.new
|
72
|
+
login = agent.get "https://www.orcacard.com/ERG-Seattle/p7_002ad.do?m=52"
|
73
|
+
|
74
|
+
cards = login.form_with :name => 'loginform' do |form|
|
75
|
+
form.j_username = @username
|
76
|
+
form.j_password = @password
|
77
|
+
end.submit
|
78
|
+
|
79
|
+
raise Error, $& if cards.title =~ /Authorization failed/
|
80
|
+
|
81
|
+
cards.links_with(:text => /\d{8}/)
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Logs in, finds cards for this account and prints them on the screen
|
86
|
+
|
87
|
+
def run
|
88
|
+
cards.each do |card|
|
89
|
+
view_card card
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Prints information about the card for link +card+
|
95
|
+
|
96
|
+
def view_card(card)
|
97
|
+
card_id = card.text
|
98
|
+
|
99
|
+
card = card.click
|
100
|
+
|
101
|
+
passenger_type = nil
|
102
|
+
vehicle_type = nil
|
103
|
+
|
104
|
+
card.root.xpath('//p/strong[@class="important"]').each do |strong|
|
105
|
+
text = strong.text.gsub(/[\r\n\t\302\240]+/u, ' ')
|
106
|
+
next unless text =~ /Passenger Type: (.*?) Vehicle Type: (.*)/
|
107
|
+
|
108
|
+
passenger_type = $1.downcase
|
109
|
+
vehicle_type = $2.strip.downcase
|
110
|
+
end
|
111
|
+
|
112
|
+
balance = nil
|
113
|
+
active = nil
|
114
|
+
|
115
|
+
card.root.xpath('//table/tbody/tr/td').each do |td|
|
116
|
+
if element = td.xpath('.//strong[text()="Amount:"]').first then
|
117
|
+
td.text =~ /\$([\d.]+)/
|
118
|
+
balance = $1.to_f
|
119
|
+
elsif element = td.xpath('.//strong[text()="Status:"]').first then
|
120
|
+
td.text =~ /Status: (.*)/
|
121
|
+
active = $1.downcase
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if vehicle_type == 'none' then
|
126
|
+
puts "Card %s for %s" % [card_id, passenger_type]
|
127
|
+
else
|
128
|
+
puts "Card %s for %s, vehicle %s" % [
|
129
|
+
card_id, passenger_type, vehicle_type
|
130
|
+
]
|
131
|
+
end
|
132
|
+
puts "E-purse %s, balance $%0.2f" % [active, balance]
|
133
|
+
puts
|
134
|
+
|
135
|
+
history = card.links_with(:text => 'View Transaction History').first.click
|
136
|
+
|
137
|
+
data = history.search '#resultTable'
|
138
|
+
|
139
|
+
puts "History:"
|
140
|
+
data.search('tr').each do |row|
|
141
|
+
cells = row.search('td').map do |cell| cell.text.strip end
|
142
|
+
|
143
|
+
next if cells.empty?
|
144
|
+
|
145
|
+
time, desc, location, product, txn, balance, method = cells
|
146
|
+
|
147
|
+
txn = txn.to_f.abs
|
148
|
+
balance = balance.to_f.abs
|
149
|
+
|
150
|
+
location = case location
|
151
|
+
when /KCM-BUS-(\d+)/ then
|
152
|
+
bus = $1.to_i
|
153
|
+
"KC Metro"
|
154
|
+
when /ORCA Cardholder website/ then
|
155
|
+
"ORCA website"
|
156
|
+
else
|
157
|
+
raise "unknown location %p" % location
|
158
|
+
end
|
159
|
+
|
160
|
+
case desc
|
161
|
+
when /Purse Use Journey, / then
|
162
|
+
journey = $'
|
163
|
+
|
164
|
+
journey = case journey
|
165
|
+
when /Route (\d+)/ then
|
166
|
+
route = $1.to_i
|
167
|
+
"Route %3d" % route
|
168
|
+
else
|
169
|
+
raise "unknown journey %p" % journey
|
170
|
+
end
|
171
|
+
|
172
|
+
if txn.zero? then
|
173
|
+
puts "%s %s %s transfer" % [time, location, journey]
|
174
|
+
else
|
175
|
+
puts "%s %s %s fare $%0.2f (balance $%0.2f)" % [
|
176
|
+
time, location, journey, txn, balance
|
177
|
+
]
|
178
|
+
end
|
179
|
+
when /Enable Product / then
|
180
|
+
puts "%s Enabled %s" % [time, $']
|
181
|
+
when /Add Purse Value/ then
|
182
|
+
puts "%s Added purse value %0.2f to card" % [time, balance]
|
183
|
+
when /Purse Add Remote, / then
|
184
|
+
puts "%s Added purse value %0.2f to account, %s" % [time, txn, $']
|
185
|
+
else
|
186
|
+
raise "unknown description %p" % desc
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: orca_card
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.0"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Hodel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy
|
14
|
+
YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu
|
15
|
+
ZXQwHhcNMDcxMjIxMDIwNDE0WhcNMDgxMjIwMDIwNDE0WjBBMRAwDgYDVQQDDAdk
|
16
|
+
cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ
|
17
|
+
FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76
|
18
|
+
LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J
|
19
|
+
U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm
|
20
|
+
Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY
|
21
|
+
mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd
|
22
|
+
g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh
|
23
|
+
sCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
24
|
+
BBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAHagT4lfX
|
25
|
+
kP/hDaiwGct7XPuVGbrOsKRVD59FF5kETBxEc9UQ1clKWngf8JoVuEoKD774dW19
|
26
|
+
bU0GOVWO+J6FMmT/Cp7nuFJ79egMf/gy4gfUfQMuvfcr6DvZUPIs9P/TlK59iMYF
|
27
|
+
DIOQ3DxdF3rMzztNUCizN4taVscEsjCcgW6WkUJnGdqlu3OHWpQxZBJkBTjPCoc6
|
28
|
+
UW6on70SFPmAy/5Cq0OJNGEWBfgD9q7rrs/X8GGwUWqXb85RXnUVi/P8Up75E0ag
|
29
|
+
14jEc90kN+C7oI/AGCBN0j6JnEtYIEJZibjjDJTSMWlUKKkj30kq7hlUC2CepJ4v
|
30
|
+
x52qPcexcYZR7w==
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
|
33
|
+
date: 2009-05-19 00:00:00 -07:00
|
34
|
+
default_executable:
|
35
|
+
dependencies:
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: mechanize
|
38
|
+
type: :runtime
|
39
|
+
version_requirement:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0.9"
|
45
|
+
version:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: hoe
|
48
|
+
type: :development
|
49
|
+
version_requirement:
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.12.1
|
55
|
+
version:
|
56
|
+
description: |-
|
57
|
+
Dumps information about your ORCA card. ORCA cards are Western Washington's
|
58
|
+
all-in-one transit smart card that allow travel via bus, train and ferry
|
59
|
+
throughout King, Kitsap, Snohomish and Pierce counties.
|
60
|
+
email:
|
61
|
+
- drbrain@segment7.net
|
62
|
+
executables:
|
63
|
+
- orca_card
|
64
|
+
extensions: []
|
65
|
+
|
66
|
+
extra_rdoc_files:
|
67
|
+
- History.txt
|
68
|
+
- Manifest.txt
|
69
|
+
- README.txt
|
70
|
+
files:
|
71
|
+
- .autotest
|
72
|
+
- History.txt
|
73
|
+
- Manifest.txt
|
74
|
+
- README.txt
|
75
|
+
- Rakefile
|
76
|
+
- bin/orca_card
|
77
|
+
- lib/orca_card.rb
|
78
|
+
has_rdoc: true
|
79
|
+
homepage: http://seattlerb.rubyforge.org/orca_card
|
80
|
+
licenses: []
|
81
|
+
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options:
|
84
|
+
- --main
|
85
|
+
- README.txt
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: "0"
|
93
|
+
version:
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "0"
|
99
|
+
version:
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project: seattlerb
|
103
|
+
rubygems_version: 1.3.3
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: Dumps information about your ORCA card
|
107
|
+
test_files: []
|
108
|
+
|
metadata.gz.sig
ADDED