mad_cart 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 96cf8c41f9f10385ad2951591b8e2dfdeb7d9aa0
4
- data.tar.gz: 28a96a5ed05429ac226932047f619181bec18796
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MzJkMmY4NjNhZmMyZTVhZDQzNmFjMmUyOGUzYWFiN2NmODE0MDBmYQ==
5
+ data.tar.gz: !binary |-
6
+ YmNmMTgyYWRmNjUyNmM2YmFmYTk1NjBkZDE3MDE1Y2Q0MjY2NDQ3Zg==
5
7
  SHA512:
6
- metadata.gz: 4a3a8a15d286bdfd3431014a6204ab1eb930e96d7b37c7905a7272f2fc0b35ee43c47613e527a510cdb3858ca8bee89209b270a5bcda54f22a4951138a1a0cee
7
- data.tar.gz: b3a5547bb315725e21c60304d8e66151266ec98aae6a6ebacbef40f28e3b0654b787f1b16f9b9156b49794671cf9d25bebde5c2cbb49c3f51aa3586012a5962e
8
+ metadata.gz: !binary |-
9
+ NTkyY2NkMzU2NDM5MWYwYWExOTYyYzdhZjNmYzJkNGVmMzM0YjEyNTQxN2Y5
10
+ NmU2NThjYWIwYjY2ZTU4MzIxYzZlZTQxMWRmMmVlMmNiZjg0MmY2ZmY5NjQz
11
+ YTU3MDQyZDUxNDk2YmFhNThhNDRlYzc2YjdiY2UxZmNkMWRjOWM=
12
+ data.tar.gz: !binary |-
13
+ MDlkOTlhZTg5MWEwYTcyYmYyYTczNDZlNmFhYjBmMmE0NDY4YjRhNTI0MjJl
14
+ ZGIwNzVhNDczZjgwOTA0MTIzYzlkNjY0NjdlNWIwMmNjZjgyM2NmNTY4Zjky
15
+ NDRjN2E2YTEwNzE0MjYwNTRhZmUwZDUwNDdkMjJjNTFhMGExYTk=
data/README.md CHANGED
@@ -7,6 +7,7 @@ A flexible DSL allows easy CRM and store integration.
7
7
  Currently supports the following stores:
8
8
  **-Etsy**
9
9
  **-Bigcommerce**
10
+ **-Spree**
10
11
 
11
12
  ## Installation
12
13
 
@@ -106,6 +107,16 @@ store = MadCart::Store::Etsy.new
106
107
  store.products.each{|p| MyProduct.create!(p.attributes) }
