rrd-track 1.0.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7dc1119a97d15171935a8fed7b8f74a44fbe755b
4
- data.tar.gz: 6c24c8b211c229e05aabc48096b7fd1472cca2e7
3
+ metadata.gz: 347aed7783f12924af79b05b36445ddb85f457a5
4
+ data.tar.gz: 158a044571e878f540639677314b184f0292bfe1
5
5
  SHA512:
6
- metadata.gz: 3f609ff5c683c0ea4cad3a405edfa9b9f7443aab179248e372cc9b272c371fd42bbd7c6a1c1636b37b1a75c0b7960cf94ab94465236c57c01453dda14fc04c2e
7
- data.tar.gz: 6071fb9e23924ccbfed59c24c82fd87106b8aa91ccfba0c62695eef200dd3be8f67cbf9191f8bbae6bcdf05b07f6a7fa6ed5343a475a9790df9b17d2a7d20f86
6
+ metadata.gz: b5d7a0ef976a86d7c0b0b7492ae89bc3807c544ae454f983e10b7b817be2a10ae7862578afbf5ec1fdc193c46ad195eea68c074eaca6427df40e0a62a764ed56
7
+ data.tar.gz: e4dc8f5c10707bcf4da0e8be7093d12b26ab517c161be3a0fd49e744ddc8dd1afcd941126f2d52136e4fe01c66642361b1fff8ccb6aaa72c6703d3d5cd183623
@@ -0,0 +1,17 @@
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
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
@@ -41,8 +41,8 @@ PLATFORMS
41
41
  ruby
42
42
 
43
43
  DEPENDENCIES
44
- awesome_print (~> 1.2.0)
45
- rake (~> 10.1.1)
44
+ awesome_print (~> 1.2)
45
+ rake (~> 10.1)
46
46
  rrd-track!
47
47
  rspec (~> 2.14)
