ups_time_in_transit 0.1.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.
- data.tar.gz.sig +0 -0
- data/LICENSE +23 -0
- data/Manifest +6 -0
- data/README +55 -0
- data/Rakefile +12 -0
- data/lib/ups_time_in_transit.rb +250 -0
- data/ups_time_in_transit.gemspec +35 -0
- metadata +114 -0
- metadata.gz.sig +2 -0
data.tar.gz.sig
ADDED
Binary file
|
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2010 Joseph Stelmach
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
ups_time_in_transit is an easy to use interface to the UPS Time in Transit API.
|
2
|
+
|
3
|
+
== installation ==
|
4
|
+
gem install ups_time_in_transit
|
5
|
+
|
6
|
+
== usage ==
|
7
|
+
|
8
|
+
# define your access options. These are options that won't change
|
9
|
+
# between requests. Take care to specify the proper UPS url:
|
10
|
+
# 'https://wwwcie.ups.com/ups.app/xml/TimeInTransit' for testing and
|
11
|
+
# development, and 'https://onlinetools.ups.com/ups.app/xml/TimeInTransit'
|
12
|
+
# for production.
|
13
|
+
access_options = {
|
14
|
+
:url => 'https://wwwcie.ups.com/ups.app/xml/TimeInTransit',
|
15
|
+
:access_license_number => 'foo',
|
16
|
+
:user_id => 'bar',
|
17
|
+
:password => 'baz',
|
18
|
+
:order_cutoff_time => 17 ,
|
19
|
+
:sender_city => 'Hoboken',
|
20
|
+
:sender_state => 'NJ',
|
21
|
+
:sender_country_code => 'US',
|
22
|
+
:sender_zip => '07030'}
|
23
|
+
|
24
|
+
# It's best to store these these options in a yaml file and load them
|
25
|
+
# into a map when you need them:
|
26
|
+
yaml = YAML.load_file("#{RAILS_ROOT}/config/ups_time_in_transit.yml")
|
27
|
+
access_options = yaml[RAILS_ENV].inject({}){|h,(k, v)| h[k.to_sym] = v; h}
|
28
|
+
|
29
|
+
# create an api instance with your access options
|
30
|
+
time_in_transit_api = UPS::TimeInTransit.new(access_options)
|
31
|
+
|
32
|
+
# for each request, generate a map of request options describing
|
33
|
+
# the shipment and where it's going
|
34
|
+
request_options = {
|
35
|
+
:total_packages => 1,
|
36
|
+
:unit_of_measurement => 'LBS',
|
37
|
+
:weight => 10,
|
38
|
+
:city => 'Newark',
|
39
|
+
:state => 'DE',
|
40
|
+
:zip => '19711',
|
41
|
+
:country_code => 'US'}
|
42
|
+
|
43
|
+
# request the map of delivery types (overnight, ground, etc.) to the expected
|
44
|
+
# delivery date for that type. Be sure to rescue any errors.
|
45
|
+
begin
|
46
|
+
delivery_dates = time_in_transit_api.request(request_options)
|
47
|
+
rescue => error
|
48
|
+
puts error.inspect
|
49
|
+
end
|
50
|
+
|
51
|
+
== changelog ==
|
52
|
+
|
53
|
+
v.0.1.0
|
54
|
+
initial release
|
55
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('ups_time_in_transit', '0.1.1') do |p|
|
6
|
+
p.description = "Provides an easy to use interface to the UPS time in transit API"
|
7
|
+
p.url = "http://github.com/joestelmach/ups_time_in_transit"
|
8
|
+
p.author = "Joe Stelmach"
|
9
|
+
p.email = "joestelmach @nospam@ gmail.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.runtime_dependencies = ['activesupport']
|
12
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'active_support'
|
7
|
+
|
8
|
+
module UPS
|
9
|
+
# Provides a simple api to to ups's time in transit service.
|
10
|
+
class TimeInTransit
|
11
|
+
XPCI_VERSION = '1.0002'
|
12
|
+
DEFAULT_CUTOFF_TIME = 14
|
13
|
+
DEFAULT_TIMEOUT = 30
|
14
|
+
DEFAULT_RETRY_COUNT = 3
|
15
|
+
DEFAULT_COUNTRY_CODE = 'US'
|
16
|
+
DEFAULT_UNIT_OF_MEASUREMENT = 'LBS'
|
17
|
+
|
18
|
+
# Creates a TimeInTransit instance based on the given hash of access
|
19
|
+
# options The following access options are available and are required
|
20
|
+
# unless a default value is specified:
|
21
|
+
#
|
22
|
+
# [<tt>:url</tt>]
|
23
|
+
# The ups api url to use
|
24
|
+
#
|
25
|
+
# [<tt>:access_license_number</tt>]
|
26
|
+
# Your ups license number
|
27
|
+
#
|
28
|
+
# [<tt>:user_id</tt>]
|
29
|
+
# Your ups user id
|
30
|
+
#
|
31
|
+
# [<tt>password</tt>]
|
32
|
+
# Your ups password
|
33
|
+
#
|
34
|
+
# [<tt>:order_cutoff_time</tt>]
|
35
|
+
# Your own arbitrary cutoff time that is some time before the actual ups cutoff
|
36
|
+
# time. Requests made after this time will use the following day as the send
|
37
|
+
# date (or the following monday if the request is made on a weekend or on a
|
38
|
+
# friday after this time.)
|
39
|
+
#
|
40
|
+
# [<tt>:sender_city</tt>]
|
41
|
+
# The city you are shipping from
|
42
|
+
#
|
43
|
+
# [<tt>:sender_state</tt>]
|
44
|
+
# The state you are shipping from
|
45
|
+
#
|
46
|
+
# [<tt>:sender_zip</tt>]
|
47
|
+
# The zip code you are shipping from
|
48
|
+
#
|
49
|
+
# [<tt>:sender_country_code</tt>]
|
50
|
+
# The country you are shipping from (defaults to 'US')
|
51
|
+
#
|
52
|
+
# [<tt>:retry_count</tt>]
|
53
|
+
# The number of times you would like to retry when a connection
|
54
|
+
# fails (defaults to 3)
|
55
|
+
#
|
56
|
+
# [<tt>:timeout</tt>]
|
57
|
+
# The number of seconds you would like to wait for a response before
|
58
|
+
# giving up (defaults to 30)
|
59
|
+
#
|
60
|
+
def initialize(access_options)
|
61
|
+
@order_cutoff_time = access_options[:order_cutoff_time] || DEFAULT_CUTOFF_TIME
|
62
|
+
@url = access_options[:url]
|
63
|
+
@timeout = access_options[:timeout] || DEFAULT_TIMEOUT
|
64
|
+
@retry_count = access_options[:retry_count] || DEFAULT_CUTOFF_TIME
|
65
|
+
|
66
|
+
@access_xml = generate_xml({
|
67
|
+
:AccessRequest => {
|
68
|
+
:AccessLicenseNumber => access_options[:access_license_number],
|
69
|
+
:UserId => access_options[:user_id],
|
70
|
+
:Password => access_options[:password]
|
71
|
+
}
|
72
|
+
})
|
73
|
+
|
74
|
+
@transit_from_attributes = {
|
75
|
+
:AddressArtifactFormat => {
|
76
|
+
:PoliticalDivision2 => access_options[:sender_city],
|
77
|
+
:PoliticalDivision1 => access_options[:sender_state],
|
78
|
+
:CountryCode => access_options[:sender_country_code] || DEFAULT_COUNTRY_CODE,
|
79
|
+
:PostcodePrimaryLow => access_options[:sender_zip]
|
80
|
+
}
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
# Requests time in transit information based on the given hash of options:
|
85
|
+
#
|
86
|
+
# [<tt>:total_packages</tt>]
|
87
|
+
# the number of packages in the shipment (defaults to 1)
|
88
|
+
#
|
89
|
+
# [<tt>:unit_of_measurement</tt>]
|
90
|
+
# the unit of measurement to use (defaults to 'LBS')
|
91
|
+
#
|
92
|
+
# [<tt>:weight</tt>]
|
93
|
+
# the weight of the shipment in the given units
|
94
|
+
#
|
95
|
+
# [<tt>:city</tt>]
|
96
|
+
# the city you are shipping to
|
97
|
+
#
|
98
|
+
# [<tt>:state</tt>]
|
99
|
+
# the state you are shipping to
|
100
|
+
#
|
101
|
+
# [<tt>:zip</tt>]
|
102
|
+
# the zip code you are shipping to
|
103
|
+
#
|
104
|
+
# [<tt>:country_code</tt>]
|
105
|
+
# the country you are shipping to (defaults to 'US')
|
106
|
+
#
|
107
|
+
# An error will be raised if the request is unsuccessful.
|
108
|
+
#
|
109
|
+
def request(options)
|
110
|
+
|
111
|
+
# build our request xml
|
112
|
+
pickup_date = calculate_pickup_date
|
113
|
+
options[:pickup_date] = pickup_date.strftime('%Y%m%d')
|
114
|
+
xml = @access_xml + generate_xml(build_transit_attributes(options))
|
115
|
+
|
116
|
+
# attempt the request in a timeout
|
117
|
+
delivery_dates = {}
|
118
|
+
attempts = 0
|
119
|
+
begin
|
120
|
+
Timeout.timeout(@timeout) do
|
121
|
+
response = send_request(@url, xml)
|
122
|
+
delivery_dates = response_to_map(response)
|
123
|
+
end
|
124
|
+
|
125
|
+
# We can only attempt to recover from Timeout errors, all other errors
|
126
|
+
# should be raised back to the user
|
127
|
+
rescue Timeout::Error => error
|
128
|
+
if(attempts < @retry_count)
|
129
|
+
attempts += 1
|
130
|
+
retry
|
131
|
+
|
132
|
+
else
|
133
|
+
raise error
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
delivery_dates
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
# calculates the next available pickup date based on the current time and the
|
143
|
+
# configured order cutoff time
|
144
|
+
def calculate_pickup_date
|
145
|
+
now = Time.now
|
146
|
+
day_of_week = now.strftime('%w').to_i
|
147
|
+
in_weekend = [6,0].include?(day_of_week)
|
148
|
+
in_friday_after_cutoff = day_of_week == 5 and now.hour > @order_cutoff_time
|
149
|
+
|
150
|
+
# If we're in a weekend (6 is Sat, 0 is Sun,) or we're in Friday after
|
151
|
+
# the cutoff time, then our ship date will move
|
152
|
+
if(in_weekend or in_friday_after_cutoff)
|
153
|
+
pickup_date = now.next_week
|
154
|
+
|
155
|
+
# if we're in another weekday but after the cutoff time, our ship date
|
156
|
+
# moves to tomorrow
|
157
|
+
elsif(now.hour > @order_cutoff_time)
|
158
|
+
pickup_date = now.tomorrow
|
159
|
+
else
|
160
|
+
pickup_date = now
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Builds a hash of transit request attributes based on the given values
|
165
|
+
def build_transit_attributes(options)
|
166
|
+
# set defaults if none given
|
167
|
+
options[:total_packages] = 1 unless options[:total_packages]
|
168
|
+
|
169
|
+
# convert all options to string values
|
170
|
+
options.each_value {|option| option = options.to_s}
|
171
|
+
|
172
|
+
transit_attributes = {
|
173
|
+
:TimeInTransitRequest => {
|
174
|
+
:Request => {
|
175
|
+
:RequestAction => 'TimeInTransit',
|
176
|
+
:TransactionReference => {
|
177
|
+
:XpciVersion => XPCI_VERSION
|
178
|
+
}
|
179
|
+
},
|
180
|
+
:TotalPackagesInShipment => options[:total_packages],
|
181
|
+
:ShipmentWeight => {
|
182
|
+
:UnitOfMeasurement => {
|
183
|
+
:Code => options[:unit_of_measurement] || DEFAULT_UNIT_OF_MEASUREMENT
|
184
|
+
},
|
185
|
+
:Weight => options[:weight],
|
186
|
+
},
|
187
|
+
:PickupDate => options[:pickup_date],
|
188
|
+
:TransitFrom => @transit_from_attributes,
|
189
|
+
:TransitTo => {
|
190
|
+
:AddressArtifactFormat => {
|
191
|
+
:PoliticalDivision2 => options[:city],
|
192
|
+
:PoliticalDivision1 => options[:state],
|
193
|
+
:CountryCode => options[:country_code] || DEFAULT_COUNTRY_CODE,
|
194
|
+
:PostcodePrimaryLow => options[:zip],
|
195
|
+
}
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
# generates an xml document for the given attributes
|
202
|
+
def generate_xml(attributes)
|
203
|
+
xml = REXML::Document.new
|
204
|
+
xml << REXML::XMLDecl.new
|
205
|
+
emit(attributes, xml)
|
206
|
+
xml.root.add_attribute("xml:lang", "en-US")
|
207
|
+
xml.to_s
|
208
|
+
end
|
209
|
+
|
210
|
+
# recursively emits xml nodes under the given node for values in the given hash
|
211
|
+
def emit(attributes, node)
|
212
|
+
attributes.each do |k,v|
|
213
|
+
child_node = REXML::Element.new(k.to_s, node)
|
214
|
+
(v.respond_to? 'each_key') ? emit(v, child_node) : child_node.add_text(v.to_s)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Posts the given data to the given url, returning the raw response
|
219
|
+
def send_request(url, data)
|
220
|
+
uri = URI.parse(url)
|
221
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
222
|
+
if uri.port == 443
|
223
|
+
http.use_ssl = true
|
224
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
225
|
+
end
|
226
|
+
response = http.post(uri.path, data)
|
227
|
+
response.code == '200' ? response.body : response.error!
|
228
|
+
end
|
229
|
+
|
230
|
+
# converts the given raw xml response to a map of local service codes
|
231
|
+
# to estimated delivery dates
|
232
|
+
def response_to_map(response)
|
233
|
+
response_doc = REXML::Document.new(response)
|
234
|
+
response_code = response_doc.elements['//ResponseStatusCode'].text.to_i
|
235
|
+
raise "Invalid response from ups:\n#{response_doc.to_s}" if(!response_code || response_code != 1)
|
236
|
+
|
237
|
+
service_codes_to_delivery_dates = {}
|
238
|
+
response_code = response_doc.elements.each('//ServiceSummary') do |service_element|
|
239
|
+
service_code = service_element.elements['Service/Code'].text
|
240
|
+
if(service_code)
|
241
|
+
date_string = service_element.elements['EstimatedArrival/Date'].text
|
242
|
+
time_string = service_element.elements['EstimatedArrival/Time'].text
|
243
|
+
delivery_date = Time.parse("#{date_string} #{time_string}")
|
244
|
+
service_codes_to_delivery_dates[service_code] = delivery_date
|
245
|
+
end
|
246
|
+
end
|
247
|
+
service_codes_to_delivery_dates
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{ups_time_in_transit}
|
5
|
+
s.version = "0.1.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Joe Stelmach"]
|
9
|
+
s.cert_chain = ["/Users/joe/workspace/personal/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2010-06-01}
|
11
|
+
s.description = %q{Provides an easy to use interface to the UPS time in transit API}
|
12
|
+
s.email = %q{joestelmach @nospam@ gmail.com}
|
13
|
+
s.extra_rdoc_files = ["LICENSE", "README", "lib/ups_time_in_transit.rb"]
|
14
|
+
s.files = ["LICENSE", "Manifest", "README", "Rakefile", "lib/ups_time_in_transit.rb", "ups_time_in_transit.gemspec"]
|
15
|
+
s.homepage = %q{http://github.com/joestelmach/ups_time_in_transit}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Ups_time_in_transit", "--main", "README"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{ups_time_in_transit}
|
19
|
+
s.rubygems_version = %q{1.3.7}
|
20
|
+
s.signing_key = %q{/Users/joe/workspace/personal/gem-private_key.pem}
|
21
|
+
s.summary = %q{Provides an easy to use interface to the UPS time in transit API}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 3
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
31
|
+
end
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ups_time_in_transit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Joe Stelmach
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain:
|
17
|
+
- |
|
18
|
+
-----BEGIN CERTIFICATE-----
|
19
|
+
MIIDODCCAiCgAwIBAgIBADANBgkqhkiG9w0BAQUFADBCMRQwEgYDVQQDDAtqb2Vz
|
20
|
+
dGVsbWFjaDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
|
21
|
+
Y29tMB4XDTEwMDYwMjAyMTEzN1oXDTExMDYwMjAyMTEzN1owQjEUMBIGA1UEAwwL
|
22
|
+
am9lc3RlbG1hY2gxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixk
|
23
|
+
ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANkIW8alNYIx
|
24
|
+
7dkzBZXc6XE3WomRJCYZLgWAlbnGT/iF9xOunTOcsYOFVaP9fY5tQ3c9DKOd/TtG
|
25
|
+
bTFKZYvOQM2ASlfJo4KrW3NqiwpG1kPsTI3wOOrOzoClnVu8EneK0kG5PETDZY2H
|
26
|
+
h0B4kd7ejCmX8L4KRIVZRljZLSjLMEPEyA2+9CPIL7UfjmKHEIWjmQli+IrfUVoa
|
27
|
+
CpcrNxG7FBa/pwfsIF8nr1xSw35K7S1oJ5ma65s2449wVspqLXg5H3IQxz/Y9coe
|
28
|
+
iuG1QhmI78RSIHfzDPNXp5smOsHrVJm21h71eF/oV19BNvGuMkavOS5NSPZ3T685
|
29
|
+
v4NVpu7qoosCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
30
|
+
BBYEFPCOueB1WpFUwO+OTSX4ABA4e/bPMA0GCSqGSIb3DQEBBQUAA4IBAQBnrQSg
|
31
|
+
rLL1UBujU/RkXPdC/xj61lywwy+HuiGruu1VbLVSten2VjjDEK4ga/7K9z3SRWiW
|
32
|
+
fFXj61rM9ljvYbQN2+74WR2WjbX7057bqY80/vSnyIxqxXoJzjg6OAHvdXq+oAel
|
33
|
+
A5jXBeb7FGd3IIUjAwWvLmvK+s3AmfOZ8y7e/A0QKtgvSufrUWN+ZaGnzP64WMPf
|
34
|
+
CHFGU7Orn1e+tYjg7zAQMXkYdQ9u/HvbJ6/gLQwD4bKwRW6jZGSBdUUQU7W4/ygC
|
35
|
+
irVgr9ouyby8ZibMqCXSRjQ9BP3xIRThygXC5MLpq4bkHn/twgUWC2FYWTeI3F43
|
36
|
+
BNAwAE8UFlzJGIy5
|
37
|
+
-----END CERTIFICATE-----
|
38
|
+
|
39
|
+
date: 2010-06-01 00:00:00 -04:00
|
40
|
+
default_executable:
|
41
|
+
dependencies:
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: activesupport
|
44
|
+
prerelease: false
|
45
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
hash: 3
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
type: :runtime
|
55
|
+
version_requirements: *id001
|
56
|
+
description: Provides an easy to use interface to the UPS time in transit API
|
57
|
+
email: joestelmach @nospam@ gmail.com
|
58
|
+
executables: []
|
59
|
+
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
extra_rdoc_files:
|
63
|
+
- LICENSE
|
64
|
+
- README
|
65
|
+
- lib/ups_time_in_transit.rb
|
66
|
+
files:
|
67
|
+
- LICENSE
|
68
|
+
- Manifest
|
69
|
+
- README
|
70
|
+
- Rakefile
|
71
|
+
- lib/ups_time_in_transit.rb
|
72
|
+
- ups_time_in_transit.gemspec
|
73
|
+
has_rdoc: true
|
74
|
+
homepage: http://github.com/joestelmach/ups_time_in_transit
|
75
|
+
licenses: []
|
76
|
+
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options:
|
79
|
+
- --line-numbers
|
80
|
+
- --inline-source
|
81
|
+
- --title
|
82
|
+
- Ups_time_in_transit
|
83
|
+
- --main
|
84
|
+
- README
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 11
|
102
|
+
segments:
|
103
|
+
- 1
|
104
|
+
- 2
|
105
|
+
version: "1.2"
|
106
|
+
requirements: []
|
107
|
+
|
108
|
+
rubyforge_project: ups_time_in_transit
|
109
|
+
rubygems_version: 1.3.7
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: Provides an easy to use interface to the UPS time in transit API
|
113
|
+
test_files: []
|
114
|
+
|
metadata.gz.sig
ADDED