etsy 0.3.0 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +14 -5
- data/CHANGELOG.md +16 -0
- data/Gemfile +0 -4
- data/README.md +50 -8
- data/etsy.gemspec +5 -5
- data/lib/etsy/about.rb +15 -0
- data/lib/etsy/attribute_value.rb +46 -0
- data/lib/etsy/bill_charge.rb +31 -0
- data/lib/etsy/bill_payment.rb +28 -0
- data/lib/etsy/billing_overview.rb +18 -0
- data/lib/etsy/image.rb +5 -2
- data/lib/etsy/listing.rb +108 -7
- data/lib/etsy/model.rb +2 -2
- data/lib/etsy/receipt.rb +23 -3
- data/lib/etsy/request.rb +5 -5
- data/lib/etsy/secure_client.rb +1 -1
- data/lib/etsy/shipping_info.rb +27 -0
- data/lib/etsy/shipping_template.rb +10 -1
- data/lib/etsy/shop.rb +5 -0
- data/lib/etsy/transaction.rb +51 -1
- data/lib/etsy/user.rb +30 -0
- data/lib/etsy/variation/property_set.rb +71 -0
- data/lib/etsy/version.rb +1 -1
- data/lib/etsy.rb +10 -3
- data/test/fixtures/about/getAbout.json +16 -0
- data/test/fixtures/attribute_value/findAllListingPropertyValues.json +44 -0
- data/test/fixtures/bill_charge/getBillCharge.json +1 -0
- data/test/fixtures/bill_payment/getBillPayment.json +1 -0
- data/test/fixtures/billing_overview/getBillingOverview.json +1 -0
- data/test/fixtures/listing/findAllShopListings.json +5 -3
- data/test/fixtures/listing/getListing.single.includeImages.json +1 -0
- data/test/fixtures/receipt/findAllShopReceipts.json +4 -4
- data/test/fixtures/shipping_info/getShippingInfo.json +1 -0
- data/test/fixtures/shop/findAllShop.json +1 -1
- data/test/fixtures/shop/findAllShop.single.json +1 -1
- data/test/fixtures/shop/getShop.multiple.json +1 -1
- data/test/fixtures/shop/getShop.single.json +2 -1
- data/test/test_helper.rb +0 -2
- data/test/unit/etsy/attribute_value_test.rb +67 -0
- data/test/unit/etsy/bill_charge_test.rb +24 -0
- data/test/unit/etsy/bill_payment_test.rb +24 -0
- data/test/unit/etsy/billing_overview_test.rb +20 -0
- data/test/unit/etsy/image_test.rb +15 -3
- data/test/unit/etsy/listing_test.rb +45 -7
- data/test/unit/etsy/model_test.rb +4 -4
- data/test/unit/etsy/receipt_test.rb +15 -0
- data/test/unit/etsy/shipping_info_test.rb +24 -0
- data/test/unit/etsy/shop_about_test.rb +43 -0
- data/test/unit/etsy/shop_test.rb +12 -0
- data/test/unit/etsy/transaction_test.rb +5 -1
- metadata +50 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 52e5bcc56a9eb4df1e1b2e732f296d82034b8b8fee77e17a7d4c567d70e8741e
|
4
|
+
data.tar.gz: bde90f57588f337c92a0a97b4c4f1c98757e6e3eff4d0372dcb9bbcd4d7b8103
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c974d38d7df6ee9be0df31072dc0cbadc59c762610b12039ad8132febea31273817c281dcd257e9b3334a3855677b8eb770df091caa58e77a5fb080214c0442b
|
7
|
+
data.tar.gz: 409997c87e75203d40037069af7deda3814954d33f88e3cc610c8976e7593fa9cad932fbe72025f79a82e1b4ea1a18b5c461ca1f782227d3479218c2e3ad9b1e
|
data/.travis.yml
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
-
|
4
|
-
-
|
5
|
-
-
|
6
|
-
-
|
7
|
-
|
3
|
+
- jruby
|
4
|
+
- 2.6.8
|
5
|
+
- 2.7.4
|
6
|
+
- 3.0.2
|
7
|
+
|
8
|
+
dist: bionic
|
9
|
+
|
10
|
+
before_install:
|
11
|
+
- gem install bundler
|
12
|
+
- sudo apt-get update && sudo apt-get install apt-transport-https ca-certificates -y && sudo update-ca-certificates
|
13
|
+
|
14
|
+
matrix:
|
15
|
+
allow_failures:
|
16
|
+
- rvm: 3.0.2
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All changes to the Etsy gem are documented here.
|
4
|
+
|
5
|
+
## [0.3.4] - November 3, 2021
|
6
|
+
|
7
|
+
Getting the gem back to life and ready to migrate to Etsy API v3.
|
8
|
+
|
9
|
+
### Added:
|
10
|
+
- States for listings as per current documentation (Etsy API v2)
|
11
|
+
- id attribute for Image class
|
12
|
+
- Change log file is here!
|
13
|
+
|
14
|
+
### Changed:
|
15
|
+
- Cleaned up the dependencies and updated old gems
|
16
|
+
- Updated ruby versions in Travis config
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# Etsy
|
2
2
|
|
3
3
|
[![Build Status](https://secure.travis-ci.org/kytrinyx/etsy.png)](http://travis-ci.org/kytrinyx/etsy)
|
4
|
-
[![Dependency Status](https://gemnasium.com/kytrinyx/etsy.png)](https://gemnasium.com/kytrinyx/etsy)
|
5
4
|
|
6
5
|
## Description
|
7
6
|
|
@@ -15,7 +14,7 @@ Installing the latest stable version is simple:
|
|
15
14
|
|
16
15
|
If you want to be on the bleeding edge, install from GitHub:
|
17
16
|
|
18
|
-
$ git clone git://github.com/
|
17
|
+
$ git clone git://github.com/iamfmjk/etsy.git
|
19
18
|
$ cd etsy
|
20
19
|
$ rake install
|
21
20
|
|
@@ -26,6 +25,32 @@ It will likely work with higher versions, but this is unproven.
|
|
26
25
|
|
27
26
|
## Usage
|
28
27
|
|
28
|
+
In order to try this out you'll need to create an app on [etsy.com/your/apps](https://www.etsy.com/your/apps).
|
29
|
+
|
30
|
+
This will give you an api key and secret.
|
31
|
+
|
32
|
+
Paste the following into IRB, replacing the api key and secret with the ones you got on Etsy:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require 'etsy'
|
36
|
+
Etsy.protocol = "https"
|
37
|
+
Etsy.api_key = 'YOUR API KEY'
|
38
|
+
Etsy.api_secret = 'YOUR SECRET'
|
39
|
+
request = Etsy.request_token
|
40
|
+
Etsy.verification_url
|
41
|
+
```
|
42
|
+
|
43
|
+
Paste the verification URL into your browser, and authorize the application. That will give you a page
|
44
|
+
with a code on it. Paste the following into IRB, replacing the code:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
access = Etsy.access_token(request.token, request.secret, 'CODE')
|
48
|
+
Etsy.myself(access.token, access.secret)
|
49
|
+
```
|
50
|
+
|
51
|
+
If you've received a 401 unauthorized error, then you likely don't have a valid api key and secret, or
|
52
|
+
perhaps the verification url timed out.
|
53
|
+
|
29
54
|
### Public Mode
|
30
55
|
|
31
56
|
The Etsy API has two modes: public, and authenticated. Public mode only requires an
|
@@ -67,6 +92,11 @@ Authenticated calls can now be made by passing an access token and secret:
|
|
67
92
|
|
68
93
|
Etsy.myself(access.token, access.secret)
|
69
94
|
|
95
|
+
The key and secret have to be passed in for the authenticated calls.
|
96
|
+
|
97
|
+
auth = {:access_token=>access.token, :access_secret=>access.secret}
|
98
|
+
Etsy::Transaction.find_all_by_shop_id(shop_id, auth.merge(options))
|
99
|
+
|
70
100
|
### Web Application
|
71
101
|
|
72
102
|
The process for authenticating via a web application is similar, but requires the configuration of a callback URL:
|
@@ -278,16 +308,28 @@ I ask that you not submit patches that include changes to the version or gemspec
|
|
278
308
|
These people have helped make the Etsy gem what it is today:
|
279
309
|
|
280
310
|
* [Patrick Reagan](https://github.com/reagent)
|
281
|
-
* [Katrina Owen](
|
311
|
+
* [Katrina Owen](https://github.com/kytrinyx)
|
312
|
+
* [Trae Robrock](https://github.com/trobrock)
|
313
|
+
* [Roger Smith](https://github.com/rogsmith)
|
314
|
+
* [Jimmy Tang](https://github.com/jimmytang)
|
282
315
|
* [Mak Nazečić-Andrlon](https://github.com/Muon)
|
316
|
+
* [Daniel Szmulewicz](https://github.com/danielsz)
|
283
317
|
* [Patrick Schless](https://github.com/plainlystated)
|
318
|
+
* [Martin Popelak](https://github.com/pupca)
|
319
|
+
* [Julio Santos](https://github.com/julio)
|
284
320
|
* [Matt Fields](https://github.com/mfields106)
|
321
|
+
* [Mike Taylor](https://github.com/sealabcore)
|
322
|
+
* [Mason Stewart](https://github.com/masondesu)
|
323
|
+
* [Sasha Gerrand](https://github.com/sgerrand)
|
285
324
|
* [Jake Boxer](https://github.com/jakeboxer)
|
286
|
-
* [
|
287
|
-
* [
|
288
|
-
* [
|
289
|
-
* [
|
290
|
-
* [
|
325
|
+
* [Sunwoo Yang](https://github.com/sunwooz)
|
326
|
+
* [Isaac Rosenberg](https://github.com/irosenb)
|
327
|
+
* [Carson Gross](https://github.com/carsongross)
|
328
|
+
* [John Amicangelo](https://github.com/JohnAmican)
|
329
|
+
* [Max Gulyaev](https://github.com/maxilev)
|
330
|
+
* [fbehrens](https://github.com/fbehrens)
|
331
|
+
* [William Jeffries](https://github.com/williamcodes)
|
332
|
+
* [Jack Guoyuan Zhao](https://github.com/zhaoguoyuan)
|
291
333
|
|
292
334
|
### Github Flow
|
293
335
|
|
data/etsy.gemspec
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
require File.expand_path('../lib/etsy/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Patrick Reagan", "Katrina Owen"]
|
6
|
-
gem.email = ["reaganpr@gmail.com", "katrina.owen@gmail.com"]
|
5
|
+
gem.authors = ["Iuliia Kolomiiets", "Patrick Reagan", "Katrina Owen"]
|
6
|
+
gem.email = ["etsygeminfo@gmail.com, reaganpr@gmail.com", "katrina.owen@gmail.com" ]
|
7
7
|
gem.description = %q{A friendly Ruby interface to the Etsy API}
|
8
8
|
gem.summary = %q{Provides a friendly ruby-like wrapper for the Etsy API}
|
9
9
|
gem.homepage = "http://github.com/kytrinyx/etsy"
|
@@ -20,9 +20,9 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.rubygems_version = "1.8.10"
|
21
21
|
|
22
22
|
gem.add_dependency "json", ">= 1.5.0"
|
23
|
-
gem.add_dependency "oauth", "
|
23
|
+
gem.add_dependency "oauth", ">= 0.5.5"
|
24
24
|
|
25
|
-
gem.add_development_dependency "rake", "~>
|
25
|
+
gem.add_development_dependency "rake", "~> 12.3.3"
|
26
26
|
gem.add_development_dependency "jnunemaker-matchy", "~> 0.4.0"
|
27
27
|
gem.add_development_dependency 'shoulda', "~> 3.4.0"
|
28
28
|
gem.add_development_dependency 'mocha', "~> 0.13.3"
|
@@ -30,5 +30,5 @@ Gem::Specification.new do |gem|
|
|
30
30
|
# on shoulda/context.rb:7
|
31
31
|
# But then when you load active_support, shoulda-context decides
|
32
32
|
# to load MiniTest
|
33
|
-
gem.add_development_dependency '
|
33
|
+
gem.add_development_dependency 'test-unit', "~>3.5.0"
|
34
34
|
end
|
data/lib/etsy/about.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Etsy
|
2
|
+
class About
|
3
|
+
include Etsy::Model
|
4
|
+
|
5
|
+
attributes :status, :story_headline, :story_leading_paragraph,
|
6
|
+
:story, :related_links, :url
|
7
|
+
attribute :id, :from => :shop_id
|
8
|
+
attribute :shop_id, :from => :shop_id
|
9
|
+
|
10
|
+
def self.find_by_shop(shop)
|
11
|
+
get("/shops/#{shop.id}/about")
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = AttributeValue
|
4
|
+
#
|
5
|
+
# An attribute of a listing according to its taxonomy.
|
6
|
+
#
|
7
|
+
# An attribute has the following attributes:
|
8
|
+
#
|
9
|
+
# [property_id] (INT) The numeric ID of this property.
|
10
|
+
# [property_name] (STRING) The name of the property, in the requested locale language.
|
11
|
+
# [scale_id] (INT) The numeric ID of the scale (if any).
|
12
|
+
# [scale_name] (STRING) The label used to describe the chosen scale (if any).
|
13
|
+
# [value_ids] (Array(INT)) The numeric IDs of the values.
|
14
|
+
# [values] (Array(STRING)) The literal values of the value
|
15
|
+
class AttributeValue
|
16
|
+
|
17
|
+
include Etsy::Model
|
18
|
+
|
19
|
+
attribute :id, :from => :property_id
|
20
|
+
attributes :property_name, :scale_id, :scale_name, :value_ids,
|
21
|
+
:values
|
22
|
+
|
23
|
+
# Fetch all property_values for a given listing.
|
24
|
+
#
|
25
|
+
def self.find_all_by_listing_id(listing_id, options = {})
|
26
|
+
get_all("/listings/#{listing_id}/attributes", options)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Adds a new attribute_value to the listing given
|
30
|
+
#
|
31
|
+
def self.create(listing, property_hash, options = {})
|
32
|
+
property_id = property_hash[:property_id]
|
33
|
+
options.merge!(:require_secure => true)
|
34
|
+
options.merge!(property_hash)
|
35
|
+
put("/listings/#{listing.id}/attributes/#{property_id}", options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Delete attribute_value from listing
|
39
|
+
#
|
40
|
+
def self.destroy(listing, property_value, options = {})
|
41
|
+
options.merge!(:require_secure => true)
|
42
|
+
delete("/listings/#{listing.id}/attributes/#{property_value.id}", options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = BillCharge
|
4
|
+
#
|
5
|
+
# Represents a charge to an Etsy member's account.
|
6
|
+
#
|
7
|
+
#
|
8
|
+
class BillCharge
|
9
|
+
|
10
|
+
include Etsy::Model
|
11
|
+
|
12
|
+
attribute :id, :from => :bill_charge_id
|
13
|
+
attribute :created, :from => :creation_tsz
|
14
|
+
attribute :last_modified, :from => :last_modified_tsz
|
15
|
+
|
16
|
+
attributes :type, :type_id, :user_id, :amount, :currency_code, :creation_month,
|
17
|
+
:creation_year
|
18
|
+
|
19
|
+
def self.find_all_by_user_id(user_id, options = {})
|
20
|
+
get_all("/users/#{user_id}/charges", options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def created_at
|
24
|
+
Time.at(created)
|
25
|
+
end
|
26
|
+
|
27
|
+
def last_modified_at
|
28
|
+
Time.at(last_modified)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = BillPayment
|
4
|
+
#
|
5
|
+
# Represents a user's Billing Payment.
|
6
|
+
#
|
7
|
+
#
|
8
|
+
class BillPayment
|
9
|
+
|
10
|
+
include Etsy::Model
|
11
|
+
|
12
|
+
attribute :id, :from => :bill_payment_id
|
13
|
+
attribute :created, :from => :creation_tsz
|
14
|
+
|
15
|
+
attributes :type, :type_id, :user_id, :amount, :currency_code, :creation_month,
|
16
|
+
:creation_year
|
17
|
+
|
18
|
+
def self.find_all_by_user_id(user_id, options = {})
|
19
|
+
get_all("/users/#{user_id}/payments", options)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Time that this listing was created
|
23
|
+
#
|
24
|
+
def created_at
|
25
|
+
Time.at(created)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = BillingOverview
|
4
|
+
#
|
5
|
+
# A user's account balance on Etsy.
|
6
|
+
#
|
7
|
+
class BillingOverview
|
8
|
+
|
9
|
+
include Etsy::Model
|
10
|
+
|
11
|
+
attributes :is_overdue, :overdue_balance, :balance_due, :total_balance, :currency_code, :date_due,
|
12
|
+
:creation_year
|
13
|
+
|
14
|
+
def self.find_all_by_user_id(user_id, options = {})
|
15
|
+
get_all("/users/#{user_id}/billing/overview", options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/etsy/image.rb
CHANGED
@@ -14,15 +14,18 @@ module Etsy
|
|
14
14
|
|
15
15
|
include Etsy::Model
|
16
16
|
|
17
|
+
attribute :id, :from => :listing_image_id
|
17
18
|
attribute :square, :from => :url_75x75
|
18
19
|
attribute :small, :from => :url_170x135
|
19
20
|
attribute :thumbnail, :from => :url_570xN
|
21
|
+
attribute :height, :from => :full_height
|
22
|
+
attribute :width, :from => :full_width
|
20
23
|
attribute :full, :from => :url_fullxfull
|
21
24
|
|
22
25
|
# Fetch all images for a given listing.
|
23
26
|
#
|
24
|
-
def self.find_all_by_listing_id(listing_id)
|
25
|
-
get_all("/listings/#{listing_id}/images")
|
27
|
+
def self.find_all_by_listing_id(listing_id, options = {})
|
28
|
+
get_all("/listings/#{listing_id}/images", options)
|
26
29
|
end
|
27
30
|
|
28
31
|
def self.create(listing, image_path, options = {})
|
data/lib/etsy/listing.rb
CHANGED
@@ -26,28 +26,45 @@ module Etsy
|
|
26
26
|
# [removed?] Has this listing been removed?
|
27
27
|
# [sold_out?] Is this listing sold out?
|
28
28
|
# [expired?] Has this listing expired?
|
29
|
-
# [
|
29
|
+
# [edit?] Is this listing inactive?
|
30
|
+
# [draft?] Is this listing in draft mode / not yet published?
|
31
|
+
# [private?] Is this a private listing?
|
32
|
+
# [unavailable?] Has this listing been removed by Etsy admins?
|
33
|
+
|
30
34
|
#
|
31
35
|
class Listing
|
32
36
|
|
33
37
|
include Etsy::Model
|
34
38
|
|
35
|
-
STATES = %w(active removed sold_out expired
|
36
|
-
|
39
|
+
STATES = %w(active removed sold_out expired edit draft private unavailable)
|
40
|
+
#TODO: re-check valid states
|
41
|
+
VALID_STATES = [:active, :draft, :expired, :featured, :inactive, :sold, :sold_out]
|
37
42
|
|
38
43
|
attribute :id, :from => :listing_id
|
39
44
|
attribute :view_count, :from => :views
|
40
45
|
attribute :created, :from => :creation_tsz
|
46
|
+
attribute :original_created, :from => :original_creation_tsz
|
41
47
|
attribute :modified, :from => :last_modified_tsz
|
42
48
|
attribute :currency, :from => :currency_code
|
43
49
|
attribute :ending, :from => :ending_tsz
|
50
|
+
attribute :shop_section, :from => :shop_section_id
|
44
51
|
|
45
52
|
attributes :title, :description, :state, :url, :price, :quantity,
|
46
53
|
:tags, :materials, :hue, :saturation, :brightness, :is_black_and_white,
|
47
|
-
:featured_rank, :occasion, :num_favorers, :user_id
|
54
|
+
:featured_rank, :occasion, :num_favorers, :user_id,
|
55
|
+
:shipping_template_id, :who_made, :when_made,
|
56
|
+
:style, :category_path, :taxonomy_id, :taxonomy_attributes
|
48
57
|
|
49
58
|
association :image, :from => 'Images'
|
50
59
|
|
60
|
+
def transactions
|
61
|
+
@transactions ||= Transaction.find_all_by_listing_id(id, oauth)
|
62
|
+
end
|
63
|
+
|
64
|
+
def receipts
|
65
|
+
transactions.map{|t|t.receipt}
|
66
|
+
end
|
67
|
+
|
51
68
|
def self.create(options = {})
|
52
69
|
options.merge!(:require_secure => true)
|
53
70
|
post("/listings", options)
|
@@ -57,7 +74,7 @@ module Etsy
|
|
57
74
|
options.merge!(:require_secure => true)
|
58
75
|
put("/listings/#{listing.id}", options)
|
59
76
|
end
|
60
|
-
|
77
|
+
|
61
78
|
def self.destroy(listing, options = {})
|
62
79
|
options.merge!(:require_secure => true)
|
63
80
|
delete("/listings/#{listing.id}", options)
|
@@ -79,7 +96,7 @@ module Etsy
|
|
79
96
|
# By default, pulls back the first 25 active listings.
|
80
97
|
# Defaults can be overridden using :limit, :offset, and :state
|
81
98
|
#
|
82
|
-
# Available states are :active, :expired, :inactive, :sold, and :featured
|
99
|
+
# Available states are :active, :expired, :inactive, :sold, and :featured, :draft, :sold_out
|
83
100
|
# where :featured is a subset of the others.
|
84
101
|
#
|
85
102
|
# options = {
|
@@ -123,7 +140,7 @@ module Etsy
|
|
123
140
|
# The collection of images associated with this listing.
|
124
141
|
#
|
125
142
|
def images
|
126
|
-
@images ||=
|
143
|
+
@images ||= listing_images
|
127
144
|
end
|
128
145
|
|
129
146
|
# The primary image for this listing.
|
@@ -132,6 +149,68 @@ module Etsy
|
|
132
149
|
images.first
|
133
150
|
end
|
134
151
|
|
152
|
+
# Listing category name
|
153
|
+
#
|
154
|
+
def category
|
155
|
+
path = category_path.join('/')
|
156
|
+
@category ||= Category.find(path)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Returns the taxonomy defined attributes for the listing
|
160
|
+
#
|
161
|
+
def taxonomy_attributes(options={})
|
162
|
+
options.merge!(:require_secure => true)
|
163
|
+
self.class.get_all("/listings/#{id}/attributes", oauth.merge(options))
|
164
|
+
end
|
165
|
+
|
166
|
+
def variations(options={})
|
167
|
+
options.merge!(:require_secure => true)
|
168
|
+
self.class.get_all("/listings/#{id}/variations", oauth.merge(options))
|
169
|
+
end
|
170
|
+
|
171
|
+
# If these are your desired variations:
|
172
|
+
# - Dimensions: 1 x 2 inches
|
173
|
+
# - Dimensions: 2 x 4 inches
|
174
|
+
#
|
175
|
+
# Then you first have to find the property ID of the property you want to vary. Eg:
|
176
|
+
# Etsy::Variation::PropertySet.find_property_by_name("Dimensions").fetch("property_id")
|
177
|
+
#
|
178
|
+
# Then you can decide which options you want to set for this property.
|
179
|
+
# Eg:
|
180
|
+
# Etsy::Variation::PropertySet.qualifying_properties_for_property("Dimension")
|
181
|
+
# => [{
|
182
|
+
# "param"=>"dimensions_scale",
|
183
|
+
# "description"=>"Sizing Scale",
|
184
|
+
# "options"=>{
|
185
|
+
# "Inches" => 344,
|
186
|
+
# "Centimeters" => 345,
|
187
|
+
# "Other" => 346
|
188
|
+
# }
|
189
|
+
# }]
|
190
|
+
#
|
191
|
+
# Put it all together for a call to add_variations:
|
192
|
+
|
193
|
+
# property_id = Etsy::Variation::PropertySet.find_property_by_name("Dimensions").fetch("property_id")
|
194
|
+
# scale = Etsy::Variation::PropertySet.qualifying_properties_for_property("Dimensions").detect {|qp| qp.fetch("description") == "Sizing Scale"}
|
195
|
+
# my_listing.add_variations(
|
196
|
+
# :variations => [
|
197
|
+
# {"property_id" => property_id, "value" => "1 x 2", "is_available" => true, "price" => 1.23},
|
198
|
+
# {"property_id" => property_id, "value" => "2 x 4", "is_available" => true, "price" => 2.34}
|
199
|
+
# ],
|
200
|
+
# scale.fetch("param") => scale.fetch("options").fetch("Inches")
|
201
|
+
# )
|
202
|
+
def add_variations(options)
|
203
|
+
options[:variations] = JSON.dump(options.delete(:variations))
|
204
|
+
options[:require_secure] = true
|
205
|
+
self.class.post("/listings/#{id}/variations", options)
|
206
|
+
end
|
207
|
+
|
208
|
+
def update_variations(options)
|
209
|
+
options[:variations] = JSON.dump(options.delete(:variations))
|
210
|
+
options[:require_secure] = true
|
211
|
+
self.class.put("/listings/#{id}/variations", options)
|
212
|
+
end
|
213
|
+
|
135
214
|
def black_and_white?
|
136
215
|
is_black_and_white
|
137
216
|
end
|
@@ -148,6 +227,11 @@ module Etsy
|
|
148
227
|
Time.at(created)
|
149
228
|
end
|
150
229
|
|
230
|
+
# Time that this listing was originally created
|
231
|
+
def original_created_at
|
232
|
+
Time.at(original_created)
|
233
|
+
end
|
234
|
+
|
151
235
|
# Time that this listing was last modified
|
152
236
|
#
|
153
237
|
def modified_at
|
@@ -169,6 +253,10 @@ module Etsy
|
|
169
253
|
(user_ids.size > 0) ? Array(Etsy::User.find(user_ids, options)) : []
|
170
254
|
end
|
171
255
|
|
256
|
+
def is_supply
|
257
|
+
@result.fetch('is_supply') == 'true'
|
258
|
+
end
|
259
|
+
|
172
260
|
private
|
173
261
|
|
174
262
|
def self.valid?(state)
|
@@ -209,5 +297,18 @@ module Etsy
|
|
209
297
|
(listing_ids.size > 0) ? Array(find(listing_ids, options)) : []
|
210
298
|
end
|
211
299
|
|
300
|
+
private
|
301
|
+
|
302
|
+
def oauth
|
303
|
+
oauth = (token && secret) ? {:access_token => token, :access_secret => secret} : {}
|
304
|
+
end
|
305
|
+
|
306
|
+
def listing_images
|
307
|
+
if result && result["Images"]
|
308
|
+
result["Images"].map { |hash| Image.new(hash) }
|
309
|
+
else
|
310
|
+
Image.find_all_by_listing_id(id, oauth)
|
311
|
+
end
|
312
|
+
end
|
212
313
|
end
|
213
314
|
end
|
data/lib/etsy/model.rb
CHANGED
@@ -43,7 +43,7 @@ module Etsy
|
|
43
43
|
if limit == :all
|
44
44
|
response = Request.get(endpoint, options.merge(:limit => batch_size, :offset => initial_offset))
|
45
45
|
result << response.result
|
46
|
-
limit = [response.
|
46
|
+
limit = [response.total - batch_size - initial_offset, 0].max
|
47
47
|
initial_offset += batch_size
|
48
48
|
end
|
49
49
|
|
@@ -83,7 +83,7 @@ module Etsy
|
|
83
83
|
def put(endpoint, options={})
|
84
84
|
Request.put(endpoint, options)
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
def delete(endpoint, options={})
|
88
88
|
Request.delete(endpoint, options)
|
89
89
|
end
|
data/lib/etsy/receipt.rb
CHANGED
@@ -5,20 +5,40 @@ module Etsy
|
|
5
5
|
attribute :id, :from => :receipt_id
|
6
6
|
attribute :buyer_id, :from => :buyer_user_id
|
7
7
|
|
8
|
+
attribute :created, :from => :creation_tsz
|
9
|
+
attribute :last_modified, :from => :last_modified_tsz
|
10
|
+
|
8
11
|
attributes :quantity, :listing_id, :name, :first_line, :second_line, :city, :state, :zip, :country_id,
|
9
|
-
:payment_email, :buyer_email
|
12
|
+
:payment_email, :buyer_email
|
13
|
+
|
14
|
+
def self.find(*identifiers_and_options)
|
15
|
+
find_one_or_more('receipts', identifiers_and_options)
|
16
|
+
end
|
10
17
|
|
11
18
|
def self.find_all_by_shop_id(shop_id, options = {})
|
12
19
|
get_all("/shops/#{shop_id}/receipts", options)
|
13
20
|
end
|
14
21
|
|
22
|
+
def self.find_all_by_shop_id_and_status(shop_id, status, options = {})
|
23
|
+
get_all("/shops/#{shop_id}/receipts/#{status}", options)
|
24
|
+
end
|
25
|
+
|
15
26
|
def created_at
|
16
|
-
Time.at(
|
27
|
+
Time.at(created)
|
17
28
|
end
|
18
29
|
|
19
30
|
def buyer
|
20
31
|
@buyer ||= User.find(buyer_id)
|
21
32
|
end
|
22
33
|
|
34
|
+
def transactions
|
35
|
+
unless @transactions
|
36
|
+
options = {}
|
37
|
+
options = options.merge(:access_token => token, :access_secret => secret) if (token && secret)
|
38
|
+
@transactions = Transaction.find_all_by_receipt_id(id, options)
|
39
|
+
end
|
40
|
+
@transactions
|
41
|
+
end
|
42
|
+
|
23
43
|
end
|
24
|
-
end
|
44
|
+
end
|
data/lib/etsy/request.rb
CHANGED
@@ -22,13 +22,13 @@ module Etsy
|
|
22
22
|
request = Request.new(resource_path, parameters)
|
23
23
|
Response.new(request.put)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def self.delete(resource_path, parameters = {})
|
27
27
|
request = Request.new(resource_path, parameters)
|
28
28
|
Response.new(request.delete)
|
29
29
|
end
|
30
|
-
|
31
|
-
|
30
|
+
|
31
|
+
|
32
32
|
|
33
33
|
# Create a new request for the resource with optional parameters
|
34
34
|
def initialize(resource_path, parameters = {})
|
@@ -75,7 +75,7 @@ module Etsy
|
|
75
75
|
def put
|
76
76
|
client.put(endpoint_url)
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def delete
|
80
80
|
client.delete(endpoint_url)
|
81
81
|
end
|
@@ -104,7 +104,7 @@ module Etsy
|
|
104
104
|
k.nil? || v.nil? || (k.respond_to?(:empty?) && k.empty?) || (v.respond_to?(:empty?) && v.empty?)
|
105
105
|
}.map { |k, v| "#{to_url(k.to_s)}=#{to_url(v)}" }.join('&')
|
106
106
|
else
|
107
|
-
URI.
|
107
|
+
URI.encode_www_form_component(val.to_s)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
data/lib/etsy/secure_client.rb
CHANGED
@@ -107,7 +107,7 @@ module Etsy
|
|
107
107
|
if value.respond_to?(:read)
|
108
108
|
body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{crlf}"
|
109
109
|
body << "Content-Type: image/jpeg#{crlf*2}"
|
110
|
-
body << value.read
|
110
|
+
body << open(value.path, "rb") {|io| io.read}
|
111
111
|
else
|
112
112
|
body << "Content-Disposition: form-data; name=\"#{esc_key}\"#{crlf*2}#{value}"
|
113
113
|
end
|
@@ -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_all_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_all("/listings/#{listing_id}/shipping/info", options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|