etsy 0.3.0 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +14 -5
  3. data/CHANGELOG.md +16 -0
  4. data/Gemfile +0 -4
  5. data/README.md +50 -8
  6. data/etsy.gemspec +5 -5
  7. data/lib/etsy/about.rb +15 -0
  8. data/lib/etsy/attribute_value.rb +46 -0
  9. data/lib/etsy/bill_charge.rb +31 -0
  10. data/lib/etsy/bill_payment.rb +28 -0
  11. data/lib/etsy/billing_overview.rb +18 -0
  12. data/lib/etsy/image.rb +5 -2
  13. data/lib/etsy/listing.rb +108 -7
  14. data/lib/etsy/model.rb +2 -2
  15. data/lib/etsy/receipt.rb +23 -3
  16. data/lib/etsy/request.rb +5 -5
  17. data/lib/etsy/secure_client.rb +1 -1
  18. data/lib/etsy/shipping_info.rb +27 -0
  19. data/lib/etsy/shipping_template.rb +10 -1
  20. data/lib/etsy/shop.rb +5 -0
  21. data/lib/etsy/transaction.rb +51 -1
  22. data/lib/etsy/user.rb +30 -0
  23. data/lib/etsy/variation/property_set.rb +71 -0
  24. data/lib/etsy/version.rb +1 -1
  25. data/lib/etsy.rb +10 -3
  26. data/test/fixtures/about/getAbout.json +16 -0
  27. data/test/fixtures/attribute_value/findAllListingPropertyValues.json +44 -0
  28. data/test/fixtures/bill_charge/getBillCharge.json +1 -0
  29. data/test/fixtures/bill_payment/getBillPayment.json +1 -0
  30. data/test/fixtures/billing_overview/getBillingOverview.json +1 -0
  31. data/test/fixtures/listing/findAllShopListings.json +5 -3
  32. data/test/fixtures/listing/getListing.single.includeImages.json +1 -0
  33. data/test/fixtures/receipt/findAllShopReceipts.json +4 -4
  34. data/test/fixtures/shipping_info/getShippingInfo.json +1 -0
  35. data/test/fixtures/shop/findAllShop.json +1 -1
  36. data/test/fixtures/shop/findAllShop.single.json +1 -1
  37. data/test/fixtures/shop/getShop.multiple.json +1 -1
  38. data/test/fixtures/shop/getShop.single.json +2 -1
  39. data/test/test_helper.rb +0 -2
  40. data/test/unit/etsy/attribute_value_test.rb +67 -0
  41. data/test/unit/etsy/bill_charge_test.rb +24 -0
  42. data/test/unit/etsy/bill_payment_test.rb +24 -0
  43. data/test/unit/etsy/billing_overview_test.rb +20 -0
  44. data/test/unit/etsy/image_test.rb +15 -3
  45. data/test/unit/etsy/listing_test.rb +45 -7
  46. data/test/unit/etsy/model_test.rb +4 -4
  47. data/test/unit/etsy/receipt_test.rb +15 -0
  48. data/test/unit/etsy/shipping_info_test.rb +24 -0
  49. data/test/unit/etsy/shop_about_test.rb +43 -0
  50. data/test/unit/etsy/shop_test.rb +12 -0
  51. data/test/unit/etsy/transaction_test.rb +5 -1
  52. metadata +50 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 63b1728090ce087c6421fdb354545b5031206bdd
4
- data.tar.gz: 720fd11d6f39fe99e5f414e54155db73c2bedce3
2
+ SHA256:
3
+ metadata.gz: 52e5bcc56a9eb4df1e1b2e732f296d82034b8b8fee77e17a7d4c567d70e8741e
4
+ data.tar.gz: bde90f57588f337c92a0a97b4c4f1c98757e6e3eff4d0372dcb9bbcd4d7b8103
5
5
  SHA512:
6
- metadata.gz: 2c7a7b67c5bb186cecfe0a61000dd6b2a6258d5e4bd915c67672e40d949af76d7c083bfd54ec7e96c7d0396665562c389deafd3a1422ca21e6a4553a47a1f5aa
7
- data.tar.gz: 60c5ad5ef28a7f5104ffcbb9e6df25f292ab31292725e9a45dddfe8fe62a93ac22ce1d0ea22d18c98db91e37b7d66e4bbc676ad6d7f422a339b86b878edc7eb7
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
- - 1.8.7
4
- - 1.9.3
5
- - jruby-18mode
6
- - jruby-19mode
7
- - rbx-2
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
@@ -1,7 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
5
- if RUBY_VERSION < '1.9'
6
- gem 'activesupport', '< 4.0'
7
- end
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/kytrinyx/etsy.git
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](http://github.com/kytrinyx)
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
- * [Trae Robrock](https://github.com/trobrock)
287
- * [Jimmy Tang](https://github.com/jimmytang)
288
- * [Julio Santos](https://github.com/julio)
289
- * [Roger Smith](https://github.com/rogsmith)
290
- * [Daniel Szmulewicz](https://github.com/danielsz)
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", "~> 0.4.0"
23
+ gem.add_dependency "oauth", ">= 0.5.5"
24
24
 
25
- gem.add_development_dependency "rake", "~> 10.0.4"
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 'minitest', "=4.7.4"
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
- # [alchemy?] Is this listing an Alchemy item? (i.e. requested by an Etsy user)
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 alchemy)
36
- VALID_STATES = [:active, :expired, :inactive, :sold, :featured]
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 ||= Image.find_all_by_listing_id(id)
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.count - batch_size - initial_offset, 0].max
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, :created_tsz
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(created_tsz)
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.escape(val.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
107
+ URI.encode_www_form_component(val.to_s)
108
108
  end
109
109
  end
110
110
 
@@ -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