merge and bring in maxmind
This commit is contained in:
parent
7bb6d6b71e
commit
ec29df6d95
5
Gemfile
5
Gemfile
|
|
@ -1,6 +1,9 @@
|
|||
#ruby=1.9.3
|
||||
source 'https://rubygems.org'
|
||||
source 'https://jamjam:blueberryjam@www.jamkazam.com/gems/'
|
||||
|
||||
# From mslemmer:
|
||||
# This source cmd doesnt work for me and blocks bundle install
|
||||
#source 'https://jamjam:blueberryjam@www.jamkazam.com/gems/'
|
||||
# Look for $WORKSPACE, otherwise use "workspace" as dev path.
|
||||
|
||||
workspace = ENV["WORKSPACE"] || "~/workspace"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class SessionsController < ApplicationController
|
|||
auth_hash[:info][:email],
|
||||
nil,
|
||||
nil,
|
||||
auth_hash[:info][:location],
|
||||
nil, # city
|
||||
nil, # state
|
||||
nil, # country
|
||||
nil, # instruments
|
||||
|
|
|
|||
|
|
@ -20,7 +20,17 @@
|
|||
|
||||
<%= f.label :password_confirmation, "Confirm Password" %>
|
||||
<%= f.password_field :password_confirmation %>
|
||||
|
||||
<!-- Allow the user to edit the auto-generated city/state/country we set -->
|
||||
<%= f.label :city %>
|
||||
<%= f.text_field :city %>
|
||||
|
||||
<%= f.label :state %>
|
||||
<%= f.text_field :state %>
|
||||
|
||||
<%= f.label :country %>
|
||||
<%= f.text_field :country %>
|
||||
|
||||
<%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
|
|
|
|||
|
|
@ -20,15 +20,6 @@
|
|||
<%= f.label :email %>
|
||||
<%= f.text_field :email %>
|
||||
|
||||
<%= f.label :city %>
|
||||
<%= f.text_field :city %>
|
||||
|
||||
<%= f.label :state %>
|
||||
<%= f.text_field :state %>
|
||||
|
||||
<%= f.label :country %>
|
||||
<%= f.text_field :country %>
|
||||
|
||||
<%= f.label :password %>
|
||||
<%= f.password_field :password %>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
class MaxMindManager < BaseManager
|
||||
|
||||
def initialize(options={})
|
||||
super(options)
|
||||
end
|
||||
|
||||
|
||||
# Returns a hash with location information. Fields are nil if they can't be figured.
|
||||
def self.lookup(ip_address)
|
||||
|
||||
city = state = country = nil
|
||||
|
||||
ActiveRecord::Base.connection_pool.with_connection do |connection|
|
||||
pg_conn = connection.instance_variable_get("@connection")
|
||||
ip_as_int = ip_address_to_int(ip_address)
|
||||
pg_conn.exec("SELECT country, region, city FROM max_mind WHERE ip_bottom <= $1 AND ip_top >= $2", [ip_as_int, ip_as_int]) do |result|
|
||||
if !result.nil? && result.ntuples > 0
|
||||
country = result.getvalue(0, 0)
|
||||
state = result[0]['region']
|
||||
city = result[0]['city']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
{
|
||||
:city => city,
|
||||
:state => state,
|
||||
:country => country
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Do this in a transaction so there's no partial import.
|
||||
def import_database(filename)
|
||||
clear_table
|
||||
# Format:
|
||||
# startIpNum,endIpNum,country,region,city,postalCode,latitude,longitude,dmaCode,areaCode
|
||||
it = 0
|
||||
CSV.foreach(filename, col_sep: ",", encoding: "ISO-8859-1") do |split_line|
|
||||
next if split_line[0] == 'startIpNum' # Ignore the legend line at the top
|
||||
it += 1
|
||||
if it > 100000
|
||||
return
|
||||
end
|
||||
unless split_line.length < 10
|
||||
@pg_conn.exec("INSERT INTO max_mind (ip_bottom, ip_top, country, region, city) VALUES ($1, $2, $3, $4, $5)",
|
||||
[
|
||||
self.class.ip_address_to_int(split_line[0]),
|
||||
self.class.ip_address_to_int(split_line[1]),
|
||||
split_line[2],
|
||||
split_line[3],
|
||||
split_line[4]
|
||||
]).clear
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_phony_database()
|
||||
clear_table
|
||||
(0..255).each do |top_octet|
|
||||
@pg_conn.exec("INSERT INTO max_mind (ip_bottom, ip_top, country, region, city) VALUES ($1, $2, $3, $4, $5)",
|
||||
[
|
||||
self.class.ip_address_to_int("#{top_octet}.0.0.0"),
|
||||
self.class.ip_address_to_int("#{top_octet}.255.255.255"),
|
||||
"Country #{top_octet}",
|
||||
"Region #{top_octet}",
|
||||
"City #{top_octet}"
|
||||
]).clear
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
# Make an IP address fit in a signed int. Just divide it by 2, as the least significant part
|
||||
# just can't possibly matter. We can verify this if needed. My guess is the entire bottom octet is
|
||||
# actually irrelevant
|
||||
def self.ip_address_to_int(ip)
|
||||
ip.split('.').inject(0) {|total,value| (total << 8 ) + value.to_i} / 2
|
||||
end
|
||||
|
||||
def clear_table
|
||||
@pg_conn.exec("DELETE FROM max_mind").clear
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -8,8 +8,10 @@ class UserManager < BaseManager
|
|||
@log = Logging.logger[self]
|
||||
end
|
||||
|
||||
def signup(first_name, last_name, email, password, password_confirmation,
|
||||
city, state, country, instruments, photo_url, signup_confirm_url)
|
||||
# Note that almost everything can be nil here. This is because when users sign up via social media,
|
||||
# we don't know much about them.
|
||||
def signup(first_name, last_name, email, password = nil, password_confirmation = nil,
|
||||
city = nil, state = nil, country = nil, instruments = nil, photo_url = nil, signup_confirm_url = nil)
|
||||
|
||||
@user = User.new
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
namespace :db do
|
||||
desc "Import a maxmind database; run like this: rake db:import_maxmind file=<path_to_file>"
|
||||
task import_maxmind: :environment do
|
||||
require 'csv'
|
||||
MaxMindManager.active_record_transaction do |manager|
|
||||
manager.import_database ENV['file']
|
||||
end
|
||||
end
|
||||
|
||||
desc "Create a fake set of maxmind data"
|
||||
task phony_maxmind: :environment do
|
||||
MaxMindManager.active_record_transaction do |manager|
|
||||
manager.create_phony_database()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue