cardmagic-etsy 0.3.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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +13 -0
- data/Gemfile +11 -0
- data/LICENSE +9 -0
- data/README.md +348 -0
- data/Rakefile +12 -0
- data/etsy.gemspec +34 -0
- data/lib/etsy.rb +223 -0
- data/lib/etsy/about.rb +15 -0
- data/lib/etsy/address.rb +47 -0
- data/lib/etsy/attribute_value.rb +46 -0
- data/lib/etsy/basic_client.rb +32 -0
- data/lib/etsy/category.rb +84 -0
- data/lib/etsy/country.rb +27 -0
- data/lib/etsy/favorite_listing.rb +26 -0
- data/lib/etsy/image.rb +44 -0
- data/lib/etsy/listing.rb +296 -0
- data/lib/etsy/model.rb +127 -0
- data/lib/etsy/payment_template.rb +33 -0
- data/lib/etsy/profile.rb +49 -0
- data/lib/etsy/receipt.rb +37 -0
- data/lib/etsy/request.rb +150 -0
- data/lib/etsy/response.rb +128 -0
- data/lib/etsy/section.rb +16 -0
- data/lib/etsy/secure_client.rb +131 -0
- data/lib/etsy/shipping_info.rb +27 -0
- data/lib/etsy/shipping_template.rb +41 -0
- data/lib/etsy/shop.rb +88 -0
- data/lib/etsy/transaction.rb +29 -0
- data/lib/etsy/user.rb +109 -0
- data/lib/etsy/variation/property_set.rb +71 -0
- data/lib/etsy/verification_request.rb +17 -0
- data/lib/etsy/version.rb +3 -0
- data/test/fixtures/about/getAbout.json +16 -0
- data/test/fixtures/address/getUserAddresses.json +12 -0
- data/test/fixtures/attribute_value/findAllListingPropertyValues.json +44 -0
- data/test/fixtures/category/findAllSubCategoryChildren.json +78 -0
- data/test/fixtures/category/findAllTopCategory.json +347 -0
- data/test/fixtures/category/findAllTopCategory.single.json +18 -0
- data/test/fixtures/category/findAllTopCategoryChildren.json +308 -0
- data/test/fixtures/category/getCategory.multiple.json +28 -0
- data/test/fixtures/category/getCategory.single.json +18 -0
- data/test/fixtures/country/getCountry.json +1 -0
- data/test/fixtures/favorite_listing/findAllFavoriteListings.json +1 -0
- data/test/fixtures/image/findAllListingImages.json +102 -0
- data/test/fixtures/listing/findAllListingActive.category.json +827 -0
- data/test/fixtures/listing/findAllShopListings.json +69 -0
- data/test/fixtures/listing/getListing.multiple.json +1 -0
- data/test/fixtures/listing/getListing.single.includeImages.json +1 -0
- data/test/fixtures/listing/getListing.single.json +1 -0
- data/test/fixtures/payment_template/getPaymentTemplate.json +1 -0
- data/test/fixtures/profile/new.json +28 -0
- data/test/fixtures/receipt/findAllShopReceipts.json +28 -0
- data/test/fixtures/section/getShopSection.json +18 -0
- data/test/fixtures/shipping_info/getShippingInfo.json +1 -0
- data/test/fixtures/shipping_template/getShippingTemplate.json +1 -0
- data/test/fixtures/shop/findAllShop.json +1 -0
- data/test/fixtures/shop/findAllShop.single.json +1 -0
- data/test/fixtures/shop/getShop.multiple.json +1 -0
- data/test/fixtures/shop/getShop.single.json +34 -0
- data/test/fixtures/transaction/findAllShopTransactions.json +1 -0
- data/test/fixtures/user/getUser.multiple.json +29 -0
- data/test/fixtures/user/getUser.single.json +13 -0
- data/test/fixtures/user/getUser.single.private.json +18 -0
- data/test/fixtures/user/getUser.single.withProfile.json +38 -0
- data/test/fixtures/user/getUser.single.withShops.json +41 -0
- data/test/test_helper.rb +45 -0
- data/test/unit/etsy/address_test.rb +61 -0
- data/test/unit/etsy/attribute_value_test.rb +67 -0
- data/test/unit/etsy/basic_client_test.rb +30 -0
- data/test/unit/etsy/category_test.rb +106 -0
- data/test/unit/etsy/country_test.rb +64 -0
- data/test/unit/etsy/favorite_listing_test.rb +44 -0
- data/test/unit/etsy/image_test.rb +51 -0
- data/test/unit/etsy/listing_test.rb +268 -0
- data/test/unit/etsy/model_test.rb +64 -0
- data/test/unit/etsy/payment_template_test.rb +68 -0
- data/test/unit/etsy/profile_test.rb +111 -0
- data/test/unit/etsy/receipt_test.rb +107 -0
- data/test/unit/etsy/request_test.rb +190 -0
- data/test/unit/etsy/response_test.rb +175 -0
- data/test/unit/etsy/section_test.rb +28 -0
- data/test/unit/etsy/secure_client_test.rb +132 -0
- data/test/unit/etsy/shipping_info_test.rb +24 -0
- data/test/unit/etsy/shipping_template_test.rb +24 -0
- data/test/unit/etsy/shop_about_test.rb +43 -0
- data/test/unit/etsy/shop_test.rb +116 -0
- data/test/unit/etsy/transaction_test.rb +61 -0
- data/test/unit/etsy/user_test.rb +250 -0
- data/test/unit/etsy/verification_request_test.rb +26 -0
- data/test/unit/etsy_test.rb +173 -0
- metadata +293 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Etsy
|
2
|
+
class ShippingInfo
|
3
|
+
include Etsy::Model
|
4
|
+
|
5
|
+
attribute :id, :from => :shipping_info_id
|
6
|
+
|
7
|
+
attributes :origin_country_id, :destination_country_id, :currency_code, :primary_cost, :secondary_cost, :listing_id, :region_id, :origin_country_name, :destination_country_name
|
8
|
+
|
9
|
+
def self.find(id, credentials = {})
|
10
|
+
options = {
|
11
|
+
:access_token => credentials[:access_token],
|
12
|
+
:access_secret => credentials[:access_secret],
|
13
|
+
:require_secure => true
|
14
|
+
}
|
15
|
+
get("/shipping/info/#{id}", options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.find_by_listing_id(listing_id, credentials = {})
|
19
|
+
options = {
|
20
|
+
:access_token => credentials[:access_token],
|
21
|
+
:access_secret => credentials[:access_secret],
|
22
|
+
:require_secure => true
|
23
|
+
}
|
24
|
+
get("/listings/#{listing_id}/shipping/info", options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Etsy
|
2
|
+
class ShippingTemplate
|
3
|
+
include Etsy::Model
|
4
|
+
|
5
|
+
attribute :id, :from => :shipping_template_id
|
6
|
+
|
7
|
+
attributes :title, :user_id
|
8
|
+
|
9
|
+
def self.create(options = {})
|
10
|
+
options.merge!(:require_secure => true)
|
11
|
+
post("/shipping/templates", options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.find(id, credentials = {})
|
15
|
+
options = {
|
16
|
+
:access_token => credentials[:access_token],
|
17
|
+
:access_secret => credentials[:access_secret],
|
18
|
+
:require_secure => true
|
19
|
+
}
|
20
|
+
get("/shipping/templates/#{id}", options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.find_entries(id, credentials = {})
|
24
|
+
options = {
|
25
|
+
:access_token => credentials[:access_token],
|
26
|
+
:access_secret => credentials[:access_secret],
|
27
|
+
:require_secure => true
|
28
|
+
}
|
29
|
+
get("/shipping/templates/#{id}/entries", options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.find_by_user(user, credentials = {})
|
33
|
+
options = {
|
34
|
+
:access_token => credentials[:access_token],
|
35
|
+
:access_secret => credentials[:access_secret],
|
36
|
+
:require_secure => true
|
37
|
+
}
|
38
|
+
get("/users/#{user.id}/shipping/templates", options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/etsy/shop.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = Shop
|
4
|
+
#
|
5
|
+
# Represents a single Etsy shop. Users may or may not have an associated shop.
|
6
|
+
#
|
7
|
+
# A shop has the following attributes:
|
8
|
+
#
|
9
|
+
# [name] The shop's name
|
10
|
+
# [title] A brief heading for the shop's main page
|
11
|
+
# [announcement] An announcement to buyers (displays on the shop's home page)
|
12
|
+
# [message] The message sent to users who buy from this shop
|
13
|
+
# [image_url] The full URL to the shops's banner image
|
14
|
+
# [active_listings_count] The number of active listings present in this shop
|
15
|
+
# [url] The full URL to the shop on Etsy
|
16
|
+
# [favorers_count] Number of favorers
|
17
|
+
|
18
|
+
class Shop
|
19
|
+
|
20
|
+
include Etsy::Model
|
21
|
+
|
22
|
+
attributes :title, :announcement, :user_id
|
23
|
+
|
24
|
+
attribute :id, :from => :shop_id
|
25
|
+
attribute :image_url, :from => 'image_url_760x100'
|
26
|
+
attribute :active_listings_count, :from => 'listing_active_count'
|
27
|
+
attribute :updated, :from => :last_updated_tsz
|
28
|
+
attribute :created, :from => :creation_tsz
|
29
|
+
attribute :name, :from => :shop_name
|
30
|
+
attribute :message, :from => :sale_message
|
31
|
+
attribute :url, :from => :url
|
32
|
+
attribute :favorers_count, :from => :num_favorers
|
33
|
+
attribute :icon_url, :from => 'icon_url_fullxfull'
|
34
|
+
|
35
|
+
# Retrieve one or more shops by name or ID:
|
36
|
+
#
|
37
|
+
# Etsy::Shop.find('reagent')
|
38
|
+
#
|
39
|
+
# You can find multiple shops by passing an array of identifiers:
|
40
|
+
#
|
41
|
+
# Etsy::Shop.find(['reagent', 'littletjane'])
|
42
|
+
#
|
43
|
+
def self.find(*identifiers_and_options)
|
44
|
+
self.find_one_or_more('shops', identifiers_and_options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Retrieve a list of all shops. By default it fetches 25 at a time, but that can
|
48
|
+
# be configured by passing the :limit and :offset parameters:
|
49
|
+
#
|
50
|
+
# Etsy::Shop.all(:limit => 100, :offset => 100)
|
51
|
+
#
|
52
|
+
def self.all(options = {})
|
53
|
+
self.get_all("/shops", options)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Time that this shop was created
|
57
|
+
#
|
58
|
+
def created_at
|
59
|
+
Time.at(created)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Time that this shop was last updated
|
63
|
+
#
|
64
|
+
def updated_at
|
65
|
+
Time.at(updated)
|
66
|
+
end
|
67
|
+
|
68
|
+
# The collection of listings associated with this shop
|
69
|
+
#
|
70
|
+
def listings(state = nil, options = {})
|
71
|
+
state = state ? {:state => state} : {}
|
72
|
+
Listing.find_all_by_shop_id(id, state.merge(options).merge(oauth))
|
73
|
+
end
|
74
|
+
|
75
|
+
def sections
|
76
|
+
Section.find_by_shop(self)
|
77
|
+
end
|
78
|
+
|
79
|
+
def about
|
80
|
+
About.find_by_shop(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
def oauth
|
85
|
+
oauth = (token && secret) ? {:access_token => token, :access_secret => secret} : {}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Etsy
|
2
|
+
class Transaction
|
3
|
+
include Model
|
4
|
+
|
5
|
+
attribute :id, :from => :transaction_id
|
6
|
+
attribute :buyer_id, :from => :buyer_user_id
|
7
|
+
attributes :quantity, :listing_id
|
8
|
+
|
9
|
+
def self.find_all_by_shop_id(shop_id, options = {})
|
10
|
+
get_all("/shops/#{shop_id}/transactions", options)
|
11
|
+
end
|
12
|
+
|
13
|
+
#Find all Transactions by the buyer_id
|
14
|
+
#
|
15
|
+
def self.find_all_by_buyer_id(user_id, options = {})
|
16
|
+
get_all("/users/#{user_id}/transactions", options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.find_all_by_receipt_id(receipt_id, options = {})
|
20
|
+
get_all("/receipts/#{receipt_id}/transactions", options)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def buyer
|
25
|
+
@buyer ||= User.find(buyer_id)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/etsy/user.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = User
|
4
|
+
#
|
5
|
+
# Represents a single Etsy user - has the following attributes:
|
6
|
+
#
|
7
|
+
# [id] The unique identifier for this user
|
8
|
+
# [username] This user's username
|
9
|
+
# [email] This user's email address (authenticated calls only)
|
10
|
+
#
|
11
|
+
class User
|
12
|
+
|
13
|
+
include Etsy::Model
|
14
|
+
|
15
|
+
attribute :id, :from => :user_id
|
16
|
+
attribute :username, :from => :login_name
|
17
|
+
attribute :email, :from => :primary_email
|
18
|
+
attribute :created, :from => :creation_tsz
|
19
|
+
|
20
|
+
association :profile, :from => 'Profile'
|
21
|
+
association :shops, :from => 'Shops'
|
22
|
+
|
23
|
+
# Retrieve one or more users by name or ID:
|
24
|
+
#
|
25
|
+
# Etsy::User.find('reagent')
|
26
|
+
#
|
27
|
+
# You can find multiple users by passing an array of identifiers:
|
28
|
+
#
|
29
|
+
# Etsy::User.find(['reagent', 'littletjane'])
|
30
|
+
#
|
31
|
+
def self.find(*identifiers_and_options)
|
32
|
+
find_one_or_more('users', identifiers_and_options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Retrieve the currently authenticated user.
|
36
|
+
#
|
37
|
+
def self.myself(token, secret, options = {})
|
38
|
+
find('__SELF__', {:access_token => token, :access_secret => secret}.merge(options))
|
39
|
+
end
|
40
|
+
|
41
|
+
# The shop associated with this user.
|
42
|
+
#
|
43
|
+
def shop
|
44
|
+
@shop ||= shops.first
|
45
|
+
end
|
46
|
+
|
47
|
+
# The addresses associated with this user.
|
48
|
+
#
|
49
|
+
def addresses
|
50
|
+
options = (token && secret) ? {:access_token => token, :access_secret => secret} : {}
|
51
|
+
@addresses ||= Address.find(username, options)
|
52
|
+
end
|
53
|
+
|
54
|
+
# The profile associated with this user.
|
55
|
+
#
|
56
|
+
def profile
|
57
|
+
unless @profile
|
58
|
+
if associated_profile
|
59
|
+
@profile = Profile.new(associated_profile)
|
60
|
+
else
|
61
|
+
options = {:fields => 'user_id', :includes => 'Profile'}
|
62
|
+
options = options.merge(:access_token => token, :access_secret => secret) if (token && secret)
|
63
|
+
tmp = User.find(username, options)
|
64
|
+
@profile = Profile.new(tmp.associated_profile)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
@profile
|
68
|
+
end
|
69
|
+
|
70
|
+
def shops
|
71
|
+
unless @shops
|
72
|
+
if associated_shops
|
73
|
+
@shops = associated_shops.map { |shop| Shop.new(shop) }
|
74
|
+
else
|
75
|
+
options = {:fields => 'user_id', :includes => 'Shops'}
|
76
|
+
options = options.merge(:access_token => token, :access_secret => secret) if (token && secret)
|
77
|
+
tmp = User.find(username, options)
|
78
|
+
@shops = tmp.associated_shops.map { |shop| Shop.new(shop) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
@shops
|
82
|
+
end
|
83
|
+
|
84
|
+
# Time that this user was created
|
85
|
+
#
|
86
|
+
def created_at
|
87
|
+
Time.at(created)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Retrieve list of favorited items for this user
|
91
|
+
#
|
92
|
+
def favorites
|
93
|
+
unless @favorites
|
94
|
+
@favorites = Listing.find_all_user_favorite_listings(id, {:access_token => token, :access_secret => secret})
|
95
|
+
end
|
96
|
+
@favorites
|
97
|
+
end
|
98
|
+
|
99
|
+
#Return a set of listings that have been bought
|
100
|
+
#
|
101
|
+
def bought_listings
|
102
|
+
unless @bought_listings
|
103
|
+
@bought_listings = Listing.bought_listings(id, {:access_token => token, :access_secret => secret})
|
104
|
+
end
|
105
|
+
@bought_listings
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Etsy
|
2
|
+
module Variation
|
3
|
+
class PropertySet
|
4
|
+
# Used to find properties which the seller can vary (eg Size, Color, etc), and options associated with those properties (eg Inches)
|
5
|
+
#
|
6
|
+
# The variations stuff is complex. See https://www.etsy.com/developers/documentation/getting_started/variations for more info.
|
7
|
+
#
|
8
|
+
# Probably the most useful method here is qualifying_properties_for_property. This method pulls in data from a few sources to get
|
9
|
+
# you everything you need to set up your variation options.
|
10
|
+
#
|
11
|
+
# Eg: I want to have a few Length options on my listings, and I want to use the unit Inches, then:
|
12
|
+
# Etsy::Variation::PropertySet.qualifying_properties_for_property("Length")
|
13
|
+
# => [{
|
14
|
+
# "param"=>"sizing_scale",
|
15
|
+
# "description"=>"Sizing Scale",
|
16
|
+
# "options"=>{
|
17
|
+
# "Alpha" => 301,
|
18
|
+
# "Inches" => 327,
|
19
|
+
# "Centimeters" => 328,
|
20
|
+
# "Fluid Ounces" => 335,
|
21
|
+
# "Millilitres" => 336,
|
22
|
+
# "Litres" => 337,
|
23
|
+
# "Other => 329
|
24
|
+
# }
|
25
|
+
# }]
|
26
|
+
#
|
27
|
+
# This tells me I want to set the parameter sizing_scale to 327 when calling Etsy::Listing.add_variations.
|
28
|
+
|
29
|
+
include Etsy::Model
|
30
|
+
|
31
|
+
|
32
|
+
attributes :properties, :category_id, :options, :qualifiers,
|
33
|
+
:qualifying_properties
|
34
|
+
|
35
|
+
def self.all
|
36
|
+
@all ||= get("/property_sets")
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.find_property_by_name(name)
|
40
|
+
property = all.properties.detect {|prop_id, prop| prop["name"] == name}
|
41
|
+
if property
|
42
|
+
property_id, property_data = property
|
43
|
+
property_data
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.qualifying_properties_for_property(name)
|
48
|
+
property = find_property_by_name(name)
|
49
|
+
return nil unless property
|
50
|
+
property_id = property["property_id"]
|
51
|
+
|
52
|
+
qualifiers = all.qualifiers[property_id.to_s]
|
53
|
+
return [] unless qualifiers
|
54
|
+
|
55
|
+
qualifiers.map do |qualifier|
|
56
|
+
qualifying_properties = all.qualifying_properties[qualifier.fetch("property_id").to_s]
|
57
|
+
options = qualifier.fetch("options").inject({}) do |acc, opt_id|
|
58
|
+
acc.merge({
|
59
|
+
all.options.fetch(opt_id.to_s) => opt_id
|
60
|
+
})
|
61
|
+
end
|
62
|
+
{
|
63
|
+
"param" => qualifying_properties.fetch("param"),
|
64
|
+
"description" => qualifying_properties.fetch("description"),
|
65
|
+
"options" => options
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Etsy
|
2
|
+
class VerificationRequest # :nodoc:all
|
3
|
+
|
4
|
+
def client
|
5
|
+
@client ||= SecureClient.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def url
|
9
|
+
request_token.params[:login_url]
|
10
|
+
end
|
11
|
+
|
12
|
+
def request_token
|
13
|
+
@request_token ||= client.request_token
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/etsy/version.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"count":1,
|
3
|
+
"results":[
|
4
|
+
{ "shop_id": 8740774,
|
5
|
+
"status": "active",
|
6
|
+
"story_headline": "A shop long in the making...",
|
7
|
+
"story_leading_paragraph": "This is the leading paragraph",
|
8
|
+
"story": "I grew up with strong women in my family who all had a love of creating. My mom and grandma always encouraged a lifelong love of creating Working with glass, wire, and mineral components brings back my graduate school days, when I studied these items from a scientific point-of-view. Here's hoping I can create something that gives you a little sparkle in your life!",
|
9
|
+
"related_links": {
|
10
|
+
"link-0": {"title": "facebook", "url": "https://www.facebook.com/pebbleplusmetal/"},
|
11
|
+
"link-1": {"title": "pinterest", "url": "https://www.pinterest.com/PebblePlusMetal/pebble%2Bmetal/"}
|
12
|
+
},
|
13
|
+
"url": "https://www.etsy.com/shop/PebblePlusMetal/about"
|
14
|
+
}
|
15
|
+
]
|
16
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"count":2,
|
3
|
+
"results":[
|
4
|
+
{"user_address_id":123,"user_id":9876,"name":"Tinker Bell","first_line":"123 Fake St.","second_line":null,"city":"BigCity","state":"XX","zip":"12345","country_id":209,"country_name":"United States"},
|
5
|
+
{"user_address_id":234,"user_id":9876,"name":"LittleCorp, Inc.","first_line":"123 Fake St.","second_line":null,"city":"BigCity","state":"XX","zip":"12345","country_id":209,"country_name":"United States"}
|
6
|
+
],
|
7
|
+
"params": {
|
8
|
+
"user_id":"PaisleyAnnHome","limit":25,"offset":0
|
9
|
+
},
|
10
|
+
"type":"UserAddress"
|
11
|
+
}
|
12
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
{
|
3
|
+
"count":4,
|
4
|
+
"results":
|
5
|
+
[
|
6
|
+
{
|
7
|
+
"property_id": 200,
|
8
|
+
"property_name": "Primary color",
|
9
|
+
"scale_id": null,
|
10
|
+
"scale_name": null,
|
11
|
+
"value_ids": [1213],
|
12
|
+
"values": ["Beige"]
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"property_id": 52047899002,
|
16
|
+
"property_name": "Secondary color",
|
17
|
+
"scale_id": null,
|
18
|
+
"scale_name": null,
|
19
|
+
"value_ids": [1],
|
20
|
+
"values": ["Black"]
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"property_id": 47626759834,
|
24
|
+
"property_name": "Height",
|
25
|
+
"scale_id": 5,
|
26
|
+
"scale_name": "Inches",
|
27
|
+
"value_ids": [0],
|
28
|
+
"values": ["15"]
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"property_id": 47626759898,
|
32
|
+
"property_name": "Width",
|
33
|
+
"scale_id": 5,
|
34
|
+
"scale_name": "Inches",
|
35
|
+
"value_ids": [0],
|
36
|
+
"values": ["25"]
|
37
|
+
}
|
38
|
+
],
|
39
|
+
"params":
|
40
|
+
{
|
41
|
+
"listing_id":"59495892"
|
42
|
+
},
|
43
|
+
"type":"ListingPropertyValue"
|
44
|
+
}
|