tracking_number 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
data/lib/base.rb CHANGED
@@ -6,12 +6,24 @@ class TrackingNumber
6
6
  @tracking_number = tracking_number.gsub(" ", "").upcase
7
7
  end
8
8
 
9
- def self.search(body)
10
- self.scan(body).uniq.collect { |possible| new(possible) }.select { |t| t.valid? }
9
+ def self.search(body)
10
+ valids = self.scan(body).uniq.collect { |possible| new(possible) }.select { |t| t.valid? }
11
+
12
+ uniques = {}
13
+ valids.each do |t|
14
+ uniques[t.tracking_number] = t unless uniques.has_key?(t.tracking_number)
15
+ end
16
+
17
+ uniques.values
11
18
  end
12
19
 
13
20
  def self.scan(body)
14
- possibles = body.scan(self.const_get("SEARCH_PATTERN")).uniq.flatten
21
+ patterns = [self.const_get("SEARCH_PATTERN")].flatten
22
+ possibles = patterns.collect do |pattern|
23
+ body.scan(pattern).uniq.flatten
24
+ end
25
+
26
+ possibles.flatten.compact.uniq
15
27
  end
16
28
 
17
29
  def valid?
data/lib/usps.rb CHANGED
@@ -6,12 +6,10 @@ class TrackingNumber
6
6
  end
7
7
 
8
8
  class USPS91 < USPS
9
- SEARCH_PATTERN = /(\b9\s*1\s*(([0-9]\s*){20,20}\b))/
9
+ SEARCH_PATTERN = [/(\b9\s*1\s*(([0-9]\s*){20,20}\b))/, /(\b([0-9]\s*){20,20}\b)/]
10
10
  VERIFY_PATTERN = /^(91[0-9]{19,19})([0-9])$/
11
-
12
- def matches
13
- self.tracking_number.scan(VERIFY_PATTERN).flatten
14
- end
11
+
12
+ # Sometimes these numbers will appear without the leading 91, though, so we need to account for that case
15
13
 
16
14
  def decode
17
15
  # Application ID: 91
@@ -28,8 +26,30 @@ class TrackingNumber
28
26
  }
29
27
  end
30
28
 
29
+ def matches
30
+ if self.tracking_number =~ /^91/
31
+ self.tracking_number.scan(VERIFY_PATTERN).flatten
32
+ else
33
+ "91#{self.tracking_number}".scan(VERIFY_PATTERN).flatten
34
+ end
35
+ end
36
+
31
37
  def valid_checksum?
32
- chars = tracking_number.chars.to_a
38
+ if self.tracking_number =~ /^91/
39
+ return true if weighted_usps_checksum_valid?(tracking_number)
40
+ else
41
+ if weighted_usps_checksum_valid?("91#{self.tracking_number}")
42
+ # set the tracking number to the 91 format if it passes this test
43
+ self.tracking_number = "91#{self.tracking_number}"
44
+ return true
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def weighted_usps_checksum_valid?(sequence)
52
+ chars = sequence.chars.to_a
33
53
  check_digit = chars.pop
34
54
 
35
55
  total = 0
@@ -47,6 +67,9 @@ class TrackingNumber
47
67
  end
48
68
 
49
69
  class USPS20 < USPS
70
+ # http://www.usps.com/cpim/ftp/pubs/pub109.pdf (Publication 109. Extra Services Technical Guide, pg. 19)
71
+ # http://www.usps.com/cpim/ftp/pubs/pub91.pdf (Publication 91. Confirmation Services Technical Guide pg. 38)
72
+
50
73
  SEARCH_PATTERN = /(\b([0-9]\s*){20,20}\b)/
51
74
  VERIFY_PATTERN = /^([0-9]{2,2})([0-9]{9,9})([0-9]{8,8})([0-9])$/
52
75
 
@@ -83,7 +106,6 @@ class TrackingNumber
83
106
  chars.reverse.each_with_index do |c, i|
84
107
  x = c.to_i
85
108
  x *= 3 if i.even?
86
-
87
109
  total += x
88
110
  end
89
111
 
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class USPSTrackingNumberTest < Test::Unit::TestCase
4
4
  context "a USPS tracking number" do
5
- ["9101 1234 5678 9000 0000 13"].each do |valid_number|
5
+ ["9101 1234 5678 9000 0000 13", "7196 9010 7560 0307 7385"].each do |valid_number|
6
6
  should "return usps with valid 22 digit number: #{valid_number}" do
7
7
  t = TrackingNumber.new("9101 1234 5678 9000 0000 13")
8
8
  assert_equal TrackingNumber::USPS91, t.class
@@ -15,8 +15,6 @@ class USPSTrackingNumberTest < Test::Unit::TestCase
15
15
  end
16
16
  end
17
17
 
18
- # Actual tracking number I got from the USPS that doesn't validate. UGghhh
19
- #"7196 9010 7560 0307 7385",
20
18
  ["0307 1790 0005 2348 3741"].each do |valid_number|
21
19
  should "detect #{valid_number} regardless of spacing" do
22
20
  should_detect_number_variants(valid_number, TrackingNumber::USPS20)
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{tracking_number}
8
- s.version = "0.3.0"
8
+ s.version = "0.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jeff Keen"]
12
- s.date = %q{2011-02-09}
12
+ s.date = %q{2011-02-22}
13
13
  s.description = %q{Match tracking numbers to a service, and search blocks of text and pull out valid tracking numbers.}
14
14
  s.email = %q{jeff@keen.me}
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tracking_number
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 0
10
- version: 0.3.0
9
+ - 1
10
+ version: 0.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeff Keen
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-09 00:00:00 -06:00
18
+ date: 2011-02-22 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency