pwinty 1.0.1

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