postmates 0.1.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: 7cf00b57dc6151452b0a344584891a6428e8bb25
4
+ data.tar.gz: 8639fcb84ca1e2c4d15ab8703848c37027be5239
5
+ SHA512:
6
+ metadata.gz: f603412097d99cb59f93589e0a9fa43939241e7626c646606be5c5b4b4377b6f46818dfdce7de4f238f86528d397445ad9348a35bd0286b85fa898202fc30b80
7
+ data.tar.gz: 221fd57a328ef694ebd35a978cfcabb3cf81fb2ae418fe022cddf7009567e192c323f100d78ce304ad808d58f79c2cc5d3c7c1d81f208edf92d96a32b8bff0f6
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.gem
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --order random
3
+ --require spec_helper
@@ -0,0 +1,22 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1
7
+ - 2.2
8
+ - jruby-19mode
9
+ - jruby-head
10
+ - rbx-2
11
+ - ruby-head
12
+
13
+ env:
14
+ global:
15
+ - JRUBY_OPTS="$JRUBY_OPTS --debug"
16
+
17
+ matrix:
18
+ allow_failures:
19
+ - rvm: jruby-head
20
+ - rvm: rbx-2
21
+ - rvm: ruby-head
22
+ fast_finish: true
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in postmates.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Rahul Horé
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,137 @@
1
+ # Postmates
2
+ [![Build Status](https://travis-ci.org/O-I/postmates.svg?branch=master)](https://travis-ci.org/O-I/postmates)
3
+ [![Coverage Status](https://img.shields.io/coveralls/O-I/postmates.svg)](https://coveralls.io/r/O-I/postmates?branch=master)
4
+
5
+ Ruby wrapper for the [Postmates API](https://postmates.com/developer/docs).
6
+
7
+ ## Installation
8
+
9
+ `gem install 'postmates'` or add `gem 'postmates'` to your Gemfile and `bundle`.
10
+
11
+ ## Configuration
12
+
13
+ You'll need an API key and your customer ID. You can sign up to register your app [here](https://postmates.com/developer/register). Just want to test things out? Postmates has you covered with a [test key and customer account](https://postmates.com/developer/testing).
14
+
15
+ ```ruby
16
+ # Create a new Postmates client
17
+ @client = Postmates.new
18
+
19
+ # Set basic config variables
20
+ @client.configure do |config|
21
+ config.api_key = 'YOUR_API_KEY'
22
+ config.customer_id = 'YOUR_CUSTOMER_ID'
23
+ end
24
+
25
+ # Or do some more advanced stuff
26
+ @client.configure do |config|
27
+ # Get full Faraday responses instead of Ruby objects representing the body
28
+ config.raw_response = true
29
+ # Ensure consistent fields & formats by specifying a version in the header
30
+ config.headers.merge!('X-Postmates-Version' => 20140825)
31
+ # Work with a possible future version of the API
32
+ config.api_url = 'https://api.postmates.com/v2/'
33
+ end
34
+
35
+ # And switch back to the defaults easily
36
+ @client.reset
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ Descriptions and examples of the supported actions are below. For a more detailed explanation of available endpoints and an exhaustive list of the properties each response returns, check out the official Postmates developer [documentation](https://postmates.com/developer/docs).
42
+
43
+ ### Customer Deliveries Endpoints
44
+
45
+ #### POST /v1/customers/:customer_id/delivery_quotes
46
+
47
+ Get a delivery quote. Returns a `Postmates::Quote` object.
48
+
49
+ ```ruby
50
+ from = "20 McAllister St, San Francisco, CA"
51
+ to = "101 Market St, San Francisco, CA"
52
+ quote = @client.quote(pickup_address: from, dropoff_address: to)
53
+
54
+ quote.fee # => 1350
55
+ quote.currency # => "usd"
56
+ format = '%m/%d/%Y %I:%M:%S%p' # all times are returned in UTC
57
+ quote.expires_at.strftime(format) # => "01/05/2015 09:35:28PM"
58
+ quote.expired? # => false
59
+ ```
60
+
61
+ #### POST /v1/customers/:customer_id/deliveries
62
+
63
+ Create a delivery. Returns a `Postmates::Delivery` object.
64
+
65
+ ```ruby
66
+ # all fields required except where noted
67
+ package = {
68
+ manifest: "a box of kittens",
69
+ pickup_name: "The Warehouse",
70
+ pickup_address: "20 McAllister St, San Francisco, CA",
71
+ pickup_phone_number: "555-555-5555",
72
+ pickup_business_name: "Optional Pickup Business Name, Inc.",
73
+ pickup_notes: "Optional note that this is Invoice #123",
74
+ dropoff_name: "Alice",
75
+ dropoff_address: "101 Market St, San Francisco, CA",
76
+ dropoff_phone_number: "415-555-1234",
77
+ dropoff_business_name: "Optional Dropoff Business Name, Inc.",
78
+ dropoff_notes: "Optional note to ring the bell",
79
+ quote_id: "dqt_K9LFfpSZCdAJsk" # optional
80
+ }
81
+ delivery = @client.create(package)
82
+
83
+ delivery.id # => "del_K9gEsDNuPJ-lLV"
84
+ delivery.status # => "pending"
85
+ delivery.delivered? # => false
86
+ delivery.pickup # a hash representing pickup information
87
+ delivery.dropoff # a hash representing dropoff information
88
+ ```
89
+
90
+ #### GET /v1/customers/:customer_id/deliveries
91
+
92
+ Fetch a list of all deliveries for a customer. Returns an array of `Postmates::Delivery` objects.
93
+
94
+ ```ruby
95
+ my_deliveries = @client.list
96
+ my_ongoing_deliveries = @client.list(filter: 'pending')
97
+
98
+ # If the result is too large for one response
99
+ # there are a few meta-attributes you can call on the returned array
100
+ # Here's a simulated example of a paginated response:
101
+ deliveries = @client.list(limit: 2)
102
+ deliveries.size # => 2 (number of deliveries in the returned array)
103
+ deliveries.total_count # => 6 (number of total deliveries)
104
+ deliveries.next_href # a URI object representing the path to the next page
105
+ ```
106
+
107
+ #### GET /v1/customers/:customer_id/deliveries/:delivery_id
108
+
109
+ Fetch a single delivery by id. Returns a `Postmates::Delivery` object.
110
+
111
+ ```ruby
112
+ @client.retrieve('del_K9gEsDNuPJ-lLV')
113
+ ```
114
+
115
+ #### POST /v1/customers/:customer_id/deliveries/:delivery_id/cancel
116
+
117
+ Cancel an ongoing delivery prior to pickup. Returns a `Postmates::Delivery` object.
118
+
119
+ ```ruby
120
+ @client.cancel('del_K9gEsDNuPJ-lLV')
121
+ ```
122
+
123
+ #### POST /v1/customers/:customer_id/deliveries/:delivery_id/return
124
+
125
+ Cancel an ongoing delivery that was already picked up and create a delivery that is a reverse of the original. The items will get returned to the original pickup location. Returns a `Postmates::Delivery` object.
126
+
127
+ ```ruby
128
+ @client.cancel('del_K9gEsDNuPJ-lLV')
129
+ ```
130
+
131
+ ## Contributing
132
+
133
+ 1. Fork it ( https://github.com/[my-github-username]/postmates/fork )
134
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
135
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
136
+ 4. Push to the branch (`git push origin my-new-feature`)
137
+ 5. Create a new Pull Request
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = FileList['spec/**/*_spec.rb']
7
+ end
8
+
9
+ task :default => :spec
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+ require 'faraday'
3
+ require_relative '../postmates/error'
4
+
5
+ module FaradayMiddleware
6
+ class RaiseHTTPException < Faraday::Middleware
7
+ def call(env)
8
+ @app.call(env).on_complete do |response|
9
+ response_hash = JSON.parse(response.body)
10
+ msg = "#{response[:status]} #{response_hash['message']}"
11
+
12
+ case response[:status]
13
+ when 400 ; raise Postmates::BadRequest, msg
14
+ when 401 ; raise Postmates::Unauthorized, msg
15
+ when 403 ; raise Postmates::Forbidden, msg
16
+ when 404 ; raise Postmates::NotFound, msg
17
+ when 500 ; raise Postmates::InternalServerError, msg
18
+ when 503 ; raise Postmates::ServiceUnavailable, msg
19
+ end
20
+ end
21
+ end
22
+
23
+ def initialize(app)
24
+ super app
25
+ @parser = nil
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'postmates/client'
2
+
3
+ module Postmates
4
+ class << self
5
+
6
+ def new
7
+ @client ||= Postmates::Client.new
8
+ end
9
+
10
+ def method_missing(method, *args, &block)
11
+ return super unless new.respond_to?(method)
12
+ new.send(method, *args, &block)
13
+ end
14
+
15
+ def respond_to?(method, include_private = false)
16
+ new.respond_to?(method, include_private) || super
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,81 @@
1
+ require_relative 'request'
2
+ require_relative 'connection'
3
+ require_relative 'configuration'
4
+
5
+ module Postmates
6
+ class Client
7
+ include Postmates::Request
8
+ include Postmates::Connection
9
+ include Postmates::Configuration
10
+
11
+ def initialize
12
+ reset
13
+ end
14
+
15
+ # POST /v1/customers/:customer_id/delivery_quotes
16
+ #
17
+ # pickup_address="20 McAllister St, San Francisco, CA"
18
+ # dropoff_address="101 Market St, San Francisco, CA"
19
+ #
20
+ # Returns a Quote object or the raw Faraday response
21
+ # if raw_response = true
22
+ def quote(options = {})
23
+ post("customers/#{customer_id}/delivery_quotes", options)
24
+ end
25
+
26
+ # POST /v1/customers/:customer_id/deliveries
27
+ #
28
+ # manifest="a box of kittens"
29
+ # pickup_name="The Warehouse"
30
+ # pickup_address="20 McAllister St, San Francisco, CA"
31
+ # pickup_phone_number="555-555-5555"
32
+ # pickup_business_name="Optional Pickup Business Name, Inc."
33
+ # pickup_notes="Optional note that this is Invoice #123"
34
+ # dropoff_name="Alice"
35
+ # dropoff_address="101 Market St, San Francisco, CA"
36
+ # dropoff_phone_number="415-555-1234"
37
+ # dropoff_business_name="Optional Dropoff Business Name, Inc."
38
+ # dropoff_notes="Optional note to ring the bell"
39
+ # quote_id=qUdje83jhdk
40
+ #
41
+ # Returns a Delivery object or the raw Faraday response
42
+ # if raw_response = true
43
+ def create(options = {})
44
+ post("customers/#{customer_id}/deliveries", options)
45
+ end
46
+
47
+ # GET /v1/customers/:customer_id/deliveries
48
+ #
49
+ # ?filter=ongoing
50
+ #
51
+ # Returns a list of Delivery objects or the raw Faraday response
52
+ # if raw_response = true
53
+ def list(options = {})
54
+ get("customers/#{customer_id}/deliveries", options)
55
+ end
56
+
57
+ # GET /v1/customers/:customer_id/deliveries/:delivery_id
58
+ #
59
+ # Returns a Delivery object or the raw Faraday response
60
+ # if raw_response = true
61
+ def retrieve(delivery_id)
62
+ get("customers/#{customer_id}/deliveries/#{delivery_id}")
63
+ end
64
+
65
+ # POST /v1/customers/:customer_id/deliveries/:delivery_id/cancel
66
+ #
67
+ # Returns a Delivery object or the raw Faraday response
68
+ # if raw_response = true
69
+ def cancel(delivery_id)
70
+ post("customers/#{customer_id}/deliveries/#{delivery_id}/cancel")
71
+ end
72
+
73
+ # POST /v1/customers/:customer_id/deliveries/:delivery_id/return
74
+ #
75
+ # Returns a Delivery object or the raw Faraday response
76
+ # if raw_response = true
77
+ def return(delivery_id)
78
+ post("customers/#{customer_id}/deliveries/#{delivery_id}/return")
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'version'
2
+
3
+ module Postmates
4
+ module Configuration
5
+
6
+ VALID_CONFIGURATION_KEYS = [:headers, :api_url, :api_key,
7
+ :customer_id, :raw_response]
8
+
9
+ attr_accessor *VALID_CONFIGURATION_KEYS
10
+
11
+ DEFAULT_API_URL = 'https://api.postmates.com/v1/'
12
+ DEFAULT_HEADERS = {
13
+ accept: 'application/json',
14
+ user_agent: "postmates gem #{Postmates::Version}"
15
+ }
16
+
17
+ def configure
18
+ yield self
19
+ end
20
+
21
+ def reset
22
+ self.headers = DEFAULT_HEADERS
23
+ self.api_url = DEFAULT_API_URL
24
+ self.api_key = nil
25
+ self.customer_id = nil
26
+ self.raw_response = false
27
+ self
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,25 @@
1
+ require 'faraday_middleware'
2
+ require_relative '../faraday/raise_http_exception'
3
+
4
+ module Postmates
5
+ module Connection
6
+
7
+ private
8
+
9
+ def connection
10
+ options = {
11
+ headers: headers,
12
+ ssl: { verify: false },
13
+ url: api_url
14
+ }
15
+
16
+ Faraday.new(options) do |connection|
17
+ connection.use Faraday::Request::UrlEncoded
18
+ connection.use Faraday::Request::BasicAuthentication, api_key, ''
19
+ connection.use Faraday::Response::ParseJson
20
+ connection.use FaradayMiddleware::RaiseHTTPException
21
+ connection.adapter(Faraday.default_adapter)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'utils'
2
+
3
+ module Postmates
4
+ class Delivery
5
+ include Postmates::Utils
6
+ attr_reader :id, :created_at, :updated_at, :status, :complete,
7
+ :pickup_eta, :dropoff_eta, :dropoff_deadline,
8
+ :quote_id, :fee, :currency, :manifest, :pickup,
9
+ :dropoff, :courier, :image_url
10
+
11
+ def initialize(hash)
12
+ @id = hash['id']
13
+ @status = hash['status']
14
+ @complete = hash['complete']
15
+ @quote_id = hash['quote_id']
16
+ @fee = hash['fee']
17
+ @currency = hash['currency']
18
+ @manifest = hash['manifest']
19
+ @pickup = hash['pickup']
20
+ @dropoff = hash['dropoff']
21
+ @courier = hash['courier']
22
+ @image_url = urlify hash['image_href']
23
+ @created_at = timeify hash['created']
24
+ @updated_at = timeify hash['updated']
25
+ @pickup_eta = timeify hash['pickup_eta']
26
+ @dropoff_eta = timeify hash['dropoff_eta']
27
+ end
28
+
29
+ def delivered?
30
+ status == 'delivered'
31
+ end
32
+ end
33
+ end