geo-ip-json 0.0.1
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.
- data/.rvmrc +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +25 -0
- data/Guardfile +5 -0
- data/README.md +41 -0
- data/Rakefile +10 -0
- data/geo_ip_json.gemspec +21 -0
- data/lib/geo-ip-json.rb +1 -0
- data/lib/geo_ip_json/app.rb +42 -0
- data/lib/geo_ip_json/version.rb +3 -0
- data/spec/app_spec.rb +73 -0
- metadata +69 -0
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2@geo-ip-json --create
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
ffi (1.0.11)
|
5
|
+
geoip (1.1.2)
|
6
|
+
guard (1.0.3)
|
7
|
+
ffi (>= 0.5.0)
|
8
|
+
thor (>= 0.14.6)
|
9
|
+
guard-minitest (0.5.0)
|
10
|
+
guard (>= 0.4)
|
11
|
+
minitest (3.0.0)
|
12
|
+
rack (1.4.1)
|
13
|
+
rack-test (0.6.1)
|
14
|
+
rack (>= 1.0)
|
15
|
+
thor (0.15.2)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
geoip
|
22
|
+
guard
|
23
|
+
guard-minitest
|
24
|
+
minitest
|
25
|
+
rack-test
|
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# GeoIPJSON - GeoIP information as JSON via a rack app
|
2
|
+
|
3
|
+
A very simple rack app to provide Geo-location Information as JSON.
|
4
|
+
|
5
|
+
By default it returns the country code of the current client.
|
6
|
+
|
7
|
+
Alternatively, an `?ip=1.2.3.4` parameter can be supplied.
|
8
|
+
|
9
|
+
We are using this as a datasource for an AJAX call.
|
10
|
+
|
11
|
+
## Install
|
12
|
+
|
13
|
+
### Rails
|
14
|
+
|
15
|
+
In `Gemfile`
|
16
|
+
|
17
|
+
gem 'geo-ip-json'
|
18
|
+
|
19
|
+
In `routes.rb`
|
20
|
+
|
21
|
+
<AppName>::Application.routes.draw do
|
22
|
+
match "/geoip.json", :to => GeoIPJson::App.new
|
23
|
+
end
|
24
|
+
|
25
|
+
Download the GeoIP database file from MaxMind (http://www.maxmind.com/)
|
26
|
+
|
27
|
+
* http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
|
28
|
+
|
29
|
+
Put it in the root of your Rails app (configurable location is coming)
|
30
|
+
|
31
|
+
## Testing
|
32
|
+
|
33
|
+
Run `rake test` to run the tests. A `Guardfile` is present to use with `Guard`.
|
34
|
+
|
35
|
+
## Thanks!
|
36
|
+
|
37
|
+
Steve England for the idea
|
38
|
+
* https://github.com/stengland
|
39
|
+
|
40
|
+
Ruby GeoIP library which does most of the work!
|
41
|
+
* http://geoip.rubyforge.org/
|
data/Rakefile
ADDED
data/geo_ip_json.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "geo_ip_json/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "geo-ip-json"
|
6
|
+
s.version = GeoIPJson::VERSION
|
7
|
+
s.authors = ["Jordan Elver"]
|
8
|
+
s.email = ["jordan.elver@gmail.com"]
|
9
|
+
s.homepage = ""
|
10
|
+
s.summary = %q{Geo IP information via JSON rack app}
|
11
|
+
s.description = %q{Geo IP information via JSON rack app}
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
# specify any dependencies here; for example:
|
19
|
+
# s.add_development_dependency "rspec"
|
20
|
+
s.add_runtime_dependency "geoip"
|
21
|
+
end
|
data/lib/geo-ip-json.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'geo_ip_json/app'
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'geoip'
|
3
|
+
|
4
|
+
module GeoIPJson
|
5
|
+
class App
|
6
|
+
attr_writer :geo_ip
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
request = Rack::Request.new(env)
|
10
|
+
|
11
|
+
geo_data = lookup(ip_or_hostname(request))
|
12
|
+
country = geo_data.fetch(:country_code2, '').downcase.gsub(/--/, '')
|
13
|
+
|
14
|
+
json = {
|
15
|
+
country: country
|
16
|
+
}.to_json
|
17
|
+
|
18
|
+
[200, {'Content-Type' => 'application/json'}, [json]]
|
19
|
+
end
|
20
|
+
|
21
|
+
def geo_ip
|
22
|
+
@geo_ip ||= GeoIP.new('GeoIP.dat')
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def ip_or_hostname(request)
|
28
|
+
if request.params['ip'].nil?
|
29
|
+
ip = request.ip
|
30
|
+
else
|
31
|
+
ip = request.params['ip']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def lookup(ip_or_hostname)
|
36
|
+
geo_ip.country(ip_or_hostname).to_hash
|
37
|
+
rescue SocketError
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/spec/app_spec.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'minitest'
|
3
|
+
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require 'minitest/pride'
|
6
|
+
require 'rack/test'
|
7
|
+
require_relative '../lib/geo-ip-json'
|
8
|
+
|
9
|
+
include Rack::Test::Methods
|
10
|
+
|
11
|
+
def app
|
12
|
+
Rack::Lint.new(@app)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Setup our rack app as we would with a config.ru file
|
16
|
+
def mock_app(options = {})
|
17
|
+
|
18
|
+
# Create a mock to pass to the app
|
19
|
+
mock = MiniTest::Mock.new
|
20
|
+
mock.expect(:country, { country_code2: options[:country] }, options[:ip])
|
21
|
+
|
22
|
+
builder = Rack::Builder.new do
|
23
|
+
map '/geoip.json' do
|
24
|
+
app = GeoIPJson::App.new
|
25
|
+
app.geo_ip = mock
|
26
|
+
run app
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
@app = builder.to_app
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "GeoIP" do
|
34
|
+
|
35
|
+
describe "valid IP address" do
|
36
|
+
|
37
|
+
it "must return the country code" do
|
38
|
+
mock_app(:country => 'us', :ip => ['1.2.3.4'])
|
39
|
+
|
40
|
+
get '/geoip.json?ip=1.2.3.4'
|
41
|
+
|
42
|
+
assert_equal 200, last_response.status
|
43
|
+
|
44
|
+
json = JSON.parse(last_response.body)
|
45
|
+
json['country'].must_equal 'us'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "must use the request IP if the ip parameter is missing" do
|
49
|
+
mock_app(:country => 'gb', :ip => ['4.5.6.7'])
|
50
|
+
|
51
|
+
get '/geoip.json', nil, { 'REMOTE_ADDR' => '4.5.6.7' }
|
52
|
+
|
53
|
+
assert_equal 200, last_response.status
|
54
|
+
|
55
|
+
json = JSON.parse(last_response.body)
|
56
|
+
json['country'].must_equal 'gb'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "invalid IP address" do
|
61
|
+
|
62
|
+
it "must return return an empty string if the ip is bogus" do
|
63
|
+
mock_app(:country => '', :ip => ['not-an-ip-address'])
|
64
|
+
|
65
|
+
get '/geoip.json?ip=not-an-ip-address'
|
66
|
+
|
67
|
+
assert_equal 200, last_response.status
|
68
|
+
|
69
|
+
json = JSON.parse(last_response.body)
|
70
|
+
json['country'].must_equal ''
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: geo-ip-json
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jordan Elver
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-06 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: geoip
|
16
|
+
requirement: &2157237940 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2157237940
|
25
|
+
description: Geo IP information via JSON rack app
|
26
|
+
email:
|
27
|
+
- jordan.elver@gmail.com
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- .rvmrc
|
33
|
+
- Gemfile
|
34
|
+
- Gemfile.lock
|
35
|
+
- Guardfile
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- geo_ip_json.gemspec
|
39
|
+
- lib/geo-ip-json.rb
|
40
|
+
- lib/geo_ip_json/app.rb
|
41
|
+
- lib/geo_ip_json/version.rb
|
42
|
+
- spec/app_spec.rb
|
43
|
+
homepage: ''
|
44
|
+
licenses: []
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
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
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.8.10
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Geo IP information via JSON rack app
|
67
|
+
test_files:
|
68
|
+
- spec/app_spec.rb
|
69
|
+
has_rdoc:
|