fletcher 0.6.5 → 0.6.6
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/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:
|