mad_cart 0.0.4 → 0.0.5

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 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'