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/
require 'geoip'
class ApplicationController < ActionController::Base
# http_basic_authenticate_with :name => "test", :password => "ttt"
@ -82,7 +80,7 @@ class ApplicationController < ActionController::Base
# check if remote ip need to be updated
if !session[:remote_id] || 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
# fill user agent

View file

@ -53,13 +53,8 @@ class Observer::User::Geo < ActiveRecord::Observer
# return if no address is given
return if address == ''
# load adapter
adapter = Setting.get('geo_backend')
return if !adapter
adapter_module = Object.const_get(adapter)
# db lookup
latlng = adapter_module.geocode(address)
# lookup
latlng = GeoLocation.geocode( address )
return if !latlng
# 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(
:title => 'Geo Location Backend',
:name => 'geo_backend',
:name => 'geo_location_backend',
:area => 'System::Geo',
:description => 'Defines the backend for geo location lookups.',
:options => {
@ -143,16 +143,38 @@ Setting.create_if_not_exists(
{
:display => '',
:null => true,
:name => 'geo_backend',
:name => 'geo_location_backend',
:tag => 'select',
: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
)

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 'cache'
module Geoip
module GeoIp::Freegeoip
def self.location(address)
# check cache
cache_key = "geoip::#{address}"
cache_key = "freegeoip::#{address}"
cache = Cache.get( cache_key )
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)
url = "http://maps.googleapis.com/maps/api/geocode/json?address=#{CGI::escape address}&sensor=true"
response = Net::HTTP.get_response( URI.parse(url) )
@ -10,15 +11,15 @@ module Gmaps
lng = result['results'].first['geometry']['location']['lng']
latlng = [lat,lng]
end
def self.reverse_geocode(lat,lng)
url = "http://maps.googleapis.com/maps/api/geocode/json?latlng=#{lat},#{lng}&sensor=true"
response = Net::HTTP.get_response( URI.parse(url) )
return if response.code.to_s != '200'
result = JSON.parse( response.body )
address = result['results'].first['address_components'].first['long_name']
return address
end
end
end