Class: CarrierInfo::Sources::Safer

Inherits:
Object
  • Object
show all
Defined in:
lib/carrier_info/sources/safer.rb

Constant Summary collapse

EQUIPMENT_CARGO_CARRIED =
{
  equipment_vans: ["General Freight", "US Mail", "Paper Products"],
  equipment_household_vans: ["Household Goods"],
  equipment_flatbeds: ["Metal: sheets, coils, rolls", "Logs, Poles, Beams, Lumber", "Building Materials", "Construction", "Machinery, Large Objects"],
  equipment_car_carriers: ["Motor Vehicles"],
  equipment_tow_trucks: ["Drive/Tow away"],
  equipment_mobile_homes: ["Mobile Homes"],
  equipment_reefers: ["Fresh Produce", "Meat", "Refrigerated Food"],
  equipment_tanks: ["Liquids/Gases", "Chemicals"],
  equipment_intermodal_containers: ["Intermodal Cont."],
  equipment_buses: ["Passengers"],
  equipment_livestock_rack: ["Livestock"],
  equipment_hopper_bottom: ["Commodities Dry Bulk", "Grain, Feed, Hay", "Agricultural/Farm Supplies"],
  equipment_coal_trailers: ["Coal/Coke"],
  equipment_garbage_trucks: ["Garbage/Refuse"],
  equipment_beverage_trucks: ["Beverages"],
  equipment_utility_trucks: ["Utilities"],
  equipment_well_trucks: ["Water Well"]
}
CLASSIFICATION_LABEL =
{
  classification_authorized_for_hire: "Auth. For Hire",
  classification_exempt_for_hire: "Exempt For Hire",
  classification_private_property: "Private(Property)",
  classification_private_passenger_business: "Priv. Pass. (Business)",
  classification_private_passenger_non_business: "Priv. Pass.(Non-business)",
  classification_migrant: "Migrant",
  classification_us_mail: "U.S. Mail",
  classification_federal_government: "Fed. Gov't",
  classification_state_government: "State Gov't",
  classification_local_government: "Local Gov't",
  classification_indian_tribe: "Indian Nation",
  classification_other: "Other"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(carrier) ⇒ Safer

Returns a new instance of Safer.



42
43
44
# File 'lib/carrier_info/sources/safer.rb', line 42

def initialize(carrier)
  @carrier = carrier
end

Instance Attribute Details

#carrierObject

Returns the value of attribute carrier.



40
41
42
# File 'lib/carrier_info/sources/safer.rb', line 40

def carrier
  @carrier
end

#contentObject

Returns the value of attribute content.



40
41
42
# File 'lib/carrier_info/sources/safer.rb', line 40

def content
  @content
end

Instance Method Details

#parse!Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/carrier_info/sources/safer.rb', line 72

def parse!
  carrier.safer_active          = parse_safer_active
  if carrier.safer_active
    carrier.usdot_number        = parse_usdot_number
    carrier.docket_prefix       = parse_docket_prefix
    carrier.docket_number       = parse_docket_number
    carrier.legal_name          = parse_legal_name
    carrier.dba_name            = parse_dba_name
    carrier.phone               = parse_phone
    carrier.power_units         = parse_power_units
    carrier.drivers             = parse_drivers
    carrier.duns_number         = parse_duns_number
    carrier.state_id_number     = parse_state_id_number
    carrier.mcs_150_form_date   = parse_mcs_150_form_date
    carrier.mcs_150_mileage     = parse_mcs_150_mileage
    carrier.mcs_150_mileage_year = parse_mcs_150_mileage_year
    carrier.out_of_service_date = parse_out_of_service_date
    carrier.operating_status    = parse_operating_status
    carrier.entity_type         = parse_entity_type
    [:physical, :mailing].each do |type|
      [:street, :city, :state, :postal_code].each do |address|
        carrier.send("#{type}_#{address}=", parse_address(type, address))
      end
    end
    carrier.equipment_names.each do |equipment_name|
      carrier.send("#{equipment_name}=", parse_equipment(equipment_name))
    end
    carrier.interstate          = parse_interstate
    carrier.instrastate_non_hazardous = parse_intrastate_non_hazardous
    carrier.intrastate_hazardous = parse_intrastate_hazardous
    carrier.classification_names.each do |classification_name|
      carrier.send("#{classification_name}=", parse_classification(classification_name))
    end
    carrier.safer_last_updated = parse_safer_last_updated
  end
end

#parse_address(type, part) ⇒ Object



198
199
200
201
# File 'lib/carrier_info/sources/safer.rb', line 198

def parse_address(type, part)
  address = parse_standard_info_field("#{type.to_s.titleize} Address")
  send("parse_#{part}", address)
end

#parse_checkbox_field(field_name) ⇒ Object



228
229
230
231
232
233
234
235
# File 'lib/carrier_info/sources/safer.rb', line 228

def parse_checkbox_field(field_name)
  if label = response.xpath(%Q(//font[text()="#{field_name}"])).first
    check_box = label.parent.previous_element
    check_box.text == "X" ? true : false        
  else
    false
  end
end

#parse_city(address) ⇒ Object



207
208
209
# File 'lib/carrier_info/sources/safer.rb', line 207

def parse_city(address)
  address.split("\n")[1].split(",")[0].strip
end

#parse_classification(classification_name) ⇒ Object



249
250
251
# File 'lib/carrier_info/sources/safer.rb', line 249

def parse_classification(classification_name)
  parse_checkbox_field(CLASSIFICATION_LABEL[classification_name])
end

#parse_dba_nameObject



125
126
127
# File 'lib/carrier_info/sources/safer.rb', line 125

def parse_dba_name
  parse_standard_info_field("DBA Name")
end

#parse_docket_numberObject



150
151
152
153
# File 'lib/carrier_info/sources/safer.rb', line 150

def parse_docket_number
  docket = parse_standard_info_field("MC or MX Number")
  docket.split("-")[1].to_i if docket =~ /-/
end

#parse_docket_prefixObject



145
146
147
148
# File 'lib/carrier_info/sources/safer.rb', line 145

def parse_docket_prefix
  docket = parse_standard_info_field("MC or MX Number")
  docket.split("-")[0] if docket =~ /-/
end

#parse_driversObject



137
138
139
# File 'lib/carrier_info/sources/safer.rb', line 137

def parse_drivers
  parse_standard_info_field("Drivers", integer: true)
end

#parse_duns_numberObject



155
156
157
158
# File 'lib/carrier_info/sources/safer.rb', line 155

def parse_duns_number
  duns = parse_standard_info_field("DUNS Number", integer: true)
  duns == 0 ? nil : duns
end

#parse_entity_typeObject



194
195
196
# File 'lib/carrier_info/sources/safer.rb', line 194

def parse_entity_type
  parse_standard_info_field("Entity Type")
end

#parse_equipment(equipment_name) ⇒ Object



221
222
223
224
225
226
# File 'lib/carrier_info/sources/safer.rb', line 221

def parse_equipment(equipment_name)
  !!EQUIPMENT_CARGO_CARRIED[equipment_name].find do |cargo_carried|
    check_box = response.xpath("//font[text()='#{cargo_carried}']").first.parent.previous_element
    check_box.text == "X" ? true : false
  end     
end

#parse_interstateObject



237
238
239
# File 'lib/carrier_info/sources/safer.rb', line 237

def parse_interstate
  parse_checkbox_field("Interstate")
end

#parse_intrastate_hazardousObject



245
246
247
# File 'lib/carrier_info/sources/safer.rb', line 245

def parse_intrastate_hazardous
  parse_checkbox_field("Intrastate Only (HM)")
end

#parse_intrastate_non_hazardousObject



241
242
243
# File 'lib/carrier_info/sources/safer.rb', line 241

def parse_intrastate_non_hazardous
  parse_checkbox_field("Intrastate Only (Non-HM)")
end


121
122
123
# File 'lib/carrier_info/sources/safer.rb', line 121

def parse_legal_name
  parse_standard_info_field("Legal Name")
end

#parse_mcs_150_form_dateObject



164
165
166
167
# File 'lib/carrier_info/sources/safer.rb', line 164

def parse_mcs_150_form_date
  date_parts = parse_standard_info_field("MCS-150 Form Date").split("/").collect(&:to_i)
  Date.new(date_parts[2], date_parts[0], date_parts[1]) if date_parts.count == 3
end

#parse_mcs_150_mileageObject



169
170
171
172
# File 'lib/carrier_info/sources/safer.rb', line 169

def parse_mcs_150_mileage
  parts = parse_standard_info_field("MCS-150 Mileage (Year)").split(" ")
  parts[0].gsub(/\D/,"").to_i if parts.count == 2
end

#parse_mcs_150_mileage_yearObject



174
175
176
177
# File 'lib/carrier_info/sources/safer.rb', line 174

def parse_mcs_150_mileage_year
  parts = parse_standard_info_field("MCS-150 Mileage (Year)").split(" ")
  parts[1].gsub(/\D/,"").to_i if parts.count == 2
end

#parse_operating_statusObject



190
191
192
# File 'lib/carrier_info/sources/safer.rb', line 190

def parse_operating_status
  parse_standard_info_field("Operating Status")
end

#parse_out_of_service_dateObject



179
180
181
182
183
184
# File 'lib/carrier_info/sources/safer.rb', line 179

def parse_out_of_service_date
  date_parts = parse_standard_info_field("Out of Service Date").split("/").collect(&:to_i)
  if date_parts.count == 3
					Date.new(date_parts[2], date_parts[0], date_parts[1]) if date_parts.count == 3
				end
end

#parse_phoneObject



129
130
131
# File 'lib/carrier_info/sources/safer.rb', line 129

def parse_phone
  parse_standard_info_field("Phone")
end

#parse_postal_code(address) ⇒ Object



216
217
218
219
# File 'lib/carrier_info/sources/safer.rb', line 216

def parse_postal_code(address)
  address.split("\n")[1].split(",")[1].strip =~ /\A(\w*)\s*(\S*)\s*\Z/
  $2
end

#parse_power_unitsObject



133
134
135
# File 'lib/carrier_info/sources/safer.rb', line 133

def parse_power_units
  parse_standard_info_field("Power Units", integer: true)
end

#parse_safer_activeObject



186
187
188
# File 'lib/carrier_info/sources/safer.rb', line 186

def parse_safer_active
  !(response.xpath("//text()='Record Inactive'") || response.xpath("//text()='Record Not Found'"))
end

#parse_safer_last_updatedObject



253
254
255
256
257
258
# File 'lib/carrier_info/sources/safer.rb', line 253

def parse_safer_last_updated
  if last_updated = response.at_xpath("//b[starts-with(.,'The information below reflects the content')]").xpath("./font").text.strip
    date_parts = last_updated.split("/").collect(&:to_i)
    Date.new(date_parts[2], date_parts[0], date_parts[1]) if date_parts.count == 3
  end
end

#parse_standard_info_field(name, args = {}) ⇒ Object



110
111
112
113
114
115
116
117
118
119
# File 'lib/carrier_info/sources/safer.rb', line 110

def parse_standard_info_field(name, args={})
  value = response.xpath("//a[text()='#{name}:']").find do |field|
    field.attr("class") == "querylabel"
  end.parent.next_element.text.gsub(/[\u0080-\u00ff]/,"").strip
  if args[:integer]
    value.gsub!(/\D/, "")
    value = value.to_i
  end
  value
end

#parse_state(address) ⇒ Object



211
212
213
214
# File 'lib/carrier_info/sources/safer.rb', line 211

def parse_state(address)
  address.split("\n")[1].split(",")[1].strip =~ /\A(\w*)\s*(\S*)\s*\Z/
  $1
end

#parse_state_id_numberObject



160
161
162
# File 'lib/carrier_info/sources/safer.rb', line 160

def parse_state_id_number
  parse_standard_info_field("State Carrier ID Number")
end

#parse_street(address) ⇒ Object



203
204
205
# File 'lib/carrier_info/sources/safer.rb', line 203

def parse_street(address)
  address.split("\n")[0].strip
end

#parse_usdot_numberObject



141
142
143
# File 'lib/carrier_info/sources/safer.rb', line 141

def parse_usdot_number
  parse_standard_info_field("USDOT Number", integer: true)
end

#query_paramObject



46
47
48
# File 'lib/carrier_info/sources/safer.rb', line 46

def query_param
  carrier.usdot_number ? "USDOT" : "MC_MX"
end

#query_stringObject



50
51
52
# File 'lib/carrier_info/sources/safer.rb', line 50

def query_string
  carrier.usdot_number || carrier.docket_number
end

#request_paramsObject



54
55
56
57
58
59
60
61
62
# File 'lib/carrier_info/sources/safer.rb', line 54

def request_params
  params = {
    query_param: query_param,
  	query_string: query_string,
  	searchtype: 'ANY',
  	query_type: 'queryCarrierSnapshot',
  	button1: 'Search'
  }        
end

#request_responseObject



68
69
70
# File 'lib/carrier_info/sources/safer.rb', line 68

def request_response
  Nokogiri::HTML(Net::HTTP.post_form(URI.parse('http://safer.fmcsa.dot.gov/query.asp'), request_params).body)
end

#responseObject



64
65
66
# File 'lib/carrier_info/sources/safer.rb', line 64

def response
  @response ||= request_response
end