melissadata 0.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.
- data/Gemfile +31 -0
- data/Gemfile.lock +69 -0
- data/Guardfile +6 -0
- data/README.md +5 -0
- data/Rakefile +47 -0
- data/Vagrantfile +17 -0
- data/bin/md +4 -0
- data/bin/md-rpc +9 -0
- data/bin/md-server +18 -0
- data/bin/melissadata +4 -0
- data/lib/md.rb +4 -0
- data/lib/melissadata.rb +2 -0
- data/lib/melissadata/cli.rb +45 -0
- data/lib/melissadata/command.rb +9 -0
- data/lib/melissadata/command/base.rb +104 -0
- data/lib/melissadata/command/helpers.rb +12 -0
- data/lib/melissadata/command/package.rb +83 -0
- data/lib/melissadata/constants.rb +14 -0
- data/lib/melissadata/env.rb +92 -0
- data/lib/melissadata/errors.rb +83 -0
- data/lib/melissadata/melissadata.rb +164 -0
- data/lib/melissadata/native_object.rb +19 -0
- data/lib/melissadata/native_object/address.rb +124 -0
- data/lib/melissadata/native_object/base.rb +79 -0
- data/lib/melissadata/native_object/client.rb +33 -0
- data/lib/melissadata/native_object/email.rb +61 -0
- data/lib/melissadata/native_object/geo.rb +61 -0
- data/lib/melissadata/native_object/ip_locator.rb +41 -0
- data/lib/melissadata/native_object/name.rb +74 -0
- data/lib/melissadata/native_object/phone.rb +96 -0
- data/lib/melissadata/prev/command_old.rb +80 -0
- data/lib/melissadata/prev/shared_objects.rb +54 -0
- data/lib/melissadata/rpc.rb +39 -0
- data/lib/melissadata/version.rb +3 -0
- data/melissadata.gemspec +40 -0
- data/pkg/melissa-data-0.0.1.gem +0 -0
- data/pkg/melissa-data-0.0.2.gem +0 -0
- data/pkg/melissa-data-0.0.3.gem +0 -0
- data/pkg/melissadata-0.0.1.gem +0 -0
- data/spec/locales/en.yml +8 -0
- data/spec/melissadata/cli_spec.rb +34 -0
- data/spec/melissadata/command/package_spec.rb +22 -0
- data/spec/melissadata/env_spec.rb +55 -0
- data/spec/spec_helper.rb +33 -0
- data/templates/config.rb +20 -0
- data/templates/locales/en.yml +4 -0
- metadata +316 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
module MelissaData
|
2
|
+
# Constants used by the system to access data.
|
3
|
+
module Constants
|
4
|
+
# Default execution address
|
5
|
+
DEFAULT_ADDRESS = '0.0.0.0'
|
6
|
+
|
7
|
+
# Default execution port
|
8
|
+
DEFAULT_PORT = 6000
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module MelissaData
|
13
|
+
include Constants
|
14
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module MelissaData
|
2
|
+
# MelissaData::Env also provides access to the logger, configuration information
|
3
|
+
# and anything else set into the config data during initialization.
|
4
|
+
class Env < Hash
|
5
|
+
include Constants
|
6
|
+
|
7
|
+
# Create a new MelissaData::Env object
|
8
|
+
#
|
9
|
+
# @return [MelissaData::Env] The MelissaData::Env object
|
10
|
+
def initialize
|
11
|
+
self[:start_time] = Time.now.to_f
|
12
|
+
self[:time] = Time.now.to_f
|
13
|
+
self[:trace] = []
|
14
|
+
end
|
15
|
+
|
16
|
+
# Add a trace timer with the given name into the environment. The tracer will
|
17
|
+
# provide information on the amount of time since the previous call to {#trace}
|
18
|
+
# or since the MelissaData::Env object was initialized.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# trace("initialize hash")
|
22
|
+
# ....
|
23
|
+
# trace("Do something else")
|
24
|
+
#
|
25
|
+
# @param name [String] The name of the trace to add
|
26
|
+
def trace(name)
|
27
|
+
self[:trace].push([name, "%.2f" % ((Time.now.to_f - self[:time]) * 1000)])
|
28
|
+
self[:time] = Time.now.to_f
|
29
|
+
end
|
30
|
+
|
31
|
+
# Retrieve the tracer stats for this request environment. This can then be
|
32
|
+
# returned in the headers hash to in development to provide some simple
|
33
|
+
# timing information for the various API components.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# [200, {}, {:meta => {:trace => env.trace_stats}}, {}]
|
37
|
+
#
|
38
|
+
# @return [Array] Array of [name, time] pairs with a Total entry added.
|
39
|
+
def trace_stats
|
40
|
+
self[:trace] + [['total', self[:trace].collect { |s| s[1].to_f }.inject(:+).to_s]]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Convenience method for accessing the rack.logger item in the environment.
|
44
|
+
#
|
45
|
+
# @return [Logger] The logger object
|
46
|
+
def logger
|
47
|
+
return @logger if @logger
|
48
|
+
|
49
|
+
# Figure out where the output should go to.
|
50
|
+
output = nil
|
51
|
+
if ENV["MELISSADATA_LOG"] == "STDOUT"
|
52
|
+
output = STDOUT
|
53
|
+
elsif ENV["MELISSADATA_LOG"] == "NULL"
|
54
|
+
output = nil
|
55
|
+
elsif ENV["MELISSADATA_LOG"]
|
56
|
+
output = ENV["MELISSADATA_LOG"]
|
57
|
+
else
|
58
|
+
output = nil #log_path.join("#{Time.now.to_i}.log")
|
59
|
+
end
|
60
|
+
|
61
|
+
# Create the logger and custom formatter
|
62
|
+
@logger = Logger.new(output)
|
63
|
+
@logger.formatter = Proc.new do |severity, datetime, progname, msg|
|
64
|
+
"#{datetime} - #{progname} - [#{resource}] #{msg}\n"
|
65
|
+
end
|
66
|
+
|
67
|
+
@logger
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param name [Symbol] The method to check if we respond to it.
|
71
|
+
# @return [Boolean] True if the Env responds to the method, false otherwise
|
72
|
+
def respond_to?(name)
|
73
|
+
return true if has_key?(name.to_s)
|
74
|
+
return true if self['config'] && self['config'].has_key?(name.to_s)
|
75
|
+
super
|
76
|
+
end
|
77
|
+
|
78
|
+
# The MelissaData::Env will provide any of it's keys as a method. It will also provide
|
79
|
+
# any of the keys in the config object as methods. The methods will return
|
80
|
+
# the value of the key. If the key doesn't exist in either hash this will
|
81
|
+
# fall back to the standard method_missing implementation.
|
82
|
+
#
|
83
|
+
# @param name [Symbol] The method to look for
|
84
|
+
# @param args The arguments
|
85
|
+
# @param blk A block
|
86
|
+
def method_missing(name, *args, &blk)
|
87
|
+
return self[name.to_s] if has_key?(name.to_s)
|
88
|
+
return self['config'][name.to_s] if self['config'] && self['config'].has_key?(name.to_s)
|
89
|
+
super(name, *args, &blk)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# This file contains all of the internal errors in MelissaData's core
|
2
|
+
# commands, actions, etc.
|
3
|
+
|
4
|
+
module MelissaData
|
5
|
+
# This module contains all of the internal errors in MelissaData's core.
|
6
|
+
# These errors are _expected_ errors and as such don't typically represent
|
7
|
+
# bugs in MelissaData itself. These are meant as a way to detect errors and
|
8
|
+
# display them in a user-friendly way.
|
9
|
+
#
|
10
|
+
# # Defining a new Error
|
11
|
+
#
|
12
|
+
# To define a new error, inherit from {MelissaDataError}, which lets MelissaData
|
13
|
+
# know that this is an expected error, and also gives you some helpers for
|
14
|
+
# providing exit codes and error messages. An example is shown below, then
|
15
|
+
# it is explained:
|
16
|
+
#
|
17
|
+
# class MyError < MelissaData::Errors::MelissaDataError
|
18
|
+
# error_key "my_error"
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# This creates an error with an I18n error key of "my_error." {MelissaDataError}
|
22
|
+
# uses I18n to look up error messages, in the "melissadata.errors" namespace. So
|
23
|
+
# in the above, the error message would be the translation of "melissadata.errors.my_error"
|
24
|
+
#
|
25
|
+
# If you don't want to use I18n, you can override the {#initialize} method and
|
26
|
+
# set your own error message.
|
27
|
+
#
|
28
|
+
# # Raising an Error
|
29
|
+
#
|
30
|
+
# To raise an error, it is nothing special, just raise it like any normal
|
31
|
+
# exception:
|
32
|
+
#
|
33
|
+
# raise MyError.new
|
34
|
+
#
|
35
|
+
# Eventually this exception will bubble out to the `melissadata` binary which
|
36
|
+
# will show a nice error message. And if it is raised in the middle of a
|
37
|
+
# middleware sequence, then {Action::Warden} will catch it and begin the
|
38
|
+
# recovery process prior to exiting.
|
39
|
+
module Errors
|
40
|
+
# Main superclass of any errors in MelissaData. This provides some
|
41
|
+
# convenience methods for setting the error key. The error key is
|
42
|
+
# used as a default message from I18n.
|
43
|
+
class MelissaDataError < StandardError
|
44
|
+
def self.error_key(key=nil, namespace=nil)
|
45
|
+
define_method(:error_key) { key }
|
46
|
+
error_namespace(namespace) if namespace
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.error_namespace(namespace)
|
50
|
+
define_method(:error_namespace) { namespace }
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(message=nil, *args)
|
54
|
+
message = { :_key => message } if message && !message.is_a?(Hash)
|
55
|
+
message = { :_key => error_key, :_namespace => error_namespace }.merge(message || {})
|
56
|
+
message = translate_error(message)
|
57
|
+
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
61
|
+
# The default error namespace which is used for the error key.
|
62
|
+
# This can be overridden here or by calling the "error_namespace"
|
63
|
+
# class method.
|
64
|
+
def error_namespace; "melissadata.errors"; end
|
65
|
+
|
66
|
+
# The key for the error message. This should be set using the
|
67
|
+
# {error_key} method but can be overridden here if needed.
|
68
|
+
def error_key; nil; end
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
def translate_error(opts)
|
73
|
+
return nil if !opts[:_key]
|
74
|
+
I18n.t("#{opts[:_namespace]}.#{opts[:_key]}", opts)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class DiscNotFound < MelissaDataError
|
79
|
+
error_key(:disc_not_found)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__)) unless $LOAD_PATH.include?(File.expand_path('..', File.dirname(__FILE__)))
|
2
|
+
require 'pathname'
|
3
|
+
require 'i18n'
|
4
|
+
require 'thor'
|
5
|
+
require 'thor/group'
|
6
|
+
require 'thor/actions'
|
7
|
+
require 'active_support/core_ext'
|
8
|
+
|
9
|
+
module MelissaData
|
10
|
+
module_function
|
11
|
+
|
12
|
+
autoload :Env, 'melissadata/env'
|
13
|
+
autoload :CLI, 'melissadata/cli'
|
14
|
+
autoload :Errors, 'melissadata/errors'
|
15
|
+
autoload :Constants, 'melissadata/constants'
|
16
|
+
|
17
|
+
ENVIRONMENTS = [:development, :production, :test, :staging]
|
18
|
+
|
19
|
+
# Retrieves the current melissadata environment
|
20
|
+
#
|
21
|
+
# @return [String] the current environment
|
22
|
+
def env
|
23
|
+
@env or fail "environment has not been set"
|
24
|
+
end
|
25
|
+
|
26
|
+
# Sets the current melissadata environment
|
27
|
+
#
|
28
|
+
# @param [String|Symbol] env the environment symbol of [dev | development | prod | production | test]
|
29
|
+
def env=(e)
|
30
|
+
es = case(e.to_sym)
|
31
|
+
when :dev then :development
|
32
|
+
when :prod then :production
|
33
|
+
else e.to_sym
|
34
|
+
end
|
35
|
+
|
36
|
+
if ENVIRONMENTS.include?(es)
|
37
|
+
@env = es
|
38
|
+
else
|
39
|
+
fail "did not recognize environment: #{e}, expected one of: #{ENVIRONMENTS.join(', ')}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Determines if we are in the production environment
|
44
|
+
#
|
45
|
+
# @return [Boolean] true if current environment is production, false otherwise
|
46
|
+
def prod?
|
47
|
+
env == :production
|
48
|
+
end
|
49
|
+
|
50
|
+
# Determines if we are in the development environment
|
51
|
+
#
|
52
|
+
# @return [Boolean] true if current environment is development, false otherwise
|
53
|
+
def dev?
|
54
|
+
env == :development
|
55
|
+
end
|
56
|
+
|
57
|
+
# Determines if we are in the test environment
|
58
|
+
#
|
59
|
+
# @return [Boolean] true if current environment is test, false otherwise
|
60
|
+
def test?
|
61
|
+
env == :test
|
62
|
+
end
|
63
|
+
|
64
|
+
# Determines if we are in the staging environment
|
65
|
+
#
|
66
|
+
# @return [Boolean] true if current environment is staging.
|
67
|
+
def staging?
|
68
|
+
env == :staging
|
69
|
+
end
|
70
|
+
|
71
|
+
def gem_root
|
72
|
+
@gem_root ||= Pathname.new(File.expand_path('../../../', __FILE__))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
I18n.load_path << File.expand_path("templates/locales/en.yml", MelissaData.gem_root)
|
77
|
+
|
78
|
+
require 'melissadata/command'
|
79
|
+
require 'melissadata/version'
|
80
|
+
|
81
|
+
|
82
|
+
# require 'rubygems'
|
83
|
+
# require 'active_support/core_ext'
|
84
|
+
# require 'melissadata/constants'
|
85
|
+
# require 'melissadata/commands'
|
86
|
+
# require 'melissadata/exceptions'
|
87
|
+
|
88
|
+
# module MelissaData
|
89
|
+
# module_function
|
90
|
+
|
91
|
+
# ENVIRONMENTS = [:development, :production, :vagrant, :test, :staging]
|
92
|
+
|
93
|
+
# # Retrieves the current MelissaData environment
|
94
|
+
# #
|
95
|
+
# # @return [String] the current environment
|
96
|
+
# def env
|
97
|
+
# @env or fail "environment has not been set"
|
98
|
+
# end
|
99
|
+
|
100
|
+
# # Sets the current MelissaData environment
|
101
|
+
# #
|
102
|
+
# # @param [String|Symbol] env the environment symbol of [dev | development | prod | production | test]
|
103
|
+
# def env=(e)
|
104
|
+
# es = case(e.to_sym)
|
105
|
+
# when :dev then :development
|
106
|
+
# when :prod then :production
|
107
|
+
# else e.to_sym
|
108
|
+
# end
|
109
|
+
|
110
|
+
# if ENVIRONMENTS.include?(es)
|
111
|
+
# @env = es
|
112
|
+
# else
|
113
|
+
# fail "did not recognize environment: #{e}, expected one of: #{ENVIRONMENTS.join(', ')}"
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
|
117
|
+
# def client=(c)
|
118
|
+
# @client = c
|
119
|
+
# end
|
120
|
+
|
121
|
+
# def client
|
122
|
+
# raise "Client has not yet been setup" if @client.nil?
|
123
|
+
# @client
|
124
|
+
# end
|
125
|
+
|
126
|
+
# def lib_path
|
127
|
+
# @lib_path ||= File.dirname(__FILE__)
|
128
|
+
# end
|
129
|
+
|
130
|
+
# # Determines if we are in the production environment
|
131
|
+
# #
|
132
|
+
# # @return [Boolean] true if current environment is production, false otherwise
|
133
|
+
# def prod?
|
134
|
+
# env == :production
|
135
|
+
# end
|
136
|
+
|
137
|
+
# # Determines if we are in the development environment
|
138
|
+
# #
|
139
|
+
# # @return [Boolean] true if current environment is development, false otherwise
|
140
|
+
# def dev?
|
141
|
+
# env == :development
|
142
|
+
# end
|
143
|
+
|
144
|
+
# # Determines if we are in the test environment
|
145
|
+
# #
|
146
|
+
# # @return [Boolean] true if current environment is test, false otherwise
|
147
|
+
# def test?
|
148
|
+
# env == :test
|
149
|
+
# end
|
150
|
+
|
151
|
+
# # Determines if we are in the staging environment
|
152
|
+
# #
|
153
|
+
# # @return [Boolean] true if current environment is staging.
|
154
|
+
# def staging?
|
155
|
+
# env == :staging
|
156
|
+
# end
|
157
|
+
|
158
|
+
# # Determines if we are in the vagrant environment
|
159
|
+
# #
|
160
|
+
# # @return [Boolean] true if current environment is vagrant.
|
161
|
+
# def vagrant?
|
162
|
+
# env == :vagrant
|
163
|
+
# end
|
164
|
+
# end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MelissaData
|
2
|
+
module NativeObject
|
3
|
+
autoload :Base, 'melissadata/native_object/base'
|
4
|
+
autoload :Client, 'melissadata/native_object/client'
|
5
|
+
|
6
|
+
autoload :Address, 'melissadata/native_object/address'
|
7
|
+
autoload :Email, 'melissadata/native_object/email'
|
8
|
+
autoload :Geo, 'melissadata/native_object/geo'
|
9
|
+
autoload :IpLocator, 'melissadata/native_object/ip_locator'
|
10
|
+
autoload :Name, 'melissadata/native_object/name'
|
11
|
+
autoload :Phone, 'melissadata/native_object/phone'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
%w[
|
16
|
+
mdAddrRubyWrapper mdEmailRubyWrapper mdGeoRubyWrapper mdNameRubyWrapper mdPhoneRubyWrapper mdIpLocatorRubyWrapper
|
17
|
+
].each do |obj|
|
18
|
+
require File.join('/opt/melissadata/lib', obj)
|
19
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module MelissaData::NativeObject
|
2
|
+
class Address < Base
|
3
|
+
def initialize(opts={})
|
4
|
+
@obj = MdAddrRubyWrapper::MdAddr.new
|
5
|
+
obj.SetPathToUSFiles(data_dir)
|
6
|
+
obj.SetUseUSPSPreferredCityNames(1)
|
7
|
+
|
8
|
+
@result_codes = [
|
9
|
+
['AS01', "Address matched to postal database"],
|
10
|
+
['AS09', "Foreign postal code detected"],
|
11
|
+
['AS10', "Address matched to CMRA"],
|
12
|
+
['AS12', "Address deliverable by non-USPS carriers"],
|
13
|
+
['AS13', "Address has been updated by LACS"],
|
14
|
+
['AS14', "Suite appended by SuiteLink"],
|
15
|
+
['AS15', "Suite appended by AddressPlus"],
|
16
|
+
['AS16', "Address is vacant"],
|
17
|
+
['AS17', "Alternate delivery"],
|
18
|
+
['AE01', "Zip code"],
|
19
|
+
['AE02', "Unknown street"],
|
20
|
+
['AE03', "Component mismatch"],
|
21
|
+
['AE04', "Non-deliverable address"],
|
22
|
+
['AE05', "Multiple match"],
|
23
|
+
['AE06', "Early warning system error"],
|
24
|
+
['AE07', "Missing minimum address input"],
|
25
|
+
['AE08', "Suite range invalid"],
|
26
|
+
['AE09', "Suite range missing"],
|
27
|
+
['AE10', "Primary range invalid"],
|
28
|
+
['AE11', "Primary range missing"],
|
29
|
+
['AE12', "PO, HC, or RR box number invalid"],
|
30
|
+
['AE13', "PO, HC, or RR box number missing"],
|
31
|
+
['AE14', "CMRA secondary missing"],
|
32
|
+
['AE15', "Demo mode"],
|
33
|
+
['AE16', "Expired database"]
|
34
|
+
]
|
35
|
+
|
36
|
+
@defaults = {
|
37
|
+
:company => '',
|
38
|
+
:address => '',
|
39
|
+
:address2 => '',
|
40
|
+
:city => '',
|
41
|
+
:state => '',
|
42
|
+
:zip => '',
|
43
|
+
:last_name => ''
|
44
|
+
}
|
45
|
+
|
46
|
+
# At least one of these needs to be present
|
47
|
+
@required_fields = [:address, :city, :state, :zip]
|
48
|
+
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_input
|
53
|
+
obj.ClearProperties
|
54
|
+
obj.SetCompany input[:company].to_s
|
55
|
+
obj.SetAddress input[:address].to_s
|
56
|
+
obj.SetAddress2 input[:address2].to_s
|
57
|
+
obj.SetCity input[:city].to_s
|
58
|
+
obj.SetState input[:state].to_s
|
59
|
+
obj.SetZip input[:zip].to_s
|
60
|
+
obj.SetLastName input[:last_name].to_s
|
61
|
+
|
62
|
+
obj.VerifyAddress
|
63
|
+
end
|
64
|
+
|
65
|
+
def assign_values
|
66
|
+
@output = {
|
67
|
+
:company => obj.GetCompany,
|
68
|
+
:address => obj.GetAddress,
|
69
|
+
:address2 => obj.GetAddress2,
|
70
|
+
:suite => obj.GetSuite,
|
71
|
+
:city => obj.GetCity,
|
72
|
+
:state => obj.GetState,
|
73
|
+
:zip => obj.GetZip,
|
74
|
+
:plus4 => obj.GetPlus4,
|
75
|
+
:country_code => obj.GetCountryCode,
|
76
|
+
:urbanization => obj.GetUrbanization,
|
77
|
+
|
78
|
+
:parsed_address_range => obj.GetParsedAddressRange,
|
79
|
+
:parsed_pre_direction => obj.GetParsedPreDirection,
|
80
|
+
:parsed_street_name => obj.GetParsedStreetName,
|
81
|
+
:parsed_post_direction => obj.GetParsedPostDirection,
|
82
|
+
:parsed_suffix => obj.GetParsedSuffix,
|
83
|
+
:parsed_suite_name => obj.GetParsedSuiteName,
|
84
|
+
:parsed_suite_range => obj.GetParsedSuiteRange,
|
85
|
+
:parsed_garbage => obj.GetParsedGarbage,
|
86
|
+
:parsed_private_mailbox_name => obj.GetParsedPrivateMailboxName,
|
87
|
+
:parsed_private_mailbox_number => obj.GetParsedPrivateMailboxNumber,
|
88
|
+
|
89
|
+
:carrier_route => obj.GetCarrierRoute,
|
90
|
+
:delivery_point_code => obj.GetDeliveryPointCode,
|
91
|
+
:delivery_point_check_digit => obj.GetDeliveryPointCheckDigit,
|
92
|
+
|
93
|
+
:address_type_code => obj.GetAddressTypeCode,
|
94
|
+
:address_type_string => obj.GetAddressTypeString,
|
95
|
+
|
96
|
+
:city_abbrev => obj.GetCityAbbreviation,
|
97
|
+
|
98
|
+
:cmra => obj.GetCMRA, # Commercial Mail Receiving Agency
|
99
|
+
:private_mailbox => obj.GetPrivateMailbox, # mailbox number at the CMRA
|
100
|
+
|
101
|
+
:msa => obj.GetMsa,
|
102
|
+
:pmsa => obj.GetPmsa,
|
103
|
+
|
104
|
+
:time_zone => obj.GetTimeZone,
|
105
|
+
:time_zone_code => obj.GetTimeZoneCode,
|
106
|
+
|
107
|
+
:county_name => obj.GetCountyName,
|
108
|
+
:county_fips => obj.GetCountyFips,
|
109
|
+
:congressional_district => obj.GetCongressionalDistrict,
|
110
|
+
:zip_type_code => obj.GetZipType
|
111
|
+
}
|
112
|
+
|
113
|
+
output[:zip_type] = case output[:zip_type_code]
|
114
|
+
when 'P' then 'PO Boxes only'
|
115
|
+
when 'U' then 'Unique - organization or government'
|
116
|
+
when 'M' then 'Military'
|
117
|
+
else 'Standard'
|
118
|
+
end
|
119
|
+
|
120
|
+
output[:zip9] = "#{output[:zip]}-#{output[:plus4]}" if output[:plus4].present?
|
121
|
+
output[:zip11] = "#{output[:zip9]}-#{output[:delivery_point_code]}" if output[:delivery_point_code].present?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|