pwinty 1.0.1

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: 5e2d69fca32fe28bbe4ed607577ebae56276c63b
4
+ data.tar.gz: 71683c3aec6864253728421f3aad4c0848bea4cf
5
+ SHA512:
6
+ metadata.gz: c7ade263209666875e70958004b94adddd09a50b73ddcecbce7d25c272450f03561c484fecc35256ac52efd86a9d300390d83614870a91ff261af72bad147bf8
7
+ data.tar.gz: 25b59d9c7fbc884b0520dc7c0b4a6004e5fd76e86e327785e878cbd252b0a10426a90d5ac544256791cf30567d8ea9b99e691cc5ba062e4f6c3ceabd0e9fe473
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .env
@@ -0,0 +1,5 @@
1
+ bundler_args: ""
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.5
5
+ - 2.2.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in pwinty.gemspec
4
+ gemspec
@@ -0,0 +1,85 @@
1
+ # Pwinty [![Build Status](https://secure.travis-ci.org/dereklucas/pwinty.png)](http://travis-ci.org/dereklucas/pwinty?branch=master) [![Dependency Status](https://gemnasium.com/dereklucas/pwinty.png)](https://gemnasium.com/dereklucas/pwinty)
2
+
3
+ This library implements a Ruby client for the [Pwinty photo printing API](http://www.pwinty.com/Api).
4
+
5
+ Documentation
6
+ -------------
7
+
8
+ Import pwinty and set your API Key and Merchent ID:
9
+
10
+ ENV['PWINTY_MERCHANT_ID'] = 'xxxxxxx'
11
+ ENV['PWINTY_API_KEY'] = 'xxxxxxx'
12
+ @client = Pwinty.client
13
+
14
+ Create an Order:
15
+
16
+ order = @client.Order.create_order(
17
+ recipientName: "FirstName LastName",
18
+ address1: "123 Anywhere Street",
19
+ addressTownOrCity: "San Francisco",
20
+ stateOrCounty: "CA",
21
+ postalOrZipCode: "94101",
22
+ countryCode: "US",
23
+ payment: "InvoiceMe",
24
+ qualityLevel: "Standard"
25
+ )
26
+
27
+ Add photos to the order:
28
+
29
+ photo = @client.add_photo(
30
+ orderId: order['id'],
31
+ type: "4x6",
32
+ url: "http://i.imgur.com/xXnrL.jpg",
33
+ copies: 1,
34
+ sizing: "Crop"
35
+ )
36
+
37
+ Check the order is valid:
38
+
39
+ order_status = @client.get_order_status(order['id'])
40
+ if !order_status['isValid']
41
+ puts "Invalid Order"
42
+ end
43
+
44
+ Submit the order:
45
+
46
+ response = @client.update_order_status(order['id'], "Submitted")
47
+
48
+
49
+ You can retrieve a previous order and check its status like so:
50
+
51
+ order = @client.get_order_status(8765)
52
+ if order['status'] == 'Complete'
53
+ puts "Order has dispatched"
54
+ end
55
+
56
+ You should find the documentation for Pwinty on [their API](https://pwinty.com/Api).
57
+
58
+ Install
59
+ --------
60
+
61
+ ```shell
62
+ gem install pwinty
63
+ ```
64
+ or add the following line to Gemfile:
65
+
66
+ ```ruby
67
+ gem 'pwinty'
68
+ ```
69
+ and run `bundle install` from your shell.
70
+
71
+ Supported Ruby versions
72
+ -----------------------
73
+
74
+ The Ruby Pwinty gem has only been tested on Ruby 2.
75
+
76
+ License
77
+ -------
78
+
79
+ MIT License
80
+
81
+ More Information
82
+ ----------------
83
+
84
+ * [Rubygems](https://rubygems.org/gems/pwinty)
85
+ * [Issues](https://github.com/dereklucas/pwinty/issues)
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "bundler/gem_tasks"
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'test'
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :default => :test
@@ -0,0 +1,76 @@
1
+ # License:: Distributed under the terms of the WTFPL (http://www.wtfpl.net/txt/copying/)
2
+
3
+ require 'rubygems'
4
+ require 'mime/types'
5
+ require 'cgi'
6
+
7
+
8
+ module Multipart
9
+ VERSION = "1.0.0"
10
+
11
+ # Formats a given hash as a multipart form post
12
+ # If a hash value responds to :string or :read messages, then it is
13
+ # interpreted as a file and processed accordingly; otherwise, it is assumed
14
+ # to be a string
15
+ class Post
16
+ # We have to pretend we're a web browser...
17
+ USERAGENT = "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/523.10.6 (KHTML, like Gecko) Version/3.0.4 Safari/523.10.6"
18
+ BOUNDARY = "0123456789ABLEWASIEREISAWELBA9876543210"
19
+ CONTENT_TYPE = "multipart/form-data; boundary=#{ BOUNDARY }"
20
+ HEADER = { "Content-Type" => CONTENT_TYPE, "User-Agent" => USERAGENT }
21
+
22
+ def self.prepare_query(params)
23
+ fp = []
24
+
25
+ params.each do |k, v|
26
+ # Are we trying to make a file parameter?
27
+ if v.respond_to?(:path) and v.respond_to?(:read) then
28
+ fp.push(FileParam.new(k.to_s, v.path, v.read))
29
+ # We must be trying to make a regular parameter
30
+ else
31
+ fp.push(StringParam.new(k.to_s, v))
32
+ end
33
+ end
34
+
35
+ # Assemble the request body using the special multipart format
36
+ query = fp.collect {|p| "--" + BOUNDARY + "\r\n" + p.to_multipart }.join("") + "--" + BOUNDARY + "--"
37
+ return query, HEADER
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ # Formats a basic string key/value pair for inclusion with a multipart post
44
+ class StringParam
45
+ attr_accessor :k, :v
46
+
47
+ def initialize(k, v)
48
+ @k = k
49
+ @v = v
50
+ end
51
+
52
+ def to_multipart
53
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
54
+ end
55
+ end
56
+
57
+ # Formats the contents of a file or string for inclusion with a multipart
58
+ # form post
59
+ class FileParam
60
+ attr_accessor :k, :filename, :content
61
+
62
+ def initialize(k, filename, content)
63
+ @k = k
64
+ @filename = filename
65
+ @content = content
66
+ end
67
+
68
+ def to_multipart
69
+ # If we can tell the possible mime-type from the filename, use the
70
+ # first in the list; otherwise, use "application/octet-stream"
71
+ mime_type = MIME::Types.type_for(filename)[0] || MIME::Types["application/octet-stream"][0]
72
+ return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{ filename }\"\r\n" +
73
+ "Content-Type: #{ mime_type.simplified }\r\n\r\n#{ content }\r\n"
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,81 @@
1
+ require "pwinty/version"
2
+ require "multipart"
3
+ require "rest_client"
4
+
5
+ module Pwinty
6
+
7
+ def self.client
8
+ @@client ||= Pwinty::Client.new
9
+ @@client
10
+ end
11
+
12
+ class Client
13
+ def initialize
14
+ subdomain = ENV['PWINTY_PRODUCTION'] == 'true' ? "api" : "sandbox"
15
+ domain = "https://#{subdomain}.pwinty.com/v2.1"
16
+
17
+ @pwinty = RestClient::Resource.new(domain, :headers => {
18
+ "X-Pwinty-MerchantId" => ENV['PWINTY_MERCHANT_ID'],
19
+ "X-Pwinty-REST-API-Key" => ENV['PWINTY_API_KEY'],
20
+ 'Accept' => 'application/json'
21
+ })
22
+ end
23
+
24
+ def catalog(countryCode: 'US', qualityLevel: 'Standard')
25
+ JSON.parse @pwinty["/Catalogue/#{countryCode}/#{qualityLevel}"].get
26
+ end
27
+
28
+ # Orders
29
+ def get_orders
30
+ JSON.parse @pwinty["/Orders"].get
31
+ end
32
+
33
+ def create_order(**args)
34
+ JSON.parse @pwinty["/Orders"].post(args)
35
+ end
36
+
37
+ def update_order(**args)
38
+ JSON.parse @pwinty["/Orders/#{args[:id]}"].put(args)
39
+ end
40
+
41
+ # Order Status
42
+ def get_order_status(id)
43
+ JSON.parse @pwinty["/Orders/#{id}/SubmissionStatus"].get
44
+ end
45
+
46
+ def update_order_status(id, status)
47
+ JSON.parse @pwinty["/Orders/#{id}/Status"].post(status: status)
48
+ end
49
+
50
+ # Order Photos
51
+ def get_photos(orderId)
52
+ JSON.parse @pwinty["/Orders/#{orderId}/Photos"].get
53
+ end
54
+
55
+ def get_photo(orderId, photoId)
56
+ JSON.parse @pwinty["/Orders/#{orderId}/Photos/#{photoId}"].get
57
+ end
58
+
59
+
60
+ def add_photo(**args)
61
+ headers = {}
62
+ orderId = args.delete(:orderId)
63
+
64
+ unless args[:file].nil?
65
+ args, headers = Multipart::Post.prepare_query(args)
66
+ end
67
+
68
+ JSON.parse @pwinty["/Orders/#{orderId}/Photos"].post(args, headers)
69
+ end
70
+
71
+ # post :add_photos, "/Orders/:orderId/Photos/Batch"
72
+ def delete_photo(orderId, photoId)
73
+ JSON.parse @pwinty["/Orders/#{orderId}/Photos/#{photoId}"].delete
74
+ end
75
+
76
+ # Countries
77
+ def countries
78
+ JSON.parse @pwinty["/Country"].get
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,3 @@
1
+ module Pwinty
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "pwinty/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "pwinty"
7
+ s.version = Pwinty::VERSION
8
+ s.authors = ["Derek Lucas"]
9
+ s.email = ["d@derekplucas.com"]
10
+ s.homepage = "http://github.com/dereklucas/pwinty"
11
+ s.licenses = ['MIT']
12
+ s.summary = %q{A Ruby client for the Pwinty API}
13
+ s.description = %q{Order photo prints with Ruby}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency "rake"
21
+ s.add_development_dependency "test-unit"
22
+ s.add_development_dependency "dotenv"
23
+ s.add_runtime_dependency "rest-client", '~> 1.8'
24
+ end
@@ -0,0 +1,116 @@
1
+ require "test_helper"
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @params = {
7
+ recipientName: "FirstName LastName",
8
+ address1: "123 Anywhere Street",
9
+ addressTownOrCity: "San Francisco",
10
+ stateOrCounty: "CA",
11
+ postalOrZipCode: "94101",
12
+ countryCode: "US",
13
+ payment: "InvoiceMe",
14
+ qualityLevel: "Standard"
15
+ }
16
+
17
+ @client = Pwinty.client
18
+
19
+ @order_keys = %w[ id status price
20
+ address1 address2
21
+ addressTownOrCity
22
+ countryCode
23
+ destinationCountryCode
24
+ errorMessage qualityLevel
25
+ payment paymentUrl
26
+ photos postalOrZipCode
27
+ recipientName shippingInfo
28
+ stateOrCounty ]
29
+ end
30
+
31
+ def test_initialize
32
+ body = @client.catalog
33
+ assert_equal body.class, Hash
34
+ end
35
+
36
+ def test_catalog_integration
37
+ body = @client.catalog
38
+ assert_equal body.class, Hash
39
+ assert_equal body["countryCode"], "US"
40
+ assert_equal body["qualityLevel"], "Standard"
41
+ assert_equal body["shippingRates"].class, Array
42
+ assert_equal body["items"].class, Array
43
+ end
44
+ def test_get_orders_integration
45
+ body = @client.get_orders
46
+ assert_equal body.class, Array
47
+ assert_equal body.first.keys.sort!, @order_keys.sort!
48
+ end
49
+ def test_countries_integration
50
+ body = @client.countries
51
+ keys = %w[ countryCode name
52
+ hasProducts errorMessage ]
53
+
54
+ assert_equal body.class, Array
55
+ assert_equal body.first.keys.sort!, keys.sort!
56
+ end
57
+
58
+ def test_orders_integration
59
+ # create Order
60
+ body = @client.create_order(@params)
61
+ assert_equal body.keys.sort!, @order_keys.sort!
62
+ assert_equal body["postalOrZipCode"], "94101"
63
+ id = body["id"]
64
+
65
+
66
+ body = @client.update_order(id: id, recipientName: 'Travis CI', postalOrZipCode: '94102')
67
+ assert_equal body.keys.sort!, @order_keys.sort!
68
+ assert_equal body["postalOrZipCode"], "94102"
69
+
70
+ # add Photo to Order via URL
71
+ body = @client.add_photo(orderId: id,
72
+ type: "4x6",
73
+ url: "http://i.imgur.com/xXnrL.jpg",
74
+ copies: 1, sizing: "Crop")
75
+ photo_id = body['id']
76
+ first_photo = body
77
+
78
+ keys = %w[ id type url
79
+ status copies
80
+ sizing priceToUser
81
+ price md5Hash previewUrl
82
+ thumbnailUrl attributes
83
+ errorMessage ]
84
+
85
+ assert_equal body.keys.sort!, keys.sort!
86
+
87
+ # Check photo was uploaded
88
+ body = @client.get_photos(id)
89
+ assert_equal body.length, 1
90
+ assert_equal body.first, first_photo
91
+
92
+ # Check photo was uploaded
93
+ body = @client.get_photo(id, photo_id)
94
+ assert_equal body, first_photo
95
+
96
+ # Delete photo
97
+ body = @client.delete_photo(id, photo_id)
98
+ assert_equal body['errorMessage'], nil
99
+
100
+ # TODO: Need to add a photo via file
101
+
102
+ # get Order Status
103
+ body = @client.get_order_status(id)
104
+ keys = %w[id isValid generalErrors photos]
105
+ if body["error"]
106
+ assert body["error"].class, String
107
+ else
108
+ assert_equal body.keys.sort!, keys.sort!
109
+ end
110
+
111
+ # Cancel Order
112
+ body = @client.update_order_status(id, "Cancelled")
113
+ assert_equal body['errorMessage'], nil
114
+ end
115
+
116
+ end
@@ -0,0 +1,5 @@
1
+ require 'dotenv'
2
+ Dotenv.load
3
+
4
+ require 'test-unit'
5
+ require 'pwinty'
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pwinty
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Derek Lucas
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: test-unit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dotenv
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
69
+ description: Order photo prints with Ruby
70
+ email:
71
+ - d@derekplucas.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - README.md
80
+ - Rakefile
81
+ - lib/multipart.rb
82
+ - lib/pwinty.rb
83
+ - lib/pwinty/version.rb
84
+ - pwinty.gemspec
85
+ - test/test_client.rb
86
+ - test/test_helper.rb
87
+ homepage: http://github.com/dereklucas/pwinty
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.2.2
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: A Ruby client for the Pwinty API
111
+ test_files:
112
+ - test/test_client.rb
113
+ - test/test_helper.rb
114
+ has_rdoc: