mm_geoip 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ class MMGeoip::Regions
2
+ class << self
3
+
4
+ # Memoization and convinience for #parse.
5
+ def [](country_key)
6
+ @regions_hash ||= parse
7
+ @regions_hash[country_key.to_sym]
8
+ end
9
+
10
+ # Parse the included regions file.
11
+ # It contains both, the ISO 3166-2 Subcountry codes for Canada and the US
12
+ # and the FIPS 10-4 Subcountry codes for the rest of the world.
13
+ # http://www.maxmind.com/app/iso3166_2
14
+ # http://www.maxmind.com/app/fips10_4)
15
+ #
16
+ def parse
17
+ regions_hash = {}
18
+ File.open(File.join(MMGeoip::data_path, 'fips_and_3166_2.txt')).each_line do |line|
19
+ line_parts = line.split(',')
20
+ country, area, area_name = line_parts[0].to_sym, line_parts[1], line_parts[2].gsub('"','').strip
21
+
22
+ regions_hash[country] ||= {}
23
+ regions_hash[country][area] = area_name
24
+ end
25
+ regions_hash
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ class MMGeoip
2
+ VERSION = '0.0.2'
3
+ end
data/lib/mm_geoip.rb ADDED
@@ -0,0 +1,74 @@
1
+ require 'geoip'
2
+
3
+ $LOAD_PATH << File.dirname(File.expand_path __FILE__)
4
+
5
+ class MMGeoip; end
6
+
7
+ require 'mm_geoip/region'
8
+
9
+ class MMGeoip
10
+ FIELDS = [:hostname, :ip, :country_code, :country_code3, :country_name,
11
+ :country_continent, :region, :city, :postal_code, :lat, :lng, :dma_code,
12
+ :area_code, :timezone]
13
+ attr_reader :lookup
14
+
15
+ class NoIpGiven < StandardError; end
16
+
17
+ def initialize(env)
18
+ @env = env # may be a Rack @env or any hash containing initial data
19
+ @env[:ip] ||= @env["REMOTE_ADDR"] # :ip or "REMOTE_ADDR" should be present
20
+
21
+ raise NoIpGiven.new unless @env[:ip]
22
+
23
+ @geodb = GeoIP.new self.class.db_path
24
+ end
25
+
26
+ FIELDS.each do |field|
27
+ define_method field do
28
+ # if already looked up, get field from lookup or environment (lookup has priority)
29
+ # else get field from environment or lookup (environment has priority; perhaps we don't have to lookup)
30
+ # looked_up? ? fields[field] || get_from_env(field) : get_from_env(field) || fields[field]
31
+ looked_up? ? lookup[field] || get_from_env(field) : get_from_env(field) || lookup[field]
32
+ end
33
+ end
34
+
35
+ def get_from_env(field)
36
+ # APACHE:GEOIP with Geolite City give us:
37
+ # GEOIP_REGION, GEOIP_CITY, GEOIP_DMA_CODE, GEOIP_AREA_CODE, GEOIP_LAT, GEOIP_LNG
38
+ #
39
+ # Nginx with HttpGeoIPModule and Geolite City makes these variables available in nginx.conf:
40
+ # $geoip_country_code, ..., you'll have to set the env variables by yourself.
41
+ # I'd recommend using the X_GEOIP_... form.
42
+ #
43
+ # Here, we look for both forms and the plain version.
44
+ #
45
+ @env[field] || @env["GEOIP_#{field.upcase}"] || @env["X_GEOIP_#{field.upcase}"]
46
+ end
47
+
48
+ def region_name
49
+ MMGeoip::Regions[country_code.to_sym] && MMGeoip::Regions[country_code.to_sym][region]
50
+ end
51
+
52
+ def looked_up?
53
+ !!@lookup
54
+ end
55
+
56
+ def lookup
57
+ return @lookup if @lookup
58
+
59
+ @lookup = Hash[FIELDS.zip @geodb.city(@env[:ip])]
60
+ @lookup[:region_name] = region_name
61
+ @lookup
62
+ end
63
+
64
+ def self.data_path
65
+ File.join(File.dirname(File.expand_path(__FILE__)), '../data')
66
+ end
67
+ def self.db_path
68
+ @db_path || File.join(data_path, 'GeoLiteCity.dat')
69
+ end
70
+ def self.db_path=(path)
71
+ @db_path = path
72
+ end
73
+
74
+ end
@@ -0,0 +1,12 @@
1
+ module Rack
2
+ class MMGeoip
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ env['GEOIP'] = ::MMGeoip.new env
9
+ @app.call(env)
10
+ end
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mm_geoip
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Niko Dittmann
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-04 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: geoip
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ description: A proxy object around the geoip gem for lazy lookup. Includes a Rack middleware.
27
+ email: mail+git@niko-dittmann.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - lib/mm_geoip/region.rb
36
+ - lib/mm_geoip/version.rb
37
+ - lib/mm_geoip.rb
38
+ - lib/rack_mm_geoip.rb
39
+ - data/fips_and_3166_2.txt
40
+ - data/GeoLiteCity.dat
41
+ homepage: http://github.com/niko/mm_geoip
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.7.2
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: A proxy object around the geoip gem for lazy lookup. Includes a Rack middleware.
68
+ test_files: []
69
+