shirtsio 1.0.0

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.
@@ -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: