wildcard-pair 0.3.1
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.
- checksums.yaml +7 -0
- data/lib/wildcard-pair.rb +5 -0
- data/lib/wildcard-pair/Article.rb +90 -0
- data/lib/wildcard-pair/ArticleCard.rb +84 -0
- data/lib/wildcard-pair/Color.rb +41 -0
- data/lib/wildcard-pair/Media.rb +4 -0
- data/lib/wildcard-pair/Media/Image.rb +46 -0
- data/lib/wildcard-pair/Media/Video.rb +70 -0
- data/lib/wildcard-pair/Offer.rb +102 -0
- data/lib/wildcard-pair/Price.rb +44 -0
- data/lib/wildcard-pair/Product.rb +132 -0
- data/lib/wildcard-pair/ProductCard.rb +117 -0
- data/lib/wildcard-pair/ProductSearchCard.rb +89 -0
- data/lib/wildcard-pair/ProductSearchResult.rb +54 -0
- data/lib/wildcard-pair/Rating.rb +47 -0
- data/lib/wildcard-pair/Review.rb +105 -0
- data/lib/wildcard-pair/ReviewCard.rb +82 -0
- data/lib/wildcard-pair/VideoCard.rb +84 -0
- data/lib/wildcard-pair/hash_mappable.rb +18 -0
- data/lib/wildcard-pair/util/extract_metatags.rb +99 -0
- metadata +124 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
require_relative 'hash_mappable.rb'
|
3
|
+
require 'active_model'
|
4
|
+
|
5
|
+
module WildcardPair
|
6
|
+
class Price
|
7
|
+
include ActiveModel::Validations
|
8
|
+
include ActiveModel::Serializers::JSON
|
9
|
+
include WildcardPair::HashMappable
|
10
|
+
|
11
|
+
attr_accessor :price, :currency
|
12
|
+
|
13
|
+
validates :price, presence: true, numericality: {greater_than_or_equal_to: 0}
|
14
|
+
|
15
|
+
def initialize(attributes = {})
|
16
|
+
|
17
|
+
#let's set currency to USD by default
|
18
|
+
@currency = "USD"
|
19
|
+
|
20
|
+
attributes.each do |name, value|
|
21
|
+
send("#{name}=", value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def attributes
|
26
|
+
instance_values
|
27
|
+
end
|
28
|
+
|
29
|
+
#exclude validation fields in the JSON output
|
30
|
+
def as_json(options={})
|
31
|
+
super(options.merge({:except => [:errors, :validation_context]}))
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def to_json(options = {})
|
36
|
+
if self.valid?
|
37
|
+
super(options)
|
38
|
+
else
|
39
|
+
raise "Price is not valid - please remedy the following errors:" << self.errors.messages.to_s
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
require 'active_model'
|
4
|
+
require_relative 'hash_mappable.rb'
|
5
|
+
|
6
|
+
module WildcardPair
|
7
|
+
class Product
|
8
|
+
|
9
|
+
include ActiveModel::Validations
|
10
|
+
include ActiveModel::Serializers::JSON
|
11
|
+
include WildcardPair::HashMappable
|
12
|
+
|
13
|
+
attr_accessor :name, :merchant, :brand, :description, :gender, :rating, :rating_scale, :rating_count, :sizes, :model, :app_link_ios, :app_link_android
|
14
|
+
attr_reader :colors, :images, :related_items, :referenced_items, :options
|
15
|
+
|
16
|
+
validates :name, presence: true
|
17
|
+
validates :description, presence: true
|
18
|
+
validates :gender, allow_nil: true, inclusion: {in: %w(male female unisex) }
|
19
|
+
|
20
|
+
validate :validateColors
|
21
|
+
validate :validateImages
|
22
|
+
|
23
|
+
def initialize(attributes = {})
|
24
|
+
attributes.each do |name, value|
|
25
|
+
send("#{name}=", value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def attributes
|
30
|
+
instance_values
|
31
|
+
end
|
32
|
+
|
33
|
+
def metatags=(metatags)
|
34
|
+
if metatags.nil? || !metatags.is_a?(Hash)
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
#see what you can set based on metatags
|
39
|
+
self.name=metatags['title']
|
40
|
+
self.description=metatags['description']
|
41
|
+
self.images=metatags['image_url']
|
42
|
+
self.app_link_ios=metatags['applink_ios']
|
43
|
+
self.app_link_android=metatags['applink_android']
|
44
|
+
end
|
45
|
+
|
46
|
+
def colors=(colors)
|
47
|
+
@colors ||= Array.new
|
48
|
+
|
49
|
+
if colors.is_a?(Array)
|
50
|
+
colors.each do |color|
|
51
|
+
@colors << map_hash(color, Color.new)
|
52
|
+
end
|
53
|
+
elsif colors.is_a?(Color)
|
54
|
+
@colors << colors
|
55
|
+
else
|
56
|
+
@colors << map_hash(colors, Color.new)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def images=(images)
|
61
|
+
@images ||= Array.new
|
62
|
+
|
63
|
+
if images.is_a?(Array)
|
64
|
+
@images = images
|
65
|
+
else
|
66
|
+
@images << images
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def related_items=(related_items)
|
71
|
+
@related_items ||= Array.new
|
72
|
+
|
73
|
+
if related_items.is_a?(Array)
|
74
|
+
@related_items = related_items
|
75
|
+
else
|
76
|
+
@related_items << related_items
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def referenced_items=(referenced_items)
|
81
|
+
@referenced_items ||= Array.new
|
82
|
+
|
83
|
+
if referenced_items.is_a?(Array)
|
84
|
+
@referenced_items = referenced_items
|
85
|
+
else
|
86
|
+
@referenced_items << referenced_items
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def options=(options)
|
91
|
+
@options ||= Array.new
|
92
|
+
|
93
|
+
if options.is_a?(Array)
|
94
|
+
@options = options
|
95
|
+
else
|
96
|
+
@options << options
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def validateColors
|
101
|
+
if (!@colors.nil? && @colors.any?)
|
102
|
+
@colors.each do |color|
|
103
|
+
if (!color.is_a?(Color) || !color.valid?)
|
104
|
+
errors.add(:colors, "At least one of the colors is an invalid color object")
|
105
|
+
return
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def validateImages
|
112
|
+
if @images.nil? || (@images.is_a?(Array) && !@images.any?)
|
113
|
+
errors.add(:images, 'A product image is required')
|
114
|
+
return
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
#exclude validation fields in the JSON output
|
119
|
+
def as_json(options={})
|
120
|
+
super(options.merge({:except => [:errors, :validation_context]}))
|
121
|
+
end
|
122
|
+
|
123
|
+
def to_json(options={})
|
124
|
+
if self.valid?
|
125
|
+
super(options)
|
126
|
+
else
|
127
|
+
raise "Product is not valid - please remedy the following errors:" << self.errors.messages.to_s
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
require 'active_model'
|
4
|
+
require_relative 'hash_mappable.rb'
|
5
|
+
|
6
|
+
module WildcardPair
|
7
|
+
class ProductCard
|
8
|
+
private
|
9
|
+
|
10
|
+
attr_accessor :offers, :product, :card_type, :pair_version
|
11
|
+
|
12
|
+
public
|
13
|
+
|
14
|
+
include ActiveModel::Validations
|
15
|
+
include ActiveModel::Serializers::JSON
|
16
|
+
include WildcardPair::HashMappable
|
17
|
+
|
18
|
+
attr_accessor :web_url
|
19
|
+
attr_reader :offers, :card_type, :pair_version, :product
|
20
|
+
|
21
|
+
validates :web_url, presence: true
|
22
|
+
validate :validateOffers
|
23
|
+
validate :validateProduct
|
24
|
+
|
25
|
+
def initialize(attributes = {})
|
26
|
+
attributes.each do |name, value|
|
27
|
+
send("#{name}=", value)
|
28
|
+
end
|
29
|
+
|
30
|
+
@card_type = 'product'
|
31
|
+
|
32
|
+
if !Gem.loaded_specs['wildcard-pair'].nil?
|
33
|
+
@pair_version = Gem.loaded_specs['wildcard-pair'].version.to_s
|
34
|
+
else
|
35
|
+
@pair_version = "unknown"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def attributes
|
40
|
+
instance_values
|
41
|
+
end
|
42
|
+
|
43
|
+
def populate_from_metatags(web_url)
|
44
|
+
@web_url=web_url
|
45
|
+
metatags = WildcardPair::ExtractMetaTags.extract(@web_url)
|
46
|
+
|
47
|
+
##now that we've extracted metatags, create a Product and Offer object with it
|
48
|
+
self.product=WildcardPair::Product.new metatags: metatags
|
49
|
+
self.offers=WildcardPair::Offer.new metatags: metatags
|
50
|
+
end
|
51
|
+
|
52
|
+
def offers=(offers)
|
53
|
+
@offers ||= Array.new
|
54
|
+
|
55
|
+
if offers.is_a?(Array)
|
56
|
+
offers.each do |offer|
|
57
|
+
@offers << map_hash(offer, Offer.new)
|
58
|
+
end
|
59
|
+
elsif offers.is_a?(Offer)
|
60
|
+
@offers << offers
|
61
|
+
else
|
62
|
+
@offers << map_hash(offers, Offer.new)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def product=(product)
|
67
|
+
@product = map_hash(product, WildcardPair::Product.new)
|
68
|
+
end
|
69
|
+
|
70
|
+
def validateOffers
|
71
|
+
if @offers.nil? || (@offers.is_a?(Array) && !@offers.any?)
|
72
|
+
errors.add(:offers, 'At least one offer is required')
|
73
|
+
return
|
74
|
+
end
|
75
|
+
|
76
|
+
@offers.each do |offer|
|
77
|
+
if !offer.is_a?(Offer)
|
78
|
+
errors.add(:offers, "At least one of the offers is invalid")
|
79
|
+
elsif !offer.valid?
|
80
|
+
offer.errors.each do |error, msg|
|
81
|
+
errors["offer[%s]" % error] = msg
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def validateProduct
|
88
|
+
if @product.nil? || !@product.is_a?(Product)
|
89
|
+
errors.add(:product, "A product is required")
|
90
|
+
return
|
91
|
+
end
|
92
|
+
|
93
|
+
if !@product.nil?
|
94
|
+
if !@product.valid?
|
95
|
+
@product.errors.each do |error, msg|
|
96
|
+
errors["product[%s]" % error] = msg
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#exclude validation fields in the JSON output
|
103
|
+
def as_json(options={})
|
104
|
+
super(options.merge({:except => [:errors, :validation_context]}))
|
105
|
+
end
|
106
|
+
|
107
|
+
def to_json(options={})
|
108
|
+
if self.valid?
|
109
|
+
super(options)
|
110
|
+
else
|
111
|
+
raise "Product Card is not valid - please remedy the following errors:" << self.errors.messages.to_s
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#ProductCard
|
2
|
+
#!/usr/bin/env ruby -wKU
|
3
|
+
|
4
|
+
require 'active_model'
|
5
|
+
require_relative 'hash_mappable.rb'
|
6
|
+
|
7
|
+
module WildcardPair
|
8
|
+
class ProductSearchCard
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
attr_accessor :products, :card_type, :pair_version
|
13
|
+
|
14
|
+
public
|
15
|
+
|
16
|
+
include ActiveModel::Validations
|
17
|
+
include ActiveModel::Serializers::JSON
|
18
|
+
include WildcardPair::HashMappable
|
19
|
+
|
20
|
+
attr_accessor :total_results
|
21
|
+
|
22
|
+
attr_reader :products, :card_type, :pair_version
|
23
|
+
|
24
|
+
validates :total_results, presence: true, numericality: {only_integer: true, greater_than_or_equal_to: 0}
|
25
|
+
validate :validateSearchResults
|
26
|
+
|
27
|
+
def initialize(attributes = {})
|
28
|
+
attributes.each do |name, value|
|
29
|
+
send("#{name}=", value)
|
30
|
+
end
|
31
|
+
|
32
|
+
@card_type = 'product_search'
|
33
|
+
|
34
|
+
if !Gem.loaded_specs['wildcard-pair'].nil?
|
35
|
+
@pair_version = Gem.loaded_specs['wildcard-pair'].version.to_s
|
36
|
+
else
|
37
|
+
@pair_version = "unknown"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def attributes
|
42
|
+
instance_values
|
43
|
+
end
|
44
|
+
|
45
|
+
def products=(products)
|
46
|
+
@products ||= Array.new
|
47
|
+
|
48
|
+
if products.is_a?(Array)
|
49
|
+
products.each do |product|
|
50
|
+
@products << map_hash(product, ProductSearchResult.new)
|
51
|
+
end
|
52
|
+
elsif products.is_a?(ProductSearchResult)
|
53
|
+
@products << products
|
54
|
+
else
|
55
|
+
@products << map_hash(products, ProductSearchResult.new)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def validateSearchResults
|
60
|
+
if @products.nil?
|
61
|
+
errors.add(:products, "Products can be empty, but must exist")
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
@products.each do |product|
|
66
|
+
if (!product.is_a?(ProductSearchResult) || !product.valid?)
|
67
|
+
errors.add(:products, "One of the products in the search result is invalid")
|
68
|
+
return
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
#exclude validation fields in the JSON output
|
75
|
+
def as_json(options={})
|
76
|
+
super(options.merge({:except => [:errors, :validation_context]}))
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_json(options={})
|
80
|
+
if self.valid?
|
81
|
+
super(options)
|
82
|
+
else
|
83
|
+
raise "Product Search Card is not valid - please remedy below errors:" << self.errors.messages.to_s
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
require_relative 'hash_mappable.rb'
|
3
|
+
|
4
|
+
module WildcardPair
|
5
|
+
class ProductSearchResult
|
6
|
+
include ActiveModel::Validations
|
7
|
+
include ActiveModel::Serializers::JSON
|
8
|
+
include WildcardPair::HashMappable
|
9
|
+
|
10
|
+
attr_accessor :name, :price, :product_card_address, :image_url
|
11
|
+
|
12
|
+
validates :name, presence: true
|
13
|
+
validates :price, presence: true
|
14
|
+
validates :product_card_address, presence: true
|
15
|
+
validates :image_url, presence: true
|
16
|
+
|
17
|
+
validate :validatePrice
|
18
|
+
|
19
|
+
def initialize(attributes = {})
|
20
|
+
attributes.each do |name, value|
|
21
|
+
send("#{name}=", value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def attributes
|
26
|
+
instance_values
|
27
|
+
end
|
28
|
+
|
29
|
+
def price=(price)
|
30
|
+
@price = map_hash(price, WildcardPair::Price.new)
|
31
|
+
end
|
32
|
+
|
33
|
+
def validatePrice
|
34
|
+
if @price.nil? || !@price.is_a?(Price) || !@price.valid?
|
35
|
+
errors.add(:price, 'Price does not exist or is invalid')
|
36
|
+
return
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
#exclude validation fields in the JSON output
|
41
|
+
def as_json(options={})
|
42
|
+
super(options.merge({:except => [:errors, :validation_context]}))
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_json(options={})
|
46
|
+
if self.valid?
|
47
|
+
super(options)
|
48
|
+
else
|
49
|
+
raise "ProductSearchResult is not valid - please remedy the following errors:" << self.errors.messages.to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
|
3
|
+
require 'active_model'
|
4
|
+
require_relative 'hash_mappable.rb'
|
5
|
+
|
6
|
+
module WildcardPair
|
7
|
+
class Rating
|
8
|
+
|
9
|
+
include ActiveModel::Validations
|
10
|
+
include ActiveModel::Serializers::JSON
|
11
|
+
include WildcardPair::HashMappable
|
12
|
+
|
13
|
+
# required fields
|
14
|
+
attr_accessor :rating, :minimum_rating, :maximum_rating
|
15
|
+
# optional fields
|
16
|
+
attr_accessor :number_of_ratings
|
17
|
+
|
18
|
+
validates :rating, presence: true, numericality: {greater_than_or_equal_to: 0}
|
19
|
+
validates :minimum_rating, presence: true, numericality: {greater_than_or_equal_to: 0}
|
20
|
+
validates :maximum_rating, presence: true, numericality: {greater_than_or_equal_to: 0}
|
21
|
+
validates :number_of_ratings, allow_nil: true, numericality: {only_integer: true, greater_than_or_equal_to: 0}
|
22
|
+
|
23
|
+
def initialize(attributes = {})
|
24
|
+
attributes.each do |name, value|
|
25
|
+
send("#{name}=", value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def attributes
|
30
|
+
instance_values
|
31
|
+
end
|
32
|
+
|
33
|
+
#exclude validation fields in the JSON output
|
34
|
+
def as_json(options={})
|
35
|
+
super(options.merge({:except => [:errors, :validation_context]}))
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_json(options={})
|
39
|
+
if self.valid?
|
40
|
+
super(options)
|
41
|
+
else
|
42
|
+
raise "Video is not valid - please remedy the following errors:" << self.errors.messages.to_s
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|