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
data/lib/etsy/country.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Etsy
|
2
|
+
class Country
|
3
|
+
include Etsy::Model
|
4
|
+
|
5
|
+
attribute :id, :from => :country_id
|
6
|
+
attributes :iso_country_code, :world_bank_country_code
|
7
|
+
attributes :name, :slug, :lat, :lon
|
8
|
+
|
9
|
+
def self.find_all
|
10
|
+
get("/countries")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(id)
|
14
|
+
get("/countries/#{id}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find_by_alpha2(alpha2)
|
18
|
+
alpha2 = alpha2.upcase
|
19
|
+
find_all.detect { |country| country.iso_country_code == alpha2}
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.find_by_world_bank_country_code(world_bank_country_code)
|
23
|
+
world_bank_country_code = world_bank_country_code.upcase
|
24
|
+
find_all.detect { |country| country.world_bank_country_code == world_bank_country_code}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Etsy
|
2
|
+
class FavoriteListing
|
3
|
+
include Model
|
4
|
+
|
5
|
+
attributes :user_id, :listing_state, :listing_id, :create_date
|
6
|
+
|
7
|
+
#Create a new favorite listing
|
8
|
+
#
|
9
|
+
def self.create(user, listing, options = {})
|
10
|
+
options.merge!(:require_secure => true)
|
11
|
+
post("/users/#{user.id}/favorites/listings/#{listing.id}", options)
|
12
|
+
end
|
13
|
+
|
14
|
+
#Find all listings favorited by a user
|
15
|
+
#
|
16
|
+
def self.find_all_user_favorite_listings(user_id, options = {})
|
17
|
+
get_all("/users/#{user_id}/favorites/listings", options)
|
18
|
+
end
|
19
|
+
|
20
|
+
#Find a set of favorelistings associated with a listing_id
|
21
|
+
#
|
22
|
+
def self.find_all_listings_favored_by(listing_id, options = {})
|
23
|
+
get_all("/listings/#{listing_id}/favored-by", options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/etsy/image.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = Image
|
4
|
+
#
|
5
|
+
# Represents an image resource of an Etsy listing and contains multiple sizes.
|
6
|
+
# Sizes available are:
|
7
|
+
#
|
8
|
+
# [square] The square image thumbnail (75x75 pixels)
|
9
|
+
# [small] The small image thumbnail (170x135 pixels)
|
10
|
+
# [thumbnail] The thumbnail for the image, no more than 570px wide
|
11
|
+
# [full] The full image for this listing, no more than 1500px wide
|
12
|
+
#
|
13
|
+
class Image
|
14
|
+
|
15
|
+
include Etsy::Model
|
16
|
+
|
17
|
+
attribute :square, :from => :url_75x75
|
18
|
+
attribute :small, :from => :url_170x135
|
19
|
+
attribute :thumbnail, :from => :url_570xN
|
20
|
+
attribute :height, :from => :full_height
|
21
|
+
attribute :width, :from => :full_width
|
22
|
+
attribute :full, :from => :url_fullxfull
|
23
|
+
|
24
|
+
# Fetch all images for a given listing.
|
25
|
+
#
|
26
|
+
def self.find_all_by_listing_id(listing_id, options = {})
|
27
|
+
get_all("/listings/#{listing_id}/images", options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.create(listing, image_path, options = {})
|
31
|
+
options.merge!(:require_secure => true)
|
32
|
+
options[:image] = File.new(image_path)
|
33
|
+
options[:multipart] = true
|
34
|
+
post("/listings/#{listing.id}/images", options)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Delete image
|
38
|
+
#
|
39
|
+
def self.destroy(listing, image, options = {})
|
40
|
+
options.merge!(:require_secure => true)
|
41
|
+
delete("/listings/#{listing.id}/images/#{image.id}", options)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/etsy/listing.rb
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
module Etsy
|
2
|
+
|
3
|
+
# = Listing
|
4
|
+
#
|
5
|
+
# Represents a single Etsy listing. Has the following attributes:
|
6
|
+
#
|
7
|
+
# [id] The unique identifier for this listing
|
8
|
+
# [title] The title of this listing
|
9
|
+
# [description] This listing's full description
|
10
|
+
# [view_count] The number of times this listing has been viewed
|
11
|
+
# [url] The full URL to this listing's detail page
|
12
|
+
# [price] The price of this listing item
|
13
|
+
# [currency] The currency that the seller is using for this listing item
|
14
|
+
# [quantity] The number of items available for sale
|
15
|
+
# [tags] An array of tags that the seller has used for this listing
|
16
|
+
# [materials] Any array of materials that was used in the production of this item
|
17
|
+
# [state] The current state of the item
|
18
|
+
# [hue] The hue of the listing's primary image (HSV color).
|
19
|
+
# [saturation] The saturation of the listing's primary image (HSV color).
|
20
|
+
# [brightness] The value of the listing's primary image (HSV color).
|
21
|
+
# [black_and_white?] True if the listing's primary image is in black & white.
|
22
|
+
#
|
23
|
+
# Additionally, the following queries on this item are available:
|
24
|
+
#
|
25
|
+
# [active?] Is this listing active?
|
26
|
+
# [removed?] Has this listing been removed?
|
27
|
+
# [sold_out?] Is this listing sold out?
|
28
|
+
# [expired?] Has this listing expired?
|
29
|
+
# [alchemy?] Is this listing an Alchemy item? (i.e. requested by an Etsy user)
|
30
|
+
#
|
31
|
+
class Listing
|
32
|
+
|
33
|
+
include Etsy::Model
|
34
|
+
|
35
|
+
STATES = %w(active removed sold_out expired alchemy)
|
36
|
+
VALID_STATES = [:active, :expired, :inactive, :sold, :featured, :draft, :sold_out]
|
37
|
+
|
38
|
+
attribute :id, :from => :listing_id
|
39
|
+
attribute :view_count, :from => :views
|
40
|
+
attribute :created, :from => :creation_tsz
|
41
|
+
attribute :modified, :from => :last_modified_tsz
|
42
|
+
attribute :currency, :from => :currency_code
|
43
|
+
attribute :ending, :from => :ending_tsz
|
44
|
+
attribute :shop_section, :from => :shop_section_id
|
45
|
+
|
46
|
+
attributes :title, :description, :state, :url, :price, :quantity,
|
47
|
+
:tags, :materials, :hue, :saturation, :brightness, :is_black_and_white,
|
48
|
+
:featured_rank, :occasion, :num_favorers, :user_id,
|
49
|
+
:shipping_template_id, :who_made, :when_made,
|
50
|
+
:original_creation_tsz, :style, :category_path,
|
51
|
+
:taxonomy_id, :taxonomy_attributes
|
52
|
+
|
53
|
+
association :image, :from => 'Images'
|
54
|
+
|
55
|
+
def self.create(options = {})
|
56
|
+
options.merge!(:require_secure => true)
|
57
|
+
post("/listings", options)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.update(listing, options = {})
|
61
|
+
options.merge!(:require_secure => true)
|
62
|
+
put("/listings/#{listing.id}", options)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.destroy(listing, options = {})
|
66
|
+
options.merge!(:require_secure => true)
|
67
|
+
delete("/listings/#{listing.id}", options)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Retrieve one or more listings by ID:
|
71
|
+
#
|
72
|
+
# Etsy::Listing.find(123)
|
73
|
+
#
|
74
|
+
# You can find multiple listings by passing an array of identifiers:
|
75
|
+
#
|
76
|
+
# Etsy::Listing.find([123, 456])
|
77
|
+
#
|
78
|
+
def self.find(*identifiers_and_options)
|
79
|
+
find_one_or_more('listings', identifiers_and_options)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Retrieve listings for a given shop.
|
83
|
+
# By default, pulls back the first 25 active listings.
|
84
|
+
# Defaults can be overridden using :limit, :offset, and :state
|
85
|
+
#
|
86
|
+
# Available states are :active, :expired, :inactive, :sold, and :featured, :draft, :sold_out
|
87
|
+
# where :featured is a subset of the others.
|
88
|
+
#
|
89
|
+
# options = {
|
90
|
+
# :state => :expired,
|
91
|
+
# :limit => 100,
|
92
|
+
# :offset => 100,
|
93
|
+
# :token => 'toke',
|
94
|
+
# :secret => 'secret'
|
95
|
+
# }
|
96
|
+
# Etsy::Listing.find_all_by_shop_id(123, options)
|
97
|
+
#
|
98
|
+
def self.find_all_by_shop_id(shop_id, options = {})
|
99
|
+
state = options.delete(:state) || :active
|
100
|
+
|
101
|
+
raise(ArgumentError, self.invalid_state_message(state)) unless valid?(state)
|
102
|
+
|
103
|
+
if state == :sold
|
104
|
+
sold_listings(shop_id, options)
|
105
|
+
else
|
106
|
+
get_all("/shops/#{shop_id}/listings/#{state}", options)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Retrieve active listings for a given category.
|
111
|
+
# By default, pulls back the first 25 active listings.
|
112
|
+
# Defaults can be overridden using :limit, :offset, and :state
|
113
|
+
#
|
114
|
+
# options = {
|
115
|
+
# :limit => 25,
|
116
|
+
# :offset => 100,
|
117
|
+
# :token => 'toke',
|
118
|
+
# :secret => 'secret'
|
119
|
+
# }
|
120
|
+
# Etsy::Listing.find_all_active_by_category("accessories", options)
|
121
|
+
#
|
122
|
+
def self.find_all_active_by_category(category, options = {})
|
123
|
+
options[:category] = category
|
124
|
+
get_all("/listings/active", options)
|
125
|
+
end
|
126
|
+
|
127
|
+
# The collection of images associated with this listing.
|
128
|
+
#
|
129
|
+
def images
|
130
|
+
@images ||= listing_images
|
131
|
+
end
|
132
|
+
|
133
|
+
# The primary image for this listing.
|
134
|
+
#
|
135
|
+
def image
|
136
|
+
images.first
|
137
|
+
end
|
138
|
+
|
139
|
+
# Listing category name
|
140
|
+
#
|
141
|
+
def category
|
142
|
+
path = category_path.join('/')
|
143
|
+
@category ||= Category.find(path)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the taxonomy defined attributes for the listing
|
147
|
+
#
|
148
|
+
def taxonomy_attributes(options={})
|
149
|
+
options.merge!(:require_secure => true)
|
150
|
+
self.class.get_all("/listings/#{id}/attributes", oauth.merge(options))
|
151
|
+
end
|
152
|
+
|
153
|
+
def variations(options={})
|
154
|
+
options.merge!(:require_secure => true)
|
155
|
+
self.class.get_all("/listings/#{id}/variations", oauth.merge(options))
|
156
|
+
end
|
157
|
+
|
158
|
+
# If these are your desired variations:
|
159
|
+
# - Dimensions: 1 x 2 inches
|
160
|
+
# - Dimensions: 2 x 4 inches
|
161
|
+
#
|
162
|
+
# Then you first have to find the property ID of the property you want to vary. Eg:
|
163
|
+
# Etsy::Variation::PropertySet.find_property_by_name("Dimensions").fetch("property_id")
|
164
|
+
#
|
165
|
+
# Then you can decide which options you want to set for this property.
|
166
|
+
# Eg:
|
167
|
+
# Etsy::Variation::PropertySet.qualifying_properties_for_property("Dimension")
|
168
|
+
# => [{
|
169
|
+
# "param"=>"dimensions_scale",
|
170
|
+
# "description"=>"Sizing Scale",
|
171
|
+
# "options"=>{
|
172
|
+
# "Inches" => 344,
|
173
|
+
# "Centimeters" => 345,
|
174
|
+
# "Other" => 346
|
175
|
+
# }
|
176
|
+
# }]
|
177
|
+
#
|
178
|
+
# Put it all together for a call to add_variations:
|
179
|
+
|
180
|
+
# property_id = Etsy::Variation::PropertySet.find_property_by_name("Dimensions").fetch("property_id")
|
181
|
+
# scale = Etsy::Variation::PropertySet.qualifying_properties_for_property("Dimensions").detect {|qp| qp.fetch("description") == "Sizing Scale"}
|
182
|
+
# my_listing.add_variations(
|
183
|
+
# :variations => [
|
184
|
+
# {"property_id" => property_id, "value" => "1 x 2", "is_available" => true, "price" => 1.23},
|
185
|
+
# {"property_id" => property_id, "value" => "2 x 4", "is_available" => true, "price" => 2.34}
|
186
|
+
# ],
|
187
|
+
# scale.fetch("param") => scale.fetch("options").fetch("Inches")
|
188
|
+
# )
|
189
|
+
def add_variations(options)
|
190
|
+
options[:variations] = JSON.dump(options.delete(:variations))
|
191
|
+
options[:require_secure] = true
|
192
|
+
self.class.post("/listings/#{id}/variations", options)
|
193
|
+
end
|
194
|
+
|
195
|
+
def update_variations(options)
|
196
|
+
options[:variations] = JSON.dump(options.delete(:variations))
|
197
|
+
options[:require_secure] = true
|
198
|
+
self.class.put("/listings/#{id}/variations", options)
|
199
|
+
end
|
200
|
+
|
201
|
+
def black_and_white?
|
202
|
+
is_black_and_white
|
203
|
+
end
|
204
|
+
|
205
|
+
STATES.each do |method_name|
|
206
|
+
define_method "#{method_name}?" do
|
207
|
+
state == method_name.sub('_', '')
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Time that this listing was created
|
212
|
+
#
|
213
|
+
def created_at
|
214
|
+
Time.at(created)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Time that this listing was last modified
|
218
|
+
#
|
219
|
+
def modified_at
|
220
|
+
Time.at(modified)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Time that this listing is ending (will be removed from store)
|
224
|
+
#
|
225
|
+
def ending_at
|
226
|
+
Time.at(ending)
|
227
|
+
end
|
228
|
+
|
229
|
+
#Return a list of users who have favorited this listing
|
230
|
+
#
|
231
|
+
def admirers(options = {})
|
232
|
+
options = options.merge(:access_token => token, :access_secret => secret) if (token && secret)
|
233
|
+
favorite_listings = FavoriteListing.find_all_listings_favored_by(id, options)
|
234
|
+
user_ids = favorite_listings.map {|f| f.user_id }.uniq
|
235
|
+
(user_ids.size > 0) ? Array(Etsy::User.find(user_ids, options)) : []
|
236
|
+
end
|
237
|
+
|
238
|
+
def is_supply
|
239
|
+
!!@result.fetch("is_supply")
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
def self.valid?(state)
|
245
|
+
VALID_STATES.include?(state)
|
246
|
+
end
|
247
|
+
|
248
|
+
def self.invalid_state_message(state)
|
249
|
+
"The state '#{state}' is invalid. Must be one of #{VALID_STATES.join(', ')}"
|
250
|
+
end
|
251
|
+
|
252
|
+
def self.sold_listings(shop_id, options = {})
|
253
|
+
includes = options.delete(:includes)
|
254
|
+
|
255
|
+
transactions = Transaction.find_all_by_shop_id(shop_id, options)
|
256
|
+
listing_ids = transactions.map {|t| t.listing_id }.uniq
|
257
|
+
|
258
|
+
options = options.merge(:includes => includes) if includes
|
259
|
+
(listing_ids.size > 0) ? Array(find(listing_ids, options)) : []
|
260
|
+
end
|
261
|
+
|
262
|
+
#Find all listings favored by a user
|
263
|
+
#
|
264
|
+
def self.find_all_user_favorite_listings(user_id, options = {})
|
265
|
+
favorite_listings = FavoriteListing.find_all_user_favorite_listings(user_id, options)
|
266
|
+
listing_ids = favorite_listings.map {|f| f.listing_id }.uniq
|
267
|
+
(listing_ids.size > 0) ? Array(find(listing_ids, options)) : []
|
268
|
+
end
|
269
|
+
|
270
|
+
#Find all listings that have been bought by a user
|
271
|
+
#
|
272
|
+
def self.bought_listings(user_id, options = {})
|
273
|
+
includes = options.delete(:includes)
|
274
|
+
|
275
|
+
transactions = Transaction.find_all_by_buyer_id(user_id, options)
|
276
|
+
listing_ids = transactions.map {|t| t.listing_id }.uniq
|
277
|
+
|
278
|
+
options = options.merge(:includes => includes) if includes
|
279
|
+
(listing_ids.size > 0) ? Array(find(listing_ids, options)) : []
|
280
|
+
end
|
281
|
+
|
282
|
+
private
|
283
|
+
|
284
|
+
def oauth
|
285
|
+
oauth = (token && secret) ? {:access_token => token, :access_secret => secret} : {}
|
286
|
+
end
|
287
|
+
|
288
|
+
def listing_images
|
289
|
+
if result && result["Images"]
|
290
|
+
result["Images"].map { |hash| Image.new(hash) }
|
291
|
+
else
|
292
|
+
Image.find_all_by_listing_id(id, oauth)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
data/lib/etsy/model.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
module Etsy
|
2
|
+
module Model # :nodoc:all
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
|
6
|
+
def attribute(name, options = {})
|
7
|
+
define_method name do
|
8
|
+
@result[options.fetch(:from, name).to_s]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def attributes(*names)
|
13
|
+
names.each {|name| attribute(name) }
|
14
|
+
end
|
15
|
+
|
16
|
+
# FIXME: not quite sure where I'm going with this yet. KO.
|
17
|
+
def association(name, options = {})
|
18
|
+
define_method "associated_#{name}" do
|
19
|
+
@result[options.fetch(:from, name).to_s]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(endpoint, options = {})
|
24
|
+
objects = get_all(endpoint, options)
|
25
|
+
if objects.length == 0
|
26
|
+
nil
|
27
|
+
elsif objects.length == 1
|
28
|
+
objects[0]
|
29
|
+
else
|
30
|
+
objects
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_all(endpoint, options={})
|
35
|
+
limit = options[:limit]
|
36
|
+
|
37
|
+
if limit
|
38
|
+
initial_offset = options.fetch(:offset, 0)
|
39
|
+
batch_size = options.fetch(:batch_size, 100)
|
40
|
+
|
41
|
+
result = []
|
42
|
+
|
43
|
+
if limit == :all
|
44
|
+
response = Request.get(endpoint, options.merge(:limit => batch_size, :offset => initial_offset))
|
45
|
+
result << response.result
|
46
|
+
limit = [response.total - batch_size - initial_offset, 0].max
|
47
|
+
initial_offset += batch_size
|
48
|
+
end
|
49
|
+
|
50
|
+
num_batches = limit / batch_size
|
51
|
+
|
52
|
+
num_batches.times do |batch|
|
53
|
+
total_offset = initial_offset + batch * batch_size
|
54
|
+
response = Request.get(endpoint, options.merge(:limit => batch_size, :offset => total_offset))
|
55
|
+
result << response.result
|
56
|
+
end
|
57
|
+
|
58
|
+
remainder = limit % batch_size
|
59
|
+
|
60
|
+
if remainder > 0
|
61
|
+
total_offset = initial_offset + num_batches * batch_size
|
62
|
+
response = Request.get(endpoint, options.merge(:limit => remainder, :offset => total_offset))
|
63
|
+
result << response.result
|
64
|
+
end
|
65
|
+
else
|
66
|
+
response = Request.get(endpoint, options)
|
67
|
+
result = response.result
|
68
|
+
end
|
69
|
+
|
70
|
+
[result].flatten.map do |data|
|
71
|
+
if options[:access_token] && options[:access_secret]
|
72
|
+
new(data, options[:access_token], options[:access_secret])
|
73
|
+
else
|
74
|
+
new(data)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def post(endpoint, options={})
|
80
|
+
Request.post(endpoint, options)
|
81
|
+
end
|
82
|
+
|
83
|
+
def put(endpoint, options={})
|
84
|
+
Request.put(endpoint, options)
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete(endpoint, options={})
|
88
|
+
Request.delete(endpoint, options)
|
89
|
+
end
|
90
|
+
|
91
|
+
def find_one_or_more(endpoint, identifiers_and_options)
|
92
|
+
options = options_from(identifiers_and_options)
|
93
|
+
append = options.delete(:append_to_endpoint)
|
94
|
+
append = append.nil? ? "" : "/#{append}"
|
95
|
+
identifiers = identifiers_and_options
|
96
|
+
get("/#{endpoint}/#{identifiers.join(',')}#{append}", options)
|
97
|
+
end
|
98
|
+
|
99
|
+
def options_from(argument)
|
100
|
+
(argument.last.class == Hash) ? argument.pop : {}
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def initialize(result = nil, token = nil, secret = nil)
|
106
|
+
@result = result
|
107
|
+
@token = token
|
108
|
+
@secret = secret
|
109
|
+
end
|
110
|
+
|
111
|
+
def token
|
112
|
+
@token
|
113
|
+
end
|
114
|
+
|
115
|
+
def secret
|
116
|
+
@secret
|
117
|
+
end
|
118
|
+
|
119
|
+
def result
|
120
|
+
@result
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.included(other)
|
124
|
+
other.extend ClassMethods
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|