dawanda_client 0.1.6
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.
- data/.gitignore +2 -0
- data/LICENSE +22 -0
- data/README.rdoc +97 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/dawanda_client.gemspec +75 -0
- data/lib/dawanda.rb +99 -0
- data/lib/dawanda/category.rb +47 -0
- data/lib/dawanda/channel.rb +26 -0
- data/lib/dawanda/color.rb +23 -0
- data/lib/dawanda/model.rb +79 -0
- data/lib/dawanda/product.rb +80 -0
- data/lib/dawanda/request.rb +56 -0
- data/lib/dawanda/response.rb +47 -0
- data/lib/dawanda/shop.rb +64 -0
- data/lib/dawanda/shop_category.rb +28 -0
- data/lib/dawanda/user.rb +60 -0
- data/test/fixtures/getCategoryDetails.json +21 -0
- data/test/fixtures/getProductDetails.json +71 -0
- data/test/fixtures/getShopDetails.json +72 -0
- data/test/fixtures/getUserDetails.json +31 -0
- data/test/test_helper.rb +53 -0
- data/test/unit/dawanda/category_test.rb +39 -0
- data/test/unit/dawanda/color_test.rb +20 -0
- data/test/unit/dawanda/product_test.rb +55 -0
- data/test/unit/dawanda/shop_category_test.rb +20 -0
- data/test/unit/dawanda/shop_test.rb +67 -0
- data/test/unit/dawanda/user_test.rb +38 -0
- data/test/unit/dawanda_test.rb +54 -0
- metadata +91 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
module Dawanda
|
2
|
+
module Model # :nodoc:all
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
|
6
|
+
def attribute(name, options = {})
|
7
|
+
from = parse_from(name,options)
|
8
|
+
if from.is_a? Array
|
9
|
+
class_eval <<-CODE
|
10
|
+
def #{name}
|
11
|
+
@result['#{from.first}']['#{from.last}']
|
12
|
+
end
|
13
|
+
CODE
|
14
|
+
else
|
15
|
+
class_eval <<-CODE
|
16
|
+
def #{name}
|
17
|
+
@result['#{from}']
|
18
|
+
end
|
19
|
+
CODE
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_from(name,options)
|
24
|
+
from = options.fetch(:from,name)
|
25
|
+
return from unless from.is_a? Hash
|
26
|
+
key = from.keys.first
|
27
|
+
value = from.fetch(key)
|
28
|
+
[key,value]
|
29
|
+
end
|
30
|
+
|
31
|
+
def attributes(*names)
|
32
|
+
names.each {|name| attribute(name) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def finder(type, endpoint)
|
36
|
+
parameter = endpoint.scan(/:\w+/).first
|
37
|
+
parameter.sub!(/^:/, '')
|
38
|
+
|
39
|
+
endpoint.sub!(":#{parameter}", '#{' + parameter + '}')
|
40
|
+
|
41
|
+
send("find_#{type}", parameter, endpoint)
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_all(parameter, endpoint)
|
45
|
+
class_eval <<-CODE
|
46
|
+
def self.find_all_by_#{parameter}(#{parameter}, params = {})
|
47
|
+
response = Request.get("#{endpoint}", params)
|
48
|
+
response.result.map {|listing| new(listing) }
|
49
|
+
end
|
50
|
+
CODE
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_one(parameter, endpoint)
|
54
|
+
class_eval <<-CODE
|
55
|
+
def self.find_by_#{parameter}(#{parameter}, params = {})
|
56
|
+
response = Request.get("#{endpoint}", params)
|
57
|
+
new response.result
|
58
|
+
end
|
59
|
+
CODE
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
module InstanceMethods
|
65
|
+
|
66
|
+
def initialize(result = nil)
|
67
|
+
@result = result
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.included(other)
|
73
|
+
other.send(:extend, Dawanda::Model::ClassMethods)
|
74
|
+
other.send(:include, Dawanda::Model::InstanceMethods)
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Dawanda
|
2
|
+
|
3
|
+
# = Product
|
4
|
+
#
|
5
|
+
# Represents a single Dawanda product. Has the following attributes:
|
6
|
+
|
7
|
+
#
|
8
|
+
# [id] The unique identifier for this product
|
9
|
+
# [name] The title of this product
|
10
|
+
# [description] This product's full description
|
11
|
+
# [view_count] The number of times this product has been viewed
|
12
|
+
# [product_url] The full URL to this product's detail page
|
13
|
+
# [price] The price of this product item
|
14
|
+
# [quantity] The number of items available for sale
|
15
|
+
# [tags] An array of tags that the seller has used for this product
|
16
|
+
# [materials] Any array of materials that was used in the production of this item
|
17
|
+
#
|
18
|
+
class Product
|
19
|
+
|
20
|
+
include Dawanda::Model
|
21
|
+
|
22
|
+
finder :all, '/shops/:shop_id/products'
|
23
|
+
finder :all, '/categories/:category_id/products'
|
24
|
+
finder :all, '/shop_categories/:shop_category_id/products'
|
25
|
+
finder :all, '/colors/:hex/products'
|
26
|
+
finder :all, '/colors/:hex_search/products/search'
|
27
|
+
finder :all, '/product/:method'
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
finder :one, '/products/:id'
|
32
|
+
|
33
|
+
attribute :created, :from => :created_at
|
34
|
+
attribute :category_id, :from => {:category => :id }
|
35
|
+
attribute :user_id, :from => {:user => :id }
|
36
|
+
|
37
|
+
attributes :id, :name, :description, :created_at, :view_count, :tags,
|
38
|
+
:ending, :quantity, :materials, :price, :restful_path, :product_url, :images
|
39
|
+
|
40
|
+
|
41
|
+
# Time that this product was created
|
42
|
+
#
|
43
|
+
def created_at
|
44
|
+
Time.parse(created)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Time that this product is ending (will be removed from store)
|
48
|
+
#
|
49
|
+
def ending_at
|
50
|
+
Time.parse(ending)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Search for users with given keyword
|
54
|
+
def self.search(keyword, params = {})
|
55
|
+
params.update(:keyword => keyword)
|
56
|
+
self.find_all_by_method('search', params)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Search for users with given keyword and color
|
60
|
+
def self.search_by_color(color, keyword, params = {})
|
61
|
+
params.update(:keyword => keyword)
|
62
|
+
self.find_all_by_hex_search(color, params)
|
63
|
+
end
|
64
|
+
|
65
|
+
# The primary image for this product. See Dawanda::Image for more
|
66
|
+
# information
|
67
|
+
#
|
68
|
+
def image_25x25
|
69
|
+
images.first['image_25x25']
|
70
|
+
end
|
71
|
+
|
72
|
+
def category(params = {})
|
73
|
+
Category.find_by_id(category_id)
|
74
|
+
end
|
75
|
+
|
76
|
+
def shop(params = {})
|
77
|
+
Shop.find_by_user_id(user_id)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Dawanda
|
2
|
+
|
3
|
+
# = Request
|
4
|
+
#
|
5
|
+
# A basic wrapper around GET requests to the Dawanda JSON API
|
6
|
+
#
|
7
|
+
class Request
|
8
|
+
|
9
|
+
# The base URL for API requests
|
10
|
+
def self.base_url
|
11
|
+
url = "http://#{Dawanda.country}.dawanda.com/api/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
|
+
#
|
17
|
+
def self.get(resource_path, parameters = {})
|
18
|
+
parameters = {:format => 'json'}.update(parameters)
|
19
|
+
request = Request.new(resource_path, parameters)
|
20
|
+
Response.new(request.get)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create a new request for the resource with optional parameters
|
24
|
+
def initialize(resource_path, parameters = {})
|
25
|
+
@resource_path = resource_path
|
26
|
+
@parameters = parameters
|
27
|
+
end
|
28
|
+
|
29
|
+
# Perform a GET request against the API endpoint and return the raw
|
30
|
+
# response data
|
31
|
+
def get
|
32
|
+
response = Net::HTTP.get_response(endpoint_uri)
|
33
|
+
case response
|
34
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
35
|
+
return response.body
|
36
|
+
else
|
37
|
+
raise response.body
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def parameters # :nodoc:
|
42
|
+
@parameters.merge(:api_key => Dawanda.api_key)
|
43
|
+
end
|
44
|
+
|
45
|
+
def query # :nodoc:
|
46
|
+
parameters.map {|k,v| "#{k}=#{v}"}.join('&')
|
47
|
+
end
|
48
|
+
|
49
|
+
def endpoint_uri # :nodoc:
|
50
|
+
uri = URI.parse("#{self.class.base_url}#{@resource_path}")
|
51
|
+
uri.query = query
|
52
|
+
uri
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Dawanda
|
2
|
+
|
3
|
+
# = Response
|
4
|
+
#
|
5
|
+
# Basic wrapper around the Dawanda JSON response data
|
6
|
+
#
|
7
|
+
class Response
|
8
|
+
|
9
|
+
# Create a new response based on the raw JSON
|
10
|
+
def initialize(data)
|
11
|
+
@data = data
|
12
|
+
end
|
13
|
+
|
14
|
+
# Convert the raw JSON data to a hash
|
15
|
+
def to_hash
|
16
|
+
@hash ||= JSON.parse(@data)
|
17
|
+
@hash['response']
|
18
|
+
end
|
19
|
+
|
20
|
+
# Number of records in the response
|
21
|
+
def entries
|
22
|
+
to_hash['entries']
|
23
|
+
end
|
24
|
+
|
25
|
+
# Number of pages in the response
|
26
|
+
def pages
|
27
|
+
to_hash['pages']
|
28
|
+
end
|
29
|
+
|
30
|
+
def type
|
31
|
+
to_hash['type']
|
32
|
+
end
|
33
|
+
|
34
|
+
def pluralized_type
|
35
|
+
type.to_s.pluralize
|
36
|
+
end
|
37
|
+
|
38
|
+
def params
|
39
|
+
to_hash['params']
|
40
|
+
end
|
41
|
+
# Results of the API request
|
42
|
+
def result
|
43
|
+
entries == 1 ? to_hash['result'][type] : to_hash['result'].values.first
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
data/lib/dawanda/shop.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Dawanda
|
2
|
+
|
3
|
+
# = Shop
|
4
|
+
#
|
5
|
+
# Represents a single Dawanda shop. Users may or may not have an associated shop -
|
6
|
+
# check the result of User#seller? to find out.
|
7
|
+
#
|
8
|
+
# A shop has the following attributes:
|
9
|
+
#
|
10
|
+
# [name] The shop's name
|
11
|
+
# [created_at] An announcement to buyers (displays on the shop's home page)
|
12
|
+
# [updated_at] The message sent to users who buy from this shop
|
13
|
+
# [banner_image_url] The full URL to the shops's banner image
|
14
|
+
#
|
15
|
+
class Shop
|
16
|
+
|
17
|
+
include Dawanda::Model
|
18
|
+
|
19
|
+
finder :one, '/shops/:user_id'
|
20
|
+
finder :all, '/shops/:method'
|
21
|
+
|
22
|
+
attribute :updated, :from => :updated_at
|
23
|
+
attribute :created, :from => :created_at
|
24
|
+
attribute :user_id, :from => { :user => :id }
|
25
|
+
attribute :banner_image_url, :from => { :images => :banner }
|
26
|
+
|
27
|
+
attributes :name
|
28
|
+
|
29
|
+
# Time that this shop was created
|
30
|
+
#
|
31
|
+
def created_at
|
32
|
+
Time.parse(created)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Time that this shop was last updated
|
36
|
+
#
|
37
|
+
def updated_at
|
38
|
+
Time.parse(updated)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Search for shops with given keyword
|
42
|
+
def self.search(keyword, params = {})
|
43
|
+
params.update(:keyword => keyword)
|
44
|
+
self.find_all_by_method('search', params)
|
45
|
+
end
|
46
|
+
|
47
|
+
# A collection of products in this user's shop. See Dawanda::Product for
|
48
|
+
# more information
|
49
|
+
#
|
50
|
+
def products(params = {})
|
51
|
+
@products ||= Product.find_all_by_shop_id(user_id.to_s, params)
|
52
|
+
end
|
53
|
+
|
54
|
+
# The user who runs this shop. See Dawanda::User for more information
|
55
|
+
def user(params = {})
|
56
|
+
@user ||= User.find_by_user_id(user_id, params)
|
57
|
+
end
|
58
|
+
|
59
|
+
# All shop categories in this shop. See Dawanda::ShopCategory for more information
|
60
|
+
def shop_categories(params = {})
|
61
|
+
@shop_categories ||= ShopCategory.find_all_by_shop_id(user_id.to_s, params)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Dawanda
|
2
|
+
|
3
|
+
# = ShopCategory
|
4
|
+
#
|
5
|
+
# Represents a single Dawanda::ShopCategory - has the following attributes:
|
6
|
+
#
|
7
|
+
# [id] The unique identifier for this shop category
|
8
|
+
# [name] This shop category's name
|
9
|
+
# [product_count] The amount of products in this shop category
|
10
|
+
# [restful_path] The path to the shop category
|
11
|
+
#
|
12
|
+
class ShopCategory
|
13
|
+
|
14
|
+
include Dawanda::Model
|
15
|
+
|
16
|
+
finder :all, '/shops/:shop_id/shop_categories'
|
17
|
+
finder :one, '/shop_categories/:id'
|
18
|
+
|
19
|
+
attributes :id, :name, :position, :restful_path, :product_count
|
20
|
+
|
21
|
+
|
22
|
+
# All products in this shop category. See Dawanda::Product for more information
|
23
|
+
def products(params = {})
|
24
|
+
Product.find_all_by_shop_category_id(id, params)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/dawanda/user.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Dawanda
|
2
|
+
|
3
|
+
# = User
|
4
|
+
#
|
5
|
+
# Represents a single Dawanda user - has the following attributes:
|
6
|
+
#
|
7
|
+
# [id] The unique identifier for this user
|
8
|
+
# [name] This user's username
|
9
|
+
# [city] The user's city / state (optional)
|
10
|
+
# [sex] The user's gender
|
11
|
+
# [transaction_sold_count] How many products have been sold by this user
|
12
|
+
# [is_seller] Is this user a seller?
|
13
|
+
# [bio] User's biography
|
14
|
+
# [restful_path]
|
15
|
+
# [url] The full URL to this user's profile page / shop (if seller)
|
16
|
+
#
|
17
|
+
class User
|
18
|
+
|
19
|
+
include Dawanda::Model
|
20
|
+
|
21
|
+
finder :one, '/users/:user_id'
|
22
|
+
finder :all, '/users/:method'
|
23
|
+
|
24
|
+
# attribute :last_login, :from => :last_login_epoch
|
25
|
+
|
26
|
+
attributes :id, :name, :url, :city, :sex, :bio, :transaction_sold_count, :is_seller, :images
|
27
|
+
|
28
|
+
# This user's shop, returns nil if user is not a seller. See Dawanda::Shop
|
29
|
+
# for more information.
|
30
|
+
#
|
31
|
+
def shop(params = {})
|
32
|
+
@shop ||= Shop.find_by_user_id(id, params) if seller?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Search for users with given keyword
|
36
|
+
def self.search(keyword, params = {})
|
37
|
+
params.update(:keyword => keyword)
|
38
|
+
self.find_all_by_method('search', params)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Is this user a seller?
|
42
|
+
#
|
43
|
+
def seller?
|
44
|
+
is_seller
|
45
|
+
end
|
46
|
+
|
47
|
+
def image_40x40
|
48
|
+
images.first['image_40x40']
|
49
|
+
end
|
50
|
+
|
51
|
+
def image_80x80
|
52
|
+
images.first['image_80x80']
|
53
|
+
end
|
54
|
+
|
55
|
+
def image_170x
|
56
|
+
images.first['image_170x']
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"response":{
|
3
|
+
"type":"category",
|
4
|
+
"pages":1,
|
5
|
+
"entries":1,
|
6
|
+
"result":{
|
7
|
+
"category":{
|
8
|
+
"name":"1003",
|
9
|
+
"product_count":754,
|
10
|
+
"id":418,
|
11
|
+
"parent_id":406,
|
12
|
+
"restful_path":"\/categories\/418"
|
13
|
+
}
|
14
|
+
},
|
15
|
+
"params":{
|
16
|
+
"format":"json",
|
17
|
+
"api_key":"foobar",
|
18
|
+
"id":"418"
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|