geoip_city 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +50 -0
- data/Rakefile +43 -0
- data/extconf.rb +7 -0
- data/geoip_city.c +88 -0
- data/test.rb +25 -0
- metadata +50 -0
data/README
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
= What?
|
2
|
+
This is a library which provides a single function. The function takes as
|
3
|
+
input an IP address and it outputs a hash containing best-guess geographical
|
4
|
+
information (like city, country, latitude, and longitude).
|
5
|
+
|
6
|
+
Actually this is only a Ruby binding to a C library which provides this
|
7
|
+
function. Also, you must download a large binary database with all this
|
8
|
+
mapping information. It is kindly provided free of charge by MaxMind.com.
|
9
|
+
|
10
|
+
= How To Use
|
11
|
+
Some variation of the following should work.
|
12
|
+
|
13
|
+
1. Install the GeoCity C library. You can get it from here
|
14
|
+
http://www.maxmind.com/app/c
|
15
|
+
For example, I like to install mine in /opt/GeoIP
|
16
|
+
so I do this:
|
17
|
+
tar -zxvf GeoIP-1.4.3.tar.gz
|
18
|
+
cd GeoIP-1.4.3
|
19
|
+
./configure --prefix=/opt/GeoIP
|
20
|
+
make && sudo make install
|
21
|
+
|
22
|
+
2. Now install the geoip Ruby gem (this package!)
|
23
|
+
|
24
|
+
Hint: You need to make sure that gcc can find the GeoIP header and library
|
25
|
+
files. One way to do this is to ensure that your CPATH and LIBRARY_PATH
|
26
|
+
enviromental variables include the GeoIP directory. So, if you want, do
|
27
|
+
this:
|
28
|
+
export CPATH="/opt/GeoIP/include:$CPATH"
|
29
|
+
export LIBRARY_PATH="/opt/GeoIP/lib:$LIBRARY_PATH"
|
30
|
+
sudo gem install geoip_city
|
31
|
+
|
32
|
+
|
33
|
+
3. Download the GeoLite City database file in binary format from:
|
34
|
+
http://www.maxmind.com/app/geolitecity
|
35
|
+
Maybe this direct link will work:
|
36
|
+
http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
|
37
|
+
I put this file in
|
38
|
+
/opt/GeoIP/share/GeoIP/GeoLiteCity.dat
|
39
|
+
|
40
|
+
|
41
|
+
4. Use it!
|
42
|
+
require 'geoip'
|
43
|
+
db = GeoIP::Database.new('/opt/GeoIP/share/GeoIP/GeoLiteCity.dat')
|
44
|
+
result = db.look_up('24.24.24.24')
|
45
|
+
puts result.inspect
|
46
|
+
|
47
|
+
= License
|
48
|
+
Copyright (C) 2007 Ryan Dahl (ry@tinyclouds.org)
|
49
|
+
|
50
|
+
I give permission for you to do whatever you'd like to do with this software.
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
|
7
|
+
task :default => [:compile, :test]
|
8
|
+
|
9
|
+
CLEAN.add "geoip_city.{o,bundle,so,obj,pdb,lib,def,exp}"
|
10
|
+
CLOBBER.add ['Makefile', 'mkmf.log','doc']
|
11
|
+
|
12
|
+
Rake::RDocTask.new do |rdoc|
|
13
|
+
rdoc.rdoc_files.add ['README', 'geoip_city.c']
|
14
|
+
rdoc.main = "README" # page to start on
|
15
|
+
rdoc.rdoc_dir = 'doc/' # rdoc output folder
|
16
|
+
end
|
17
|
+
|
18
|
+
Rake::TestTask.new do |t|
|
19
|
+
t.test_files = 'test.rb'
|
20
|
+
t.verbose = true
|
21
|
+
end
|
22
|
+
|
23
|
+
spec = Gem::Specification.new do |s|
|
24
|
+
s.name = 'geoip_city'
|
25
|
+
s.author = 'ry dahl'
|
26
|
+
s.email = 'ry@tinyclouds.org'
|
27
|
+
s.version = "0.1"
|
28
|
+
s.summary = "A Binding to the GeoIP C library"
|
29
|
+
s.homepage = "http://geoip_city.rubyforge.org"
|
30
|
+
s.files = FileList['Rakefile', '*.rb', '*.c', 'README*']
|
31
|
+
s.test_files = 'test.rb'
|
32
|
+
s.extensions = 'extconf.rb'
|
33
|
+
s.require_path = '.'
|
34
|
+
end
|
35
|
+
|
36
|
+
Rake::GemPackageTask.new(spec) do |p|
|
37
|
+
p.need_tar = true
|
38
|
+
p.gem_spec = spec
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'compile the extension'
|
42
|
+
task(:compile => 'Makefile') { sh 'make' }
|
43
|
+
file('Makefile' => "geoip_city.c") { ruby 'extconf.rb' }
|
data/extconf.rb
ADDED
data/geoip_city.c
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
/* ry dahl <ry@tinyclouds.org> May 21, 2007 */
|
2
|
+
/* This program is free software. It comes without any warranty, to
|
3
|
+
* the extent permitted by applicable law. You can redistribute it
|
4
|
+
* and/or modify it under the terms of the Do What The Fuck You Want
|
5
|
+
* To Public License, Version 2, as published by Sam Hocevar. See
|
6
|
+
* http://sam.zoy.org/wtfpl/COPYING for more details. */
|
7
|
+
#include <ruby.h>
|
8
|
+
#include <GeoIP.h>
|
9
|
+
#include <GeoIPCity.h>
|
10
|
+
|
11
|
+
static VALUE cDB;
|
12
|
+
|
13
|
+
/* The argument is the filename of the GeoIPCity.dat file */
|
14
|
+
VALUE rb_geoip_new(VALUE self, VALUE filename) {
|
15
|
+
GeoIP *gi;
|
16
|
+
VALUE database = Qnil;
|
17
|
+
|
18
|
+
if(gi = GeoIP_open(STR2CSTR(filename), GEOIP_MEMORY_CACHE)) {
|
19
|
+
database = Data_Wrap_Struct(cDB, 0, GeoIP_delete, gi);
|
20
|
+
rb_obj_call_init(database, 0, 0);
|
21
|
+
}
|
22
|
+
return database;
|
23
|
+
}
|
24
|
+
|
25
|
+
/* helper */
|
26
|
+
void rb_hash_sset(VALUE hash, const char *str, VALUE v) {
|
27
|
+
rb_hash_aset(hash, ID2SYM(rb_intern(str)), v);
|
28
|
+
}
|
29
|
+
|
30
|
+
VALUE rb_record_to_hash (GeoIPRecord *record)
|
31
|
+
{
|
32
|
+
VALUE hash = rb_hash_new();
|
33
|
+
|
34
|
+
if(record->country_code)
|
35
|
+
rb_hash_sset(hash, "country_code", rb_str_new2(record->country_code));
|
36
|
+
if(record->country_code3)
|
37
|
+
rb_hash_sset(hash, "country_code3", rb_str_new2(record->country_code3));
|
38
|
+
if(record->country_name)
|
39
|
+
rb_hash_sset(hash, "country_name", rb_str_new2(record->country_name));
|
40
|
+
if(record->region)
|
41
|
+
rb_hash_sset(hash, "region", rb_str_new2(record->region));
|
42
|
+
if(record->city)
|
43
|
+
rb_hash_sset(hash, "city", rb_str_new2(record->city));
|
44
|
+
if(record->postal_code)
|
45
|
+
rb_hash_sset(hash, "postal_code", rb_str_new2(record->postal_code));
|
46
|
+
if(record->latitude)
|
47
|
+
rb_hash_sset(hash, "latitude", rb_float_new((double)record->latitude));
|
48
|
+
if(record->longitude)
|
49
|
+
rb_hash_sset(hash, "longitude", rb_float_new((double)record->longitude));
|
50
|
+
if(record->dma_code)
|
51
|
+
rb_hash_sset(hash, "dma_code", INT2NUM(record->dma_code));
|
52
|
+
if(record->area_code)
|
53
|
+
rb_hash_sset(hash, "area_code", INT2NUM(record->area_code));
|
54
|
+
|
55
|
+
return hash;
|
56
|
+
}
|
57
|
+
|
58
|
+
/* Pass this function an IP address as a string, it will return a hash
|
59
|
+
* containing all the information that the database knows about the IP
|
60
|
+
* db.look_up('24.24.24.24')
|
61
|
+
* => {:city=>"Ithaca", :latitude=>42.4277992248535,
|
62
|
+
* :country_code=>"US", :longitude=>-76.4981994628906,
|
63
|
+
* :country_code3=>"USA", :dma_code=>555,
|
64
|
+
* :country_name=>"United States", :area_code=>607,
|
65
|
+
* :region=>"NY"}
|
66
|
+
*/
|
67
|
+
VALUE rb_geoip_look_up(VALUE self, VALUE addr) {
|
68
|
+
GeoIP *gi;
|
69
|
+
GeoIPRecord *record = NULL;
|
70
|
+
VALUE hash = Qnil;
|
71
|
+
|
72
|
+
Check_Type(addr, T_STRING);
|
73
|
+
Data_Get_Struct(self, GeoIP, gi);
|
74
|
+
if(record = GeoIP_record_by_addr(gi, STR2CSTR(addr))) {
|
75
|
+
hash = rb_record_to_hash(record);
|
76
|
+
GeoIPRecord_delete(record);
|
77
|
+
}
|
78
|
+
return hash;
|
79
|
+
}
|
80
|
+
|
81
|
+
void Init_geoip_city ()
|
82
|
+
{
|
83
|
+
VALUE mGeoIP = rb_define_module("GeoIPCity");
|
84
|
+
|
85
|
+
cDB = rb_define_class_under(mGeoIP, "Database", rb_cObject);
|
86
|
+
rb_define_singleton_method(cDB, "new", rb_geoip_new, 1);
|
87
|
+
rb_define_method(cDB, "look_up", rb_geoip_look_up, 1);
|
88
|
+
}
|
data/test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'geoip_city'
|
3
|
+
|
4
|
+
class GeoIPTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
## Change me!
|
8
|
+
@dbfile = '/opt/GeoIP-1.4.2/share/GeoIP/GeoLiteCity.dat'
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def test_construction
|
13
|
+
db = GeoIPCity::Database.new(@dbfile)
|
14
|
+
|
15
|
+
assert_raises TypeError do
|
16
|
+
db.look_up(nil)
|
17
|
+
end
|
18
|
+
|
19
|
+
h = db.look_up('24.24.24.24')
|
20
|
+
assert_kind_of Hash, h
|
21
|
+
assert_equal 'Ithaca', h[:city]
|
22
|
+
assert_equal 'United States', h[:country_name]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: geoip_city
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.1"
|
7
|
+
date: 2007-10-27 00:00:00 +02:00
|
8
|
+
summary: A Binding to the GeoIP C library
|
9
|
+
require_paths:
|
10
|
+
- .
|
11
|
+
email: ry@tinyclouds.org
|
12
|
+
homepage: http://geoip_city.rubyforge.org
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- ry dahl
|
31
|
+
files:
|
32
|
+
- Rakefile
|
33
|
+
- extconf.rb
|
34
|
+
- test.rb
|
35
|
+
- geoip_city.c
|
36
|
+
- README
|
37
|
+
test_files:
|
38
|
+
- test.rb
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions:
|
46
|
+
- extconf.rb
|
47
|
+
requirements: []
|
48
|
+
|
49
|
+
dependencies: []
|
50
|
+
|