melissadata 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|