mmdb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/ext/mmdb/extconf.rb +5 -0
  3. data/ext/mmdb/mmdb.c +216 -0
  4. metadata +89 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad529fdf8ed88f374d68a50945c7d35545e5e951
4
+ data.tar.gz: 1df94fc12ba9eb92b999e2fa0944dbcdeae89072
5
+ SHA512:
6
+ metadata.gz: 3d3bd638e59a2c155bb00cbb320a9bc909f0543441a74504b5d667fec5d96e7bd38da9caed2caac2d356960bcbcf6afe70e2e255150025dd857b15310abff377
7
+ data.tar.gz: e85ff600fb171883011c9ce26821f2c0c68cbf29d9563aee1d92b9d1016fca359e725416f9a7d95bc3a6e5831a328a0fb9cb54b461b69279146e593773c6b92b
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ if have_header("maxminddb.h") && have_library("maxminddb")
4
+ create_makefile("mmdb")
5
+ end
@@ -0,0 +1,216 @@
1
+ #include <ruby.h>
2
+
3
+ #include <maxminddb.h>
4
+ #include <netdb.h>
5
+ #include <stdio.h>
6
+ #include <sys/socket.h>
7
+ #include <sys/types.h>
8
+
9
+ static VALUE rb_cMaxMindDB;
10
+
11
+ static VALUE rb_sym_city;
12
+ static VALUE rb_sym_country;
13
+ static VALUE rb_sym_country_code;
14
+ static VALUE rb_sym_continent;
15
+ static VALUE rb_sym_latitude;
16
+ static VALUE rb_sym_longitude;
17
+ static VALUE rb_sym_postcode;
18
+
19
+ const static char *en = "en";
20
+ const static char *names = "names";
21
+ const static char *city = "city";
22
+ const static char *country = "country";
23
+ const static char *country_code = "country_code";
24
+ const static char *continent = "continent";
25
+ const static char *location = "location";
26
+ const static char *latitude = "latitude";
27
+ const static char *longitude = "longitude";
28
+ const static char *postal = "postal";
29
+ const static char *code = "code";
30
+ const static char *iso_code = "iso_code";
31
+ const static char *postcode = "postcode";
32
+
33
+ struct MaxMindDB {
34
+ MMDB_s *mmdb;
35
+ };
36
+
37
+ static size_t
38
+ maxminddb_memsize(const void *p) {
39
+ const struct MaxMindDB *ptr = p;
40
+ size_t size = 0;
41
+
42
+ if (ptr) {
43
+ size += sizeof(ptr);
44
+ if (ptr->mmdb) {
45
+ size += sizeof(MMDB_s);
46
+ }
47
+ }
48
+
49
+ return size;
50
+ }
51
+
52
+ void
53
+ maxminddb_free(void *p) {
54
+ struct MaxMindDB *ptr = p;
55
+ if (ptr) {
56
+ if (ptr->mmdb) {
57
+ MMDB_close(ptr->mmdb);
58
+ }
59
+ xfree(ptr);
60
+ }
61
+ }
62
+
63
+ static const rb_data_type_t mmdb_data_type = {
64
+ "mmdb",
65
+ {0, maxminddb_free, maxminddb_memsize,},
66
+ 0, 0,
67
+ RUBY_TYPED_FREE_IMMEDIATELY,
68
+ };
69
+
70
+ #define check_maxminddb(self) ((struct MaxMindDB*)rb_check_typeddata((self), &mmdb_data_type))
71
+
72
+ static struct MaxMindDB*
73
+ get_maxminddb(VALUE self) {
74
+ struct MaxMindDB *ptr = check_maxminddb(self);
75
+ if (!ptr) {
76
+ rb_raise(rb_eStandardError, "uninitialized");
77
+ }
78
+ return ptr;
79
+ }
80
+
81
+ #define MaxMindDB(self) get_maxminddb(self)
82
+
83
+ static VALUE
84
+ maxminddb_alloc(VALUE klass) {
85
+ return TypedData_Wrap_Struct(klass, &mmdb_data_type, 0);
86
+ }
87
+
88
+ static void
89
+ maxminddb_set_result(VALUE hash, VALUE key, MMDB_entry_data_s *data) {
90
+ if (data->has_data) {
91
+ switch (data->type) {
92
+ case MMDB_DATA_TYPE_UTF8_STRING:
93
+ rb_hash_aset(hash, key, rb_utf8_str_new(data->utf8_string, data->data_size));
94
+ break;
95
+ case MMDB_DATA_TYPE_DOUBLE:
96
+ rb_hash_aset(hash, key, rb_float_new(data->double_value));
97
+ break;
98
+ default:
99
+ rb_hash_aset(hash, key, Qnil);
100
+ }
101
+ } else {
102
+ rb_hash_aset(hash, key, Qnil);
103
+ }
104
+ }
105
+
106
+ VALUE
107
+ maxminddb_initialize(int argc, VALUE* argv, VALUE self) {
108
+ VALUE db_path;
109
+ MMDB_s *mmdb = ALLOC(MMDB_s);
110
+ struct MaxMindDB *ptr;
111
+
112
+ rb_scan_args(argc, argv, "1", &db_path);
113
+
114
+ FilePathValue(db_path);
115
+
116
+ if (MMDB_open(StringValuePtr(db_path), MMDB_MODE_MMAP, mmdb) != MMDB_SUCCESS) {
117
+ rb_sys_fail_str(db_path);
118
+ }
119
+
120
+ ptr = ALLOC(struct MaxMindDB);
121
+ DATA_PTR(self) = ptr;
122
+ ptr->mmdb = mmdb;
123
+
124
+ return self;
125
+ }
126
+
127
+ /**
128
+ *
129
+ * mmdb.lookup("123.45.67.89") -> Hash
130
+ *
131
+ * TODO:
132
+ * To receive `opts` argument that have language code and respond specified language data.
133
+ */
134
+ VALUE
135
+ maxminddb_lookup(VALUE self, VALUE ip) {
136
+ VALUE ret;
137
+ char *target;
138
+ int gai_error, mmdb_error;
139
+ struct MaxMindDB *ptr = MaxMindDB(self);
140
+ MMDB_s *mmdb = ptr->mmdb;
141
+
142
+ if (NIL_P(ip)) {
143
+ return Qnil;
144
+ }
145
+
146
+ target = StringValuePtr(ip);
147
+
148
+ MMDB_lookup_result_s lookuped = MMDB_lookup_string(mmdb, target, &gai_error, &mmdb_error);
149
+ if (gai_error) {
150
+ rb_sys_fail(gai_strerror(gai_error));
151
+ }
152
+ if (mmdb_error) {
153
+ rb_sys_fail(MMDB_strerror(mmdb_error));
154
+ }
155
+
156
+ if (lookuped.found_entry) {
157
+ ret = rb_hash_new();
158
+ MMDB_entry_data_s data;
159
+ MMDB_entry_s *entry = &lookuped.entry;
160
+ MMDB_get_value(entry, &data, city, names, en, NULL);
161
+ maxminddb_set_result(ret, rb_sym_city, &data);
162
+ MMDB_get_value(entry, &data, country, names, en, NULL);
163
+ maxminddb_set_result(ret, rb_sym_country, &data);
164
+ MMDB_get_value(entry, &data, country, iso_code, NULL);
165
+ maxminddb_set_result(ret, rb_sym_country_code, &data);
166
+ MMDB_get_value(entry, &data, continent, names, en, NULL);
167
+ maxminddb_set_result(ret, rb_sym_continent, &data);
168
+ MMDB_get_value(entry, &data, location, latitude, NULL);
169
+ maxminddb_set_result(ret, rb_sym_latitude, &data);
170
+ MMDB_get_value(entry, &data, location, longitude, NULL);
171
+ maxminddb_set_result(ret, rb_sym_longitude, &data);
172
+ MMDB_get_value(entry, &data, postal, code, NULL);
173
+ maxminddb_set_result(ret, rb_sym_postcode, &data);
174
+ } else {
175
+ ret = Qnil;
176
+ }
177
+
178
+ return ret;
179
+ }
180
+
181
+ VALUE
182
+ maxminddb_close(VALUE self) {
183
+ struct MaxMindDB *ptr = MaxMindDB(self);
184
+
185
+ if (ptr) {
186
+ if (ptr->mmdb) {
187
+ MMDB_close(ptr->mmdb);
188
+ }
189
+ }
190
+
191
+ return Qnil;
192
+ }
193
+
194
+ void
195
+ maxminddb_init_rb_variables() {
196
+ rb_sym_city = rb_to_symbol(rb_str_new2(city));
197
+ rb_sym_country = rb_to_symbol(rb_str_new2(country));
198
+ rb_sym_country_code = rb_to_symbol(rb_str_new2(country_code));
199
+ rb_sym_continent = rb_to_symbol(rb_str_new2(continent));
200
+ rb_sym_latitude = rb_to_symbol(rb_str_new2(latitude));
201
+ rb_sym_longitude = rb_to_symbol(rb_str_new2(longitude));
202
+ rb_sym_postcode = rb_to_symbol(rb_str_new2(postcode));
203
+ }
204
+
205
+ void
206
+ Init_mmdb() {
207
+ rb_cMaxMindDB = rb_define_class("MaxMindDB", rb_cObject);
208
+
209
+ rb_define_alloc_func(rb_cMaxMindDB, maxminddb_alloc);
210
+
211
+ rb_define_method(rb_cMaxMindDB, "initialize", maxminddb_initialize, -1);
212
+ rb_define_method(rb_cMaxMindDB, "lookup", maxminddb_lookup, 1);
213
+ rb_define_method(rb_cMaxMindDB, "close", maxminddb_close, 0);
214
+
215
+ maxminddb_init_rb_variables();
216
+ }
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mmdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - yoppi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: Fast looking-up IP address from MaxMindDB(GeoIP2 format)
56
+ email:
57
+ - y.hirokazu@gmail.com
58
+ executables: []
59
+ extensions:
60
+ - ext/mmdb/extconf.rb
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ext/mmdb/extconf.rb
64
+ - ext/mmdb/mmdb.c
65
+ homepage: https://github.com/yoppi/mmdb
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.5.1
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: MaxMindDB client for Ruby
89
+ test_files: []