48
- webmock (~> 1.17.4)
48
+ webmock (~> 1.17)
@@ -0,0 +1,27 @@
1
+ require "rrd-track/client"
2
+ require "rrd-track/configuration"
3
+ require "rrd-track/version"
4
+
5
+ module RRD
6
+ class << self
7
+ attr_writer :configuration
8
+
9
+ def client
10
+ @client ||= Client.new
11
+ end
12
+
13
+ def configuration
14
+ @configuration ||= Configuration.new
15
+ end
16
+
17
+ def configure
18
+ yield(configuration)
19
+ end
20
+
21
+ def track(tracking_number)
22
+ client.request(RRD::Request::Tracking.new(tracking_number))
23
+ end
24
+
25
+ alias_method :config, :configuration
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ require 'nokogiri'
2
+ require 'typhoeus'
3
+
4
+ require "rrd-track/errors"
5
+ require "rrd-track/request/tracking"
6
+ require "rrd-track/response/tracking"
7
+
8
+ module RRD
9
+ class Client
10
+
11
+ def request(request, &block)
12
+ response = Typhoeus::Request.get(tracking_api_url, {
13
+ timeout: RRD.config.timeout,
14
+ params: request.api_params,
15
+ headers: { Accept: "application/xml" }
16
+ })
17
+
18
+ # Parse the request
19
+ xml = Nokogiri::XML.parse(response.body)
20
+
21
+ if (error = xml.search('error')).any?
22
+ code = error.search('code').text
23
+ description = error.search('description').text
24
+
25
+ raise Error.for_code(code).new(code, description)
26
+ end
27
+
28
+ request.response_handler(xml)
29
+ end
30
+
31
+ private
32
+
33
+ def tracking_api_url
34
+ "http://www.ppxtrack.com/api/ParcelTracking"
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,9 @@
1
+ module RRD
2
+ class Configuration
3
+ attr_accessor :timeout
4
+
5
+ def initialize
6
+ @timeout = 5000
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ module RRD
2
+ class Error < StandardError
3
+ attr_reader :code, :description
4
+
5
+ def initialize(code, description)
6
+ super(description)
7
+ @code = code
8
+ @description = description
9
+ end
10
+
11
+ class << self
12
+ def for_code(code)
13
+ case code
14
+ when '100'; UsernameNotFoundError
15
+ when '110'; PasswordNotFoundError
16
+ when '120'; TrackingNumberNotFoundError
17
+ when '130'; AuthenticationError
18
+ when '200'; ShippingSiteError
19
+ when '300'; DatabaseError
20
+ when '400'; BadTrackingNumberError
21
+ else ; Error
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ class ValidationError < Error; end
28
+ class UsernameNotFoundError < ValidationError; end
29
+ class PasswordNotFoundError < ValidationError; end
30
+ class TrackingNumberNotFoundError < ValidationError; end
31
+ class AuthenticationError < Error; end
32
+ class ShippingSiteError < Error; end
33
+ class DatabaseError < Error; end
34
+ class BadTrackingNumberError < Error; end
35
+ end
@@ -0,0 +1,21 @@
1
+ module RRD::Request
2
+ class Tracking
3
+
4
+ attr_accessor :tracking_number
5
+
6
+ def initialize(tracking_number)
7
+ @tracking_number = tracking_number
8
+ end
9
+
10
+ def api_params
11
+ {
12
+ id: tracking_number
13
+ }
14
+ end
15
+
16
+ def response_handler(xml)
17
+ RRD::Response::Tracking.new(xml)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ module RRD::Response
2
+ class ShipmentDetail
3
+ attr_accessor :airway_bill,
4
+ :tracking_number,
5
+ :location,
6
+ :status,
7
+ :vendor_code,
8
+ :vendor_name,
9
+ :is_courier
10
+
11
+ def initialize(init)
12
+ init.each_pair do |key, val|
13
+ instance_variable_set('@' + key.to_s, val)
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ module RRD::Response
2
+ class TrackDetail
3
+ attr_accessor :description,
4
+ :location,
5
+ :timestamp
6
+
7
+ def initialize(init)
8
+ init.each_pair do |key, val|
9
+ instance_variable_set('@' + key.to_s, val)
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,43 @@
1
+ module RRD::Response
2
+ class Tracking
3
+ require 'rrd-track/response/shipment_detail'
4
+ require 'rrd-track/response/track_detail'
5
+
6
+ attr_accessor :tracking_events, :shipment_detail
7
+
8
+ def initialize(xml)
9
+ @shipment_detail = parse_shipment_detail(xml.search("ParcelTrackingViewModel"))
10
+ @tracking_events = []
11
+ xml.search("StopDetailViewModel").each do |event|
12
+ @tracking_events << parse_tracking_detail(event)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def parse_shipment_detail(node)
19
+ RRD::Response::ShipmentDetail.new(
20
+ {
21
+ airway_bill: node.search('AirwayBill').text,
22
+ tracking_number: node.search('TrackingNumber').text,
23
+ location: node.search('Location').text,
24
+ status: node.search('Status').text,
25
+ vendor_code: node.search('VendorCode').text,
26
+ vendor_name: node.search('VendorName').text,
27
+ is_courier: node.search('IsCourier').text
28
+ }
29
+ )
30
+ end
31
+
32
+ def parse_tracking_detail(node)
33
+ RRD::Response::TrackDetail.new(
34
+ {
35
+ description: node.search('Description').text,
36
+ location: node.search('Location').text,
37
+ timestamp: node.search('TimeStamp').text
38
+ }
39
+ )
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module RRD
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe RRD do
4
+
5
+ it "tracks shipped packages" do
6
+
7
+ rrd_tracking_xml = File.read("#{Dir.pwd}/spec/rrd_api_responses/shipment_shipped.xml")
8
+
9
+ WebMock.stub_request(:get, "http://www.ppxtrack.com/api/ParcelTracking?id=2043XXXXXX1513").
10
+ with(headers: {'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}).
11
+ to_return(status: 200, body: rrd_tracking_xml)
12
+
13
+ result = RRD::track('2043XXXXXX1513')
14
+
15
+ expect(result).to be_kind_of(RRD::Response::Tracking)
16
+ end
17
+
18
+
19
+ it "tracks shipped packages with two events" do
20
+
21
+ rrd_tracking_xml = File.read("#{Dir.pwd}/spec/rrd_api_responses/shipment_shipped.xml")
22
+
23
+ WebMock.stub_request(:get, "http://www.ppxtrack.com/api/ParcelTracking?id=2043XXXXXX1513").
24
+ with(headers: {'User-Agent'=>'Typhoeus - https://github.com/typhoeus/typhoeus'}).
25
+ to_return(status: 200, body: rrd_tracking_xml)
26
+
27
+ result = RRD::track('2043XXXXXX1513')
28
+
29
+ expect(result.tracking_events.count).to eq(11)
30
+ expect(result.tracking_events.first).to be_kind_of(RRD::Response::TrackDetail)
31
+ end
32
+
33
+
34
+ end
@@ -0,0 +1 @@
1
+ <ParcelTrackingViewModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Rrdl.International.Model.ViewModel"><AirwayBill>3999682</AirwayBill><AirwayBillDisplay>3999682(02)</AirwayBillDisplay><IsCourier>false</IsCourier><LastActivity>2014-02-07T10:09:58</LastActivity><Location>Brampton</Location><Status>Item successfully delivered</Status><Stops><StopDetailViewModel><Description>Item successfully delivered</Description><Location>Brampton</Location><TimeStamp>2014-02-07T10:09:58</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item out for delivery</Description><Location>Brampton</Location><TimeStamp>2014-02-07T08:57:21</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item processed at local delivery facility</Description><Location>Brampton</Location><TimeStamp>2014-02-07T05:34:21</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item processed</Description><Location>Mississauga</Location><TimeStamp>2014-02-06T20:02:32</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item processed</Description><Location>Mississauga</Location><TimeStamp>2014-02-06T19:52:56</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Item picked up by Canada Post</Description><Location>Mississauga</Location><TimeStamp>2014-02-06T19:22:53</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Electronic information submitted by shipper</Description><Location>Mississauga</Location><TimeStamp>2014-02-03T19:34:30</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>In transit to Canada Post tracking#: 7100848307767497</Description><Location></Location><TimeStamp>2014-02-03T14:22:54</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Parcel Shipped</Description><Location>Itasca IL</Location><TimeStamp>2014-02-03T14:21:54</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>Parcel Received</Description><Location>Itasca IL</Location><TimeStamp>2014-02-03T14:07:40</TimeStamp></StopDetailViewModel><StopDetailViewModel><Description>E-File Uploaded</Description><Location>Itasca IL</Location><TimeStamp>2014-02-03T11:59:14</TimeStamp></StopDetailViewModel></Stops><TrackingNumber>7100848307767497</TrackingNumber><VendorCode>02</VendorCode><VendorName>CPC-PARCELS</VendorName></ParcelTrackingViewModel>
@@ -0,0 +1,9 @@
1
+ require 'awesome_print'
2
+ require 'rrd-track'
3
+ require 'webmock/rspec'
4
+
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.order = 'random'
8
+ WebMock.disable_net_connect!(:allow_localhost => true)
9
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rrd-track
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Rocher
@@ -101,12 +101,26 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
+ - ".gitignore"
105
+ - ".travis.yml"
104
106
  - Gemfile
105
107
  - Gemfile.lock
106
108
  - LICENSE.txt
107
109
  - README.md
108
110
  - Rakefile
111
+ - lib/rrd-track.rb
112
+ - lib/rrd-track/client.rb
113
+ - lib/rrd-track/configuration.rb
114
+ - lib/rrd-track/errors.rb
115
+ - lib/rrd-track/request/tracking.rb
116
+ - lib/rrd-track/response/shipment_detail.rb
117
+ - lib/rrd-track/response/track_detail.rb
118
+ - lib/rrd-track/response/tracking.rb
119
+ - lib/rrd-track/version.rb
109
120
  - rrd-track.gemspec
121
+ - spec/rrd-track/track_spec.rb
122
+ - spec/rrd_api_responses/shipment_shipped.xml
123
+ - spec/spec_helper.rb
110
124
  homepage: https://github.com/rochers/rrd-track
111
125
  licenses: []
112
126
  metadata: {}
@@ -130,4 +144,7 @@ rubygems_version: 2.2.2
130
144
  signing_key:
131
145
  specification_version: 4
132
146
  summary: Request, parse, and work with RR Donnelley tracking events.
133
- test_files: []
147
+ test_files:
148
+ - spec/rrd-track/track_spec.rb
149
+ - spec/rrd_api_responses/shipment_shipped.xml
150
+ - spec/spec_helper.rb