jam-cloud/ruby/lib/jam_ruby/models/max_mind_geo.rb

144 lines
5.1 KiB
Ruby
Raw Normal View History

require 'csv'
module JamRuby
class MaxMindGeo < ActiveRecord::Base
self.table_name = 'max_mind_geo'
@@log = Logging.logger[MaxMindGeo]
def self.import_from_max_mind(options)
file = options[:file]
use_copy = options[:use_copy]
2013-10-28 14:22:06 +00:00
# File Geo-139
# Format:
# startIpNum,endIpNum,country,region,city,postalCode,latitude,longitude,dmaCode,areaCode
start = Time.now
MaxMindGeo.delete_all
if use_copy
Database.copy(MaxMindGeo.table_name, file)
else
2013-11-03 03:07:16 +00:00
File.open(file, 'r:ISO-8859-1') do |io|
s = io.gets.strip # eat the headers line
unless s.eql? 'startIpNum,endIpNum,country,region,city,postalCode,latitude,longitude,dmaCode,areaCode'
puts s
puts 'startIpNum,endIpNum,country,region,city,postalCode,latitude,longitude,dmaCode,areaCode'
raise 'file does not start with expected header (line 1): startIpNum,endIpNum,country,region,city,postalCode,latitude,longitude,dmaCode,areaCode'
end
saved_level = ActiveRecord::Base.logger ? ActiveRecord::Base.logger.level : 0
count = 0
stmt = "insert into #{MaxMindGeo.table_name} (country,region,city,lat,lng,ip_start,ip_end) values"
vals = ''
sep = ''
i = 0
n = 20 # going from 20 to 40 only changed things a little bit
csv = ::CSV.new(io, {encoding: 'ISO-8859-1', headers: false})
csv.each do |row|
raise "file does not have expected number of columns (10): #{row.length}" unless row.length == 10
ip_start = ip_address_to_int(strip_quotes(row[0]))
ip_end = ip_address_to_int(strip_quotes(row[1]))
country = row[2]
region = row[3]
city = row[4]
#postalcode = row[5]
lat = row[6]
lng = row[7]
#dmacode = row[8]
#areacode = row[9]
vals = vals+sep+"(#{quote_value(country, nil)},#{quote_value(region, nil)},#{quote_value(city, nil)},#{lat},#{lng},#{ip_start},#{ip_end})"
sep = ','
i += 1
if count == 0 or i >= n then
MaxMindGeo.connection.execute stmt+vals
count += i
vals = ''
sep = ''
i = 0
if ActiveRecord::Base.logger and ActiveRecord::Base.logger.level > 1 then
ActiveRecord::Base.logger.debug "... logging inserts into #{MaxMindGeo.table_name} suspended ..."
ActiveRecord::Base.logger.level = 1
end
if ActiveRecord::Base.logger and count%10000 < n then
ActiveRecord::Base.logger.level = saved_level
ActiveRecord::Base.logger.debug "... inserted #{count} into #{MaxMindGeo.table_name} ..."
ActiveRecord::Base.logger.level = 1
end
end
end
if i > 0 then
MaxMindGeo.connection.execute stmt+vals
count += i
end
if ActiveRecord::Base.logger then
ActiveRecord::Base.logger.level = saved_level
ActiveRecord::Base.logger.debug "loaded #{count} records into #{MaxMindGeo.table_name}"
2013-11-03 03:07:16 +00:00
end
end
end
# User.find_each { |usr| usr.update_lat_lng }
# THIS DOESNT ACTUALLY DO ANYTHING BECAUSE IT NEVER SAVES
Band.find_each { |bnd| bnd.update_lat_lng }
elapsed = Time.now - start
@@log.debug("#{MaxMindGeo.table_name} import took #{elapsed} seconds")
end
def self.where_latlng(relation, params, current_user=nil)
# this is only valid to call when relation is about bands
distance = params[:distance].to_i
if distance > 0
latlng = nil
location_city = params[:city]
location_state = params[:state]
location_country = params[:country]
remote_ip = params[:remote_ip]
if location_city and location_state and location_country
geo = self.where(city: location_city, region: location_state, countrycode: location_country).limit(1).first
if geo and geo.lat and geo.lng and (geo.lat != 0 or geo.lng != 0)
# it isn't reasonable for both to be 0...
latlng = [geo.lat, geo.lng]
end
elsif current_user and current_user.locidispid and current_user.locidispid != 0
location = GeoIpLocations.find_by_locid(current_user.locidispid/1000000)
if location and location.latitude and location.longitude and (location.latitude != 0 or location.longitude != 0)
# it isn't reasonable for both to be 0...
latlng = [location.latitude, location.longitude]
end
elsif remote_ip
geo = self.ip_lookup(remote_ip)
if geo and geo.lat and geo.lng and (geo.lat != 0 or geo.lng != 0)
# it isn't reasonable for both to be 0...
latlng = [geo.lat, geo.lng]
end
end
if latlng
relation = relation.where(['lat IS NOT NULL AND lng IS NOT NULL']).within(distance, origin: latlng)
end
end
relation
end
end
2013-10-28 14:22:06 +00:00
end