107
108
  ```
108
109
 
110
+ ### Exceptions
111
+
112
+ MadCart throws several types of exceptions:
113
+
114
+ ```ruby
115
+ MadCart::Store::ServerError #=> when Store's API returns server error response (status code: 500).
116
+ MadCart::Store::InvalidCredentials #=> when Store's API returns unauthorized response (status code: 401).
117
+ MadCart::Store::InvalidStore #=> when there is a problem with connection to Store's API.
118
+ ```
119
+
109
120
  ## Contributing
110
121
 
111
122
  See the [Contributor's Guide](https://github.com/madmimi/mad_cart/wiki/Contributor's-Guide) for info on the store integration API.
@@ -9,7 +9,10 @@ module MadCart
9
9
  "in your initialize method should you require it."
10
10
  end
11
11
  end
12
- class InvalidStore < StandardError; end
12
+
13
+ InvalidStore = Class.new(StandardError)
14
+ ServerError = Class.new(StandardError)
15
+ InvalidCredentials = Class.new(StandardError)
13
16
 
14
17
  module Base
15
18
  def self.included(base)
@@ -1,10 +1,6 @@
1
1
  module MadCart
2
2
  module Store
3
3
  class BigCommerce
4
- class InvalidStore < StandardError; end;
5
- class ServerError < StandardError; end;
6
- class InvalidCredentials < StandardError; end;
7
-
8
4
  include MadCart::Store::Base
9
5
 
10
6
  create_connection_with :create_connection, :requires => [:api_key, :store_url, :username]
@@ -16,7 +12,7 @@ module MadCart
16
12
  connection.get('time.json')
17
13
  end
18
14
  return true
19
-
15
+
20
16
  rescue InvalidCredentials => e
21
17
  return false
22
18
  end
@@ -30,11 +26,11 @@ module MadCart
30
26
  def make_customer_request(params={:min_id => 1})
31
27
  parse_response { connection.get('customers.json', params) }
32
28
  end
33
-
29
+
34
30
  def get_products(options={})
35
31
  product_hashes = connection.get('products.json', options).try(:body)
36
32
  return [] unless product_hashes
37
-
33
+
38
34
  threads, images = [], []
39
35
  product_hashes.each do |product|
40
36
  threads << Thread.new do
@@ -44,7 +40,7 @@ module MadCart
44
40
  end
45
41
  end
46
42
  end
47
- threads.each { |t| t.join }
43
+ threads.each { |t| t.join }
48
44
 
49
45
  product_hashes.map do |p|
50
46
 
@@ -10,7 +10,7 @@ module MadCart
10
10
  create_connection_with :create_connection, :requires => [:store_name, :api_key]
11
11
  fetch :products, :with => :get_products
12
12
  format :products, :with => :format_products
13
-
13
+
14
14
  def valid?
15
15
  self.connection ? true : false
16
16
  end
@@ -39,19 +39,18 @@ module MadCart
39
39
  store = ::Etsy::Shop.find(args[:store_name])
40
40
  if store.is_a? Array
41
41
  return store.first
42
- else
42
+ else
43
43
  raise InvalidStore if store.nil?
44
44
  return store
45
45
  end
46
46
  end
47
-
47
+
48
48
  def product_options(options)
49
49
  prod_options = options.clone
50
50
  prod_options[:page] ||= 1
51
-
51
+
52
52
  return prod_options
53
53
  end
54
54
  end
55
55
  end
56
56
  end
57
-
@@ -0,0 +1,123 @@
1
+ module MadCart
2
+ module Store
3
+ class Spree
4
+ include MadCart::Store::Base
5
+
6
+ ORDERS_PER_PAGE = 50
7
+
8
+ create_connection_with :create_connection, :requires => [:api_key, :store_url]
9
+ fetch :customers, :with => :get_customer_hashes
10
+ fetch :products, :with => :get_products
11
+
12
+ def valid?
13
+ check_for_errors do
14
+ connection.get('orders.json')
15
+ end
16
+ return true
17
+ rescue InvalidCredentials => e
18
+ return false
19
+ end
20
+
21
+ def products_count
22
+ (parse_response { connection.get('products.json') })["count"]
23
+ end
24
+
25
+ private
26
+
27
+ def make_order_request(params={})
28
+ params = params.deep_merge({ :page => 1, :per_page => ORDERS_PER_PAGE })
29
+ parse_response { connection.get('orders.json', params) }["orders"]
30
+ end
31
+
32
+ def get_products(options={})
33
+ product_hashes = connection.get('products.json', options).try{ |c| c.body["products"] }
34
+ return [] unless product_hashes
35
+
36
+ product_hashes.map do |product|
37
+ if product["master"]["images"]
38
+ image = product["master"]["images"].first
39
+ product = product.merge({
40
+ :url => connection.build_url("/products/#{ product["slug"] }").to_s,
41
+ :image_square_url => connection.build_url(image["product_url"]).to_s,
42
+ :image_url => connection.build_url(image["large_url"]).to_s
43
+ })
44
+ end
45
+
46
+ product
47
+ end
48
+ end
49
+
50
+ def get_customer_hashes
51
+ result = []
52
+
53
+ loop(:make_order_request) do |c|
54
+ result << {
55
+ order_number: c["number"],
56
+ user_email: c["email"]
57
+ }
58
+ end
59
+
60
+ result.reverse.select{ |r| r[:user_email].present? }.uniq{ |r| r[:user_email] }.map do |r|
61
+ c = parse_response { connection.get("orders/#{ r[:order_number] }.json") }
62
+ if c['email']
63
+ {
64
+ first_name: c['bill_address'].try(:[], 'firstname'),
65
+ last_name: c['bill_address'].try(:[], 'lastname'),
66
+ email: c['email'],
67
+ id: c['email']
68
+ }
69
+ end
70
+ end.compact
71
+ end
72
+
73
+ def loop(source, &block)
74
+ page = 1
75
+ items = send(source, { :page => page })
76
+
77
+ while true
78
+ items.each &block
79
+ break if items.count < ORDERS_PER_PAGE
80
+ items = send(source, { :page => page += 1 })
81
+ end
82
+
83
+ end
84
+
85
+ def parse_response(&block)
86
+ response = check_for_errors &block
87
+ return [] if empty_body?(response)
88
+ return response.body
89
+ end
90
+
91
+ def check_for_errors(&block)
92
+ response = yield
93
+
94
+ case response.status
95
+ when 401
96
+ raise InvalidCredentials
97
+ when 500
98
+ raise ServerError
99
+ end
100
+
101
+ response
102
+ rescue Faraday::Error::ConnectionFailed => e
103
+ raise InvalidStore
104
+ end
105
+
106
+ def api_url_for(store_domain)
107
+ "http://#{store_domain}/api/"
108
+ end
109
+
110
+ def empty_body?(response)
111
+ true if response.status == 204 || response.body.nil?
112
+ end
113
+
114
+ def create_connection(args={})
115
+ Faraday.new(:url => api_url_for(args[:store_url])) do |connection|
116
+ connection.response :json
117
+ connection.adapter Faraday.default_adapter
118
+ connection.headers['X-Spree-Token'] = args[:api_key]
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -1,3 +1,3 @@
1
1
  module MadCart
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/mad_cart.rb CHANGED
@@ -21,3 +21,4 @@ require 'mad_cart/model/product'
21
21
  require 'mad_cart/store/base'
22
22
  require 'mad_cart/store/big_commerce'
23
23
  require 'mad_cart/store/etsy'
24
+ require 'mad_cart/store/spree'