Moved to adapter backends for geo location and geo ip lookups.

This commit is contained in:
Martin Edenhofer 2013-08-15 22:40:22 +02:00
parent 1e9a072a6e
commit 3a0bddd79a
9 changed files with 187 additions and 20 deletions

View file

@ -1,7 +1,5 @@
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
require 'geoip'
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
# http_basic_authenticate_with :name => "test", :password => "ttt" # http_basic_authenticate_with :name => "test", :password => "ttt"
@ -82,7 +80,7 @@ class ApplicationController < ActionController::Base
# check if remote ip need to be updated # check if remote ip need to be updated
if !session[:remote_id] || session[:remote_id] != request.remote_ip if !session[:remote_id] || session[:remote_id] != request.remote_ip
session[:remote_id] = request.remote_ip session[:remote_id] = request.remote_ip
session[:geo] = Geoip.location( request.remote_ip ) session[:geo] = GeoIp.location( request.remote_ip )
end end
# fill user agent # fill user agent

View file

@ -53,13 +53,8 @@ class Observer::User::Geo < ActiveRecord::Observer
# return if no address is given # return if no address is given
return if address == '' return if address == ''
# load adapter # lookup
adapter = Setting.get('geo_backend') latlng = GeoLocation.geocode( address )
return if !adapter
adapter_module = Object.const_get(adapter)
# db lookup
latlng = adapter_module.geocode(address)
return if !latlng return if !latlng
# store data # store data

View file

@ -0,0 +1,52 @@
class UpdateGeo2 < ActiveRecord::Migration
def up
Setting.where( :name => 'geo_backend' ).destroy_all
Setting.create_if_not_exists(
:title => 'Geo Location Backend',
:name => 'geo_location_backend',
:area => 'System::Geo',
:description => 'Defines the backend for geo location lookups.',
:options => {
:form => [
{
:display => '',
:null => true,
:name => 'geo_location_backend',
:tag => 'select',
:options => {
'' => '-',
'GeoLocation::Gmaps' => 'Google Maps',
},
},
],
},
:state => 'GeoLocation::Gmaps',
:frontend => false
)
Setting.create_if_not_exists(
:title => 'Geo IP Backend',
:name => 'geo_ip_backend',
:area => 'System::Geo',
:description => 'Defines the backend for geo ip lookups.',
:options => {
:form => [
{
:display => '',
:null => true,
:name => 'geo_ip_backend',
:tag => 'select',
:options => {
'' => '-',
'GeoIp::Freegeoip' => 'freegeoip.net',
},
},
],
},
:state => 'GeoIp::Freegeoip',
:frontend => false
)
end
def down
end
end

View file

@ -135,7 +135,7 @@ Setting.create_if_not_exists(
) )
Setting.create_if_not_exists( Setting.create_if_not_exists(
:title => 'Geo Location Backend', :title => 'Geo Location Backend',
:name => 'geo_backend', :name => 'geo_location_backend',
:area => 'System::Geo', :area => 'System::Geo',
:description => 'Defines the backend for geo location lookups.', :description => 'Defines the backend for geo location lookups.',
:options => { :options => {
@ -143,16 +143,38 @@ Setting.create_if_not_exists(
{ {
:display => '', :display => '',
:null => true, :null => true,
:name => 'geo_backend', :name => 'geo_location_backend',
:tag => 'select', :tag => 'select',
:options => { :options => {
'' => '-', '' => '-',
'Gmaps' => 'Google Maps', 'GeoLocation::Gmaps' => 'Google Maps',
}, },
}, },
], ],
}, },
:state => 'Gmaps', :state => 'GeoLocation::Gmaps',
:frontend => false
)
Setting.create_if_not_exists(
:title => 'Geo IP Backend',
:name => 'geo_ip_backend',
:area => 'System::Geo',
:description => 'Defines the backend for geo ip lookups.',
:options => {
:form => [
{
:display => '',
:null => true,
:name => 'geo_ip_backend',
:tag => 'select',
:options => {
'' => '-',
'GeoIp::Freegeoip' => 'freegeoip.net',
},
},
],
},
:state => 'GeoIp::Freegeoip',
:frontend => false :frontend => false
) )

