shirtsio 1.0.0

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: cb8da6ea02a157477414d05adb7c6b87a2870dcf
4
+ data.tar.gz: 51f822aa19b970e7531cfadd8a2dad55fc0487d8
5
+ SHA512:
6
+ metadata.gz: a69d934ccba8b365b53d69d955b5883c29529fa2b320b3ed218c51cb5cf2ce44702adbf31fa2b985394127ac0892b4aa9c041e621ff8ef789d11812918984ab1
7
+ data.tar.gz: fd215fdf061db9e1516e6c2a07d2bc510b42237024a998aa2489c64b700390e28a0b7ef6875a37284ec0bbd32d925d6edb5a8870a62f187595613b5dc2551be1
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+ .rbenv*
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in shirtsio.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'bundler', '~> 1.3'
8
+ gem 'rake'
9
+ gem 'yard'
10
+ end
11
+
12
+ group :test do
13
+ gem 'rspec'
14
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Anthony Smith
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,163 @@
1
+ # Shirtsio
2
+
3
+ A Ruby wrapper around the shirts.io API
4
+
5
+ ## Documentation
6
+
7
+ You can view detailed documentation of this library at http://rdoc.info/github/anthonator/shirtsio/frames. We try to make sure that our documentation is up-to-date and thorough. However, we do recommend keeping the [shirts.io API documentation](https://www.shirts.io/docs/overview/) handy.
8
+
9
+ If you find any discrepency in our documentation please [file an issue](https://github.com/anthonator/shirtsio/issues).
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'shirtsio'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install shirtsio
24
+
25
+ ## Quick Start Guide
26
+
27
+ Before you can start ordering some sweet shirts you'll need to tell shirts.io who you are.
28
+
29
+ Grab your super secret API key from the [shirts.io dashboard](https://www.shirts.io/accounts/dashboard/).
30
+
31
+ Sprinkle some pixie-dust...
32
+
33
+ ```ruby
34
+ Shirtsio.configure do |config|
35
+ config.api_key = YOUR_API_KEY
36
+ end
37
+ ```
38
+
39
+ BAM! Print some shirts!
40
+
41
+ ```ruby
42
+ Shirtsio::Order.create do |order|
43
+ ...
44
+ end
45
+ ```
46
+
47
+ ## Product API
48
+
49
+ ```ruby
50
+ # Return details about a specific product
51
+ product = Shirtsio::Product.find(3)
52
+
53
+ # Return a list of categories
54
+ categories = Shirtsio::Product::Category.list
55
+
56
+ # Return a list of products for a specific category
57
+ products = categories[0].products
58
+
59
+ # Since shirts.io doesn't return full product data when requesting from a category, return it now
60
+ product = products[0].full_product
61
+ ```
62
+
63
+ ## Quote API
64
+
65
+ ```ruby
66
+ # Assembling the parameters necessary to generate a quote is messy
67
+ # business. Luckily there's a DSL for that.
68
+ quote = Shirtsio::Quote.create do |quote|
69
+ quote.print_type 'Digital Print'
70
+ quote.garment do |garment|
71
+ garment.product_id 3
72
+ garment.color 'Black'
73
+ garment.sizes do |size|
74
+ size.med 1
75
+ end
76
+ end
77
+ quote.print do |print|
78
+ print.front do |front|
79
+ front.color_count 1
80
+ front.colors ['Black']
81
+ end
82
+ print.back do |back|
83
+ back.color_count 1
84
+ back.colors ['Black']
85
+ end
86
+ end
87
+ end
88
+ ```
89
+
90
+ ## Order API
91
+ ```ruby
92
+ # Yep, there's one for orders too
93
+ order = Shirtsio::Order.create do |order|
94
+ order.test true
95
+ order.price 18.99
96
+ order.print_type 'Digital Print'
97
+ order.extra_screens 'None'
98
+ order.ship_type 'Standard'
99
+ order.garment do |garment|
100
+ garment.product_id 3
101
+ garment.color 'Black'
102
+ garment.sizes do |size|
103
+ size.med 1
104
+ end
105
+ end
106
+ order.print do |print|
107
+ print.front do |front|
108
+ front.artwork File.new('/path/to/file.png')
109
+ front.proof File.new('/path/to/file.jpg')
110
+ front.color_count 1
111
+ front.colors ['Black']
112
+ front.dimensions '5.0 inches wide'
113
+ front.placement '4.0 inches below bottom of collar'
114
+ end
115
+ end
116
+ order.personalization do |personalization|
117
+ personalization.size 'med'
118
+ personalization.batch 1
119
+ personalization.number 1
120
+ personalization.number_size 2
121
+ personalization.name 'Bob'
122
+ personalization.name_size 1
123
+ end
124
+ order.addresses do |address|
125
+ address.name 'Bob'
126
+ address.company 'Sticksnleaves'
127
+ address.address '1234 Hopes and Dreams Ln.'
128
+ address.address2 'Apt. <3'
129
+ address.city 'Indianapolis'
130
+ address.state 'IN'
131
+ address.country 'US'
132
+ address.batch 1
133
+ address.sizes do |size}
134
+ size.med 1
135
+ end
136
+ end
137
+ end
138
+ ```
139
+
140
+ ## Status API
141
+ ```ruby
142
+ # Get an order's status
143
+ status = Shirtsio::Status.find(1234)
144
+
145
+ # Register a status webhook
146
+ Shirtsio::Status::Webhook.create('http://www.example.com') #returns true or false
147
+
148
+ # List webhooks
149
+ webhooks = Shirtsio::Status::Webhook.list
150
+
151
+ # Delete a webhook
152
+ Shirtsio::Status::Webhook.delete('http://www.example.com')
153
+ # or
154
+ webhooks[0].delete
155
+ ```
156
+
157
+ ## Contributing
158
+
159
+ 1. Fork it
160
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
161
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
162
+ 4. Push to the branch (`git push origin my-new-feature`)
163
+ 5. Create new Pull Request
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
data/e ADDED
File without changes
@@ -0,0 +1,36 @@
1
+ require 'faraday'
2
+ require 'hashie'
3
+ require 'multi_json'
4
+
5
+ require 'shirtsio/version'
6
+ require 'shirtsio/error'
7
+ require 'shirtsio/utils'
8
+
9
+ require 'shirtsio/configuration'
10
+ require 'shirtsio/connection'
11
+ require 'shirtsio/request'
12
+ require 'shirtsio/api'
13
+ require 'shirtsio/dsl'
14
+ require 'shirtsio/endpoint'
15
+
16
+ require 'shirtsio/product'
17
+ require 'shirtsio/quote'
18
+ require 'shirtsio/order'
19
+ require 'shirtsio/status'
20
+
21
+ module Shirtsio
22
+ extend Configuration
23
+
24
+ def self.api(options = {})
25
+ Shirtsio::API.new(options)
26
+ end
27
+
28
+ def self.method_missing(method, *args, &block)
29
+ return super unless api.respond_to?(method)
30
+ api.send(method, *args, &block)
31
+ end
32
+
33
+ def self.respond_to?(method)
34
+ api.respond_to?(method) || super
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ module Shirtsio
2
+ # @private
3
+ class API
4
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
5
+
6
+ def initialize(options = {})
7
+ options = Shirtsio.options.merge(options)
8
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
9
+ send("#{key}=", options[key])
10
+ end
11
+ end
12
+
13
+ include Connection
14
+ include Request
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ module Shirtsio
2
+ # Defines constants and methods related to configuration.
3
+ module Configuration
4
+ VALID_OPTIONS_KEYS = [
5
+ :api_key,
6
+ :endpoint,
7
+ :proxy,
8
+ :user_agent
9
+ ].freeze
10
+
11
+ # By default, don't set API key.
12
+ DEFAULT_API_KEY = nil.freeze
13
+
14
+ # The endpoint that will be used to authorize a user if none is set.
15
+ DEFAULT_ENDPOINT = 'https://www.shirts.io/api/v1'.freeze
16
+
17
+ # By default, don't set a proxy server
18
+ DEFAULT_PROXY = nil.freeze
19
+
20
+ # The user agent that will be sent to the API endpoint if none is set.
21
+ DEFAULT_USER_AGENT = "shirtsio gem v#{Shirtsio::VERSION}".freeze
22
+
23
+ # @private
24
+ attr_accessor(*VALID_OPTIONS_KEYS)
25
+
26
+ # When this module is extended, set all configuration options to their
27
+ # default values.
28
+ def self.extended(base)
29
+ base.reset
30
+ end
31
+
32
+ # Convenience method to allow configuration options to be set in a
33
+ # block.
34
+ def configure
35
+ yield self
36
+ end
37
+
38
+ # Create a hash of options and their values.
39
+ def options
40
+ VALID_OPTIONS_KEYS.inject({}) do |option, key|
41
+ option.merge!(key => send(key))
42
+ end
43
+ end
44
+
45
+ # Reset all configuration options to default.
46
+ def reset
47
+ self.api_key = DEFAULT_API_KEY
48
+ self.endpoint = DEFAULT_ENDPOINT
49
+ self.proxy = DEFAULT_PROXY
50
+ self.user_agent = DEFAULT_USER_AGENT
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,16 @@
1
+ module Shirtsio
2
+ # @private
3
+ module Connection
4
+ private
5
+ def connection
6
+ options = {
7
+ :ssl => { :verify => true }
8
+ }
9
+ Faraday.new(endpoint, options) do |faraday|
10
+ faraday.request :multipart
11
+ faraday.request :url_encoded
12
+ faraday.adapter :net_http
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,116 @@
1
+ class Shirtsio::DSL
2
+ SIZES = [:xxsml, :xsml, :sml, :med, :lrg, :xlg, :xxl, :xxxl, :xxxxl, :xxxxxl, :xxxxxxl]
3
+
4
+ QUOTE = [
5
+ :print_type,
6
+ :personalization,
7
+ :address_count,
8
+ :extra_screens,
9
+ :ship_type,
10
+ :international_garment_count,
11
+ :garment => [
12
+ :product_id,
13
+ :color,
14
+ :sizes => SIZES
15
+ ],
16
+ :print => [
17
+ :front => [:color_count, :colors],
18
+ :left => [:color_count, :colors],
19
+ :right => [:color_count, :colors],
20
+ :back => [:color_count, :colors]
21
+ ]
22
+ ]
23
+
24
+ ORDER = [
25
+ :test,
26
+ :price,
27
+ :print_type,
28
+ :extra_screens,
29
+ :ship_type,
30
+ :packing_slip,
31
+ :garment => [
32
+ :product_id,
33
+ :color,
34
+ :sizes => SIZES
35
+ ],
36
+ :print => [
37
+ :front => [:artwork, :proof, :color_count, :colors, :dimensions, :placement],
38
+ :left => [:artwork, :proof, :color_count, :colors, :dimensions, :placement],
39
+ :right => [:artwork, :proof, :color_count, :colors, :dimensions, :placement],
40
+ :back => [:artwork, :proof, :color_count, :colors, :dimensions, :placement]
41
+ ],
42
+ :personalization => [
43
+ :size,
44
+ :batch,
45
+ :number,
46
+ :number_size,
47
+ :name,
48
+ :name_size
49
+ ],
50
+ :addresses => [
51
+ :name,
52
+ :company,
53
+ :address,
54
+ :address2,
55
+ :city,
56
+ :state,
57
+ :zipcode,
58
+ :country,
59
+ :batch,
60
+ :sizes => SIZES
61
+ ]
62
+ ]
63
+
64
+ class QueryBuilder
65
+ def initialize(dsl, prefixes_with_index = [], &block)
66
+ @dsl = dsl
67
+ @prefixes_with_index = []
68
+ @prefixes_with_index << prefixes_with_index
69
+ @prefixes_with_index.flatten!
70
+ @params = {}
71
+ yield self
72
+ end
73
+
74
+ def method_missing(method, *args, &block)
75
+ index = extract_index(method.to_sym)
76
+ return super unless index
77
+ params = {}
78
+ if index.kind_of?(Symbol)
79
+ if args[0].kind_of?(Array)
80
+ args[0].each_with_index do |v,i|
81
+ params[method] = { i => v }
82
+ end
83
+ elsif args[0].kind_of?(File)
84
+ params[method] = Faraday::UploadIO.new(args[0].path, Shirtsio::Utils.mime_type(args[0].path))
85
+ else
86
+ params[method] = args[0]
87
+ end
88
+ elsif index.kind_of?(Array)
89
+ params[method] = QueryBuilder.new(index, @prefixes_with_index, &block).to_hash
90
+ end
91
+ params.map do |k,v|
92
+ if @prefixes_with_index.include?(k)
93
+ @params[k] = {} if @params[k].nil?
94
+ @params[k].merge!({ @params[k].size => v })
95
+ else
96
+ @params.merge!({ k => v })
97
+ end
98
+ end
99
+ end
100
+
101
+ def to_hash
102
+ @params
103
+ end
104
+
105
+ private
106
+ def extract_index(method)
107
+ return method if @dsl.include?(method)
108
+ @dsl.each do |i|
109
+ if i.kind_of?(Hash) && !i[method].nil?
110
+ return i[method]
111
+ end
112
+ end
113
+ nil
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,14 @@
1
+ class Shirtsio::Endpoint
2
+ def initialize(json)
3
+ @mash = Hashie::Mash.new(json)
4
+ end
5
+
6
+ def method_missing(method, *args, &block)
7
+ return super unless @mash.respond_to?(method)
8
+ @mash.send(method, *args, &block)
9
+ end
10
+
11
+ def respond_to?(method)
12
+ @mash.respond_to?(method)
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Shirtsio
2
+ # Custom error class for rescuing from all known shirts.io errors
3
+ class Error < StandardError; attr_accessor :result, :error end
4
+
5
+ # Raised when shirts.io returns HTTP status code 400
6
+ class BadRequest < Error; end
7
+
8
+ # Raised when shirts.io returns HTTP status code 401
9
+ class Unauthorized < Error; end
10
+
11
+ # Raised when shirts.io returns HTTP status code 402
12
+ class RequestFailed < Error; end
13
+ end
@@ -0,0 +1,63 @@
1
+ # Place an order.
2
+ class Shirtsio::Order < Shirtsio::Endpoint
3
+ # Create an order
4
+ #
5
+ # This method specifies a DSL for building the parameters necessary for
6
+ # creating an order.
7
+ #
8
+ # @note See documentation provided by shirts.io for a thorough description of all parameters supported by this endpoint.
9
+ #
10
+ # Example:
11
+ #
12
+ # Shirtsio::Order.create do |order|
13
+ # order.test true
14
+ # order.price 18.99
15
+ # order.print_type 'Digital Print'
16
+ # order.extra_screens 'None'
17
+ # order.ship_type 'Standard'
18
+ # order.garment do |garment|
19
+ # garment.product_id 1
20
+ # garment.color 'Black'
21
+ # garment.sizes do |size|
22
+ # size.med 1
23
+ # end
24
+ # end
25
+ # order.print do |print|
26
+ # print.front do |front|
27
+ # front.artwork ''
28
+ # front.proof ''
29
+ # front.color_count 1
30
+ # front.colors ['Black']
31
+ # front.dimensions '5.0 inches wide'
32
+ # front.placement '4.0 inches below bottom of collar'
33
+ # end
34
+ # end
35
+ # order.personalization do |personalization|
36
+ # personalization.size 'med'
37
+ # personalization.batch 1
38
+ # personalization.number 1
39
+ # personalization.number_size 2
40
+ # personalization.name 'Bob'
41
+ # personalization.name_size 1
42
+ # end
43
+ # order.addresses do |address|
44
+ # address.name 'Bob'
45
+ # address.company 'Sticksnleaves'
46
+ # address.address '1234 Hopes and Dreams Ln.'
47
+ # address.address2 'Apt. <3'
48
+ # address.city 'Indianapolis'
49
+ # address.state 'IN'
50
+ # address.country 'US'
51
+ # address.batch 1
52
+ # address.sizes do |size|
53
+ # size.med 1
54
+ # end
55
+ # end
56
+ # end
57
+ #
58
+ # @see https://www.shirts.io/docs/order_reference/
59
+ def self.create(&block)
60
+ query = Shirtsio::DSL::QueryBuilder.new(Shirtsio::DSL::ORDER, [:garment, :personalization, :addresses], &block).to_hash
61
+ new(Shirtsio.post('/order/', query))
62
+ end
63
+ end
@@ -0,0 +1,46 @@
1
+ # Provides specifications, inventory data, and pictures of all products
2
+ # available before printing.
3
+ class Shirtsio::Product < Shirtsio::Endpoint
4
+ # Get product catalog information for a specific product id.
5
+ #
6
+ # @return [Shirtsio::Product] a complete product object
7
+ def self.find(id)
8
+ new(Shirtsio.get("/products/#{id}/"))
9
+ end
10
+
11
+ class Simple < Shirtsio::Endpoint
12
+ # Get the complete product object.
13
+ #
14
+ # @return [Shirtsio::Product] a complete product object
15
+ def full_product
16
+ Shirtsio::Product.find(product_id)
17
+ end
18
+ end
19
+
20
+ class Category < Shirtsio::Endpoint
21
+ # Get a list of products in the current category.
22
+ #
23
+ # @note This endpoint does not return complete product objects
24
+ # @see {Shirtsio::Product::Simple#full_product}
25
+ # @return [Array] an array of simple product objects
26
+ def products
27
+ products = []
28
+ response = Shirtsio.get("/products/category/#{category_id}/")
29
+ response.each do |product|
30
+ products << Shirtsio::Product::Simple.new(product)
31
+ end
32
+ end
33
+
34
+ # Get a list of all available product categories.
35
+ #
36
+ # @return [Array] an array of category objects
37
+ def self.list
38
+ categories = []
39
+ response = Shirtsio.get('/products/category/')
40
+ response.each do |category|
41
+ categories << new(category)
42
+ end
43
+ categories
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,34 @@
1
+ # Provides an exact quote before placing an order.
2
+ class Shirtsio::Quote < Shirtsio::Endpoint
3
+ # Get a quote for specified garments.
4
+ #
5
+ # This method specifies a DSL for building the parameters necessary for
6
+ # retrieving a quote.
7
+ #
8
+ # @note See documentation provided by shirts.io for a thorough description of all parameters supported by this endpoint.
9
+ #
10
+ # Example:
11
+ #
12
+ # Shirtsio::Quote.create do |quote|
13
+ # quote.garment do |garment|
14
+ # garment.product_id 1
15
+ # garment.color 'Grey'
16
+ # garment.sizes do |size|
17
+ # size.med 1
18
+ # end
19
+ # end
20
+ # quote.print do |print|
21
+ # print.front do |front|
22
+ # front.color_count 1
23
+ # front.colors ['Black']
24
+ # end
25
+ # end
26
+ # quote.ship_type 'Rush'
27
+ # end
28
+ #
29
+ # @see https://www.shirts.io/docs/quote_reference/
30
+ def self.create(&block)
31
+ query = Shirtsio::DSL::QueryBuilder.new(Shirtsio::DSL::QUOTE, :garment, &block).to_hash
32
+ new(Shirtsio.get('/quote/', query))
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ module Shirtsio
2
+ module Request
3
+ def get(path, options = {}, headers = {}, raw = false)
4
+ request(:get, path, options, headers, raw)
5
+ end
6
+
7
+ def post(path, options = {}, headers = {}, raw = false)
8
+ request(:post, path, options, headers, raw)
9
+ end
10
+
11
+ private
12
+ # Perform an HTTP request
13
+ def request(method, path, options, headers, raw)
14
+ headers.merge!({
15
+ 'User-Agent' => user_agent
16
+ })
17
+
18
+ options.merge!({
19
+ :api_key => api_key
20
+ })
21
+
22
+ response = connection.send(method) do |request|
23
+ if method == :get
24
+ request.url "#{endpoint}#{path}", options
25
+ else
26
+ request.url "#{endpoint}#{path}"
27
+ request.body = options
28
+ end
29
+ request.headers = headers
30
+ end
31
+ Shirtsio::Utils.handle_api_error(response) if response.status != 200
32
+
33
+ if raw
34
+ result = response.body
35
+ else
36
+ # The API is returning the "result" encoded as a string rather than
37
+ # object notation so it requires a second pass of the JSON parser
38
+ result = Shirtsio::Utils.parse_json(response.body)[:result]
39
+ end
40
+
41
+ result
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,72 @@
1
+ # Retrieves the current state of any previously placed order.
2
+ class Shirtsio::Status < Shirtsio::Endpoint
3
+ # Retrieve an order's possible status.
4
+ #
5
+ # Possible statuses include:
6
+ # * Processing - Order was accepted by the API and is being processed
7
+ # before production.
8
+ # * Printing - Order is in the production process.
9
+ # * Shipped - Order has been shipped.
10
+ # * If an order is shipped or delivered, you will be given tracking
11
+ # numbers for each package.
12
+ # * Generally, larget orders are shipped via UPS and smaller orders
13
+ # are shipped via USPS.
14
+ # * Delivered - Order has been delivered.
15
+ # * Canceled - Order has been canceled.
16
+ # * If an order is canceled, you will be given a reason for
17
+ # cencellation.
18
+ # * Possible reasons include: incorrect color count, intellectual
19
+ # property infringement, out of stock, invalid printing
20
+ # specifications.
21
+ #
22
+ # @param [Integer] id Order identification number
23
+ # @return [Shirtsio::Status] the order's status
24
+ # @see https://www.shirts.io/docs/status_reference/
25
+ def self.find(id)
26
+ new(Shirtsio.get("/status/#{id}"))
27
+ end
28
+
29
+ # Provides the ability to have status updates pushed to a URL.
30
+ class Webhook < Shirtsio::Endpoint
31
+ # Delete the current webhook.
32
+ #
33
+ # @return [Boolean] true if successful; otherwise false;
34
+ # @see https://www.shirts.io/docs/status_reference/#webhooks_section
35
+ def delete
36
+ Webhook.delete(url)
37
+ end
38
+
39
+ # Register a new webhook URL.
40
+ #
41
+ # @param [String] url URL status updates will be pushed to
42
+ # @return [Boolean] true if successful; otherwise false
43
+ # @see https://www.shirts.io/docs/status_reference/#webhooks_section
44
+ def self.create(url)
45
+ Shirtsio.post('/webhooks/register/', { :url => url })[:success]
46
+ end
47
+
48
+ # Retrieve all registered webhook URLs.
49
+ #
50
+ # @return [Shirtsio::Status::Webhook] a list of registered webhook URLs
51
+ # @see https://www.shirts.io/docs/status_reference/#webhooks_section
52
+ def self.list
53
+ webhooks = []
54
+ response = new(Shirtsio.get('/webhooks/list/'))
55
+ if response.respond_to?(:listener_url)
56
+ response.listener_url.each do |webhook|
57
+ webhooks << new({ :url => webhook })
58
+ end
59
+ end
60
+ webhooks
61
+ end
62
+
63
+ # Delete a registered webhook URL.
64
+ #
65
+ # @param [String] url URL of webhook to be removed
66
+ # @return [Boolean] true if successful; otherwise false
67
+ # @see https://www.shirts.io/docs/status_reference/#webhooks_section
68
+ def self.delete(url)
69
+ Shirtsio.post('/webhooks/delete/', { :url => url })[:success]
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,39 @@
1
+ module Shirtsio
2
+ # @private
3
+ module Utils
4
+ private
5
+ def self.handle_api_error(response)
6
+ result = parse_json(response.body)
7
+ error = case response.status
8
+ when 400 then BadRequest.new
9
+ when 401 then Unauthorized.new
10
+ when 402 then RequestFailed.new
11
+ else Error.new
12
+ end
13
+ error.result = result[:result]
14
+ error.error = result[:error]
15
+ raise error
16
+ end
17
+
18
+ def self.parse_json(json)
19
+ MultiJson.load(json, :symbolize_keys => true)
20
+ end
21
+
22
+ def self.build_query(hash)
23
+ Faraday::Utils.build_nested_query(hash)
24
+ end
25
+
26
+ def self.mime_type(path)
27
+ case path
28
+ when /\.jpe?g/i
29
+ 'image/jpeg'
30
+ when /\.eps$/i
31
+ 'image/eps'
32
+ when /\.png$/i
33
+ 'image/png'
34
+ else
35
+ 'application/octet-stream'
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Shirtsio
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'shirtsio/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "shirtsio"
8
+ spec.version = Shirtsio::VERSION
9
+ spec.authors = ["Anthony Smith"]
10
+ spec.email = ["anthony@sticksnleaves.com"]
11
+ spec.description = %q{A shirts.io API wrapper written in Ruby}
12
+ spec.summary = %q{shirts.io REST API client library for Ruby}
13
+ spec.homepage = "https://github.com/anthonator/shirtsio"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ # Runtime dependencies
22
+ spec.add_dependency "faraday", "~> 0.8"
23
+ spec.add_dependency "hashie", "~> 2.0"
24
+ spec.add_dependency "multi_json", "~> 1.7"
25
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shirtsio::DSL::QueryBuilder do
4
+ it "should build a query without an index" do
5
+ query = Shirtsio::Utils.build_query(Shirtsio::DSL::QueryBuilder.new([:a_method], nil) do |builder|
6
+ builder.a_method 'value'
7
+ end.to_hash)
8
+ query.should == 'a_method=value'
9
+ end
10
+
11
+ it "should build a query with an index" do
12
+ query = Shirtsio::Utils.build_query(Shirtsio::DSL::QueryBuilder.new([:a_method], :a_method) do |builder|
13
+ builder.a_method 'value'
14
+ end.to_hash)
15
+ URI::unescape(query).should == 'a_method[0]=value'
16
+ end
17
+
18
+ it "should allow for nested methods" do
19
+ query = Shirtsio::Utils.build_query(Shirtsio::DSL::QueryBuilder.new([:a_method => [:b_method]]) do |builder|
20
+ builder.a_method do |builder|
21
+ builder.b_method 'value'
22
+ end
23
+ end.to_hash)
24
+ URI::unescape(query).should == 'a_method[b_method]=value'
25
+ end
26
+
27
+ it "should allow for nested methods with arrays" do
28
+ query = Shirtsio::Utils.build_query(Shirtsio::DSL::QueryBuilder.new([:a_method => [:b_method]]) do |builder|
29
+ builder.a_method do |builder|
30
+ builder.b_method ['value']
31
+ end
32
+ end.to_hash)
33
+ URI::unescape(query).should == 'a_method[b_method][0]=value'
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+
3
+ require 'shirtsio'
4
+
5
+ # Require supporting ruby files with custom matchers and macros, etc,
6
+ # in spec/support/ and its subdirectories.
7
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
8
+
9
+ RSpec.configure do |config|
10
+
11
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shirtsio
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Anthony Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hashie
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: multi_json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ description: A shirts.io API wrapper written in Ruby
56
+ email:
57
+ - anthony@sticksnleaves.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - e
68
+ - lib/shirtsio.rb
69
+ - lib/shirtsio/api.rb
70
+ - lib/shirtsio/configuration.rb
71
+ - lib/shirtsio/connection.rb
72
+ - lib/shirtsio/dsl.rb
73
+ - lib/shirtsio/endpoint.rb
74
+ - lib/shirtsio/error.rb
75
+ - lib/shirtsio/order.rb
76
+ - lib/shirtsio/product.rb
77
+ - lib/shirtsio/quote.rb
78
+ - lib/shirtsio/request.rb
79
+ - lib/shirtsio/status.rb
80
+ - lib/shirtsio/utils.rb
81
+ - lib/shirtsio/version.rb
82
+ - shirtsio.gemspec
83
+ - spec/dsl_spec.rb
84
+ - spec/spec_helper.rb
85
+ homepage: https://github.com/anthonator/shirtsio
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.0.0
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: shirts.io REST API client library for Ruby
109
+ test_files:
110
+ - spec/dsl_spec.rb
111
+ - spec/spec_helper.rb
112
+ has_rdoc: