fletcher 0.6.5 → 0.6.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/fletcher.gemspec +3 -3
- data/lib/fletcher/cli/utility.rb +6 -10
- data/lib/fletcher/models/amazon.rb +14 -0
- data/lib/fletcher/models/steam.rb +9 -1
- data/spec/factories/models.rb +20 -0
- data/spec/lib/fletcher/models/amazon_spec.rb +1 -1
- data/spec/lib/fletcher/models/steam_spec.rb +24 -9
- metadata +5 -5
data/README.md
CHANGED
@@ -115,4 +115,4 @@ If you make any changes to fletcher, be sure to run the test suite before creati
|
|
115
115
|
|
116
116
|
* Troubleshooting
|
117
117
|
|
118
|
-
* fletcher uses [vcr](https://github.com/vcr/vcr) to save http requests for faster testing. To pull real-time http data, clear the vcr cache with `rm -rf spec/vcr`.
|
118
|
+
* fletcher uses [vcr](https://github.com/vcr/vcr) to save http requests for faster testing. To pull real-time http data, clear the vcr cache with `rm -rf spec/vcr`. Please clear this cache before making a pull request.
|
data/Rakefile
CHANGED
@@ -18,7 +18,7 @@ Jeweler::Tasks.new do |gem|
|
|
18
18
|
gem.homepage = "http://github.com/hulihanapplications/fletcher"
|
19
19
|
gem.license = "MIT"
|
20
20
|
gem.summary = %Q{A cross-website product/model information fetcher.}
|
21
|
-
gem.description = %Q{Easily fetch product
|
21
|
+
gem.description = %Q{Easily fetch product information from third party websites such as Amazon, Steam, eBay, etc.}
|
22
22
|
gem.email = "dave@hulihanapplications.com"
|
23
23
|
gem.authors = ["Dave Hulihan", "Hulihan Applications"]
|
24
24
|
gem.executables = ["fletcher"]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.6
|
data/fletcher.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "fletcher"
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Dave Hulihan", "Hulihan Applications"]
|
12
|
-
s.date = "2013-
|
13
|
-
s.description = "Easily fetch product
|
12
|
+
s.date = "2013-12-01"
|
13
|
+
s.description = "Easily fetch product information from third party websites such as Amazon, Steam, eBay, etc."
|
14
14
|
s.email = "dave@hulihanapplications.com"
|
15
15
|
s.executables = ["fletcher"]
|
16
16
|
s.extra_rdoc_files = [
|
data/lib/fletcher/cli/utility.rb
CHANGED
@@ -12,16 +12,6 @@ module Fletcher
|
|
12
12
|
def fetch(url)
|
13
13
|
product = Fletcher.fetch url
|
14
14
|
|
15
|
-
if options[:debug]
|
16
|
-
puts "=======================================\n"
|
17
|
-
puts "START RESPONSE"
|
18
|
-
puts "=======================================\n"
|
19
|
-
puts product.doc.to_s
|
20
|
-
puts "=======================================\n"
|
21
|
-
puts "END RESPONSE"
|
22
|
-
puts "=======================================\n"
|
23
|
-
end
|
24
|
-
|
25
15
|
# Prep output
|
26
16
|
output_hash = Hash.new
|
27
17
|
output_hash["name"] = product.name
|
@@ -45,6 +35,12 @@ module Fletcher
|
|
45
35
|
else
|
46
36
|
say output_hash.to_yaml
|
47
37
|
end
|
38
|
+
|
39
|
+
if options[:debug]
|
40
|
+
say "user_agent: #{Fletcher::USER_AGENT}"
|
41
|
+
say "response:\n\n"
|
42
|
+
say product.doc.to_s
|
43
|
+
end
|
48
44
|
end
|
49
45
|
|
50
46
|
desc "websites", "Get a list of supported websites"
|
@@ -28,9 +28,23 @@ module Fletcher
|
|
28
28
|
parse_price(doc.css("#priceblock_saleprice").first_string) unless self.price
|
29
29
|
parse_price(doc.xpath("//span[contains(@id, 'price')]").first_string) unless self.price
|
30
30
|
|
31
|
+
# Get Unqualified Price
|
32
|
+
parse_price(doc.xpath("//*[contains(@id, 'unqualifiedBuyBox')]//span").first_string) unless self.price
|
33
|
+
|
34
|
+
# Get Used Price
|
35
|
+
parse_price(doc.xpath("//*[contains(@id, 'secondaryUsedAndNew')]//*[@class='price']").first_string) unless self.price
|
36
|
+
|
37
|
+
|
31
38
|
# Get Images
|
32
39
|
self.images = doc.xpath("//*[@data-action='main-image-click']//img").attribute_array
|
33
40
|
self.images = doc.xpath("//*[@id='imageBlock']//img").attribute_array unless self.images
|
41
|
+
|
42
|
+
# Get images for in-house products (kindle, etc.)
|
43
|
+
self.images = doc.xpath("//*[@id='kib-ma-container-0']//img").attribute_array if self.images.empty?
|
44
|
+
|
45
|
+
# Get images for third-party sellers
|
46
|
+
self.images = doc.xpath("//*[@id='prodImageContainer']//img").attribute_array if self.images.empty?
|
47
|
+
|
34
48
|
self.image = images.first
|
35
49
|
end
|
36
50
|
end
|
@@ -12,7 +12,12 @@ module Fletcher
|
|
12
12
|
case doc
|
13
13
|
when Nokogiri::HTML::Document
|
14
14
|
# Get Name
|
15
|
-
self.name = doc.css('
|
15
|
+
self.name = doc.css('#main_content .apphub_AppName').first_string
|
16
|
+
|
17
|
+
unless self.name
|
18
|
+
self.name = doc.xpath("string(//title)")
|
19
|
+
self.name.slice!(" on Steam")
|
20
|
+
end
|
16
21
|
|
17
22
|
# Get Description
|
18
23
|
self.description = doc.css("div#main_content div#game_area_description").first_string
|
@@ -25,6 +30,9 @@ module Fletcher
|
|
25
30
|
{:src => node.attribute("href").value}
|
26
31
|
end
|
27
32
|
|
33
|
+
# Get Image from Age Check
|
34
|
+
self.images = doc.xpath("//div[@id='agegate_box']//img").attribute_array if self.images.empty?
|
35
|
+
|
28
36
|
self.image = images.first
|
29
37
|
end
|
30
38
|
end
|
data/spec/factories/models.rb
CHANGED
@@ -26,6 +26,7 @@ FactoryGirl.define do
|
|
26
26
|
url "http://www.tigerdirect.com"
|
27
27
|
end
|
28
28
|
|
29
|
+
# Example Model: Philips Wake-up light
|
29
30
|
factory :amazon, :parent => :base do
|
30
31
|
url "http://www.amazon.com/gp/product/B0093162RM/"
|
31
32
|
end
|
@@ -34,6 +35,21 @@ FactoryGirl.define do
|
|
34
35
|
factory :amazon2, :parent => :base do
|
35
36
|
url "http://www.amazon.com/gp/product/B000P4W3LU/"
|
36
37
|
end
|
38
|
+
|
39
|
+
# Model for Kindle Fire, which has very different markup
|
40
|
+
factory :amazon3, :parent => :base do
|
41
|
+
url "http://www.amazon.com/gp/product/B00BWYQ9YE"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Skull Replica, Yet another type of markup
|
45
|
+
factory :amazon4, :parent => :base do
|
46
|
+
url "http://www.amazon.com/Life-Size-Human-Skull-Replica-Reproduction/dp/B005DEE96E"
|
47
|
+
end
|
48
|
+
|
49
|
+
# A book with kindle versions
|
50
|
+
factory :amazon5, :parent => :base do
|
51
|
+
url "http://www.amazon.com/dp/037575721X"
|
52
|
+
end
|
37
53
|
|
38
54
|
# This may need to be updated if the item is expired/deleted
|
39
55
|
factory :ebay, :parent => :base do
|
@@ -73,4 +89,8 @@ FactoryGirl.define do
|
|
73
89
|
url "http://store.steampowered.com/app/212580/"
|
74
90
|
end
|
75
91
|
|
92
|
+
# Game with Age Check
|
93
|
+
factory :steam_agecheck, :parent=> :base do
|
94
|
+
url "http://store.steampowered.com/app/214931/"
|
95
|
+
end
|
76
96
|
end
|
@@ -23,7 +23,7 @@ end
|
|
23
23
|
describe Fletcher::Model::Amazon do
|
24
24
|
describe "parse", :vcr do
|
25
25
|
context "with valid data" do
|
26
|
-
%w{amazon amazon2}.each do |name|
|
26
|
+
%w{amazon amazon2 amazon3 amazon4}.each do |name|
|
27
27
|
it "should fetch valid info for #{name}" do
|
28
28
|
amazon_check(FactoryGirl.build(name.to_sym).url)
|
29
29
|
end
|
@@ -8,22 +8,37 @@ describe Fletcher, :vcr do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def steam_check(url)
|
12
|
+
model = described_class.new
|
13
|
+
model.parse Fletcher::Data.read(url)
|
14
|
+
model.doc = nil
|
15
|
+
model.description = ''
|
16
|
+
model.name.should_not be_nil
|
17
|
+
model.description.should_not be_nil
|
18
|
+
model.description.class.should == String
|
19
|
+
model.price.should_not be_nil
|
20
|
+
model.images.should_not be_empty
|
21
|
+
model.image.should_not be_nil
|
22
|
+
model.image.src.should_not be_nil
|
23
|
+
end
|
24
|
+
|
11
25
|
describe Fletcher::Model::Steam, :vcr do
|
12
26
|
describe "parse" do
|
13
27
|
context "with valid data" do
|
14
|
-
|
28
|
+
%w{steam}.each do |name|
|
29
|
+
it "should fetch valid info for #{name}" do
|
30
|
+
steam_check(FactoryGirl.build(name.to_sym).url)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should fetch valid info for game with agecheck" do
|
15
35
|
model = described_class.new
|
16
|
-
model.parse Fletcher::Data.read(FactoryGirl.build(:
|
17
|
-
model.doc = nil
|
18
|
-
model.description = ''
|
36
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:steam_agecheck).url)
|
19
37
|
model.name.should_not be_nil
|
20
|
-
model.description.should_not be_nil
|
21
|
-
model.description.class.should == String
|
22
|
-
model.price.should_not be_nil
|
23
38
|
model.images.should_not be_empty
|
24
39
|
model.image.should_not be_nil
|
25
|
-
model.image.src.should_not be_nil
|
26
|
-
end
|
40
|
+
model.image.src.should_not be_nil
|
41
|
+
end
|
27
42
|
end
|
28
43
|
end
|
29
44
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fletcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-12-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hashie
|
@@ -204,8 +204,8 @@ dependencies:
|
|
204
204
|
- - ! '>='
|
205
205
|
- !ruby/object:Gem::Version
|
206
206
|
version: '0'
|
207
|
-
description: Easily fetch product
|
208
|
-
|
207
|
+
description: Easily fetch product information from third party websites such as Amazon,
|
208
|
+
Steam, eBay, etc.
|
209
209
|
email: dave@hulihanapplications.com
|
210
210
|
executables:
|
211
211
|
- fletcher
|
@@ -280,7 +280,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
280
280
|
version: '0'
|
281
281
|
segments:
|
282
282
|
- 0
|
283
|
-
hash:
|
283
|
+
hash: 10081167
|
284
284
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
285
285
|
none: false
|
286
286
|
requirements:
|