17
lib/application_lib.rb Normal file
View file

@ -0,0 +1,17 @@
class ApplicationLib
def self.load_adapter_by_setting(setting)
adapter = Setting.get( setting )
return if !adapter
# load backend
self.load_adapter(adapter)
end
def self.load_adapter(adapter)
# load adapter
backend = Object.const_get(adapter)
# return backend
return backend
end
end

36
lib/geo_ip.rb Normal file
View file

@ -0,0 +1,36 @@
class GeoIp < ApplicationLib
=begin
lookup location based on ip or hostname
result = GeoIp.location( '172.0.0.1' )
returns
result = {
"ip" => "172.0.0.1"
"country_code" => "DE",
"country_name" => "Germany",
"region_code" => "05",
"region_name" => "Hessen",
"city" => "Frankfurt Am Main"
"zipcode" => "12345",
"latitude" => 50.1167,
"longitude" => 8.6833,
"metro_code" => "",
"areacode" => ""
}
=end
def self.location(address)
# load backend
backend = self.load_adapter_by_setting( 'geo_ip_backend' )
return if !backend
# db lookup
backend.location(address)
end
end

View file

@ -1,11 +1,11 @@
require 'faraday' require 'faraday'
require 'cache' require 'cache'
module Geoip module GeoIp::Freegeoip
def self.location(address) def self.location(address)
# check cache # check cache
cache_key = "geoip::#{address}" cache_key = "freegeoip::#{address}"
cache = Cache.get( cache_key ) cache = Cache.get( cache_key )
return cache if cache return cache if cache

46
lib/geo_location.rb Normal file
View file

@ -0,0 +1,46 @@
class GeoLocation < ApplicationLib
=begin
lookup lat and lng for address
result = GeoLocation.geocode( 'Marienstrasse 13, 10117 Berlin' )
returns
result = [ 4.21312, 1.3123 ]
=end
def self.geocode(address)
# load backend
backend = self.load_adapter_by_setting( 'geo_location_backend' )
return if !backend
# db lookup
backend.geocode(address)
end
=begin
lookup address for lat and lng
result = GeoLocation.reverse_geocode( 4.21312, 1.3123 )
returns
result = 'some address'
=end
def self.reverse_geocode(lat,lng)
# load backend
backend = self.load_adapter_by_setting( 'geo_location_backend' )
return if !backend
# db lookup
backend.reverse_geocode(lat,lng)
end
end

View file

@ -1,4 +1,5 @@
module Gmaps class GeoLocation::Gmaps
def self.geocode(address) def self.geocode(address)
url = "http://maps.googleapis.com/maps/api/geocode/json?address=#{CGI::escape address}&sensor=true" url = "http://maps.googleapis.com/maps/api/geocode/json?address=#{CGI::escape address}&sensor=true"
response = Net::HTTP.get_response( URI.parse(url) ) response = Net::HTTP.get_response( URI.parse(url) )
@ -10,15 +11,15 @@ module Gmaps
lng = result['results'].first['geometry']['location']['lng'] lng = result['results'].first['geometry']['location']['lng']
latlng = [lat,lng] latlng = [lat,lng]
end end
def self.reverse_geocode(lat,lng) def self.reverse_geocode(lat,lng)
url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=#{lat},#{lng}&sensor=true" url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=#{lat},#{lng}&sensor=true"
response = Net::HTTP.get_response( URI.parse(url) ) response = Net::HTTP.get_response( URI.parse(url) )
return if response.code.to_s != '200' return if response.code.to_s != '200'
result = JSON.parse( response.body ) result = JSON.parse( response.body )
address = result['results'].first['address_components'].first['long_name'] address = result['results'].first['address_components'].first['long_name']
return address return address
end end
end end