bart_waiting_list 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a0ddc96388c11f08156aba995fd2f5851fa2491e
4
+ data.tar.gz: d3bca95f79402f30ed4dd92bbe37fefc13eeef86
5
+ SHA512:
6
+ metadata.gz: f0f0b61b00eddcb6a794a206b5b94b744d550138e88c6e18462b8b9cd027cb64790d8ee5b0965316ae88cc6949535102f52443fe1b08cedbc270a3896c7e843c
7
+ data.tar.gz: 55892a49e7d84b3fd5206201b938f2d2fd25ac8d8a496a05feb9c78157e0f61eab05e6a5fdcb74a32116b39cb607b71e7d7b4b041bb4120ba209c0b7b28b59d1
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bart_waiting_list.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Brian O'Keefe
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # BartWaitingList
2
+
3
+ Retrieves your BART parking waiting list position from select-a-spot.com
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'bart_waiting_list'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install bart_waiting_list
18
+
19
+ ## Usage
20
+
21
+ require 'bart_waiting_list'
22
+
23
+ # log in with your select-a-spot.com username and password
24
+ waiting_list = BartWaitingList.new 'email@example.com', 'my-password'
25
+
26
+ # get your position for a station, a Fixnum
27
+ position = waiting_list.get_waiting_list_position :fruitvale
28
+
29
+ ### Available stations
30
+
31
+ :ashby
32
+ :bay_fair
33
+ :castro_valley
34
+ :coliseum_oakland_airport
35
+ :colma
36
+ :concord
37
+ :daly_city
38
+ :dublin_pleasanton
39
+ :el_cerrito_del_norte
40
+ :el_cerrito_plaza
41
+ :fremont
42
+ :fruitvale
43
+ :hayward
44
+ :lafayette
45
+ :lake_merritt
46
+ :macarthur
47
+ :millbrae
48
+ :north_berkeley
49
+ :north_concord_martinez
50
+ :orinda
51
+ :pittsburg_bay_point
52
+ :pleasant_hill_contra_costa_centre
53
+ :richmond
54
+ :rockridge
55
+ :san_bruno
56
+ :san_leandro
57
+ :south_hayward
58
+ :south_san_francisco
59
+ :union_city
60
+ :walnut_creek
61
+ :west_dublin_dublin
62
+ :west_dublin_pleasanton
63
+
64
+ ## Contributing
65
+
66
+ 1. Fork it ( https://github.com/brianokeefe/bart_waiting_list/fork )
67
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
68
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
69
+ 4. Push to the branch (`git push origin my-new-feature`)
70
+ 5. Create a new Pull Request
71
+
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'bart_waiting_list'
7
+ spec.version = '0.0.1'
8
+ spec.authors = ["Brian O'Keefe"]
9
+ spec.email = ['brian@bokstuff.com']
10
+ spec.summary = %q{Get data from the BART select-a-spot waiting list page}
11
+ spec.description = spec.summary
12
+ spec.homepage = 'https://github.com/brianokeefe/bart_waiting_list'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'mechanize', '~> 2.7.3'
21
+ spec.add_development_dependency 'bundler', '~> 1.6'
22
+ spec.add_development_dependency 'webmock', '~> 1.20.4'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'rspec', '~> 3.1'
25
+ end
@@ -0,0 +1,24 @@
1
+ <html>
2
+
3
+ <head>
4
+ <title>BART</title>
5
+ </head>
6
+
7
+ <body id="home">
8
+ <div id="container">
9
+ <form action="/bart/users/login/" method="post" id="site-login">
10
+ <div style='display:none'>
11
+ <input type='hidden' name='csrfmiddlewaretoken' value='fake-value' />
12
+ </div>
13
+ <div>
14
+ <input class="input" type="text" name="username" id="username" placeholder="Username">
15
+ <input class="input" type="password" name="password" id="password" placeholder="Password">
16
+ </div>
17
+ <div>
18
+ <input class="input" id="submit" type="submit" name="login" value="Login" />
19
+ </div>
20
+ </form>
21
+ </div>
22
+ </body>
23
+
24
+ </html>
@@ -0,0 +1 @@
1
+ <p>You are currently at <span class="bold">position 113</span> on the waiting list for <span class="bold">Monthly Reserved</span> at <span class="bold">Fruitvale Station</span>.</p>
@@ -0,0 +1,89 @@
1
+ require 'mechanize'
2
+
3
+ HOME_URL = 'https://www.select-a-spot.com/bart/'
4
+ WAITING_LIST_URL = 'https://www.select-a-spot.com/bart/waiting_lists/'
5
+
6
+ class BartWaitingList
7
+
8
+ attr_reader :page
9
+
10
+ def initialize(email, password)
11
+ @page = get_waiting_list_page(email, password)
12
+ end
13
+
14
+ def get_waiting_list_position(station)
15
+ station_name = get_station_name station
16
+
17
+ /currently at <span class="bold">position (\d+)<\/span> on the waiting list for <span class="bold">Monthly Reserved<\/span> at <span class="bold">#{station_name}<\/span>/.match @page
18
+
19
+ if $1.nil?
20
+ $1
21
+ else
22
+ $1.to_i
23
+ end
24
+ end
25
+
26
+ private
27
+ def get_waiting_list_page(email, password)
28
+ # mechanize agent
29
+ # http://stackoverflow.com/questions/6918277/ruby-mechanize-web-scraper-library-returns-file-instead-of-page
30
+ agent = Mechanize.new do |a|
31
+ a.post_connect_hooks << lambda do |_,_,response,_|
32
+ if response.content_type.nil? || response.content_type.empty?
33
+ response.content_type = 'text/html'
34
+ end
35
+ end
36
+ end
37
+
38
+ # fetch the home page
39
+ page = agent.get HOME_URL
40
+
41
+ # get the login form
42
+ form = page.form
43
+
44
+ # submit login form
45
+ form.username email
46
+ form.password password
47
+ form.submit
48
+
49
+ # now that we're logged in, return the waiting list page
50
+ agent.get(WAITING_LIST_URL).body
51
+ end
52
+
53
+ def get_station_name(station)
54
+ {
55
+ :ashby => 'Ashby Station',
56
+ :bay_fair => 'Bay Fair Station',
57
+ :castro_valley => 'Castro Valley Station',
58
+ :coliseum_oakland_airport => 'Coliseum/Oakland Airport Station',
59
+ :colma => 'Colma Station',
60
+ :concord => 'Concord Station',
61
+ :daly_city => 'Daly City Station',
62
+ :dublin_pleasanton => 'Dublin/Pleasanton Station',
63
+ :el_cerrito_del_norte => 'El Cerrito del Norte Station',
64
+ :el_cerrito_plaza => 'El Cerrito Plaza Station',
65
+ :fremont => 'Fremont Station',
66
+ :fruitvale => 'Fruitvale Station',
67
+ :hayward => 'Hayward Station',
68
+ :lafayette => 'Lafayette Station',
69
+ :lake_merritt => 'Lake Merritt Station',
70
+ :macarthur => 'MacArthur Station',
71
+ :millbrae => 'Millbrae Station',
72
+ :north_berkeley => 'North Berkeley Station',
73
+ :north_concord_martinez => 'North Concord/Martinez Station',
74
+ :orinda => 'Orinda Station',
75
+ :pittsburg_bay_point => 'Pittsburg/Bay Point Station',
76
+ :pleasant_hill_contra_costa_centre => 'Pleasant Hill/Contra Costa Centre Station',
77
+ :richmond => 'Richmond Station',
78
+ :rockridge => 'Rockridge Station',
79
+ :san_bruno => 'San Bruno Station',
80
+ :san_leandro => 'San Leandro Station',
81
+ :south_hayward => 'South Hayward Station',
82
+ :south_san_francisco => 'South San Francisco Station',
83
+ :union_city => 'Union City Station',
84
+ :walnut_creek => 'Walnut Creek Station',
85
+ :west_dublin_dublin => 'West Dublin Station - Dublin',
86
+ :west_dublin_pleasanton => 'West Dublin Station - Pleasanton'
87
+ }[station]
88
+ end
89
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe BartWaitingList do
4
+ subject { BartWaitingList.new 'test@example.com', 'password' }
5
+
6
+ describe '#new' do
7
+ it 'should return a BartWaitingList object' do
8
+ expect(subject).to be_an_instance_of BartWaitingList
9
+ end
10
+
11
+ it 'should contain the source for the waiting list page' do
12
+ expect(subject.page).to be_an_instance_of String
13
+ end
14
+ end
15
+
16
+ describe '#get_waiting_list_position' do
17
+ it 'should return Fixnum if successful' do
18
+ expect(subject.get_waiting_list_position(:fruitvale)).to be_an_instance_of Fixnum
19
+ end
20
+
21
+ it 'should parse the result and get the correct position' do
22
+ expect(subject.get_waiting_list_position(:fruitvale)).to eq 113
23
+ end
24
+
25
+ it 'should return nil if invalid' do
26
+ expect(subject.get_waiting_list_position(:montgomery)).to be_nil
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,18 @@
1
+ require 'bart_waiting_list'
2
+ require 'webmock/rspec'
3
+
4
+ WebMock.disable_net_connect!
5
+
6
+ RSpec.configure do |config|
7
+ config.before :each do
8
+ stub_request(:get, 'https://www.select-a-spot.com/bart/').
9
+ to_return :status => 200, :body => File.read('fixtures/mock_home_page.html')
10
+
11
+ stub_request(:post, 'https://www.select-a-spot.com/bart/users/login/').
12
+ to_return :status => 200, :body => 'it worked'
13
+
14
+ stub_request(:get, 'https://www.select-a-spot.com/bart/waiting_lists/').
15
+ to_return :status => 200, :body => File.read('fixtures/mock_waiting_list_page.html')
16
+ end
17
+ end
18
+
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bart_waiting_list
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Brian O'Keefe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mechanize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.7.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.7.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: webmock
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.20.4
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.20.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.1'
83
+ description: Get data from the BART select-a-spot waiting list page
84
+ email:
85
+ - brian@bokstuff.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - bart_waiting_list.gemspec
96
+ - fixtures/mock_home_page.html
97
+ - fixtures/mock_waiting_list_page.html
98
+ - lib/bart_waiting_list.rb
99
+ - spec/bart_waiting_list_spec.rb
100
+ - spec/spec_helper.rb
101
+ homepage: https://github.com/brianokeefe/bart_waiting_list
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.4.5
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Get data from the BART select-a-spot waiting list page
125
+ test_files:
126
+ - spec/bart_waiting_list_spec.rb
127
+ - spec/spec_helper.rb