geoip_server 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. data/.gems +2 -0
  2. data/README.markdown +31 -0
  3. data/Rakefile +46 -0
  4. data/VERSION +1 -0
  5. data/config.ru +6 -0
  6. data/lib/geoip_server.rb +73 -0
  7. data/test.rb +73 -0
  8. metadata +86 -0
data/.gems ADDED
@@ -0,0 +1,2 @@
1
+ sinatra
2
+ geoip
@@ -0,0 +1,31 @@
1
+ # GeoIP Server
2
+
3
+ This simple Rack server is useful as a self-hosted service for making lookups to the GeoIP database from MaxMind.com
4
+
5
+
6
+ ## Instant installation and deploy
7
+
8
+ * Clone this: `git clone git://github.com/JackDanger/geoip_server.git`
9
+ * Download the free GeoIP data files: `rake geoip:update_city_lite`
10
+ * Commit that data file to your clone: `git add vendor && git commit -m "adding data file"`
11
+ * Signup for an account at Heroku ([better details here](http://github.com/sinatra/heroku-sinatra-app))
12
+ * Create and name a new app where you want to host this
13
+ * push it to Heroku.com: `git push heroku master`
14
+
15
+
16
+ ## HowTo
17
+
18
+ Once the server is running you can make a GET request to the server and receive lookup results in JSON format.
19
+
20
+ ip = request.remote_ip
21
+ require 'open-uri'
22
+ data = JSON.decode(open("http://my-geoip-service-app.heroku.com/#{ip}").read)
23
+ render :text => "You're in: #{data[:city]}"
24
+
25
+ Or, straight from a terminal:
26
+
27
+ curl -X POST http://my-geoip-service-app.heroku.com/207.97.227.239
28
+
29
+ Patches welcome, forks celebrated.
30
+
31
+ Copyright (c) 2010 [Jack Danger Canty](http://jåck.com). Released under the MIT License.
@@ -0,0 +1,46 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "geoip_server"
5
+ gem.summary = %Q{Query the MaxMind GeoIP data records via a web service}
6
+ gem.description = %Q{Query the MaxMind GeoIP data records via a web service}
7
+ gem.email = "gitcommit@6brand.com"
8
+ gem.homepage = "http://github.com/JackDanger/geoip_server"
9
+ gem.authors = ["Jack Danger Canty"]
10
+ gem.add_development_dependency "shoulda", ">= 0"
11
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
12
+ end
13
+ Jeweler::GemcutterTasks.new
14
+ rescue LoadError
15
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
16
+ end
17
+
18
+
19
+
20
+ task :default => :test
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << '.'
25
+ test.pattern = 'test.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+
30
+
31
+
32
+ namespace :geoip do
33
+ desc "Update GeoIP City data file"
34
+ task :update_city_lite => :vendor do
35
+ %x{wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz && gzip -d GeoLiteCity.dat.gz && mv GeoLiteCity.dat ./vendor}
36
+ end
37
+
38
+ desc "Update GeoIP Country data file"
39
+ task :update_country_lite => :vendor do
40
+ %x{wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz && gzip -d GeoIP.dat.gz && mv GeoIP.dat ./vendor}
41
+ end
42
+
43
+ task :vendor do
44
+ %x{mkdir -p vendor}
45
+ end
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,6 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib/geoip_server'))
2
+
3
+ ## There is no need to set directories here anymore;
4
+ ## Just run the application
5
+
6
+ run Sinatra::Application
@@ -0,0 +1,73 @@
1
+ ## Resources
2
+ gem 'sinatra', :version => '1.0'
3
+ require 'sinatra'
4
+ require 'geoip'
5
+ require 'json'
6
+
7
+ data_file = File.expand_path(File.join(File.dirname(__FILE__), '..', 'vendor', 'GeoLiteCity.dat'))
8
+
9
+ ## Application
10
+
11
+ get '/' do
12
+ %Q{
13
+ <html><title>Detect a computer's location by IP address</title>
14
+ <body style='line-height: 1.8em; font-family: Archer, Museo, Helvetica, Georgia; font-size 25px; text-align: center; padding-top: 20%;'>
15
+ Lookup a location by IP address. Example:
16
+ <pre style='font-family: Iconsolata, monospace;background-color:#EEE'>curl http://#{request.host}/207.97.227.239</pre>
17
+ <br />
18
+ <form action=/ method=GET onsubmit='if(\"\"==this.ip.value)return false;else{this.action=\"/\"+this.ip.value}'>
19
+ <input type=text name='ip' value='#{request.env['HTTP_X_REAL_IP']}' />
20
+ <input type=submit value='Lookup!' />
21
+ </form>
22
+ <div>None of this would be possible without <a href='http://www.maxmind.com/app/geolitecity'>MaxMind</a></div>
23
+ </body></html>
24
+ }
25
+ end
26
+
27
+ get '/:ip' do
28
+ pass unless params[:ip] =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
29
+
30
+ data = GeoIP.new(data_file).city(params[:ip])
31
+
32
+ content_type 'application/json'
33
+ headers['Cache-Control'] = "public; max-age=#{365*24*60*60}"
34
+
35
+ return "{}" unless data
36
+
37
+ encode(data).to_json
38
+
39
+ end
40
+
41
+ def encode data
42
+ {
43
+ # * The host or IP address string as requested
44
+ :ip => data.shift,
45
+ # * The IP address string after looking up the host
46
+ :ip_lookup => data.shift,
47
+ # * The GeoIP country-ID as an integer
48
+ # :country_id => data.shift,
49
+ # * The ISO3166-1 two-character country code
50
+ :country_code => data.shift,
51
+ # * The ISO3166-2 three-character country code
52
+ :country_code_long => data.shift,
53
+ # * The ISO3166 English-language name of the country
54
+ :country => data.shift,
55
+ # * The two-character continent code
56
+ :continent => data.shift,
57
+ # * The region name
58
+ :region => data.shift,
59
+ # * The city name
60
+ :city => data.shift,
61
+ # * The postal code
62
+ :postal_code => data.shift,
63
+ # * The latitude
64
+ :lat => data.shift,
65
+ # * The longitude
66
+ :lng => data.shift,
67
+ # * The USA dma_code and area_code, if available (REV1 City database)
68
+ :dma_code => data.shift,
69
+ :area_code => data.shift,
70
+ # Timezone, if available
71
+ :timezone => data.shift
72
+ }
73
+ end
data/test.rb ADDED
@@ -0,0 +1,73 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'shoulda'
6
+ require 'rack/test'
7
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib/geoip_server'))
8
+
9
+ class GeoipServerTest < Test::Unit::TestCase
10
+ include Rack::Test::Methods
11
+
12
+ def app
13
+ Sinatra::Application
14
+ end
15
+
16
+ context "on GET to /" do
17
+ setup {
18
+ get '/'
19
+ }
20
+ should "return ok" do
21
+ assert last_response.ok?
22
+ end
23
+ should "have some kind of welcome" do
24
+ assert last_response.body =~ /curl/
25
+ end
26
+ end
27
+
28
+ context "on GET to /:ip" do
29
+ setup {
30
+ get '/67.161.92.71'
31
+ }
32
+ should "return ok" do
33
+ assert last_response.ok?
34
+ end
35
+ should "return json content-type" do
36
+ assert_equal 'application/json', last_response.headers['Content-Type']
37
+ end
38
+ end
39
+
40
+ context "converting array" do
41
+ setup {
42
+ array = [
43
+ "67.161.92.71",
44
+ "67.161.92.71",
45
+ "US",
46
+ "USA",
47
+ "United States",
48
+ "NA",
49
+ "WA",
50
+ "Seattle",
51
+ "98117",
52
+ 47.6847,
53
+ -122.3848,
54
+ 819,
55
+ 206,
56
+ "America/Los_Angeles"
57
+ ]
58
+ @hash = encode(array)
59
+ }
60
+ should "find city" do
61
+ assert_equal 'Seattle', @hash[:city]
62
+ end
63
+ should "find country" do
64
+ assert_equal 'United States', @hash[:country]
65
+ end
66
+ should "find lat" do
67
+ assert_equal 47.6847, @hash[:lat]
68
+ end
69
+ should "find lng" do
70
+ assert_equal -122.3848, @hash[:lng]
71
+ end
72
+ end
73
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geoip_server
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Jack Danger Canty
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-27 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Query the MaxMind GeoIP data records via a web service
36
+ email: gitcommit@6brand.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.markdown
43
+ files:
44
+ - .gems
45
+ - README.markdown
46
+ - Rakefile
47
+ - VERSION
48
+ - config.ru
49
+ - lib/geoip_server.rb
50
+ - test.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/JackDanger/geoip_server
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --charset=UTF-8
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.3.7
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Query the MaxMind GeoIP data records via a web service
85
+ test_files: []
86
+