geoip_city 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.
Files changed (6) hide show
  1. data/README +50 -0
  2. data/Rakefile +43 -0
  3. data/extconf.rb +7 -0
  4. data/geoip_city.c +88 -0
  5. data/test.rb +25 -0
  6. 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.
@@ -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' }
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("geoip")
4
+
5
+ if have_library('GeoIP', 'GeoIP_record_by_ipnum') and have_header('GeoIPCity.h')
6
+ create_makefile('geoip_city')
7
+ end
@@ -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
+