etsy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,125 @@
1
+ = Etsy
2
+
3
+ == Description
4
+
5
+ The Etsy gem provides a friendly Ruby interface to the Etsy API
6
+
7
+ == Installation
8
+
9
+ Installing the latest stable version is simple:
10
+
11
+ sudo gem install etsy
12
+
13
+ If you want to be on the bleeding edge, install from GitHub:
14
+
15
+ sudo gem install reagent-etsy --source=http://gems.github.com
16
+
17
+ == Usage
18
+
19
+ The Etsy API is read-only - all you need to gain access is an API Key (available
20
+ from http://developer.etsy.com). Once you have your API key, set it in your script:
21
+
22
+ require 'rubygems'
23
+ require 'etsy'
24
+ Etsy.api_key = 'foobar'
25
+
26
+ From there, you can make any calls to the API that you need.
27
+
28
+ === Users
29
+
30
+ If you're starting with a user, the easiest way is to use the Etsy.user method:
31
+
32
+ >> user = Etsy.user('littletjane')
33
+ => #<Etsy::User:0x107f82c @result=[{"city"=>"Washington, DC", ... >
34
+ >> user.username
35
+ => "littletjane"
36
+ >> user.id
37
+ => 5327518
38
+ >> user.url
39
+ => "http://www.etsy.com/shop.php?user_id=5327518"
40
+
41
+ For more information about what is available for a user, check out the documentation
42
+ for Etsy::User.
43
+
44
+ == Shops
45
+
46
+ Each user may optionally have a shop. If a user is a seller, he / she also has an
47
+ associated shop object:
48
+
49
+ >> user.seller?
50
+ => true
51
+ >> shop = user.shop
52
+ => #<Etsy::Shop:0x102578c @result={"is_vacation"=>"", "announcement"=> ... >
53
+ >> shop.name
54
+ => "littletjane"
55
+ >> shop.title
56
+ => "a cute and crafty mix of handmade goods."
57
+
58
+ More information about shops can be found in the documentation for Etsy::Shop.
59
+
60
+ == Listings
61
+
62
+ Shops contain multiple listings:
63
+
64
+ >> shop.listings
65
+ => [#<Etsy::Listing:0x119acac @result={} ...>, ... ]
66
+ >> listing = shop.listings.first
67
+ => #<Etsy::Listing:0x19a981c @result={} ... >
68
+ >> listing.title
69
+ => "hanging with the bad boys matchbox"
70
+ >> listing.description
71
+ => "standard size matchbox, approx. 1.5 x 2 inches ..."
72
+ >> listing.url
73
+ => "http://www.etsy.com/view_listing.php?listing_id=24165902"
74
+ >> listing.view_count
75
+ => 19
76
+ >> listing.created_at
77
+ => Sat Apr 25 11:31:34 -0400 2009
78
+
79
+ See the documentation for Etsy::Listing for more information.
80
+
81
+ == Images
82
+
83
+ Each listing has one or more images available:
84
+
85
+ >> listing.images
86
+ => [#<Etsy::Image:0x18f85e4 @result={} ... >,
87
+ #<Etsy::Image:0x18f85d0 @result={} ... >]
88
+ >> listing.images.first.small_square
89
+ => "http://ny-image2.etsy.com/il_25x25.67765346.jpg"
90
+ >> listing.images.first.large
91
+ => "http://ny-image2.etsy.com/il_430xN.67765346.jpg"
92
+
93
+ Listings also have a primary image:
94
+
95
+ >> listing.image
96
+ => #<Etsy::Image:0x18c3060 @result={} ... >
97
+ >> listing.image.large
98
+ => "http://ny-image2.etsy.com/il_430xN.67765346.jpg"
99
+
100
+ More information is available in the documentation for Etsy::Image.
101
+
102
+ == License
103
+
104
+ Copyright (c) 2009 Patrick Reagan (reaganpr@gmail.com)
105
+
106
+ Permission is hereby granted, free of charge, to any person
107
+ obtaining a copy of this software and associated documentation
108
+ files (the "Software"), to deal in the Software without
109
+ restriction, including without limitation the rights to use,
110
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
111
+ copies of the Software, and to permit persons to whom the
112
+ Software is furnished to do so, subject to the following
113
+ conditions:
114
+
115
+ The above copyright notice and this permission notice shall be
116
+ included in all copies or substantial portions of the Software.
117
+
118
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
119
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
120
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
121
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
122
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
123
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
124
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
125
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+
5
+ require 'lib/etsy/version'
6
+
7
+ task :default => :test
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'etsy'
11
+ s.version = Etsy::Version.to_s
12
+ s.has_rdoc = true
13
+ s.extra_rdoc_files = %w(README.rdoc)
14
+ s.rdoc_options = %w(--main README.rdoc)
15
+ s.summary = "Provides a friendly ruby-like interface to the Etsy API"
16
+ s.author = 'Patrick Reagan'
17
+ s.email = 'reaganpr@gmail.com'
18
+ s.homepage = 'http://sneaq.net'
19
+ s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
20
+ # s.executables = ['etsy']
21
+
22
+ s.add_dependency('json', '~> 1.1.0')
23
+ end
24
+
25
+ Rake::GemPackageTask.new(spec) do |pkg|
26
+ pkg.gem_spec = spec
27
+ end
28
+
29
+ Rake::TestTask.new do |t|
30
+ t.libs << 'test'
31
+ t.test_files = FileList["test/**/*_test.rb"]
32
+ t.verbose = true
33
+ end
34
+
35
+ desc 'Generate the gemspec to serve this Gem from Github'
36
+ task :github do
37
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
38
+ File.open(file, 'w') {|f| f << spec.to_ruby }
39
+ puts "Created gemspec: #{file}"
40
+ end
@@ -0,0 +1,65 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+
6
+ require 'etsy/request'
7
+ require 'etsy/response'
8
+
9
+ require 'etsy/model'
10
+ require 'etsy/user'
11
+ require 'etsy/shop'
12
+ require 'etsy/listing'
13
+ require 'etsy/image'
14
+
15
+ # = Etsy: A friendly Ruby interface to the Etsy API
16
+ #
17
+ # == Quick Start
18
+ #
19
+ # Getting started is easy. First, you will need a valid API key from the Etsy
20
+ # developer site (http://developer.etsy.com/). Since the API is read-only at
21
+ # the moment, that's all you need to do.
22
+ #
23
+ # To start using the API, require the etsy gem and set it up to use your API key:
24
+ #
25
+ # require 'rubygems'
26
+ # require 'etsy'
27
+ #
28
+ # Etsy.api_key = 'itsasecret'
29
+ #
30
+ # Now you can make API calls that originate from an Etsy user:
31
+ #
32
+ # # Find a user by username
33
+ # user = Etsy.user('littletjane')
34
+ #
35
+ # # Grab that user's shop information
36
+ # user.seller?
37
+ # user.shop
38
+ # user.shop.title
39
+ #
40
+ # # ... and the listings in the shop
41
+ # listing = user.shop.listings.first
42
+ # listing.title
43
+ # listing.description
44
+ #
45
+ # To see what else is available for a user, check out the full documentation for
46
+ # the Etsy::User class.
47
+ #
48
+ module Etsy
49
+
50
+ # Set the API key for all requests
51
+ def self.api_key=(api_key)
52
+ @api_key = api_key
53
+ end
54
+
55
+ # Retrieve the API key
56
+ def self.api_key
57
+ @api_key
58
+ end
59
+
60
+ # Find a user by username. See Etsy::User for more information.
61
+ def self.user(username)
62
+ User.find_by_username(username)
63
+ end
64
+
65
+ end
@@ -0,0 +1,27 @@
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
+ # [small_square] The smallest square image (25x25 pixels)
9
+ # [medium_square] The medium square image (50x50 pixels)
10
+ # [large_square] The largest square image (75x75 pixels)
11
+ # [small] The small image for this listing (155x125 pixels)
12
+ # [medium] The medium image for this listing (200x200 pixels)
13
+ # [large] The largest image available for this listing (430x? pixels)
14
+ #
15
+ class Image
16
+
17
+ include Etsy::Model
18
+
19
+ attribute :small_square, :from => :image_url_25x25
20
+ attribute :medium_square, :from => :image_url_50x50
21
+ attribute :large_square, :from => :image_url_75x75
22
+ attribute :small, :from => :image_url_155x125
23
+ attribute :medium, :from => :image_url_200x200
24
+ attribute :large, :from => :image_url_430xN
25
+
26
+ end
27
+ end
@@ -0,0 +1,76 @@
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
+ #
18
+ # Additionally, the following queries on this item are available:
19
+ #
20
+ # [active?] Is this listing active?
21
+ # [removed?] Has this listing been removed?
22
+ # [sold_out?] Is this listing sold out?
23
+ # [expired?] Has this listing expired?
24
+ # [alchemy?] Is this listing an Alchemy item? (i.e. requested by an Etsy user)
25
+ #
26
+ class Listing
27
+
28
+ include Etsy::Model
29
+
30
+ STATES = %w(active removed sold_out expired alchemy)
31
+
32
+ finder :all, '/shops/:user_id/listings'
33
+
34
+ attribute :id, :from => :listing_id
35
+ attribute :view_count, :from => :views
36
+ attribute :created, :from => :creation_epoch
37
+ attribute :currency, :from => :currency_code
38
+ attribute :ending, :from => :ending_epoch
39
+
40
+ attributes :title, :description, :state, :url, :price, :quantity,
41
+ :tags, :materials
42
+
43
+ STATES.each do |state|
44
+ define_method "#{state}?" do
45
+ self.state == state.sub('_', '')
46
+ end
47
+ end
48
+
49
+ # Time that this listing was created
50
+ #
51
+ def created_at
52
+ Time.at(created)
53
+ end
54
+
55
+ # Time that this listing is ending (will be removed from store)
56
+ #
57
+ def ending_at
58
+ Time.at(ending)
59
+ end
60
+
61
+ # The list of images associated with this listing. See Etsy::Image
62
+ # for more information
63
+ #
64
+ def images
65
+ @result['all_images'].map {|image_data| Image.new(image_data) }
66
+ end
67
+
68
+ # The primary image for this listing. See Etsy::Image for more
69
+ # information
70
+ #
71
+ def image
72
+ images.first
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,64 @@
1
+ module Etsy
2
+ module Model # :nodoc:all
3
+
4
+ module ClassMethods
5
+
6
+ def attribute(name, options = {})
7
+ from = options.fetch(:from, name)
8
+
9
+ class_eval <<-CODE
10
+ def #{name}
11
+ @result['#{from}']
12
+ end
13
+ CODE
14
+ end
15
+
16
+ def attributes(*names)
17
+ names.each {|name| attribute(name) }
18
+ end
19
+
20
+ def finder(type, endpoint)
21
+ parameter = endpoint.scan(/:\w+/).first
22
+ parameter.sub!(/^:/, '')
23
+
24
+ endpoint.sub!(":#{parameter}", '#{' + parameter + '}')
25
+
26
+ send("find_#{type}", parameter, endpoint)
27
+ end
28
+
29
+ def find_all(parameter, endpoint)
30
+ class_eval <<-CODE
31
+ def self.find_all_by_#{parameter}(#{parameter})
32
+ response = Request.get("#{endpoint}")
33
+ response.result.map {|listing| new(listing) }
34
+ end
35
+ CODE
36
+ end
37
+
38
+ def find_one(parameter, endpoint)
39
+ class_eval <<-CODE
40
+ def self.find_by_#{parameter}(#{parameter})
41
+ response = Request.get("#{endpoint}")
42
+ new response.result
43
+ end
44
+ CODE
45
+ end
46
+
47
+ end
48
+
49
+ module InstanceMethods
50
+
51
+ def initialize(result = nil)
52
+ @result = result
53
+ end
54
+
55
+ end
56
+
57
+ def self.included(other)
58
+ other.send(:extend, Etsy::Model::ClassMethods)
59
+ other.send(:include, Etsy::Model::InstanceMethods)
60
+ end
61
+
62
+
63
+ end
64
+ end
@@ -0,0 +1,48 @@
1
+ module Etsy
2
+
3
+ # = Request
4
+ #
5
+ # A basic wrapper around GET requests to the Etsy JSON API
6
+ #
7
+ class Request
8
+
9
+ # The base URL for API requests
10
+ def self.base_url
11
+ "http://beta-api.etsy.com/v1"
12
+ end
13
+
14
+ # Perform a GET request for the resource with optional parameters - returns
15
+ # A Response object with the payload data
16
+ def self.get(resource_path, parameters = {})
17
+ request = Request.new(resource_path, parameters)
18
+ Response.new(request.get)
19
+ end
20
+
21
+ # Create a new request for the resource with optional parameters
22
+ def initialize(resource_path, parameters = {})
23
+ @resource_path = resource_path
24
+ @parameters = parameters
25
+ end
26
+
27
+ # Perform a GET request against the API endpoint and return the raw
28
+ # response data
29
+ def get
30
+ Net::HTTP.get(endpoint_uri)
31
+ end
32
+
33
+ def parameters # :nodoc:
34
+ @parameters.merge(:api_key => Etsy.api_key, :detail_level => 'high')
35
+ end
36
+
37
+ def query # :nodoc:
38
+ parameters.map {|k,v| "#{k}=#{v}"}.join('&')
39
+ end
40
+
41
+ def endpoint_uri # :nodoc:
42
+ uri = URI.parse("#{self.class.base_url}#{@resource_path}")
43
+ uri.query = query
44
+ uri
45
+ end
46
+
47
+ end
48
+ end