oshpark 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ee78c703d525696803787f9a3b4f84d6249404d
4
+ data.tar.gz: c329b89fc0acdbdcd5b2fffc5712e69868db28b1
5
+ SHA512:
6
+ metadata.gz: bd155da443cc8ff5467e0aa0fc4d1201738149203c990942ecbef3382b1433250aed80fb446ca5080fac53c670657b4b1872a8abc05430e8f91b716db4b8c878
7
+ data.tar.gz: fe3cd0d02b224992ffbd1c1454a654b52a2952a240f88fed5756d95fb63872f98111e06918d617dd6ec9a058f5c7a68168bccb2a680c211193813574394ea7e5
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
17
+ *.bundle
18
+ *.so
19
+ *.o
20
+ *.a
21
+ mkmf.log
22
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ ruby '2.1.2'
3
+
4
+ # Specify your gem's dependencies in oshpark.gemspec
5
+ gemspec
@@ -0,0 +1,97 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ oshpark (0.0.3)
5
+ micro_token
6
+ thor
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ builder (3.2.2)
12
+ byebug (2.7.0)
13
+ columnize (~> 0.3)
14
+ debugger-linecache (~> 1.2)
15
+ celluloid (0.15.2)
16
+ timers (~> 1.1.0)
17
+ coderay (1.1.0)
18
+ columnize (0.8.9)
19
+ cucumber (1.3.15)
20
+ builder (>= 2.1.2)
21
+ diff-lcs (>= 1.1.3)
22
+ gherkin (~> 2.12)
23
+ multi_json (>= 1.7.5, < 2.0)
24
+ multi_test (>= 0.1.1)
25
+ debugger-linecache (1.2.0)
26
+ diff-lcs (1.2.5)
27
+ ffi (1.9.3)
28
+ formatador (0.2.5)
29
+ gherkin (2.12.2)
30
+ multi_json (~> 1.3)
31
+ guard (2.6.1)
32
+ formatador (>= 0.2.4)
33
+ listen (~> 2.7)
34
+ lumberjack (~> 1.0)
35
+ pry (>= 0.9.12)
36
+ thor (>= 0.18.1)
37
+ guard-bundler (2.0.0)
38
+ bundler (~> 1.0)
39
+ guard (~> 2.2)
40
+ guard-cucumber (1.4.1)
41
+ cucumber (>= 1.2.0)
42
+ guard (>= 1.1.0)
43
+ guard-rspec (4.2.9)
44
+ guard (~> 2.1)
45
+ rspec (>= 2.14, < 4.0)
46
+ listen (2.7.7)
47
+ celluloid (>= 0.15.2)
48
+ rb-fsevent (>= 0.9.3)
49
+ rb-inotify (>= 0.9)
50
+ lumberjack (1.0.6)
51
+ method_source (0.8.2)
52
+ micro_token (0.0.3)
53
+ multi_json (1.10.1)
54
+ multi_test (0.1.1)
55
+ pry (0.9.12.6)
56
+ coderay (~> 1.0)
57
+ method_source (~> 0.8)
58
+ slop (~> 3.4)
59
+ rake (10.3.0)
60
+ rb-fsevent (0.9.4)
61
+ rb-inotify (0.9.5)
62
+ ffi (>= 0.5.0)
63
+ rspec (3.0.0)
64
+ rspec-core (~> 3.0.0)
65
+ rspec-expectations (~> 3.0.0)
66
+ rspec-mocks (~> 3.0.0)
67
+ rspec-core (3.0.0)
68
+ rspec-support (~> 3.0.0)
69
+ rspec-expectations (3.0.0)
70
+ diff-lcs (>= 1.2.0, < 2.0)
71
+ rspec-support (~> 3.0.0)
72
+ rspec-its (1.0.1)
73
+ rspec-core (>= 2.99.0.beta1)
74
+ rspec-expectations (>= 2.99.0.beta1)
75
+ rspec-mocks (3.0.1)
76
+ rspec-support (~> 3.0.0)
77
+ rspec-support (3.0.0)
78
+ slop (3.5.0)
79
+ thor (0.19.1)
80
+ timers (1.1.0)
81
+
82
+ PLATFORMS
83
+ ruby
84
+
85
+ DEPENDENCIES
86
+ bundler (~> 1.6)
87
+ byebug
88
+ cucumber
89
+ guard-bundler
90
+ guard-cucumber
91
+ guard-rspec
92
+ oshpark!
93
+ pry
94
+ rake
95
+ rspec-core
96
+ rspec-its
97
+ rspec-mocks
@@ -0,0 +1,17 @@
1
+ guard :rspec do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
6
+
7
+
8
+ guard 'cucumber' do
9
+ watch(%r{^features/.+\.feature$})
10
+ watch(%r{^features/support/.+$}) { 'features' }
11
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
12
+ end
13
+
14
+ guard :bundler do
15
+ watch('Gemfile')
16
+ watch(/^.+\.gemspec/)
17
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 James Harton
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,85 @@
1
+ # Oshpark
2
+ ##An electric ecosystem
3
+
4
+ [ ![Codeship Status for OSHPark/ruby-api-client](https://codeship.io/projects/a0abc8d0-d247-0131-3eb6-7653b9bc7be9/status?branch=master)](https://codeship.io/projects/23318)
5
+
6
+ [OSH Park](https://oshpark.com) is a community printed circuit board (PCB) order.
7
+ The Oshpark gem allows developers to easily access the Oshpark API. Developer resources can be found at [https://oshpark.com/developer](https://oshpark.com/developer)
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'oshpark'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install oshpark
22
+
23
+ ## Usage
24
+
25
+ Before you begin you need to have an [Oshpark account](http://oshpark.com/users/sign_up) and then request access to the Oshpark API. Do this by contacting ????
26
+
27
+ This gem provides two interfaces to the OShpark API.
28
+
29
+ ### Low level API
30
+
31
+ For use when you have an ORM, framework or pre-exsiting classes that you want to load the Oshpark data into.
32
+
33
+ The API consists of a number of methods that map to the methods exposed by the Oshpark REST API. These methods take Ruby hashes representing the request data and return hashes of the API responses. Refer to [https://oshpark.com/developer/resources](https://oshpark.com/developer/resources) for details.
34
+
35
+ First create an Oshpark::client object and authenticate;
36
+
37
+ client = Oshpark::client
38
+ client.authenticate 'jane@resistor.io', {with_password: 'secret'}
39
+
40
+ Then you can can use this object to interact with Oshpark;
41
+
42
+ file = File.open('my_pcb.zip', 'r')
43
+ upload = client.create_upload file
44
+ ...
45
+ my_projects = client.projects
46
+ ...
47
+ project = client.project 'id'
48
+ client.update_project project["id"], {"name" => "my awesome project"}
49
+ ...
50
+ new_order = client.create_order
51
+ ...
52
+
53
+ All low level methods will call to Oshpark's servers. Refer to the [source documentation](http://www.rubydoc.info/github/OSHPark/ruby-api-client/master) for more detailed information on each of the available methods.
54
+
55
+ ### High Level API
56
+
57
+ This is more suited to when you are writing a script or application and you want to use Ruby objects to represent the Oshpark data. It uses the Low Level API underneath but wraps the return data in nice Ruby objects.
58
+
59
+ Again begin by creating an Oshpark::client and authenticating;
60
+
61
+ client = Oshpark::client
62
+ client.authenticate 'jane@resistor.io', {with_password: 'secret'}
63
+
64
+ file = File.open('my_pcb.zip', 'r')
65
+ upload = Oshpark::Upload.create file
66
+ ...
67
+ my_projects = Oshpark::Project.all
68
+ ...
69
+ project = Oshpark::Project.find 'id'
70
+ project.name = "my awesome project"
71
+ project.save!
72
+ ...
73
+ new_order = Oshpark::Order.create
74
+ ...
75
+
76
+
77
+ ## Contributing
78
+
79
+ 1. Fork it ( https://github.com/[my-github-username]/oshpark/fork )
80
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
81
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
82
+ 4. Push to the branch (`git push origin my-new-feature`)
83
+ 5. Create a new Pull Request
84
+
85
+
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new :spec
5
+
6
+ task default: :spec
7
+
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'byebug'
4
+
5
+ require 'oshpark'
6
+
7
+ # Oshpark::client
8
+
9
+ @client = Oshpark::client url: 'http://localhost:3000/api/v1', connection: Oshpark::Connection
10
+
11
+ @client.authenticate 'jamesotron', 'frobotz'
12
+ puts "authed!" if @client.authenticated?
13
+
14
+ projects = Oshpark::Project.all
15
+
16
+ puts "Retrieved #{projects.size} projects:"
17
+ projects.each do |project|
18
+ puts " - #{project.name}"
19
+ end
20
+
21
+ project = Oshpark::Project.find projects.last.id
22
+ puts "Retrieved single project by id: #{project.name}"
23
+
24
+ # project.name = "my awesome project"
25
+ # project.save!
26
+
27
+ orders = Oshpark::Order.all # @client.orders
28
+
29
+ puts "Retrieved #{orders.size} orders:"
30
+ orders.each do |order|
31
+ puts " - #{order.quantity} x #{order.project_name}"
32
+ end
33
+
34
+ order = Oshpark::Order.find orders.first.id # @client.order orders.first.id
35
+ puts "Retrieved single order by id: #{order.quantity} x #{order.project_name}"
36
+
37
+ panels = Oshpark::Panel.all
38
+ puts "Retrieved #{panels.size} panels:"
39
+ panels.each do |panel|
40
+ puts " - #{panel.scheduled_order_time}"
41
+ end
42
+
43
+ panel = Oshpark::Panel.find panels.last.id
44
+ puts "Retrieved single panel by id: #{panel.scheduled_order_time}"
@@ -0,0 +1,31 @@
1
+ require "oshpark/version"
2
+ require "oshpark/ext"
3
+ require "oshpark/client"
4
+ require "oshpark/connection"
5
+ require "oshpark/model"
6
+ require "oshpark/dimensionable"
7
+ require "oshpark/order_option"
8
+ require "oshpark/project"
9
+ require "oshpark/order"
10
+ require "oshpark/panel"
11
+ require "oshpark/image"
12
+ require "oshpark/layer"
13
+ require "oshpark/user"
14
+ require "oshpark/import"
15
+ require "oshpark/upload"
16
+ require "oshpark/token"
17
+ require "oshpark/address"
18
+ require "oshpark/shipping_rate"
19
+
20
+ module Oshpark
21
+
22
+ module_function
23
+
24
+ def client *args
25
+ if args.size > 0
26
+ @client = Client.new *args
27
+ else
28
+ @client ||= Client.new
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,46 @@
1
+ module Oshpark
2
+ class Address
3
+ REQUIRED_ARGS = %w|name address_line_1 address_line_2 city country|
4
+ def self.attrs
5
+ %w| name company_name address_line_1 address_line_2 city state zip_or_postal_code country phone_number is_business |
6
+ end
7
+
8
+ include Model
9
+
10
+ attrs.each {|a| attr_accessor a }
11
+
12
+ def initialize args={}
13
+ args = check_args args
14
+ Address.attrs.each do |a|
15
+ v = args.fetch(a, nil)
16
+ public_send :"#{a}=", v
17
+ end
18
+ end
19
+
20
+ def to_h
21
+ {}.tap do |hash|
22
+ Address.attrs.each do |a|
23
+ hash[a] = public_send a
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def check_args args
31
+ unless (args.keys.map(&:to_s) & REQUIRED_ARGS) == REQUIRED_ARGS
32
+ raise ArgumentError, "Missing required arguments #{(REQUIRED_ARGS - args.keys).join(' ')}"
33
+ end
34
+
35
+ stingify_hash_keys args
36
+ end
37
+
38
+ def stingify_hash_keys hash
39
+ {}.tap do |h|
40
+ hash.each do |k, v|
41
+ h[k.to_s] = v
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,222 @@
1
+ require 'openssl'
2
+ require 'json'
3
+
4
+ module Oshpark
5
+ class Client
6
+ attr_accessor :token, :connection
7
+
8
+ # Create an new Client object.
9
+ #
10
+ # @param connection:
11
+ # pass in a subclass of connection which implements the `request` method
12
+ # with whichever HTTP client library you prefer. Default is Net::HTTP.
13
+ def initialize args = {}
14
+ url = args.fetch(:url, "https://oshpark.com/api/v1")
15
+ connection = args.fetch(:connection, Connection)
16
+
17
+ self.connection = if connection.respond_to? :new
18
+ connection.new url
19
+ else
20
+ connection
21
+ end
22
+ refresh_token
23
+ end
24
+
25
+ # Authenticate to the API using a email and password.
26
+ #
27
+ # @param email
28
+ # @param credentials
29
+ # A hash with either the `with_password` or `with_api_secret` key.
30
+ def authenticate email, credentials={}
31
+ if password = credentials[:with_password]
32
+ refresh_token email: email, password: password
33
+ elsif secret = credentials[:with_api_secret]
34
+ api_key = OpenSSL::Digest::SHA256.new("#{email}:#{secret}:#{token.token}").to_s
35
+ refresh_token email: email, api_key: api_key
36
+ else
37
+ raise ArgumentError, "Must provide either `with_password` or `with_api_secret` arguments."
38
+ end
39
+ end
40
+
41
+ # Retrieve a list of projects for the current user.
42
+ def projects
43
+ get_request 'projects'
44
+ end
45
+
46
+ # Retrieve a particular project from the current user's collection by ID.
47
+ #
48
+ # @param id
49
+ def project id
50
+ get_request "projects/#{id}"
51
+ end
52
+
53
+ # Approve a particular project from the current user's collection by ID.
54
+ # We strongly suggest that you allow the user to view the rendered images
55
+ # in Project#top_image, Project#bottom_image and Project#layers[]#image
56
+ # You should probably call Project#approve! instead.
57
+ #
58
+ # @param id
59
+ def approve_project id
60
+ get_request "projects/#{id}/approve"
61
+ end
62
+
63
+ # Update a project's data.
64
+ #
65
+ # @param id
66
+ # @param attrs
67
+ # A hash of attributes to update.
68
+ def update_project id, attrs
69
+ put_request "projects/#{id}", project: attrs
70
+ end
71
+
72
+ # Destroy a particular project from the current user's collection by ID.
73
+ #
74
+ # @param id
75
+ def destroy_project id
76
+ delete_request "projects/#{id}"
77
+ true
78
+ end
79
+
80
+ # List all the current user's orders, and their status.
81
+ def orders
82
+ get_request 'orders'
83
+ end
84
+
85
+ # Retrieve a specific order by ID.
86
+ #
87
+ # @param id
88
+ def order id
89
+ get_request "orders/#{id}"
90
+ end
91
+
92
+ # Create a new Order
93
+ def create_order
94
+ post_request "orders"
95
+ end
96
+
97
+ # Add a Project to an Order
98
+ #
99
+ # @param id
100
+ # @param project_id
101
+ # @param quantity
102
+ def add_order_item id, project_id, quantity
103
+ put_request "orders/#{id}/add_item", {project_id: project_id, quantity: quantity}
104
+ end
105
+
106
+ # Set the delivery address for an Order
107
+ #
108
+ # @param id
109
+ # @param address
110
+ def set_order_address id, address
111
+ put_request "orders/#{id}/set_address", address.to_h
112
+ end
113
+
114
+ # Set the delivery address for an Order
115
+ #
116
+ # @param id
117
+ # @param carrier_name
118
+ # @param service_name
119
+ def set_order_shipping_rate id, carrier_name, service_name
120
+ put_request "orders/#{id}/set_shipping_rate", {carrier_name: carrier_name, service_name: service_name}
121
+ end
122
+
123
+ # Checkout a specific order by ID.
124
+ #
125
+ # @param id
126
+ def checkout_order id
127
+ put_request "orders/#{id}/checkout"
128
+ end
129
+
130
+ # Cancel a specific order by ID.
131
+ # This can only be done when the order is in the 'RECEIVED' and
132
+ # 'AWAITING PANEL' states.
133
+ #
134
+ # @param id
135
+ def cancel_order id
136
+ delete_request "orders/#{id}"
137
+ true
138
+ end
139
+
140
+ # List all currently open and recently closed panels, including some
141
+ # interesting information about them.
142
+ def panels
143
+ get_request "panels"
144
+ end
145
+
146
+ # Retrieve a specific panel by ID.
147
+ #
148
+ # @param id
149
+ def panel id
150
+ get_request "panels/#{id}"
151
+ end
152
+
153
+ # Retrieve a specific upload by ID
154
+ #
155
+ # @param id
156
+ def upload id
157
+ get_request "uploads/#{id}"
158
+ end
159
+
160
+ # Create an upload by passing in an IO
161
+ #
162
+ # @param io
163
+ # An IO object.
164
+ def create_upload io
165
+ post_request "uploads", {file: io}
166
+ end
167
+
168
+ # Retrieve a specific import by ID
169
+ #
170
+ # @param id
171
+ def import id
172
+ get_request "imports/#{id}"
173
+ end
174
+
175
+ # Create an import by passing in a URL
176
+ #
177
+ # @param io
178
+ # A URL
179
+ def create_import url
180
+ post_request "imports", {url: url}
181
+ end
182
+
183
+ # Do we have a currently valid API token?
184
+ def has_token?
185
+ !!@token
186
+ end
187
+
188
+ # Are we successfully authenticated to the API?
189
+ def authenticated?
190
+ @token && !!@token.user
191
+ end
192
+
193
+ private
194
+
195
+ def connection
196
+ @connection
197
+ end
198
+
199
+ def refresh_token params={}
200
+ json = post_request 'sessions', params
201
+ self.token = Token.from_json json['api_session_token']
202
+ # Hey @hmaddocks - how are we going to set a timer to make the token refresh?
203
+ end
204
+
205
+ def post_request endpoint, params={}
206
+ connection.request :post, endpoint, params, token
207
+ end
208
+
209
+ def put_request endpoint, params={}
210
+ connection.request :put, endpoint, params, token
211
+ end
212
+
213
+ def get_request endpoint, params={}
214
+ connection.request :get, endpoint, params, token
215
+ end
216
+
217
+ def delete_request endpoint, params={}
218
+ connection.request :delete, endpoint, params, token
219
+ end
220
+ end
221
+
222
+ end