autostats 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +24 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +71 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/autostats.gemspec +73 -0
- data/lib/autostats.rb +7 -0
- data/lib/car.rb +234 -0
- data/lib/trim.rb +67 -0
- data/test/helper.rb +18 -0
- data/test/test_autostats.rb +7 -0
- metadata +152 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
gem "progressbar"
|
7
|
+
gem "nokogiri"
|
8
|
+
# Add dependencies to develop your gem here.
|
9
|
+
# Include everything needed to run rake, tests, features, etc.
|
10
|
+
group :development do
|
11
|
+
gem "shoulda", ">= 0"
|
12
|
+
gem "bundler", "~> 1.0.0"
|
13
|
+
gem "jeweler", "~> 1.6.4"
|
14
|
+
gem "rcov", ">= 0"
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
jeweler (1.6.4)
|
6
|
+
bundler (~> 1.0)
|
7
|
+
git (>= 1.2.5)
|
8
|
+
rake
|
9
|
+
nokogiri (1.5.0)
|
10
|
+
progressbar (0.9.2)
|
11
|
+
rake (0.9.2.2)
|
12
|
+
rcov (0.9.11)
|
13
|
+
shoulda (2.11.3)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
bundler (~> 1.0.0)
|
20
|
+
jeweler (~> 1.6.4)
|
21
|
+
nokogiri
|
22
|
+
progressbar
|
23
|
+
rcov
|
24
|
+
shoulda
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Conner Wingard
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
= autostats
|
2
|
+
|
3
|
+
Autostats is a simple gem that can be used to easily get a long list of information about a car, from aol autos. Create a car object like so:
|
4
|
+
car = Car.new("2012","Ford","Mustang").
|
5
|
+
Since cars come in a variety of trim packages and variations, the car object has an array of trims composed of all its statistics. As an example, you could get the engine
|
6
|
+
information of the first trim of a car like this:
|
7
|
+
car.trims[0].engine
|
8
|
+
|
9
|
+
Example Use:
|
10
|
+
|
11
|
+
ruby-1.9.2-p290 :001 > require 'autostats'
|
12
|
+
=> true
|
13
|
+
ruby-1.9.2-p290 :002 > car = Car.new("2012","Ford","Mustang")
|
14
|
+
Getting specs: 100% |oooooooooooooooooooooooooooooooooooooooooo| Time: 00:00:00
|
15
|
+
=> #<Car:0x007fb95b2b0590 @make="Ford", @model="Mustang", @model_year="2012", @base_url="http://autos.aol.com/cars-Ford-Mustang-2012", @overview_url="http://autos.aol.com/cars-Ford-Mustang-2012/overview", @trims_url="http://autos.aol.com/cars-Ford-Mustang-2012/available-trims/", @specs_url="http://autos.aol.com/cars-Ford-Mustang-2012/specs", @mpg_url="http://autos.aol.com/cars-Ford-Mustang-2012/specs/mpg", @trims=[V6 2dr Coupe, V6 Premium 2dr Coupe, GT 2dr
|
16
|
+
Coupe, GT Premium 2dr Coupe, Boss 302 2dr Coupe, V6 2dr Convertible, V6 Premium 2dr Convertible, GT 2dr Convertible, GT Premium 2dr Convertible], @overview="\n\t\t\t\tThe Mustang
|
17
|
+
remains one of the most widely recognized, respected and desired nameplates in the automobile business. It may be retro inspired, but the Mustang is a thoroughly modern car. Today's
|
18
|
+
Mustang still delivers the bold styling, rear-drive performance and affordability that have been Mustang hallmarks for decades.\n\t\t\t\t\tThe Mustang is available either as a coupe or
|
19
|
+
convertible. Each is available with a 305-hp 3.7-liter V6 or a 412-hp 5.0-liter V8 engine. A six-speed manual transmission is standard; a six-speed automatic is optional. A 302 Boss or
|
20
|
+
Laguna Seca coupe with a 444-hp 5.0-liter V8 with six-speed manual is also available. Standard safety features include electronic stability control, traction control, four-wheel
|
21
|
+
anti-lock disc brakes, side-impact airbags and LED sequential tail lamps. The Mustang can be equipped with alloy wheels, automatic headlights, heated power leather seats, satellite
|
22
|
+
radio, navigation system and more.\n\t\t\t\t\tThe big news for 2012 is the addition of the Boss 302 and Laguna Seca - both with a revised version of the five-liter that revs higher and
|
23
|
+
has more horsepower than the GT.\n\t\t\t\t\t">
|
24
|
+
ruby-1.9.2-p290 :003 > car.trims[0].available_stats
|
25
|
+
performance.base_engine_type
|
26
|
+
performance.horsepower
|
27
|
+
performance.horsepower_rpm
|
28
|
+
performance.torque
|
29
|
+
performance.torque_rpm
|
30
|
+
performance.maximum_towing_capacity
|
31
|
+
performance.drive_type
|
32
|
+
performance.turning_radius
|
33
|
+
interior.rear_head_room
|
34
|
+
interior.front_shoulder_room
|
35
|
+
interior.rear_shoulder_room
|
36
|
+
interior.front_hip_room
|
37
|
+
interior.rear_hip_room
|
38
|
+
interior.front_leg_room
|
39
|
+
interior.rear_leg_room
|
40
|
+
interior.luggage_capacity
|
41
|
+
interior.maximum_cargo_capacity
|
42
|
+
interior.standard_seating
|
43
|
+
exterior.length
|
44
|
+
exterior.body_width
|
45
|
+
exterior.body_height
|
46
|
+
exterior.wheelbase
|
47
|
+
exterior.curb
|
48
|
+
fuel_economy.fuel_tank_capacity
|
49
|
+
fuel_economy.epa_mileage_estimates
|
50
|
+
=> [:fuel_tank_capacity, :epa_mileage_estimates]
|
51
|
+
ruby-1.9.2-p290 :004 > car.trims[0].engine
|
52
|
+
V-6 - with 305 hp at 6,500rpm and 280 lb-ft. of torque at 4,250rpm
|
53
|
+
=> nil
|
54
|
+
ruby-1.9.2-p290 :005 > car.trims[0].mpg_combined
|
55
|
+
=> 24
|
56
|
+
|
57
|
+
== Contributing to autostats
|
58
|
+
|
59
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
60
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
61
|
+
* Fork the project
|
62
|
+
* Start a feature/bugfix branch
|
63
|
+
* Commit and push until you are happy with your contribution
|
64
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
65
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
66
|
+
|
67
|
+
== Copyright
|
68
|
+
|
69
|
+
Copyright (c) 2012 Conner Wingard. See LICENSE.txt for
|
70
|
+
further details.
|
71
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "autostats"
|
18
|
+
gem.homepage = "http://github.com/ConnerMan/Auto-Stats"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Tool to easily retrieve stats on any car}
|
21
|
+
gem.description = %Q{Scrapes data from aol.autos.com to get all relevant information specific to a car based on year, make, and model}
|
22
|
+
gem.email = "connerd@connerwingard.com"
|
23
|
+
gem.authors = ["Conner Wingard"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
gem.add_dependency 'nokogiri'
|
26
|
+
gem.add_dependency 'progressbar'
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
Rake::TestTask.new(:test) do |test|
|
32
|
+
test.libs << 'lib' << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'rcov/rcovtask'
|
38
|
+
Rcov::RcovTask.new do |test|
|
39
|
+
test.libs << 'test'
|
40
|
+
test.pattern = 'test/**/test_*.rb'
|
41
|
+
test.verbose = true
|
42
|
+
test.rcov_opts << '--exclude "gems/*"'
|
43
|
+
end
|
44
|
+
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
Rake::RDocTask.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "autostats #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/autostats.gemspec
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{autostats}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = [%q{Conner Wingard}]
|
12
|
+
s.date = %q{2012-01-22}
|
13
|
+
s.description = %q{Scrapes data from aol.autos.com to get all relevant information specific to a car based on year, make, and model}
|
14
|
+
s.email = %q{connerd@connerwingard.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"autostats.gemspec",
|
28
|
+
"lib/autostats.rb",
|
29
|
+
"lib/car.rb",
|
30
|
+
"lib/trim.rb",
|
31
|
+
"test/helper.rb",
|
32
|
+
"test/test_autostats.rb"
|
33
|
+
]
|
34
|
+
s.homepage = %q{http://github.com/ConnerMan/Auto-Stats}
|
35
|
+
s.licenses = [%q{MIT}]
|
36
|
+
s.require_paths = [%q{lib}]
|
37
|
+
s.rubygems_version = %q{1.8.6}
|
38
|
+
s.summary = %q{Tool to easily retrieve stats on any car}
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
s.specification_version = 3
|
42
|
+
|
43
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
44
|
+
s.add_runtime_dependency(%q<progressbar>, [">= 0"])
|
45
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
|
46
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
47
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
48
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
49
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
50
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
|
51
|
+
s.add_runtime_dependency(%q<progressbar>, [">= 0"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<progressbar>, [">= 0"])
|
54
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
55
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
56
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
58
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
59
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
60
|
+
s.add_dependency(%q<progressbar>, [">= 0"])
|
61
|
+
end
|
62
|
+
else
|
63
|
+
s.add_dependency(%q<progressbar>, [">= 0"])
|
64
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
65
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
66
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
67
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
68
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
69
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
70
|
+
s.add_dependency(%q<progressbar>, [">= 0"])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
data/lib/autostats.rb
ADDED
data/lib/car.rb
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
class Car
|
2
|
+
attr_accessor :make, :model, :photo_url, :model_year, :details_url, :overview, :trims, :trims_url, :overview_url, :base_url, :specs_url
|
3
|
+
|
4
|
+
|
5
|
+
def initialize(model_year, make, car_model)
|
6
|
+
@make = make.capitalize
|
7
|
+
@model = car_model
|
8
|
+
@model_year = model_year
|
9
|
+
@base_url = "http://autos.aol.com/cars-#{make}-#{car_model}-#{model_year}"
|
10
|
+
@overview_url = "#{@base_url}/overview"
|
11
|
+
@trims_url = "#{@base_url}/available-trims/"
|
12
|
+
@specs_url = "#{@base_url}/specs"
|
13
|
+
@mpg_url = "#{@specs_url}/mpg"
|
14
|
+
@trims = Array.new
|
15
|
+
|
16
|
+
Struct.new(
|
17
|
+
"ExteriorStats",
|
18
|
+
:length,
|
19
|
+
:body_width,
|
20
|
+
:body_height,
|
21
|
+
:wheelbase,
|
22
|
+
:ground_clearance,
|
23
|
+
:curb,
|
24
|
+
:gross_weight
|
25
|
+
)
|
26
|
+
|
27
|
+
Struct.new(
|
28
|
+
"InteriorStats",
|
29
|
+
:front_head_room,
|
30
|
+
:rear_head_room,
|
31
|
+
:front_shoulder_room,
|
32
|
+
:rear_shoulder_room,
|
33
|
+
:front_hip_room,
|
34
|
+
:rear_hip_room,
|
35
|
+
:front_leg_room,
|
36
|
+
:rear_leg_room,
|
37
|
+
:luggage_capacity,
|
38
|
+
:maximum_cargo_capacity,
|
39
|
+
:standard_seating
|
40
|
+
)
|
41
|
+
|
42
|
+
Struct.new(
|
43
|
+
"PerformanceStats",
|
44
|
+
:base_engine_size,
|
45
|
+
:base_engine_type,
|
46
|
+
:horsepower,
|
47
|
+
:horsepower_rpm,
|
48
|
+
:torque,
|
49
|
+
:torque_rpm,
|
50
|
+
:payload,
|
51
|
+
:maximum_towing_capacity,
|
52
|
+
:drive_type,
|
53
|
+
:turning_radius
|
54
|
+
)
|
55
|
+
|
56
|
+
Struct.new(
|
57
|
+
"FuelEconomyStats",
|
58
|
+
:fuel_tank_capacity,
|
59
|
+
:epa_mileage_estimates
|
60
|
+
)
|
61
|
+
|
62
|
+
|
63
|
+
get_overview
|
64
|
+
get_specs
|
65
|
+
get_features
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_overview
|
69
|
+
car_page = Nokogiri::HTML(open(@overview_url))
|
70
|
+
|
71
|
+
if car_page.xpath("//title").text == "Site Map - AOL Autos"
|
72
|
+
puts "Requested car does not exist"
|
73
|
+
return
|
74
|
+
end
|
75
|
+
|
76
|
+
@overview = car_page.xpath("//div[@class = 'rv_box']").text
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_specs
|
80
|
+
car_page = Nokogiri::HTML(open(@specs_url))
|
81
|
+
|
82
|
+
if car_page.xpath("//title").text == "Site Map - AOL Autos"
|
83
|
+
puts "Requested car does not exist"
|
84
|
+
return
|
85
|
+
end
|
86
|
+
trim_list = car_page.xpath("//div[@class = 'sliding_columns_container']")
|
87
|
+
|
88
|
+
category_name_table = car_page.xpath("//div[@class = 'ymm_data_table']/ul[@class = 'data_column']/li/span")
|
89
|
+
|
90
|
+
i = 0
|
91
|
+
exterior_stats_names = []
|
92
|
+
interior_stats_names = []
|
93
|
+
performance_stats_names = []
|
94
|
+
mpg_stats_names = []
|
95
|
+
sub_category_name = ""
|
96
|
+
category_name = category_name_table[i].text
|
97
|
+
if category_name == "Exterior"
|
98
|
+
i+=1
|
99
|
+
until sub_category_name == "Interior"
|
100
|
+
if sub_category_name != "";exterior_stats_names << sub_category_name; end
|
101
|
+
sub_category_name = category_name_table[i].text
|
102
|
+
i+=1
|
103
|
+
end
|
104
|
+
i+=1
|
105
|
+
sub_category_name = category_name_table[i].text
|
106
|
+
until sub_category_name == "Performance"
|
107
|
+
interior_stats_names << sub_category_name
|
108
|
+
sub_category_name = category_name_table[i].text
|
109
|
+
i+=1
|
110
|
+
end
|
111
|
+
i+=1
|
112
|
+
sub_category_name = category_name_table[i].text
|
113
|
+
until sub_category_name == "MPG"
|
114
|
+
performance_stats_names << sub_category_name
|
115
|
+
sub_category_name = category_name_table[i].text
|
116
|
+
i+=1
|
117
|
+
end
|
118
|
+
i+=1
|
119
|
+
sub_category_name = category_name_table[i].text
|
120
|
+
while i < category_name_table.size
|
121
|
+
sub_category_name = category_name_table[i].text
|
122
|
+
mpg_stats_names << sub_category_name
|
123
|
+
i+=1
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
interior_stats_names = unspacify(interior_stats_names)
|
128
|
+
exterior_stats_names = unspacify(exterior_stats_names)
|
129
|
+
performance_stats_names = unspacify(performance_stats_names)
|
130
|
+
mpg_stats_names = unspacify(mpg_stats_names)
|
131
|
+
total_stats = interior_stats_names.size + exterior_stats_names.size
|
132
|
+
+ performance_stats_names.size + mpg_stats_names.size
|
133
|
+
|
134
|
+
exterior = trim_list[0].xpath("./ul[@class = 'data_column']")
|
135
|
+
num_trims = exterior.size
|
136
|
+
|
137
|
+
# create array to hold all of the cars trim variations
|
138
|
+
@trims = Array.new
|
139
|
+
|
140
|
+
exterior.each do |ext|
|
141
|
+
trim = Trim.new
|
142
|
+
trim.trim_name = ext.xpath("./li[@class='header']/span/a").text
|
143
|
+
@trims << trim
|
144
|
+
end
|
145
|
+
|
146
|
+
#visually track progress of fetching
|
147
|
+
pbar = ProgressBar.new("Getting specs", total_stats * @trims.size )
|
148
|
+
|
149
|
+
#exterior statistics for table
|
150
|
+
exterior.each_with_index do |exterior_stats, index|
|
151
|
+
stats = exterior_stats.xpath("./li/span")
|
152
|
+
stat_index = 1
|
153
|
+
exterior_stats_names.each do |stat_name|
|
154
|
+
unless stat_name == ""
|
155
|
+
@trims[index].exterior[stat_name.to_sym] = stats[stat_index].text
|
156
|
+
end
|
157
|
+
stat_index += 1
|
158
|
+
pbar.inc
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
#fetch interior statistics from table
|
163
|
+
interior = trim_list[1].xpath("./ul[@class = 'data_column']")
|
164
|
+
interior.each_with_index do |interior_stats, index|
|
165
|
+
stats = interior_stats.xpath("./li/span")
|
166
|
+
stat_index = 1
|
167
|
+
interior_stats_names.each do |stat_name|
|
168
|
+
unless stat_name == ""
|
169
|
+
@trims[index].interior[stat_name.to_sym] = stats[stat_index].text
|
170
|
+
end
|
171
|
+
stat_index += 1
|
172
|
+
pbar.inc
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
#fetch performance data from table
|
177
|
+
performance = trim_list[2].xpath("./ul[@class = 'data_column']")
|
178
|
+
performance.each_with_index do |performance_stats, index|
|
179
|
+
stats = performance_stats.xpath("./li/span")
|
180
|
+
stat_index = 1
|
181
|
+
performance_stats_names.each do |stat_name|
|
182
|
+
unless stat_name == ""
|
183
|
+
@trims[index].performance[stat_name.to_sym] = stats[stat_index].text
|
184
|
+
end
|
185
|
+
stat_index += 1
|
186
|
+
pbar.inc
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
#fetch fuel economy data from table
|
191
|
+
fuel_economy = trim_list[3].xpath("./ul[@class = 'data_column']")
|
192
|
+
fuel_economy.each_with_index do |fuel_economy_stats, index|
|
193
|
+
stats = fuel_economy_stats.xpath("./li/span")
|
194
|
+
@trims[index].fuel_economy.fuel_tank_capacity = stats[1].text
|
195
|
+
@trims[index].fuel_economy.epa_mileage_estimates = stats[2].text
|
196
|
+
pbar.inc
|
197
|
+
end
|
198
|
+
|
199
|
+
pbar.finish
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
def get_features
|
205
|
+
car_page = Nokogiri::HTML(open(@trims_url))
|
206
|
+
|
207
|
+
available_tables = car_page.xpath("//table[@class = 'availableTable']")
|
208
|
+
available_tables.each do |table|
|
209
|
+
trim_text = table.xpath(".//div[@class = 'headrow']/a")[0].text
|
210
|
+
trim = find_trim_by_name(trim_text)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def print_trims
|
215
|
+
@trims.each { |trim| puts "#{trim.trim_name}\n" }
|
216
|
+
end
|
217
|
+
|
218
|
+
def find_trim_by_name(trim_name)
|
219
|
+
@trims.select { |trim| trim_name.include? trim.trim_name }
|
220
|
+
end
|
221
|
+
|
222
|
+
private
|
223
|
+
|
224
|
+
def unspacify(string_array)
|
225
|
+
ret = Array.new
|
226
|
+
string_array.each do |string|
|
227
|
+
if string != nil
|
228
|
+
ret << string.downcase.gsub(" ", "_")
|
229
|
+
end
|
230
|
+
end
|
231
|
+
ret
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
data/lib/trim.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class Trim
|
2
|
+
attr_accessor :trim_name, :exterior, :interior, :performance, :fuel_economy
|
3
|
+
|
4
|
+
def initialize()
|
5
|
+
@exterior = Struct::ExteriorStats.new
|
6
|
+
@interior = Struct::InteriorStats.new
|
7
|
+
@performance = Struct::PerformanceStats.new
|
8
|
+
@fuel_economy = Struct::FuelEconomyStats.new
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def mpg_combined
|
13
|
+
(self.mpg_city + self.mpg_highway) / 2
|
14
|
+
end
|
15
|
+
|
16
|
+
def mpg_city
|
17
|
+
divider_index = @fuel_economy.epa_mileage_estimates.index('C')
|
18
|
+
Integer(@fuel_economy.epa_mileage_estimates[0..divider_index-1])
|
19
|
+
end
|
20
|
+
|
21
|
+
def mpg_highway
|
22
|
+
divider_index = @fuel_economy.epa_mileage_estimates.index("/") + 1
|
23
|
+
end_index = @fuel_economy.epa_mileage_estimates.index('H')
|
24
|
+
Integer(@fuel_economy.epa_mileage_estimates[divider_index..end_index-1].strip)
|
25
|
+
end
|
26
|
+
|
27
|
+
def highway_range
|
28
|
+
self.mpg_highway * @fuel_economy.fuel_tank_capacity
|
29
|
+
end
|
30
|
+
|
31
|
+
def city_range
|
32
|
+
self.mpg_city * @fuel_economy.fuel_tank_capacity
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_stat(type)
|
36
|
+
if @performance.members.include? type.to_sym; return @performance[type]; end
|
37
|
+
if @interior.members.include? type.to_sym; return @interior[type]; end
|
38
|
+
if @exterior.members.include? type.to_sym; return @exterior[type]; end
|
39
|
+
if @fuel_economy.members.include? type.to_sym; return @fuel_economy[type]; end
|
40
|
+
end
|
41
|
+
|
42
|
+
def available_stats
|
43
|
+
@performance.members.each do |stat_name|
|
44
|
+
unless @performance[stat_name].nil?;puts "performance.#{stat_name.to_s}"end
|
45
|
+
end
|
46
|
+
@interior.members.each do |stat_name|
|
47
|
+
unless @interior[stat_name].nil?;puts "interior.#{stat_name.to_s}"end
|
48
|
+
end
|
49
|
+
@exterior.members.each do |stat_name|
|
50
|
+
unless @exterior[stat_name].nil?;puts "exterior.#{stat_name.to_s}"end
|
51
|
+
end
|
52
|
+
@fuel_economy.members.each do |stat_name|
|
53
|
+
unless @fuel_economy[stat_name].nil?;puts "fuel_economy.#{stat_name.to_s}"end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def engine
|
59
|
+
puts "#{@performance.base_engine_size} #{@performance.base_engine_type} - with #{@performance.horsepower} at #{@performance.horsepower_rpm}rpm" +
|
60
|
+
" and #{@performance.torque} of torque at #{@performance.torque_rpm}rpm"
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
@trim_name
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'autostats'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: autostats
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Conner Wingard
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-22 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: progressbar
|
16
|
+
requirement: &70204693793260 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70204693793260
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: nokogiri
|
27
|
+
requirement: &70204693792140 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70204693792140
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: shoulda
|
38
|
+
requirement: &70204693791100 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70204693791100
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bundler
|
49
|
+
requirement: &70204693790000 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.0
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70204693790000
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: jeweler
|
60
|
+
requirement: &70204693788900 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.6.4
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70204693788900
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rcov
|
71
|
+
requirement: &70204693788200 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70204693788200
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: nokogiri
|
82
|
+
requirement: &70204693787000 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70204693787000
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: progressbar
|
93
|
+
requirement: &70204693785840 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70204693785840
|
102
|
+
description: Scrapes data from aol.autos.com to get all relevant information specific
|
103
|
+
to a car based on year, make, and model
|
104
|
+
email: connerd@connerwingard.com
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files:
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.rdoc
|
110
|
+
files:
|
111
|
+
- .document
|
112
|
+
- Gemfile
|
113
|
+
- Gemfile.lock
|
114
|
+
- LICENSE.txt
|
115
|
+
- README.rdoc
|
116
|
+
- Rakefile
|
117
|
+
- VERSION
|
118
|
+
- autostats.gemspec
|
119
|
+
- lib/autostats.rb
|
120
|
+
- lib/car.rb
|
121
|
+
- lib/trim.rb
|
122
|
+
- test/helper.rb
|
123
|
+
- test/test_autostats.rb
|
124
|
+
homepage: http://github.com/ConnerMan/Auto-Stats
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
hash: 3294937515312711188
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 1.8.6
|
149
|
+
signing_key:
|
150
|
+
specification_version: 3
|
151
|
+
summary: Tool to easily retrieve stats on any car
|
152
|
+
test_files: []
|