fletcher 0.6.1 → 0.6.2
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/.travis.yml +2 -2
- data/Gemfile +0 -1
- data/Gemfile.lock +24 -23
- data/README.md +1 -0
- data/Rakefile +15 -15
- data/VERSION +1 -1
- data/fletcher.gemspec +7 -5
- data/lib/fletcher.rb +28 -39
- data/lib/fletcher/model.rb +23 -0
- data/lib/fletcher/models/base.rb +4 -27
- data/lib/fletcher/models/googleshopping.rb +2 -1
- data/lib/fletcher/models/newegg.rb +31 -0
- data/lib/fletcher/models/thinkgeek.rb +1 -1
- data/lib/fletcher/string.rb +23 -1
- data/spec/factories/models.rb +8 -0
- data/spec/lib/fletcher/data_spec.rb +1 -1
- data/spec/lib/fletcher/model_spec.rb +19 -0
- data/spec/lib/fletcher/models/amazon_spec.rb +2 -2
- data/spec/lib/fletcher/models/base_spec.rb +12 -1
- data/spec/lib/fletcher/models/ebay_spec.rb +2 -2
- data/spec/lib/fletcher/models/etsy_spec.rb +2 -2
- data/spec/lib/fletcher/models/gamecouk_spec.rb +2 -2
- data/spec/lib/fletcher/models/googleshopping_spec.rb +2 -2
- data/spec/lib/fletcher/models/newegg_spec.rb +26 -0
- data/spec/lib/fletcher/models/playcom_spec.rb +2 -2
- data/spec/lib/fletcher/models/steam_spec.rb +2 -3
- data/spec/lib/fletcher/models/thinkgeek_spec.rb +3 -3
- data/spec/lib/fletcher/nokogiri_spec.rb +3 -3
- data/spec/lib/fletcher/string_spec.rb +4 -0
- data/spec/lib/fletcher_spec.rb +8 -12
- metadata +8 -19
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,39 +1,41 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (3.2.
|
4
|
+
activesupport (3.2.9)
|
5
5
|
i18n (~> 0.6)
|
6
6
|
multi_json (~> 1.0)
|
7
7
|
diff-lcs (1.1.3)
|
8
|
-
factory_girl (
|
9
|
-
activesupport (>=
|
8
|
+
factory_girl (4.1.0)
|
9
|
+
activesupport (>= 3.0.0)
|
10
10
|
fakeweb (1.3.0)
|
11
11
|
git (1.2.5)
|
12
12
|
hashie (1.2.0)
|
13
|
-
i18n (0.6.
|
13
|
+
i18n (0.6.1)
|
14
14
|
jeweler (1.6.4)
|
15
15
|
bundler (~> 1.0)
|
16
16
|
git (>= 1.2.5)
|
17
17
|
rake
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
rspec-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
shoulda (
|
18
|
+
money (5.1.0)
|
19
|
+
i18n (~> 0.6.0)
|
20
|
+
multi_json (1.3.7)
|
21
|
+
nokogiri (1.5.5)
|
22
|
+
rake (10.0.1)
|
23
|
+
rspec (2.12.0)
|
24
|
+
rspec-core (~> 2.12.0)
|
25
|
+
rspec-expectations (~> 2.12.0)
|
26
|
+
rspec-mocks (~> 2.12.0)
|
27
|
+
rspec-core (2.12.0)
|
28
|
+
rspec-expectations (2.12.0)
|
29
|
+
diff-lcs (~> 1.1.3)
|
30
|
+
rspec-mocks (2.12.0)
|
31
|
+
shoulda (3.3.2)
|
32
|
+
shoulda-context (~> 1.0.1)
|
33
|
+
shoulda-matchers (~> 1.4.1)
|
34
|
+
shoulda-context (1.0.1)
|
35
|
+
shoulda-matchers (1.4.1)
|
36
|
+
activesupport (>= 3.0.0)
|
35
37
|
thor (0.16.0)
|
36
|
-
vcr (2.
|
38
|
+
vcr (2.3.0)
|
37
39
|
|
38
40
|
PLATFORMS
|
39
41
|
ruby
|
@@ -47,7 +49,6 @@ DEPENDENCIES
|
|
47
49
|
jeweler (~> 1.6.4)
|
48
50
|
money
|
49
51
|
nokogiri
|
50
|
-
rcov
|
51
52
|
rspec
|
52
53
|
shoulda
|
53
54
|
thor
|
data/README.md
CHANGED
@@ -16,6 +16,7 @@ Fletcher is a cross-website product information fetcher. Just give fletcher a pr
|
|
16
16
|
* [Etsy](http://www.etsy.com)
|
17
17
|
* [game.co.uk](http://www.game.co.uk)
|
18
18
|
* [Google Shopping](http://www.google.com/products/)
|
19
|
+
* [Newegg](http://www.newegg.com)
|
19
20
|
* [play.com](http://www.play.com)
|
20
21
|
* [Steam](http://store.steampowered.com)
|
21
22
|
* [ThinkGeek](http://www.thinkgeek.com)
|
data/Rakefile
CHANGED
@@ -33,22 +33,22 @@ Rake::TestTask.new(:test) do |test|
|
|
33
33
|
test.verbose = true
|
34
34
|
end
|
35
35
|
|
36
|
-
require 'rcov/rcovtask'
|
37
|
-
Rcov::RcovTask.new do |test|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
36
|
+
# require 'rcov/rcovtask'
|
37
|
+
# Rcov::RcovTask.new do |test|
|
38
|
+
# test.libs << 'test'
|
39
|
+
# test.pattern = 'test/**/test_*.rb'
|
40
|
+
# test.verbose = true
|
41
|
+
# test.rcov_opts << '--exclude "gems/*"'
|
42
|
+
# end
|
43
43
|
|
44
44
|
task :default => :test
|
45
45
|
|
46
|
-
require 'rake/rdoctask'
|
47
|
-
Rake::RDocTask.new do |rdoc|
|
48
|
-
|
46
|
+
# require 'rake/rdoctask'
|
47
|
+
# Rake::RDocTask.new do |rdoc|
|
48
|
+
# version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
50
|
+
# rdoc.rdoc_dir = 'rdoc'
|
51
|
+
# rdoc.title = "fletcher #{version}"
|
52
|
+
# rdoc.rdoc_files.include('README*')
|
53
|
+
# rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
# end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.2
|
data/fletcher.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "fletcher"
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.2"
|
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 = "2012-11-
|
12
|
+
s.date = "2012-11-16"
|
13
13
|
s.description = "Easily fetch product/model information from third party websites such as Amazon, eBay, etc."
|
14
14
|
s.email = "dave@hulihanapplications.com"
|
15
15
|
s.executables = ["fletcher"]
|
@@ -32,12 +32,14 @@ Gem::Specification.new do |s|
|
|
32
32
|
"lib/fletcher.rb",
|
33
33
|
"lib/fletcher/cli/utility.rb",
|
34
34
|
"lib/fletcher/data.rb",
|
35
|
+
"lib/fletcher/model.rb",
|
35
36
|
"lib/fletcher/models/amazon.rb",
|
36
37
|
"lib/fletcher/models/base.rb",
|
37
38
|
"lib/fletcher/models/ebay.rb",
|
38
39
|
"lib/fletcher/models/etsy.rb",
|
39
40
|
"lib/fletcher/models/gamecouk.rb",
|
40
41
|
"lib/fletcher/models/googleshopping.rb",
|
42
|
+
"lib/fletcher/models/newegg.rb",
|
41
43
|
"lib/fletcher/models/playcom.rb",
|
42
44
|
"lib/fletcher/models/steam.rb",
|
43
45
|
"lib/fletcher/models/thinkgeek.rb",
|
@@ -46,16 +48,19 @@ Gem::Specification.new do |s|
|
|
46
48
|
"spec/bin/fletcher_spec.rb",
|
47
49
|
"spec/factories/models.rb",
|
48
50
|
"spec/lib/fletcher/data_spec.rb",
|
51
|
+
"spec/lib/fletcher/model_spec.rb",
|
49
52
|
"spec/lib/fletcher/models/amazon_spec.rb",
|
50
53
|
"spec/lib/fletcher/models/base_spec.rb",
|
51
54
|
"spec/lib/fletcher/models/ebay_spec.rb",
|
52
55
|
"spec/lib/fletcher/models/etsy_spec.rb",
|
53
56
|
"spec/lib/fletcher/models/gamecouk_spec.rb",
|
54
57
|
"spec/lib/fletcher/models/googleshopping_spec.rb",
|
58
|
+
"spec/lib/fletcher/models/newegg_spec.rb",
|
55
59
|
"spec/lib/fletcher/models/playcom_spec.rb",
|
56
60
|
"spec/lib/fletcher/models/steam_spec.rb",
|
57
61
|
"spec/lib/fletcher/models/thinkgeek_spec.rb",
|
58
62
|
"spec/lib/fletcher/nokogiri_spec.rb",
|
63
|
+
"spec/lib/fletcher/string_spec.rb",
|
59
64
|
"spec/lib/fletcher_spec.rb",
|
60
65
|
"spec/spec_helper.rb",
|
61
66
|
"spec/support/benchmark.rb",
|
@@ -82,7 +87,6 @@ Gem::Specification.new do |s|
|
|
82
87
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
83
88
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
84
89
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
85
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
86
90
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
87
91
|
s.add_development_dependency(%q<factory_girl>, [">= 0"])
|
88
92
|
s.add_development_dependency(%q<i18n>, [">= 0"])
|
@@ -96,7 +100,6 @@ Gem::Specification.new do |s|
|
|
96
100
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
97
101
|
s.add_dependency(%q<bundler>, [">= 0"])
|
98
102
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
99
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
100
103
|
s.add_dependency(%q<rspec>, [">= 0"])
|
101
104
|
s.add_dependency(%q<factory_girl>, [">= 0"])
|
102
105
|
s.add_dependency(%q<i18n>, [">= 0"])
|
@@ -111,7 +114,6 @@ Gem::Specification.new do |s|
|
|
111
114
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
112
115
|
s.add_dependency(%q<bundler>, [">= 0"])
|
113
116
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
114
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
115
117
|
s.add_dependency(%q<rspec>, [">= 0"])
|
116
118
|
s.add_dependency(%q<factory_girl>, [">= 0"])
|
117
119
|
s.add_dependency(%q<i18n>, [">= 0"])
|
data/lib/fletcher.rb
CHANGED
@@ -3,53 +3,30 @@
|
|
3
3
|
require "uri"
|
4
4
|
|
5
5
|
require File.expand_path("fletcher/data", File.dirname(__FILE__))
|
6
|
+
require File.expand_path("fletcher/model", File.dirname(__FILE__))
|
6
7
|
require File.expand_path("fletcher/string", File.dirname(__FILE__))
|
7
8
|
require File.expand_path("fletcher/nokogiri", File.dirname(__FILE__))
|
8
9
|
|
9
10
|
module Fletcher
|
10
11
|
# Module Methods
|
11
|
-
class << self
|
12
|
-
# Detect model by url
|
13
|
-
# Fletcher.identify_model("http://www.amazon.com/whatever") # => :amazon
|
14
|
-
def identify_model(url)
|
15
|
-
if url =~ ::URI::regexp
|
16
|
-
uri = ::URI::parse(url)
|
17
|
-
host = uri.host
|
18
|
-
if host =~ Fletcher::Model::Amazon.regexp
|
19
|
-
model = :amazon
|
20
|
-
elsif host =~ Fletcher::Model::Ebay.regexp
|
21
|
-
model = :ebay
|
22
|
-
elsif host =~ Fletcher::Model::Etsy.regexp
|
23
|
-
model = :etsy
|
24
|
-
elsif host =~ Fletcher::Model::Gamecouk.regexp
|
25
|
-
model = :gamecouk
|
26
|
-
elsif host =~ Fletcher::Model::Googleshopping.regexp
|
27
|
-
model = :googleshopping
|
28
|
-
elsif host =~ Fletcher::Model::Playcom.regexp
|
29
|
-
model = :playcom
|
30
|
-
elsif host =~ Fletcher::Model::Thinkgeek.regexp
|
31
|
-
model = :thinkgeek
|
32
|
-
elsif host =~ Fletcher::Model::Steam.regexp
|
33
|
-
model = :steam
|
34
|
-
else
|
35
|
-
model = :unknown
|
36
|
-
raise ArgumentError, "Fletcher doesn't support #{host} yet."
|
37
|
-
end
|
38
|
-
else
|
39
|
-
raise ArgumentError, "not a url"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
12
|
+
class << self
|
43
13
|
# Fetch information based on url
|
44
14
|
def fetch(url)
|
45
|
-
model
|
15
|
+
# Look for model based on url
|
16
|
+
model_class = Fletcher::Model.identify(url)
|
17
|
+
|
18
|
+
# Use Base class for fallback
|
19
|
+
model_class = Fletcher::Model::Base unless model_class
|
20
|
+
|
46
21
|
data = Fletcher::Data.read(url)
|
47
|
-
|
48
|
-
|
49
|
-
|
22
|
+
|
23
|
+
product = model_class.new
|
24
|
+
product.parse(data)
|
25
|
+
|
26
|
+
# Save url
|
27
|
+
product.url = url
|
50
28
|
|
51
|
-
|
52
|
-
return model
|
29
|
+
return product
|
53
30
|
end
|
54
31
|
|
55
32
|
# Get gem version
|
@@ -62,6 +39,7 @@ module Fletcher
|
|
62
39
|
File.expand_path("../..", __FILE__)
|
63
40
|
end
|
64
41
|
|
42
|
+
# get array of models syms
|
65
43
|
def models
|
66
44
|
models = Array.new
|
67
45
|
Dir[File.join(File.dirname(__FILE__), "fletcher", "models", "*.rb")].each do |f|
|
@@ -70,6 +48,17 @@ module Fletcher
|
|
70
48
|
end
|
71
49
|
return models
|
72
50
|
end
|
51
|
+
|
52
|
+
# get array of model classes
|
53
|
+
# Fletcher.model_classes = [Amazon, Ebay, ThinkGeek]
|
54
|
+
def model_classes
|
55
|
+
models = Array.new
|
56
|
+
Dir[File.join(File.dirname(__FILE__), "fletcher", "models", "*.rb")].each do |f|
|
57
|
+
filename = File.basename(f, ".rb")
|
58
|
+
models << ["Fletcher", "Model", filename.camelize].join("::").constantize unless filename == "base"
|
59
|
+
end
|
60
|
+
return models
|
61
|
+
end
|
73
62
|
end
|
74
63
|
|
75
64
|
LIBRARY_PATH = File.join(File.dirname(__FILE__), 'fletcher')
|
@@ -85,7 +74,7 @@ module Fletcher
|
|
85
74
|
module Model
|
86
75
|
autoload :Base, File.join(MODEL_PATH, "base")
|
87
76
|
for model in Fletcher.models
|
88
|
-
autoload model.to_s.
|
77
|
+
autoload model.to_s.camelize.to_sym, File.join(MODEL_PATH, model.to_s)
|
89
78
|
end
|
90
79
|
end
|
91
80
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Fletcher
|
2
|
+
module Model
|
3
|
+
class << self
|
4
|
+
# Detect model by url
|
5
|
+
# Fletcher::Model.identify("http://www.amazon.com/whatever") # => Flether::Models::Amazon
|
6
|
+
def identify(url)
|
7
|
+
if url =~ ::URI::regexp
|
8
|
+
uri = ::URI::parse(url)
|
9
|
+
host = uri.host
|
10
|
+
matched_model = nil
|
11
|
+
for model in Fletcher.model_classes
|
12
|
+
#model_class =
|
13
|
+
matched_model = model if host =~ model.regexp
|
14
|
+
end
|
15
|
+
# raise ArgumentError, "Fletcher doesn't support #{host} yet." unless matched_model_class
|
16
|
+
return matched_model
|
17
|
+
else
|
18
|
+
raise ArgumentError, "not a url"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/fletcher/models/base.rb
CHANGED
@@ -4,37 +4,14 @@ require "money"
|
|
4
4
|
module Fletcher
|
5
5
|
module Model
|
6
6
|
class Base < ::Hashie::Mash
|
7
|
-
# Create a product object based on service
|
8
|
-
# Fletcher::Model::Base.generate(:amazon, "<html>...") # => #<Fletcher::Model::Amazon:0x...>
|
9
|
-
def self.generate(service = nil, data = nil)
|
10
|
-
case service
|
11
|
-
when :amazon
|
12
|
-
model = Fletcher::Model::Amazon.new
|
13
|
-
when :ebay
|
14
|
-
model = Fletcher::Model::Ebay.new
|
15
|
-
when :thinkgeek
|
16
|
-
model = Fletcher::Model::Thinkgeek.new
|
17
|
-
when :etsy
|
18
|
-
model = Fletcher::Model::Etsy.new
|
19
|
-
when :googleshopping
|
20
|
-
model = Fletcher::Model::Googleshopping.new
|
21
|
-
when :gamecouk
|
22
|
-
model = Fletcher::Model::Gamecouk.new
|
23
|
-
when :steam
|
24
|
-
model = Fletcher::Model::Steam.new
|
25
|
-
when :playcom
|
26
|
-
model = Fletcher::Model::Playcom.new
|
27
|
-
end
|
28
|
-
|
29
|
-
model.parse(data)
|
30
|
-
return model
|
31
|
-
end
|
32
|
-
|
33
7
|
# Parse data and set object attributes
|
34
8
|
def parse(data)
|
35
9
|
self.doc = data # save data for if user wants to access it later
|
10
|
+
|
11
|
+
# Get page title as name
|
12
|
+
self.name = doc.css("head > title").first_string
|
36
13
|
end
|
37
|
-
|
14
|
+
|
38
15
|
# Parse a raw price string to get usable data
|
39
16
|
# model.parse_price("$5.00") # => #<Money cents:500 currency:USD>
|
40
17
|
# model.price.to_f # => 5.0
|
@@ -12,7 +12,8 @@ module Fletcher
|
|
12
12
|
case doc
|
13
13
|
when Nokogiri::HTML::Document
|
14
14
|
# Get Name
|
15
|
-
|
15
|
+
name = doc.css('h1#product-name span.main-title').first_string
|
16
|
+
self.name = name if name
|
16
17
|
|
17
18
|
# Get Description
|
18
19
|
self.description = doc.css("div.product-desc-cont div.product-desc").first_string
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fletcher
|
2
|
+
module Model
|
3
|
+
class Newegg < Fletcher::Model::Base
|
4
|
+
# A regular expression for determining if a url comes from a specific service/website
|
5
|
+
def self.regexp
|
6
|
+
/newegg\.com/
|
7
|
+
end
|
8
|
+
|
9
|
+
# Parse data and look for object attributes to give to object
|
10
|
+
def parse(data)
|
11
|
+
super(data)
|
12
|
+
case doc
|
13
|
+
when Nokogiri::HTML::Document
|
14
|
+
# Get Name
|
15
|
+
self.name = doc.css("#synopsis .grpDesc .wrapper h1 > span").first_string
|
16
|
+
#self.name = doc.css("#synopsis .grpDesc .wrapper > .span").first_string
|
17
|
+
|
18
|
+
# Description
|
19
|
+
self.description = doc.css("#fullInfo .itmDesc > p").first_string
|
20
|
+
|
21
|
+
# Get Price (currently disabled because price is displayed after page load)
|
22
|
+
#parse_price doc.css("li.price-current").attribute("content").content
|
23
|
+
|
24
|
+
# # Get Images
|
25
|
+
self.images = [{:src => doc.css('.mainSlide > img').attribute("src").content}]
|
26
|
+
self.image = images.first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -14,7 +14,7 @@ module Fletcher
|
|
14
14
|
when Nokogiri::HTML::Document
|
15
15
|
# Get Name
|
16
16
|
self.name = doc.xpath("//meta[@property='og:title']/@content").first_string
|
17
|
-
|
17
|
+
|
18
18
|
# Get Description
|
19
19
|
self.description = doc.xpath("//meta[@property='og:description']/@content").first_string
|
20
20
|
|
data/lib/fletcher/string.rb
CHANGED
@@ -1,10 +1,32 @@
|
|
1
|
-
|
2
1
|
module Fletcher
|
3
2
|
# This class extends string functions
|
4
3
|
module String
|
5
4
|
def sanitize
|
6
5
|
self.strip
|
7
6
|
end
|
7
|
+
|
8
|
+
def camelize(first_letter_in_uppercase = true)
|
9
|
+
lower_case_and_underscored_word = self.dup.underscore
|
10
|
+
if first_letter_in_uppercase
|
11
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
12
|
+
else
|
13
|
+
lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def constantize
|
18
|
+
self.split("::").inject(Module) {|acc, val| acc.const_get(val)}
|
19
|
+
end
|
20
|
+
|
21
|
+
def underscore
|
22
|
+
word = self.dup
|
23
|
+
word.gsub!(/::/, '/')
|
24
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
25
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
26
|
+
word.tr!("-", "_")
|
27
|
+
word.downcase!
|
28
|
+
word
|
29
|
+
end
|
8
30
|
end
|
9
31
|
end
|
10
32
|
|
data/spec/factories/models.rb
CHANGED
@@ -22,6 +22,10 @@ FactoryGirl.define do
|
|
22
22
|
images_xpath "//table[@class='productImageGrid']//img"
|
23
23
|
end
|
24
24
|
|
25
|
+
factory :unsupported, :parent => :base do
|
26
|
+
url "http://www.tigerdirect.com"
|
27
|
+
end
|
28
|
+
|
25
29
|
factory :amazon, :parent => :base do
|
26
30
|
url "http://www.amazon.com/gp/product/B004HZYA6E/"
|
27
31
|
end
|
@@ -31,6 +35,10 @@ FactoryGirl.define do
|
|
31
35
|
url "http://www.ebay.com/itm/Franklin-Library-3V-ESSAYS-MONTAIGNE-Leather-Great-Books-1979-Donald-Frame-/190654183378"
|
32
36
|
end
|
33
37
|
|
38
|
+
factory :newegg, :parent => :base do
|
39
|
+
url "http://www.newegg.com/Product/Product.aspx?Item=9SIA03E0004DP7"
|
40
|
+
end
|
41
|
+
|
34
42
|
factory :thinkgeek, :parent => :base do
|
35
43
|
url "http://www.thinkgeek.com/geektoys/plush/e7f8/"
|
36
44
|
end
|
@@ -9,7 +9,7 @@ describe Fletcher::Data do
|
|
9
9
|
|
10
10
|
describe "read" do
|
11
11
|
it "should return a valid document", :vcr do
|
12
|
-
doc = Fletcher::Data.read(
|
12
|
+
doc = Fletcher::Data.read(FactoryGirl.build(:valid).url)
|
13
13
|
end
|
14
14
|
|
15
15
|
# This is just a rough indicator of how long a data should take to download
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fletcher::Model do
|
4
|
+
describe "identify" do
|
5
|
+
it "should return the model when a valid url is used" do
|
6
|
+
described_class.identify(FactoryGirl.build(:amazon).url).should == Fletcher::Model::Amazon
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return nil when using an unsupported domain" do
|
10
|
+
described_class.identify(FactoryGirl.build(:invalid).url).should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# for model in Fletcher.model_classes
|
14
|
+
# it "should return #{model} sym when using a #{model} domain" do
|
15
|
+
# described_class.identify(FactoryGirl.build(model).url).should == model
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch amazon product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:amazon).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Amazon do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:amazon).url)
|
20
20
|
model.name.should_not be_nil
|
21
21
|
model.description.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
@@ -1,5 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
describe Fletcher, :vcr do
|
4
|
+
describe :fetch, :vcr do
|
5
|
+
context "when using an unsupported website" do
|
6
|
+
it "should return meta title as name" do
|
7
|
+
item = described_class.fetch(FactoryGirl.build(:unsupported).url)
|
8
|
+
item.name.should_not be_nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
3
14
|
describe Fletcher::Model::Base do
|
4
15
|
describe "generate" do
|
5
16
|
end
|
@@ -11,7 +22,7 @@ describe Fletcher::Model::Base do
|
|
11
22
|
|
12
23
|
describe "parse_price", :vcr do
|
13
24
|
it "should return a price float and currency" do
|
14
|
-
model =
|
25
|
+
model = FactoryGirl.build(:sample)
|
15
26
|
model.parse_price(model.raw_price)
|
16
27
|
model.price.is_a?(Money).should == true
|
17
28
|
model.price.currency.should_not be_nil
|
@@ -4,7 +4,7 @@ describe Fletcher, :vcr do
|
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
# Force use of ebay cassette since auctions always end
|
6
6
|
it "should fetch ebay product", :vcr => { :cassette_name => "ebay_fetch" } do
|
7
|
-
item = described_class.fetch(
|
7
|
+
item = described_class.fetch(FactoryGirl.build(:ebay).url)
|
8
8
|
item.should_not be_nil
|
9
9
|
item.name.should_not be_nil
|
10
10
|
end
|
@@ -17,7 +17,7 @@ describe Fletcher::Model::Ebay, :vcr => { :cassette_name => "ebay_model" } do
|
|
17
17
|
# Diable Realtime Test, too inconsistent
|
18
18
|
it "should return correct model info" do
|
19
19
|
model = described_class.new
|
20
|
-
model.parse Fletcher::Data.read(
|
20
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:ebay).url)
|
21
21
|
model.name.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
23
23
|
model.image.should_not be_nil
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch etsy product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:etsy).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -17,7 +17,7 @@ describe Fletcher::Model::Etsy, :vcr do
|
|
17
17
|
context "with valid data" do
|
18
18
|
it "should return correct model info" do
|
19
19
|
model = described_class.new
|
20
|
-
model.parse Fletcher::Data.read(
|
20
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:etsy).url)
|
21
21
|
model.name.should_not be_nil
|
22
22
|
model.description.should_not be_nil
|
23
23
|
model.price.should_not be_nil
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch gamecouk product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:gamecouk).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Gamecouk, :vcr do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:gamecouk).url)
|
20
20
|
model.name.should_not be_nil
|
21
21
|
model.description.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch googleshopping product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:googleshopping).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Googleshopping, :vcr do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:googleshopping).url)
|
20
20
|
model.name.should_not be_nil
|
21
21
|
model.description.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fletcher, :vcr do
|
4
|
+
describe :fetch, :vcr do
|
5
|
+
it "should return correct product info" do
|
6
|
+
product = Fletcher.fetch FactoryGirl.build(:newegg).url
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Fletcher::Model::Newegg, :vcr do
|
12
|
+
describe "parse", :vcr do
|
13
|
+
context "with valid data" do
|
14
|
+
it "should return correct product info" do
|
15
|
+
product = described_class.new
|
16
|
+
product.parse Fletcher::Data.read(FactoryGirl.build(:newegg).url)
|
17
|
+
product.name.should_not be_nil
|
18
|
+
product.description.should_not be_nil
|
19
|
+
#product.price.should_not be_nil
|
20
|
+
product.images.should_not be_empty
|
21
|
+
product.image.should_not be_nil
|
22
|
+
product.image.src.should_not be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch playcom product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:playcom).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Playcom, :vcr do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:playcom).url)
|
20
20
|
model.doc = nil
|
21
21
|
model.name.should_not be_nil
|
22
22
|
model.description.should_not be_nil
|
@@ -3,8 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should return correct model info" do
|
6
|
-
product = Fletcher.fetch
|
7
|
-
puts product.image.inspect
|
6
|
+
product = Fletcher.fetch FactoryGirl.build(:steam).url
|
8
7
|
end
|
9
8
|
end
|
10
9
|
end
|
@@ -14,7 +13,7 @@ describe Fletcher::Model::Steam, :vcr do
|
|
14
13
|
context "with valid data" do
|
15
14
|
it "should return correct model info" do
|
16
15
|
model = described_class.new
|
17
|
-
model.parse Fletcher::Data.read(
|
16
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:steam).url)
|
18
17
|
model.doc = nil
|
19
18
|
model.description = ''
|
20
19
|
model.name.should_not be_nil
|
@@ -9,7 +9,7 @@ end
|
|
9
9
|
describe Fletcher, :vcr do
|
10
10
|
describe :fetch, :vcr do
|
11
11
|
it "should fetch a thinkgeek product's information" do
|
12
|
-
item = Fletcher.fetch(
|
12
|
+
item = Fletcher.fetch(FactoryGirl.build(:thinkgeek).url)
|
13
13
|
item.should_not be_nil
|
14
14
|
item.image.should_not be_nil
|
15
15
|
item.name.should_not be_nil
|
@@ -17,7 +17,7 @@ describe Fletcher, :vcr do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should fetch a thinkgeek product with price range" do
|
20
|
-
item = Fletcher.fetch(
|
20
|
+
item = Fletcher.fetch(FactoryGirl.build(:thinkgeek_with_price_range).url)
|
21
21
|
item.should_not be_nil
|
22
22
|
item.image.should_not be_nil
|
23
23
|
item.name.should_not be_nil
|
@@ -31,7 +31,7 @@ describe Fletcher::Model::Thinkgeek, :vcr do
|
|
31
31
|
context "with valid data" do
|
32
32
|
it "should return correct model info" do
|
33
33
|
model = described_class.new
|
34
|
-
model.parse Fletcher::Data.read(
|
34
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:thinkgeek).url)
|
35
35
|
model.name.should_not be_nil
|
36
36
|
model.price.should_not be_nil
|
37
37
|
model.image.should_not be_nil
|
@@ -6,12 +6,12 @@ end
|
|
6
6
|
|
7
7
|
describe Fletcher::Nokogiri::XML::NodeSet, :vcr do
|
8
8
|
before :each do
|
9
|
-
@doc = Fletcher::Data.read(
|
9
|
+
@doc = Fletcher::Data.read(FactoryGirl.build(:valid).url)
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "first_string", :vcr do
|
13
13
|
it "should return a valid string" do
|
14
|
-
nodeset = @doc.xpath(
|
14
|
+
nodeset = @doc.xpath(FactoryGirl.build(:valid).title_xpath)
|
15
15
|
string = nodeset.first_string
|
16
16
|
string.should_not be_nil
|
17
17
|
end
|
@@ -19,7 +19,7 @@ describe Fletcher::Nokogiri::XML::NodeSet, :vcr do
|
|
19
19
|
|
20
20
|
describe "attribute_array", :vcr do
|
21
21
|
it "should return an array of attribute hashes" do
|
22
|
-
nodeset = @doc.xpath(
|
22
|
+
nodeset = @doc.xpath(FactoryGirl.build(:valid).images_xpath)
|
23
23
|
attribute_array = nodeset.attribute_array
|
24
24
|
attribute_array.class.should == Array
|
25
25
|
end
|
data/spec/lib/fletcher_spec.rb
CHANGED
@@ -8,19 +8,15 @@ describe Fletcher, :vcr do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
it "should return #{model} sym when using a #{model} domain" do
|
19
|
-
described_class.identify_model(Factory(model).url).should == model
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
11
|
+
describe :model_classes do
|
12
|
+
it "should return an array of classes" do
|
13
|
+
models = described_class.model_classes
|
14
|
+
models.is_a?(Array).should == true
|
15
|
+
models.first.class.should == Class
|
16
|
+
end
|
17
|
+
end
|
23
18
|
|
19
|
+
context :models do
|
24
20
|
describe :fetch, :vcr do
|
25
21
|
# for model in Fletcher.models
|
26
22
|
# it "should return valid data for #{model} model" do
|
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.2
|
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: 2012-11-
|
13
|
+
date: 2012-11-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hashie
|
@@ -124,22 +124,6 @@ dependencies:
|
|
124
124
|
- - ~>
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: 1.6.4
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
|
-
name: rcov
|
129
|
-
requirement: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
|
-
requirements:
|
132
|
-
- - ! '>='
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
version: '0'
|
135
|
-
type: :development
|
136
|
-
prerelease: false
|
137
|
-
version_requirements: !ruby/object:Gem::Requirement
|
138
|
-
none: false
|
139
|
-
requirements:
|
140
|
-
- - ! '>='
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
version: '0'
|
143
127
|
- !ruby/object:Gem::Dependency
|
144
128
|
name: rspec
|
145
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -244,12 +228,14 @@ files:
|
|
244
228
|
- lib/fletcher.rb
|
245
229
|
- lib/fletcher/cli/utility.rb
|
246
230
|
- lib/fletcher/data.rb
|
231
|
+
- lib/fletcher/model.rb
|
247
232
|
- lib/fletcher/models/amazon.rb
|
248
233
|
- lib/fletcher/models/base.rb
|
249
234
|
- lib/fletcher/models/ebay.rb
|
250
235
|
- lib/fletcher/models/etsy.rb
|
251
236
|
- lib/fletcher/models/gamecouk.rb
|
252
237
|
- lib/fletcher/models/googleshopping.rb
|
238
|
+
- lib/fletcher/models/newegg.rb
|
253
239
|
- lib/fletcher/models/playcom.rb
|
254
240
|
- lib/fletcher/models/steam.rb
|
255
241
|
- lib/fletcher/models/thinkgeek.rb
|
@@ -258,16 +244,19 @@ files:
|
|
258
244
|
- spec/bin/fletcher_spec.rb
|
259
245
|
- spec/factories/models.rb
|
260
246
|
- spec/lib/fletcher/data_spec.rb
|
247
|
+
- spec/lib/fletcher/model_spec.rb
|
261
248
|
- spec/lib/fletcher/models/amazon_spec.rb
|
262
249
|
- spec/lib/fletcher/models/base_spec.rb
|
263
250
|
- spec/lib/fletcher/models/ebay_spec.rb
|
264
251
|
- spec/lib/fletcher/models/etsy_spec.rb
|
265
252
|
- spec/lib/fletcher/models/gamecouk_spec.rb
|
266
253
|
- spec/lib/fletcher/models/googleshopping_spec.rb
|
254
|
+
- spec/lib/fletcher/models/newegg_spec.rb
|
267
255
|
- spec/lib/fletcher/models/playcom_spec.rb
|
268
256
|
- spec/lib/fletcher/models/steam_spec.rb
|
269
257
|
- spec/lib/fletcher/models/thinkgeek_spec.rb
|
270
258
|
- spec/lib/fletcher/nokogiri_spec.rb
|
259
|
+
- spec/lib/fletcher/string_spec.rb
|
271
260
|
- spec/lib/fletcher_spec.rb
|
272
261
|
- spec/spec_helper.rb
|
273
262
|
- spec/support/benchmark.rb
|
@@ -291,7 +280,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
291
280
|
version: '0'
|
292
281
|
segments:
|
293
282
|
- 0
|
294
|
-
hash:
|
283
|
+
hash: -4007123474311124799
|
295
284
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
296
285
|
none: false
|
297
286
|
requirements:
|