oshpark 0.0.3
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 +22 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +97 -0
- data/Guardfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +85 -0
- data/Rakefile +7 -0
- data/bin/oshpark +44 -0
- data/lib/oshpark.rb +31 -0
- data/lib/oshpark/address.rb +46 -0
- data/lib/oshpark/client.rb +222 -0
- data/lib/oshpark/connection.rb +85 -0
- data/lib/oshpark/dimensionable.rb +27 -0
- data/lib/oshpark/ext.rb +122 -0
- data/lib/oshpark/image.rb +9 -0
- data/lib/oshpark/import.rb +38 -0
- data/lib/oshpark/layer.rb +13 -0
- data/lib/oshpark/model.rb +110 -0
- data/lib/oshpark/order.rb +72 -0
- data/lib/oshpark/order_option.rb +9 -0
- data/lib/oshpark/panel.rb +28 -0
- data/lib/oshpark/project.rb +50 -0
- data/lib/oshpark/rubymotion.rb +9 -0
- data/lib/oshpark/shipping_rate.rb +11 -0
- data/lib/oshpark/token.rb +24 -0
- data/lib/oshpark/upload.rb +37 -0
- data/lib/oshpark/user.rb +9 -0
- data/lib/oshpark/version.rb +3 -0
- data/oshpark.gemspec +29 -0
- data/spec/lib/oshpark/address_spec.rb +13 -0
- data/spec/lib/oshpark/client_spec.rb +139 -0
- data/spec/lib/oshpark/image_spec.rb +9 -0
- data/spec/lib/oshpark/import_spec.rb +19 -0
- data/spec/lib/oshpark/layer_spec.rb +14 -0
- data/spec/lib/oshpark/model_spec.rb +41 -0
- data/spec/lib/oshpark/order_spec.rb +87 -0
- data/spec/lib/oshpark/panel_spec.rb +17 -0
- data/spec/lib/oshpark/project_spec.rb +9 -0
- data/spec/lib/oshpark/upload_spec.rb +18 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/http_client.rb +24 -0
- metadata +282 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'uri'
|
3
|
+
require 'net/http'
|
4
|
+
require 'micro_token'
|
5
|
+
|
6
|
+
module Oshpark
|
7
|
+
Unauthorized = Class.new(RuntimeError)
|
8
|
+
NotFound = Class.new(RuntimeError)
|
9
|
+
ServerError = Class.new(RuntimeError)
|
10
|
+
|
11
|
+
class Connection
|
12
|
+
def initialize endpoint_url
|
13
|
+
self.api_endpoint = endpoint_url
|
14
|
+
end
|
15
|
+
|
16
|
+
def request method, endpoint, params={}, token
|
17
|
+
method = method[0].upcase + method[1..-1]
|
18
|
+
uri = uri_for endpoint
|
19
|
+
|
20
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
21
|
+
http.use_ssl = true if uri.port == 443
|
22
|
+
|
23
|
+
request = Net::HTTP.const_get(method).new(uri.path)
|
24
|
+
|
25
|
+
default_headers(token).each do |header, value|
|
26
|
+
request[header] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
if params.keys.include? :file
|
30
|
+
boundary = MicroToken.generate 20
|
31
|
+
request.body = "--#{boundary}\r\n" +
|
32
|
+
params.to_multipart.join('--' + boundary + "\r\n") +
|
33
|
+
"--#{boundary}--\r\n"
|
34
|
+
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
|
35
|
+
|
36
|
+
else
|
37
|
+
request.body = params.to_query
|
38
|
+
end
|
39
|
+
|
40
|
+
response = http.request(request)
|
41
|
+
|
42
|
+
json = JSON.parse(response.body)
|
43
|
+
|
44
|
+
case response.code.to_i
|
45
|
+
when 401
|
46
|
+
raise Unauthorized, json['error']
|
47
|
+
when 404
|
48
|
+
raise NotFound, json['error']
|
49
|
+
when 500...599
|
50
|
+
raise ServerError, json['error']
|
51
|
+
end
|
52
|
+
|
53
|
+
json
|
54
|
+
|
55
|
+
rescue JSON::ParserError => e
|
56
|
+
raise ServerError, "Bad response from server"
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_accessor :api_endpoint
|
62
|
+
|
63
|
+
def uri_for endpoint
|
64
|
+
URI("#{api_endpoint}/#{endpoint}")
|
65
|
+
end
|
66
|
+
|
67
|
+
def default_headers token=nil
|
68
|
+
header = {
|
69
|
+
'Accept' => 'application/json',
|
70
|
+
# 'Content-Type' => 'application/json'
|
71
|
+
}
|
72
|
+
header['Authorization'] = token.token if token
|
73
|
+
header
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def prepare_params params
|
78
|
+
if params.keys.include? :file
|
79
|
+
params.to_multipart
|
80
|
+
else
|
81
|
+
params.to_query
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Oshpark
|
2
|
+
module Dimensionable
|
3
|
+
def width_in_inches
|
4
|
+
width_in_mils / 1000.0
|
5
|
+
end
|
6
|
+
|
7
|
+
def height_in_inches
|
8
|
+
height_in_mils / 1000.0
|
9
|
+
end
|
10
|
+
|
11
|
+
def area_in_square_inches
|
12
|
+
width_in_inches * height_in_inches
|
13
|
+
end
|
14
|
+
|
15
|
+
def width_in_mm
|
16
|
+
width_in_inches * 25.4
|
17
|
+
end
|
18
|
+
|
19
|
+
def height_in_mm
|
20
|
+
height_in_inches * 25.4
|
21
|
+
end
|
22
|
+
|
23
|
+
def area_in_square_mm
|
24
|
+
width_in_mm * height_in_mm
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/oshpark/ext.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
#:nodoc: all
|
2
|
+
module OshparkArrayExtensions
|
3
|
+
def to_multipart key
|
4
|
+
prefix = "#{key}[]"
|
5
|
+
collect {|a| a.to_multipart(prefix)}.flatten.compact
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_query key
|
9
|
+
prefix = "#{key}[]"
|
10
|
+
collect { |value| value.to_query(prefix) }.flatten.join '&'
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_params
|
14
|
+
collect {|a| a.to_params }.flatten
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module OshparkHashExtensions
|
19
|
+
def to_multipart key = nil
|
20
|
+
collect {|k, v| v.to_multipart(key ? "#{key}[#{k}]" : k)}.flatten.compact
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_query key = nil
|
24
|
+
collect {|k, v| v.to_query(key ? "#{key}[#{k}]" : k)}.flatten.join '&'
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_params
|
28
|
+
self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module OshparkStringExtensions
|
33
|
+
def to_multipart key
|
34
|
+
"Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n" +
|
35
|
+
"#{self}\r\n"
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_query key = nil
|
39
|
+
key ? URI.escape("#{key}=#{self}") : URI.escape(self)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module OshparkFileExtensions
|
44
|
+
def to_multipart key = nil
|
45
|
+
"Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{File.basename(self.path)}\"\r\n" +
|
46
|
+
"Content-Transfer-Encoding: binary\r\n" +
|
47
|
+
"Content-Type: application/#{File.extname(self.path)}\r\n\r\n" +
|
48
|
+
"#{self.read}\r\n"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module OshparkFixnumExtensions
|
53
|
+
def to_query key = nil
|
54
|
+
key ? URI.escape("#{key}=#{self}") : URI.escape(self)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module OshparkFloatExtensions
|
59
|
+
def to_query key = nil
|
60
|
+
key ? URI.escape("#{key}=#{self}") : URI.escape(self)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module OshparkTrueClassExtensions
|
65
|
+
def to_multipart key
|
66
|
+
"Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n" +
|
67
|
+
"1\r\n"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module OshparkFalseClassExtensions
|
72
|
+
def to_multipart key
|
73
|
+
"Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n" +
|
74
|
+
"0\r\n"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module OshparkNilClassExtensions
|
79
|
+
def to_query key = nil
|
80
|
+
""
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_multipart key = nil
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class Array
|
89
|
+
include OshparkArrayExtensions
|
90
|
+
end
|
91
|
+
|
92
|
+
class Hash
|
93
|
+
include OshparkHashExtensions
|
94
|
+
end
|
95
|
+
|
96
|
+
class String
|
97
|
+
include OshparkStringExtensions
|
98
|
+
end
|
99
|
+
|
100
|
+
class File
|
101
|
+
include OshparkFileExtensions
|
102
|
+
end
|
103
|
+
|
104
|
+
class Fixnum
|
105
|
+
include OshparkFixnumExtensions
|
106
|
+
end
|
107
|
+
|
108
|
+
class Float
|
109
|
+
include OshparkFloatExtensions
|
110
|
+
end
|
111
|
+
|
112
|
+
class TrueClass
|
113
|
+
include OshparkTrueClassExtensions
|
114
|
+
end
|
115
|
+
|
116
|
+
class FalseClass
|
117
|
+
include OshparkFalseClassExtensions
|
118
|
+
end
|
119
|
+
|
120
|
+
class NilClass
|
121
|
+
include OshparkNilClassExtensions
|
122
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Oshpark
|
2
|
+
class Import
|
3
|
+
def self.attrs
|
4
|
+
%w| id state original_url original_filename error_message queued_at started_at completed_at errored_at failed_at project_id |
|
5
|
+
end
|
6
|
+
|
7
|
+
include Model
|
8
|
+
|
9
|
+
def self.create url
|
10
|
+
self.from_json(Oshpark::client.create_import(url))
|
11
|
+
end
|
12
|
+
|
13
|
+
def project
|
14
|
+
Project.find project_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def queued_at
|
18
|
+
time_from @queued_at
|
19
|
+
end
|
20
|
+
|
21
|
+
def started_at
|
22
|
+
time_from @started_at
|
23
|
+
end
|
24
|
+
|
25
|
+
def completed_at
|
26
|
+
time_from @completed_at
|
27
|
+
end
|
28
|
+
|
29
|
+
def errored_at
|
30
|
+
time_from @errored_at
|
31
|
+
end
|
32
|
+
|
33
|
+
def failed_at
|
34
|
+
time_from @failed_at
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module Oshpark
|
4
|
+
module Model
|
5
|
+
|
6
|
+
def initialize json
|
7
|
+
reload_with json
|
8
|
+
end
|
9
|
+
|
10
|
+
def dirty?
|
11
|
+
@dirty_attributes.size > 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def save!
|
15
|
+
attrs = {}
|
16
|
+
@dirty_attributes.map do |attr|
|
17
|
+
attrs[attr] = public_send(attr)
|
18
|
+
end
|
19
|
+
|
20
|
+
Oshpark::client.public_send("update_#{object_name}", id, attrs)
|
21
|
+
end
|
22
|
+
|
23
|
+
def reload!
|
24
|
+
json = Oshpark::client.public_send(object_name, id)[object_name]
|
25
|
+
reload_with json
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy!
|
29
|
+
Oshpark::client.public_send("destroy_#{object_name}", id)[object_name]
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.included base
|
34
|
+
base.send :extend, ClassMethods
|
35
|
+
|
36
|
+
base.instance_eval do
|
37
|
+
attr_reader *base.attrs
|
38
|
+
end
|
39
|
+
|
40
|
+
base.write_attrs.each do |attr|
|
41
|
+
define_method "#{attr}=" do |new_value|
|
42
|
+
@dirty_attributes << attr unless @dirty_attributes.include?(attr)
|
43
|
+
instance_variable_set "@#{attr}".to_sym, new_value
|
44
|
+
end
|
45
|
+
end if base.respond_to? :write_attrs
|
46
|
+
end
|
47
|
+
|
48
|
+
module ClassMethods
|
49
|
+
def from_json json
|
50
|
+
model = self.new json
|
51
|
+
model
|
52
|
+
end
|
53
|
+
|
54
|
+
def attrs
|
55
|
+
[]
|
56
|
+
end
|
57
|
+
|
58
|
+
def all
|
59
|
+
Oshpark::client.public_send(object_names)[object_names].map do |json|
|
60
|
+
self.from_json json
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def find id
|
65
|
+
self.from_json(Oshpark::client.public_send(object_name, id)[object_name])
|
66
|
+
end
|
67
|
+
|
68
|
+
def object_name
|
69
|
+
self.name.split('::').last.downcase
|
70
|
+
end
|
71
|
+
|
72
|
+
def object_names
|
73
|
+
"#{object_name}s"
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
# Override hook for converting JSON serialized time strings into Ruby
|
80
|
+
# Time objects. Only needed if `Time.parse` doesn't work as expected
|
81
|
+
# on your platform (ie RubyMotion).
|
82
|
+
def time_from json_time
|
83
|
+
Time.parse json_time if json_time
|
84
|
+
end
|
85
|
+
|
86
|
+
def object_name
|
87
|
+
self.class.object_name
|
88
|
+
end
|
89
|
+
|
90
|
+
def object_names
|
91
|
+
self.class.object_names
|
92
|
+
end
|
93
|
+
|
94
|
+
def reload_with json
|
95
|
+
guard_against_invalid_arguments json.keys
|
96
|
+
json.each do |key,value|
|
97
|
+
instance_variable_set "@#{key}", value
|
98
|
+
end
|
99
|
+
@dirty_attributes = []
|
100
|
+
end
|
101
|
+
|
102
|
+
def guard_against_invalid_arguments keys
|
103
|
+
if (extra = keys.map(&:to_s) - self.class.attrs) && extra.any?
|
104
|
+
raise ArgumentError, "Unknown attribute: #{extra.join(' ')}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Oshpark
|
2
|
+
class Order
|
3
|
+
|
4
|
+
def self.attrs
|
5
|
+
%w| id board_cost cancellation_reason cancelled_at ordered_at
|
6
|
+
payment_provider payment_received_at project_name quantity
|
7
|
+
shipping_address shipping_cost shipping_country
|
8
|
+
shipping_method shipping_name state total_cost project_id
|
9
|
+
panel_id coupon_rebate address shipping_rate order_items |
|
10
|
+
end
|
11
|
+
|
12
|
+
include Model
|
13
|
+
|
14
|
+
def self.create
|
15
|
+
self.from_json(Oshpark::client.create_order)
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_item order_item, quantity
|
19
|
+
json = Oshpark::client.add_order_item id, order_item.id, quantity
|
20
|
+
reload_with json
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_address address
|
24
|
+
json = Oshpark::client.set_order_address id, address
|
25
|
+
reload_with json
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_shipping_rate carrier_name, service_name
|
29
|
+
json = Oshpark::client.set_order_shipping_rate id, carrier_name, service_name
|
30
|
+
reload_with json
|
31
|
+
end
|
32
|
+
|
33
|
+
def checkout
|
34
|
+
json = Oshpark::client.checkout_order id
|
35
|
+
reload_with json
|
36
|
+
end
|
37
|
+
|
38
|
+
def panel
|
39
|
+
Panel.find panel_id
|
40
|
+
end
|
41
|
+
|
42
|
+
def project
|
43
|
+
Project.find project_id
|
44
|
+
end
|
45
|
+
|
46
|
+
def cancelled_at
|
47
|
+
time_from @cancelled_at
|
48
|
+
end
|
49
|
+
|
50
|
+
def ordered_at
|
51
|
+
time_from @ordered_at
|
52
|
+
end
|
53
|
+
|
54
|
+
def payment_received_at
|
55
|
+
time_from @payment_received_at
|
56
|
+
end
|
57
|
+
|
58
|
+
def address
|
59
|
+
Oshpark::Address.from_json @address if @address
|
60
|
+
end
|
61
|
+
|
62
|
+
def shipping_rate
|
63
|
+
Oshpark::ShippingRate.from_json @shipping_rate if @shipping_rate
|
64
|
+
end
|
65
|
+
|
66
|
+
def order_items
|
67
|
+
Array(@order_items).map do |order_item|
|
68
|
+
Oshpark::OrderItem.from_json order_item
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|