mtodd-geoip 0.5.0 → 0.5.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/README.md +46 -10
- data/Rakefile +8 -5
- data/geoip.c +55 -103
- data/test.rb +74 -22
- metadata +1 -1
data/README.md
CHANGED
@@ -15,7 +15,7 @@ mapping information. It is kindly provided free of charge by MaxMind.com.
|
|
15
15
|
Usage
|
16
16
|
|
17
17
|
require 'geoip'
|
18
|
-
db = GeoIP::City
|
18
|
+
db = GeoIP::City.new('/opt/GeoIP/share/GeoIP/GeoLiteCity.dat')
|
19
19
|
result = db.look_up('24.24.24.24')
|
20
20
|
p result
|
21
21
|
# => {:city=>"Ithaca",
|
@@ -49,8 +49,17 @@ There are arguments to database initializer.
|
|
49
49
|
|
50
50
|
For example
|
51
51
|
|
52
|
-
|
52
|
+
GeoIP::City.new(dbfile, :filesystem, true)
|
53
53
|
|
54
|
+
Usage for Organization Search
|
55
|
+
-----------------------------
|
56
|
+
|
57
|
+
require 'geoip'
|
58
|
+
db = GeoIP::Organization.new('/opt/GeoIP/share/GeoIP/GeoIPOrg.dat')
|
59
|
+
db.look_up('24.24.24.24')
|
60
|
+
# => {:name=>"Road Runner"}
|
61
|
+
|
62
|
+
The name is the only data available for Organizations.
|
54
63
|
|
55
64
|
Install
|
56
65
|
-------
|
@@ -69,18 +78,34 @@ Some variation of the following should work.
|
|
69
78
|
|
70
79
|
make && sudo make install
|
71
80
|
|
72
|
-
|
81
|
+
NOTE: for Intel Mac OS X platforms, try the following:
|
82
|
+
|
83
|
+
env ARCHFLAGS="-arch i386" ./configure --prefix=/opt/GeoIP
|
73
84
|
|
74
|
-
|
85
|
+
env ARCHFLAGS="-arch i386" make
|
86
|
+
|
87
|
+
sudo env ARCHFLAGS="-arch i386" make install
|
88
|
+
|
89
|
+
2. Now install the `geoip` gem
|
90
|
+
|
91
|
+
gem install mtodd-geoip -s http://gems.github.com/ -- --with-geoip-dir=/opt/GeoIP
|
75
92
|
|
76
93
|
3. Download the GeoLite City database file in binary format at http://www.maxmind.com/app/geolitecity
|
77
|
-
Maybe this [direct link](http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz) will work.
|
94
|
+
Maybe this [direct link](http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz) will work.
|
78
95
|
I put this file in
|
79
96
|
|
80
97
|
/opt/GeoIP/share/GeoIP/GeoLiteCity.dat
|
81
98
|
|
99
|
+
If you are a paying customer, you will download the files required below:
|
100
|
+
|
101
|
+
[MaxMind Customer Downloads](http://www.maxmind.com/app/download_files)
|
102
|
+
|
103
|
+
You will want to get the City Rev1 data file and Organization files at minimum.
|
104
|
+
|
82
105
|
4. Use it!
|
83
106
|
|
107
|
+
See above for usage details.
|
108
|
+
|
84
109
|
Hints
|
85
110
|
-----
|
86
111
|
|
@@ -92,14 +117,25 @@ Hints
|
|
92
117
|
|
93
118
|
Example:
|
94
119
|
|
95
|
-
|
120
|
+
env ARCHFLAGS="-arch i386" gem install mtodd-geoip -s http://gems.github.com/ -- --with-geoip-dir=/opt/GeoIP
|
96
121
|
|
97
|
-
2. You might find [this shell
|
98
|
-
script](http://github.com/grimen/my_shell_scripts/blob/8cf04cb6829e68a47f2d6f9d9e057766ea72beb4/install_geoip-city.sh)
|
122
|
+
2. You might find [this shell script](http://github.com/grimen/my_shell_scripts/blob/8cf04cb6829e68a47f2d6f9d9e057766ea72beb4/install_geoip-city.sh)
|
99
123
|
helpful to install the C library.
|
100
124
|
|
101
|
-
|
125
|
+
Links
|
126
|
+
-----
|
127
|
+
|
128
|
+
This iteration of the library is based on the hard work of Ryan Dahl (ry@tinyclouds.org). You can find the original RDocs and Git Repo below:
|
129
|
+
|
130
|
+
[rdocs](http://geoip-city.rubyforge.org/)
|
131
|
+
[git repo](https://github.com/ry/geoip-city/tree)
|
132
|
+
|
133
|
+
License
|
102
134
|
-------
|
103
135
|
Copyright (C) 2007--2009 Ryan Dahl (ry@tinyclouds.org), Matt Todd (mtodd@highgroove.com)
|
104
136
|
|
105
|
-
|
137
|
+
This program is free software. It comes without any warranty, to
|
138
|
+
the extent permitted by applicable law. You can redistribute it
|
139
|
+
and/or modify it under the terms of the Do What The Fuck You Want
|
140
|
+
To Public License, Version 2, as published by Sam Hocevar. See
|
141
|
+
http://sam.zoy.org/wtfpl/COPYING for more details.
|
data/Rakefile
CHANGED
@@ -22,13 +22,16 @@ end
|
|
22
22
|
|
23
23
|
spec = Gem::Specification.new do |s|
|
24
24
|
s.name = 'geoip'
|
25
|
-
s.
|
26
|
-
|
25
|
+
s.version = "0.5.1"
|
26
|
+
|
27
|
+
s.authors = ['Ryan Dahl', 'Matt Todd', 'Charles Brian Quinn']
|
27
28
|
s.email = 'mtodd@highgroove.com'
|
28
|
-
|
29
|
+
|
29
30
|
s.summary = "A Binding to the GeoIP C library"
|
31
|
+
s.description = 'Generic GeoIP lookup tool. Based on the geoip_city RubyGem by Ryan Dahl'
|
30
32
|
s.homepage = "http://github.com/mtodd/geoip"
|
31
|
-
|
33
|
+
|
34
|
+
s.files = ["Rakefile", "extconf.rb", "test.rb", "geoip.c", "README.md"]
|
32
35
|
s.test_files = 'test.rb'
|
33
36
|
s.extensions = 'extconf.rb'
|
34
37
|
s.require_path = '.'
|
@@ -44,7 +47,7 @@ task(:compile => 'Makefile') { sh 'make' }
|
|
44
47
|
file('Makefile' => "geoip.c") { ruby 'extconf.rb' }
|
45
48
|
|
46
49
|
task :install => [:gem] do
|
47
|
-
`
|
50
|
+
`env ARCHFLAGS="-arch i386" gem install pkg/geoip-0.5.0.gem -- --with-geoip-dir=/opt/GeoIP`
|
48
51
|
end
|
49
52
|
|
50
53
|
task(:webpage) do
|
data/geoip.c
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
/* ry dahl <ry@tinyclouds.org> May 21, 2007 */
|
2
|
+
/* Matt Todd <mtodd@highgroove.com> June 4, 2009 */
|
2
3
|
/* This program is free software. It comes without any warranty, to
|
3
4
|
* the extent permitted by applicable law. You can redistribute it
|
4
5
|
* and/or modify it under the terms of the Do What The Fuck You Want
|
@@ -15,11 +16,52 @@ static VALUE rb_geoip_memory;
|
|
15
16
|
static VALUE rb_geoip_filesystem;
|
16
17
|
static VALUE rb_geoip_index;
|
17
18
|
|
18
|
-
/*
|
19
|
+
/* helpers */
|
19
20
|
void rb_hash_sset(VALUE hash, const char *str, VALUE v) {
|
20
21
|
rb_hash_aset(hash, ID2SYM(rb_intern(str)), v);
|
21
22
|
}
|
22
23
|
|
24
|
+
int check_load_option(VALUE load_option) {
|
25
|
+
if(load_option == rb_geoip_memory) {
|
26
|
+
return GEOIP_MEMORY_CACHE;
|
27
|
+
} else if(load_option == rb_geoip_filesystem) {
|
28
|
+
return GEOIP_STANDARD;
|
29
|
+
} else if(load_option == rb_geoip_index) {
|
30
|
+
return GEOIP_INDEX_CACHE;
|
31
|
+
} else {
|
32
|
+
rb_raise(rb_eTypeError, "the second option must be :memory, :filesystem, or :index");
|
33
|
+
return Qnil;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
/* Generic initializer */
|
38
|
+
static VALUE rb_geoip_database_new(VALUE mGeoIP_Database_Class, int argc, VALUE *argv, VALUE self)
|
39
|
+
{
|
40
|
+
GeoIP *gi;
|
41
|
+
VALUE database = Qnil;
|
42
|
+
VALUE filename, load_option = Qnil, check_cache = Qnil;
|
43
|
+
int flag;
|
44
|
+
|
45
|
+
rb_scan_args(argc, argv, "12", &filename, &load_option, &check_cache);
|
46
|
+
if(NIL_P(load_option))
|
47
|
+
load_option = rb_geoip_memory;
|
48
|
+
if(NIL_P(check_cache))
|
49
|
+
check_cache = Qfalse;
|
50
|
+
Check_Type(load_option, T_SYMBOL);
|
51
|
+
|
52
|
+
if(flag = check_load_option(load_option)) flag;
|
53
|
+
|
54
|
+
if(RTEST(check_cache)) flag |= GEOIP_CHECK_CACHE;
|
55
|
+
|
56
|
+
if(gi = GeoIP_open(STR2CSTR(filename), flag)) {
|
57
|
+
database = Data_Wrap_Struct(mGeoIP_Database_Class, 0, GeoIP_delete, gi);
|
58
|
+
rb_obj_call_init(database, 0, 0);
|
59
|
+
} else {
|
60
|
+
rb_sys_fail("Problem opening database");
|
61
|
+
}
|
62
|
+
return database;
|
63
|
+
}
|
64
|
+
|
23
65
|
/* GeoIP::City ***************************************************************/
|
24
66
|
|
25
67
|
VALUE rb_city_record_to_hash(GeoIPRecord *record)
|
@@ -65,38 +107,7 @@ VALUE rb_city_record_to_hash(GeoIPRecord *record)
|
|
65
107
|
*/
|
66
108
|
static VALUE rb_geoip_city_new(int argc, VALUE *argv, VALUE self)
|
67
109
|
{
|
68
|
-
|
69
|
-
VALUE database = Qnil;
|
70
|
-
VALUE filename, load_option = Qnil, check_cache = Qnil;
|
71
|
-
int flag;
|
72
|
-
|
73
|
-
rb_scan_args(argc, argv, "12", &filename, &load_option, &check_cache);
|
74
|
-
if(NIL_P(load_option))
|
75
|
-
load_option = rb_geoip_memory;
|
76
|
-
if(NIL_P(check_cache))
|
77
|
-
check_cache = Qfalse;
|
78
|
-
Check_Type(load_option, T_SYMBOL);
|
79
|
-
|
80
|
-
if(load_option == rb_geoip_memory) {
|
81
|
-
flag = GEOIP_MEMORY_CACHE;
|
82
|
-
} else if(load_option == rb_geoip_filesystem) {
|
83
|
-
flag = GEOIP_STANDARD;
|
84
|
-
} else if(load_option == rb_geoip_index) {
|
85
|
-
flag = GEOIP_INDEX_CACHE;
|
86
|
-
} else {
|
87
|
-
rb_raise(rb_eTypeError, "the second option must be :memory, :filesystem, or :index");
|
88
|
-
return Qnil;
|
89
|
-
}
|
90
|
-
|
91
|
-
if(RTEST(check_cache)) flag |= GEOIP_CHECK_CACHE;
|
92
|
-
|
93
|
-
if(gi = GeoIP_open(STR2CSTR(filename), flag)) {
|
94
|
-
database = Data_Wrap_Struct(mGeoIP_City, 0, GeoIP_delete, gi);
|
95
|
-
rb_obj_call_init(database, 0, 0);
|
96
|
-
} else {
|
97
|
-
rb_sys_fail("Problem opening database");
|
98
|
-
}
|
99
|
-
return database;
|
110
|
+
return rb_geoip_database_new(mGeoIP_City, argc, argv, self);
|
100
111
|
}
|
101
112
|
|
102
113
|
/* Pass this function an IP address as a string, it will return a hash
|
@@ -124,84 +135,31 @@ VALUE rb_geoip_city_look_up(VALUE self, VALUE addr) {
|
|
124
135
|
|
125
136
|
/* GeoIP::Organization *******************************************************/
|
126
137
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
// rb_hash_sset(hash, "country_code3", rb_str_new2(record->country_code3));
|
135
|
-
// if(record->country_name)
|
136
|
-
// rb_hash_sset(hash, "country_name", rb_str_new2(record->country_name));
|
137
|
-
// if(record->region)
|
138
|
-
// rb_hash_sset(hash, "region", rb_str_new2(record->region));
|
139
|
-
// if(record->city)
|
140
|
-
// rb_hash_sset(hash, "city", rb_str_new2(record->city));
|
141
|
-
// if(record->postal_code)
|
142
|
-
// rb_hash_sset(hash, "postal_code", rb_str_new2(record->postal_code));
|
143
|
-
// if(record->latitude)
|
144
|
-
// rb_hash_sset(hash, "latitude", rb_float_new((double)record->latitude));
|
145
|
-
// if(record->longitude)
|
146
|
-
// rb_hash_sset(hash, "longitude", rb_float_new((double)record->longitude));
|
147
|
-
// if(record->dma_code)
|
148
|
-
// rb_hash_sset(hash, "dma_code", INT2NUM(record->dma_code));
|
149
|
-
// if(record->area_code)
|
150
|
-
// rb_hash_sset(hash, "area_code", INT2NUM(record->area_code));
|
151
|
-
//
|
152
|
-
// return hash;
|
153
|
-
// }
|
154
|
-
|
138
|
+
/* GeoIP::Organization.new('/path/to/GeoIPOrg.dat', load_option)
|
139
|
+
* load_option can be:
|
140
|
+
* * :memory - load the data into memory, fastest (default)
|
141
|
+
* * :filesystem - look up from filesystem, least memory intensive
|
142
|
+
* * :index - stores in memory most recent queries
|
143
|
+
*
|
144
|
+
*/
|
155
145
|
static VALUE rb_geoip_org_new(int argc, VALUE *argv, VALUE self)
|
156
146
|
{
|
157
|
-
|
158
|
-
VALUE database = Qnil;
|
159
|
-
VALUE filename, load_option = Qnil, check_cache = Qnil;
|
160
|
-
int flag;
|
161
|
-
|
162
|
-
rb_scan_args(argc, argv, "12", &filename, &load_option, &check_cache);
|
163
|
-
if(NIL_P(load_option))
|
164
|
-
load_option = rb_geoip_memory;
|
165
|
-
if(NIL_P(check_cache))
|
166
|
-
check_cache = Qfalse;
|
167
|
-
Check_Type(load_option, T_SYMBOL);
|
168
|
-
|
169
|
-
if(load_option == rb_geoip_memory) {
|
170
|
-
flag = GEOIP_MEMORY_CACHE;
|
171
|
-
} else if(load_option == rb_geoip_filesystem) {
|
172
|
-
flag = GEOIP_STANDARD;
|
173
|
-
} else if(load_option == rb_geoip_index) {
|
174
|
-
flag = GEOIP_INDEX_CACHE;
|
175
|
-
} else {
|
176
|
-
rb_raise(rb_eTypeError, "the second option must be :memory, :filesystem, or :index");
|
177
|
-
return Qnil;
|
178
|
-
}
|
179
|
-
|
180
|
-
if(RTEST(check_cache)) flag |= GEOIP_CHECK_CACHE;
|
181
|
-
|
182
|
-
if(gi = GeoIP_open(STR2CSTR(filename), flag)) {
|
183
|
-
database = Data_Wrap_Struct(mGeoIP_Organization, 0, GeoIP_delete, gi);
|
184
|
-
rb_obj_call_init(database, 0, 0);
|
185
|
-
} else {
|
186
|
-
rb_sys_fail("Problem opening database");
|
187
|
-
}
|
188
|
-
return database;
|
147
|
+
return rb_geoip_database_new(mGeoIP_Organization, argc, argv, self);
|
189
148
|
}
|
190
149
|
|
191
150
|
/* Pass this function an IP address as a string, it will return a hash
|
192
|
-
* containing all the information that the database knows about the IP
|
151
|
+
* containing all the information that the database knows about the IP:
|
193
152
|
* db.look_up('24.24.24.24')
|
194
|
-
* => {}
|
153
|
+
* => {:name => "Road Runner"}
|
195
154
|
*/
|
196
155
|
VALUE rb_geoip_org_look_up(VALUE self, VALUE addr) {
|
197
156
|
GeoIP *gi;
|
198
|
-
GeoIPRecord *record = NULL;
|
199
157
|
VALUE hash = rb_hash_new();
|
200
158
|
char * name = NULL;
|
201
159
|
|
202
160
|
Check_Type(addr, T_STRING);
|
203
161
|
Data_Get_Struct(self, GeoIP, gi);
|
204
|
-
if(name =
|
162
|
+
if(name = GeoIP_name_by_addr(gi, STR2CSTR(addr))) {
|
205
163
|
rb_hash_sset(hash, "name", rb_str_new2(name));
|
206
164
|
}
|
207
165
|
return hash;
|
@@ -209,12 +167,6 @@ VALUE rb_geoip_org_look_up(VALUE self, VALUE addr) {
|
|
209
167
|
|
210
168
|
/* GeoIP *********************************************************************/
|
211
169
|
|
212
|
-
/* module GeoIP
|
213
|
-
* class City; end
|
214
|
-
* class Organization; end
|
215
|
-
* end
|
216
|
-
*/
|
217
|
-
|
218
170
|
void Init_geoip()
|
219
171
|
{
|
220
172
|
mGeoIP = rb_define_module("GeoIP");
|
data/test.rb
CHANGED
@@ -1,19 +1,28 @@
|
|
1
1
|
require 'test/unit'
|
2
|
-
require File.dirname(__FILE__) + '/
|
2
|
+
require File.dirname(__FILE__) + '/geoip'
|
3
3
|
require 'rubygems'
|
4
|
-
require 'ruby-debug'
|
5
|
-
Debugger.start
|
4
|
+
# require 'ruby-debug'
|
5
|
+
# Debugger.start
|
6
6
|
|
7
|
-
class
|
7
|
+
class Test::Unit::TestCase
|
8
|
+
|
9
|
+
def assert_look_up(db, addr, field, value)
|
10
|
+
h = db.look_up(addr)
|
11
|
+
assert_equal value, h[field]
|
12
|
+
h
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
class GeoIPCityTest < Test::Unit::TestCase
|
8
18
|
|
9
19
|
def setup
|
10
20
|
## Change me!
|
11
|
-
@dbfile = '/opt/GeoIP
|
21
|
+
@dbfile = '/opt/GeoIP/share/GeoIP/GeoLiteCity.dat'
|
12
22
|
end
|
13
|
-
|
14
|
-
|
23
|
+
|
15
24
|
def test_construction_default
|
16
|
-
db =
|
25
|
+
db = GeoIP::City.new(@dbfile)
|
17
26
|
|
18
27
|
assert_raises TypeError do
|
19
28
|
db.look_up(nil)
|
@@ -22,38 +31,81 @@ class GeoIPTest < Test::Unit::TestCase
|
|
22
31
|
h = db.look_up('24.24.24.24')
|
23
32
|
#debugger
|
24
33
|
assert_kind_of Hash, h
|
25
|
-
assert_equal '
|
34
|
+
assert_equal 'Jamaica', h[:city]
|
26
35
|
assert_equal 'United States', h[:country_name]
|
27
36
|
end
|
28
37
|
|
29
38
|
def test_construction_index
|
30
|
-
db =
|
31
|
-
|
32
|
-
assert_equal 'Ithaca', h[:city]
|
39
|
+
db = GeoIP::City.new(@dbfile, :index)
|
40
|
+
assert_look_up(db, '24.24.24.24', :city, 'Jamaica')
|
33
41
|
end
|
34
42
|
|
35
43
|
def test_construction_filesystem
|
36
|
-
db =
|
37
|
-
|
38
|
-
assert_equal 'Ithaca', h[:city]
|
44
|
+
db = GeoIP::City.new(@dbfile, :filesystem)
|
45
|
+
assert_look_up(db, '24.24.24.24', :city, 'Jamaica')
|
39
46
|
end
|
40
47
|
|
41
48
|
def test_construction_memory
|
42
|
-
db =
|
43
|
-
|
44
|
-
assert_equal 'Ithaca', h[:city]
|
49
|
+
db = GeoIP::City.new(@dbfile, :memory)
|
50
|
+
assert_look_up(db, '24.24.24.24', :city, 'Jamaica')
|
45
51
|
end
|
46
52
|
|
47
53
|
def test_construction_filesystem_check
|
48
|
-
db =
|
49
|
-
|
50
|
-
assert_equal 'Ithaca', h[:city]
|
54
|
+
db = GeoIP::City.new(@dbfile, :filesystem, true)
|
55
|
+
assert_look_up(db, '24.24.24.24', :city, 'Jamaica')
|
51
56
|
end
|
52
57
|
|
53
58
|
def test_bad_db_file
|
54
59
|
assert_raises Errno::ENOENT do
|
55
|
-
|
60
|
+
GeoIP::City.new('/blah')
|
56
61
|
end
|
57
62
|
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
class GeoIPOrgTest < Test::Unit::TestCase
|
58
67
|
|
68
|
+
def setup
|
69
|
+
## Change me!
|
70
|
+
@dbfile = '/opt/GeoIP/share/GeoIP/GeoIPOrg.dat'
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_construction_default
|
74
|
+
db = GeoIP::Organization.new(@dbfile)
|
75
|
+
|
76
|
+
assert_raises TypeError do
|
77
|
+
db.look_up(nil)
|
78
|
+
end
|
79
|
+
|
80
|
+
h = db.look_up('24.24.24.24')
|
81
|
+
assert_kind_of Hash, h
|
82
|
+
assert_equal 'Road Runner', h[:name]
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_construction_index
|
86
|
+
db = GeoIP::Organization.new(@dbfile, :index)
|
87
|
+
assert_look_up(db, '24.24.24.24', :name, 'Road Runner')
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_construction_filesystem
|
91
|
+
db = GeoIP::Organization.new(@dbfile, :filesystem)
|
92
|
+
assert_look_up(db, '24.24.24.24', :name, 'Road Runner')
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_construction_memory
|
96
|
+
db = GeoIP::Organization.new(@dbfile, :memory)
|
97
|
+
assert_look_up(db, '24.24.24.24', :name, 'Road Runner')
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_construction_filesystem_check
|
101
|
+
db = GeoIP::Organization.new(@dbfile, :filesystem, true)
|
102
|
+
assert_look_up(db, '24.24.24.24', :name, 'Road Runner')
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_bad_db_file
|
106
|
+
assert_raises Errno::ENOENT do
|
107
|
+
GeoIP::Organization.new('/blah')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
59
111
|
end
|