geoip2_c 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a385241251a43ddd2d075ae6edf6079eee160022
4
+ data.tar.gz: ba99231f74e179e16f3274eda636860123e2923b
5
+ SHA512:
6
+ metadata.gz: 460dc2adc04bb35833fe48b27688a8d1709ad39526e067bc13ce41d64bb85ee10326c6ff5f493668fad85d135ff213aad862f292e9754db518770e023b2e8756
7
+ data.tar.gz: 81b9fb3f1b408568894747fe0695d5892250a94dfdc373c663c6fdcd3d6d9def2fc3eacdeffbfdff77fb303b8fff75cb12ae742284eadba62400cf3b0f5a445d
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "test/MaxMind-DB"]
2
+ path = test/MaxMind-DB
3
+ url = https://github.com/maxmind/MaxMind-DB.git
data/.travis.yml ADDED
@@ -0,0 +1,25 @@
1
+ sudo: required
2
+ services:
3
+ - docker
4
+
5
+ env:
6
+ DOCKER_COMPOSE_VERSION: 1.8.1
7
+
8
+ before_install:
9
+ #- sudo apt-get update
10
+ #- sudo apt-get install -y docker-engine
11
+ - sudo rm /usr/local/bin/docker-compose
12
+ - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) > docker-compose
13
+ - chmod +x docker-compose
14
+ - sudo mv docker-compose /usr/local/bin/
15
+
16
+ before_script:
17
+ - docker-compose build
18
+ - docker-compose ps
19
+ - docker-compose up -d
20
+ - docker-compose exec test bundle install
21
+ - docker-compose exec test bundle exec rake compile
22
+
23
+ script:
24
+ - docker-compose exec test bundle exec rake test
25
+
data/Dockerfile ADDED
@@ -0,0 +1,6 @@
1
+ FROM ruby:2.3.3-alpine
2
+
3
+ RUN apk --no-cache --update add build-base ruby-dev libc6-compat libmaxminddb-dev git
4
+
5
+ WORKDIR /app
6
+ COPY . .
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in geoip2_c.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 okkez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # GeoIP2
2
+
3
+ This gem provides binding [libmaxminddb](http://maxmind.github.io/libmaxminddb/).
4
+
5
+ This binding does not traverse all elements in lookup result by default.
6
+ So you can get the element you want fast such as city name, country name or etc.
7
+
8
+ ## Requirements
9
+
10
+ * Ruby 2.3 or later
11
+
12
+ NOTE:
13
+
14
+ This library uses `Hash#dig` and `Array#dig`.
15
+ If you want to use this library with Ruby2.1 or Ruby2.2, you can install a gem which adds support `#dig` method.
16
+ But I don't want to add extra dependency to this library, so I decided not to add extra dependency to support old Ruby versions.
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ ```ruby
23
+ gem 'geoip2_c'
24
+ ```
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install geoip2_c
33
+
34
+ ## Usage
35
+
36
+ ```ruby
37
+ require "geoip2"
38
+
39
+ db = GeoIP2::Databaes.new("/path/to/GeoLite2-City.mmdb")
40
+ result = db.lookup("66.102.9.80")
41
+ retuls.get_value("city", "names", "en") # => "Mountain View"
42
+ ```
43
+
44
+ ## Development
45
+
46
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake test` to run the tests.
47
+
48
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
49
+
50
+ ## Contributing
51
+
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/okkez/geoip2_c.
53
+
54
+ ## License
55
+
56
+ The gem is available as open source under the terms of the [Apache-2.0](http://opensource.org/licenses/Apache-2.0).
57
+
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/test_*.rb"]
8
+ end
9
+
10
+ require "rake/extensiontask"
11
+
12
+ task :build => :compile
13
+
14
+ Rake::ExtensionTask.new("geoip2") do |ext|
15
+ ext.lib_dir = "lib/geoip2"
16
+ end
17
+
18
+ task :default => [:clobber, :compile, :test]
@@ -0,0 +1,6 @@
1
+ version: "2"
2
+ services:
3
+ test:
4
+ build:
5
+ context: .
6
+ command: ruby -run -e httpd
@@ -0,0 +1,10 @@
1
+ require "mkmf"
2
+
3
+ dir_config("maxminddb")
4
+ have_header("maxminddb.h")
5
+ have_library("maxminddb")
6
+
7
+ $CFLAGS << " -std=c99"
8
+ # $CFLAGS << " -g -O0"
9
+
10
+ create_makefile("geoip2/geoip2")
@@ -0,0 +1,421 @@
1
+ #include <ruby.h>
2
+ #include <ruby/encoding.h>
3
+ #include <maxminddb.h>
4
+
5
+ VALUE rb_mGeoIP2;
6
+ VALUE rb_cGeoIP2Database;
7
+ VALUE rb_cGeoIP2LookupResult;
8
+ VALUE rb_eGeoIP2Error;
9
+
10
+ static void mmdb_open(const char *db_path, MMDB_s *mmdb);
11
+ static void mmdb_close(MMDB_s *mmdb);
12
+ static bool mmdb_is_closed(MMDB_s *mmdb);
13
+ static void mmdb_free(void *mmdb);
14
+ static MMDB_lookup_result_s mmdb_lookup(MMDB_s *mmdb, const char *ip_str, bool cleanup);
15
+ static VALUE mmdb_entry_data_decode(MMDB_entry_data_s *entry_data);
16
+ static VALUE mmdb_guard_parse_entry_data_list(VALUE ptr);
17
+ static MMDB_entry_data_list_s *mmdb_parse_entry_data_list(MMDB_entry_data_list_s *data_list, VALUE *obj);
18
+
19
+ static VALUE rb_geoip2_db_alloc(VALUE klass);
20
+ static VALUE rb_geoip2_db_initialize(VALUE self, VALUE path);
21
+ static VALUE rb_geoip2_db_close(VALUE self);
22
+ static VALUE rb_geoip2_db_lookup(VALUE self, VALUE ip);
23
+
24
+ static VALUE rb_geoip2_lr_alloc(VALUE klass);
25
+ static VALUE rb_geoip2_lr_initialize(VALUE self);
26
+ static VALUE rb_geoip2_lr_get_value(int argc, VALUE *argv, VALUE self);
27
+ static VALUE rb_geoip2_lr_to_h(VALUE self);
28
+
29
+ // static void lookup_result_free(void *pointer);
30
+ // static size_t lookup_result_size(void *pointer);
31
+
32
+ static const rb_data_type_t rb_mmdb_type = {
33
+ "geoip2/mmdb", {
34
+ 0, mmdb_free, 0,
35
+ }, NULL, NULL
36
+ };
37
+
38
+ static const rb_data_type_t rb_lookup_result_type = {
39
+ "geoip2/lookup_result", {
40
+ 0, 0, 0,
41
+ }, NULL, NULL
42
+ };
43
+
44
+ static void
45
+ mmdb_open(const char *db_path, MMDB_s *mmdb)
46
+ {
47
+ int status = MMDB_open(db_path, MMDB_MODE_MMAP, mmdb);
48
+
49
+ if (status != MMDB_SUCCESS) {
50
+ rb_raise(rb_eGeoIP2Error, "%s: %s", MMDB_strerror(status), db_path);
51
+ }
52
+ }
53
+
54
+ static void
55
+ mmdb_close(MMDB_s *mmdb)
56
+ {
57
+ MMDB_close(mmdb);
58
+ mmdb->file_content = NULL;
59
+ }
60
+
61
+ static bool
62
+ mmdb_is_closed(MMDB_s *mmdb)
63
+ {
64
+ return mmdb->file_content == NULL;
65
+ }
66
+
67
+ static void
68
+ mmdb_free(void *ptr)
69
+ {
70
+ MMDB_s *mmdb = (MMDB_s *)ptr;
71
+ if (!mmdb_is_closed(mmdb)) {
72
+ mmdb_close(mmdb);
73
+ }
74
+
75
+ xfree(mmdb);
76
+ }
77
+
78
+ static MMDB_lookup_result_s
79
+ mmdb_lookup(MMDB_s *mmdb, const char *ip_str, bool cleanup)
80
+ {
81
+ int gai_error;
82
+ int mmdb_error;
83
+
84
+ MMDB_lookup_result_s result =
85
+ MMDB_lookup_string(mmdb, ip_str, &gai_error, &mmdb_error);
86
+
87
+ if (gai_error != 0) {
88
+ if (cleanup && !mmdb_is_closed(mmdb)) {
89
+ mmdb_close(mmdb);
90
+ }
91
+ rb_raise(rb_eGeoIP2Error,
92
+ "getaddrinfo failed: %s", gai_strerror(gai_error));
93
+ }
94
+
95
+ if (mmdb_error != MMDB_SUCCESS) {
96
+ if (cleanup && !mmdb_is_closed(mmdb)) {
97
+ mmdb_close(mmdb);
98
+ }
99
+ rb_raise(rb_eGeoIP2Error,
100
+ "lookup failed: %s", MMDB_strerror(mmdb_error));
101
+ }
102
+
103
+ return result;
104
+ }
105
+
106
+ static VALUE
107
+ mmdb_entry_data_decode(MMDB_entry_data_s *entry_data)
108
+ {
109
+ switch (entry_data->type) {
110
+ case MMDB_DATA_TYPE_EXTENDED:
111
+ /* TODO: not implemented */
112
+ return Qnil;
113
+ case MMDB_DATA_TYPE_POINTER:
114
+ /* TODO: not implemented */
115
+ return Qnil;
116
+ case MMDB_DATA_TYPE_UTF8_STRING:
117
+ return rb_enc_str_new(entry_data->utf8_string,
118
+ entry_data->data_size,
119
+ rb_utf8_encoding());
120
+ case MMDB_DATA_TYPE_DOUBLE:
121
+ return DBL2NUM(entry_data->double_value);
122
+ case MMDB_DATA_TYPE_BYTES:
123
+ return rb_enc_str_new((const char *)entry_data->bytes,
124
+ entry_data->data_size,
125
+ rb_ascii8bit_encoding());
126
+ case MMDB_DATA_TYPE_UINT16:
127
+ return UINT2NUM(entry_data->uint16);
128
+ case MMDB_DATA_TYPE_UINT32:
129
+ return UINT2NUM(entry_data->uint32);
130
+ case MMDB_DATA_TYPE_MAP:
131
+ /* TODO: not implemented */
132
+ return Qnil;
133
+ case MMDB_DATA_TYPE_INT32:
134
+ return INT2NUM(entry_data->int32);
135
+ case MMDB_DATA_TYPE_UINT64:
136
+ return UINT2NUM(entry_data->uint64);
137
+ case MMDB_DATA_TYPE_UINT128:
138
+ /* FIXME I'm not sure */
139
+ return UINT2NUM(entry_data->uint128);
140
+ case MMDB_DATA_TYPE_ARRAY:
141
+ /* TODO: not implemented */
142
+ return Qnil;
143
+ case MMDB_DATA_TYPE_CONTAINER:
144
+ /* TODO: not implemented */
145
+ return Qnil;
146
+ case MMDB_DATA_TYPE_END_MARKER:
147
+ return Qnil;
148
+ case MMDB_DATA_TYPE_BOOLEAN:
149
+ return entry_data->boolean ? Qtrue : Qfalse;
150
+ case MMDB_DATA_TYPE_FLOAT:
151
+ return rb_float_new(entry_data->float_value);
152
+ default:
153
+ rb_raise(rb_eGeoIP2Error, "Unkown type: %d", entry_data->type);
154
+ }
155
+ }
156
+
157
+ static VALUE
158
+ mmdb_guard_parse_entry_data_list(VALUE ptr)
159
+ {
160
+ MMDB_entry_data_list_s *data_list =
161
+ (struct MMDB_entry_data_list_s *)ptr;
162
+ VALUE obj;
163
+
164
+ mmdb_parse_entry_data_list(data_list, &obj);
165
+ return obj;
166
+ }
167
+
168
+ static MMDB_entry_data_list_s *
169
+ mmdb_parse_entry_data_list(MMDB_entry_data_list_s *data_list, VALUE *obj)
170
+ {
171
+ switch (data_list->entry_data.type) {
172
+ case MMDB_DATA_TYPE_MAP:
173
+ {
174
+ uint32_t data_size = data_list->entry_data.data_size;
175
+ VALUE hash = rb_hash_new();
176
+ for (data_list = data_list->next; data_size && data_list; data_size--) {
177
+ VALUE key;
178
+ VALUE val;
179
+ key = mmdb_entry_data_decode(&data_list->entry_data);
180
+ data_list = data_list->next;
181
+ data_list = mmdb_parse_entry_data_list(data_list, &val);
182
+ rb_hash_aset(hash, key, val);
183
+ }
184
+ *obj = hash;
185
+ break;
186
+ }
187
+ case MMDB_DATA_TYPE_ARRAY:
188
+ {
189
+ uint32_t data_size = data_list->entry_data.data_size;
190
+ VALUE array = rb_ary_new();
191
+ for (data_list = data_list->next; data_size && data_list; data_size--) {
192
+ VALUE val;
193
+ data_list = mmdb_parse_entry_data_list(data_list, &val);
194
+ rb_ary_push(array, val);
195
+ }
196
+ *obj = array;
197
+ break;
198
+ }
199
+ case MMDB_DATA_TYPE_UTF8_STRING: /* fall through */
200
+ case MMDB_DATA_TYPE_BYTES:
201
+ case MMDB_DATA_TYPE_DOUBLE:
202
+ case MMDB_DATA_TYPE_UINT16:
203
+ case MMDB_DATA_TYPE_UINT32:
204
+ case MMDB_DATA_TYPE_INT32:
205
+ case MMDB_DATA_TYPE_UINT64:
206
+ case MMDB_DATA_TYPE_UINT128:
207
+ case MMDB_DATA_TYPE_BOOLEAN:
208
+ case MMDB_DATA_TYPE_FLOAT:
209
+ {
210
+ VALUE val = mmdb_entry_data_decode(&data_list->entry_data);
211
+ data_list = data_list->next;
212
+ *obj = val;
213
+ break;
214
+ }
215
+ default:
216
+ rb_raise(rb_eGeoIP2Error,
217
+ "Unkown type: %d",
218
+ data_list->entry_data.type);
219
+ }
220
+ return data_list;
221
+ }
222
+
223
+ static VALUE
224
+ rb_geoip2_db_alloc(VALUE klass)
225
+ {
226
+ VALUE obj;
227
+ MMDB_s *mmdb;
228
+ obj = TypedData_Make_Struct(klass, struct MMDB_s, &rb_mmdb_type, mmdb);
229
+ return obj;
230
+ }
231
+
232
+ static VALUE
233
+ rb_geoip2_db_initialize(VALUE self, VALUE path)
234
+ {
235
+ char *db_path;
236
+ MMDB_s *mmdb;
237
+
238
+ Check_Type(path, T_STRING);
239
+
240
+ db_path = StringValueCStr(path);
241
+
242
+ TypedData_Get_Struct(self, struct MMDB_s, &rb_mmdb_type, mmdb);
243
+ mmdb_open(db_path, mmdb);
244
+
245
+ return Qnil;
246
+ }
247
+
248
+ static VALUE
249
+ rb_geoip2_db_close(VALUE self)
250
+ {
251
+ MMDB_s *mmdb;
252
+
253
+ TypedData_Get_Struct(self, struct MMDB_s, &rb_mmdb_type, mmdb);
254
+
255
+ if (!mmdb_is_closed(mmdb)) {
256
+ mmdb_close(mmdb);
257
+ }
258
+
259
+ return Qnil;
260
+ }
261
+
262
+ static VALUE
263
+ rb_geoip2_db_lookup(VALUE self, VALUE ip)
264
+ {
265
+ char *ip_str;
266
+ MMDB_s *mmdb;
267
+ MMDB_lookup_result_s result;
268
+ MMDB_lookup_result_s *result_ptr;
269
+ VALUE obj;
270
+
271
+ Check_Type(ip, T_STRING);
272
+ ip_str = StringValueCStr(ip);
273
+
274
+ TypedData_Get_Struct(self, struct MMDB_s, &rb_mmdb_type, mmdb);
275
+ result = mmdb_lookup(mmdb, ip_str, false);
276
+
277
+ if (!result.found_entry) {
278
+ return Qnil;
279
+ }
280
+
281
+ obj = TypedData_Make_Struct(rb_cGeoIP2LookupResult,
282
+ struct MMDB_lookup_result_s,
283
+ &rb_lookup_result_type,
284
+ result_ptr);
285
+ result_ptr->found_entry = result.found_entry;
286
+ result_ptr->entry = result.entry;
287
+ result_ptr->netmask = result.netmask;
288
+ return obj;
289
+ }
290
+
291
+ static VALUE
292
+ rb_geoip2_lr_alloc(VALUE klass)
293
+ {
294
+ VALUE obj;
295
+ MMDB_lookup_result_s *result;
296
+ obj = TypedData_Make_Struct(klass,
297
+ struct MMDB_lookup_result_s,
298
+ &rb_lookup_result_type,
299
+ result);
300
+ return obj;
301
+ }
302
+
303
+ static VALUE
304
+ rb_geoip2_lr_initialize(VALUE self)
305
+ {
306
+ return Qnil;
307
+ }
308
+
309
+ static VALUE
310
+ rb_geoip2_lr_get_value(int argc, VALUE *argv, VALUE self)
311
+ {
312
+ VALUE arg;
313
+ VALUE rest;
314
+ char **path;
315
+ int i = 0;
316
+ MMDB_lookup_result_s *result = NULL;
317
+ MMDB_entry_s entry;
318
+ MMDB_entry_data_s entry_data;
319
+ char *tmp;
320
+ VALUE e;
321
+ int status;
322
+
323
+ rb_scan_args(argc, argv, "1*", &arg, &rest);
324
+ Check_Type(arg, T_STRING);
325
+ path = malloc(sizeof(char *) * (RARRAY_LEN(rest) + 2));
326
+
327
+ TypedData_Get_Struct(self,
328
+ struct MMDB_lookup_result_s,
329
+ &rb_lookup_result_type,
330
+ result);
331
+
332
+ path[i] = StringValueCStr(arg);
333
+ while (RARRAY_LEN(rest) != 0) {
334
+ ++i;
335
+ e = rb_ary_shift(rest);
336
+ tmp = StringValueCStr(e);
337
+ path[i] = tmp;
338
+ }
339
+
340
+ path[i+1] = NULL;
341
+
342
+ entry = result->entry;
343
+
344
+ status = MMDB_aget_value(&entry, &entry_data, (const char *const *const)path);
345
+
346
+ if (status != MMDB_SUCCESS) {
347
+ free(path);
348
+ fprintf(stderr, "%s\n", MMDB_strerror(status));
349
+ return Qnil;
350
+ }
351
+
352
+ if (!entry_data.has_data) {
353
+ free(path);
354
+ return Qnil;
355
+ }
356
+
357
+ if (entry_data.type == MMDB_DATA_TYPE_MAP ||
358
+ entry_data.type == MMDB_DATA_TYPE_ARRAY) {
359
+ // FIXME optimize below code
360
+ VALUE array = rb_ary_new();
361
+ VALUE hash;
362
+ VALUE val;
363
+ for (int j = 0; path[j] != NULL; j++) {
364
+ rb_ary_push(array, rb_str_new_cstr(path[j]));
365
+ }
366
+ hash = rb_funcall(self, rb_intern("to_h"), 0);
367
+ val = rb_apply(hash, rb_intern("dig"), array);
368
+ free(path);
369
+ return val;
370
+ }
371
+
372
+ free(path);
373
+ return mmdb_entry_data_decode(&entry_data);
374
+ }
375
+
376
+ static VALUE
377
+ rb_geoip2_lr_to_h(VALUE self)
378
+ {
379
+ MMDB_lookup_result_s *result = NULL;
380
+ MMDB_entry_data_list_s *entry_data_list = NULL;
381
+ VALUE hash;
382
+ int status = 0;
383
+ int exception = 0;
384
+
385
+ TypedData_Get_Struct(self,
386
+ struct MMDB_lookup_result_s,
387
+ &rb_lookup_result_type,
388
+ result);
389
+ status = MMDB_get_entry_data_list(&result->entry, &entry_data_list);
390
+ if (status != MMDB_SUCCESS) {
391
+ rb_raise(rb_eGeoIP2Error, "%s", MMDB_strerror(status));
392
+ }
393
+
394
+ hash = rb_protect(mmdb_guard_parse_entry_data_list, (VALUE)entry_data_list, &exception);
395
+ MMDB_free_entry_data_list(entry_data_list);
396
+
397
+ if (exception != 0) {
398
+ rb_jump_tag(exception);
399
+ }
400
+
401
+ return hash;
402
+ }
403
+
404
+ void
405
+ Init_geoip2(void)
406
+ {
407
+ rb_mGeoIP2 = rb_define_module("GeoIP2");
408
+ rb_cGeoIP2Database = rb_define_class_under(rb_mGeoIP2, "Database", rb_cData);
409
+ rb_cGeoIP2LookupResult = rb_define_class_under(rb_mGeoIP2, "LookupResult", rb_cData);
410
+ rb_eGeoIP2Error = rb_define_class_under(rb_mGeoIP2, "Error", rb_eStandardError);
411
+
412
+ rb_define_alloc_func(rb_cGeoIP2Database, rb_geoip2_db_alloc);
413
+ rb_define_method(rb_cGeoIP2Database, "initialize", rb_geoip2_db_initialize, 1);
414
+ rb_define_method(rb_cGeoIP2Database, "close", rb_geoip2_db_close, 0);
415
+ rb_define_method(rb_cGeoIP2Database, "lookup", rb_geoip2_db_lookup, 1);
416
+
417
+ rb_define_alloc_func(rb_cGeoIP2LookupResult, rb_geoip2_lr_alloc);
418
+ rb_define_method(rb_cGeoIP2LookupResult, "initialize", rb_geoip2_lr_initialize, 0);
419
+ rb_define_method(rb_cGeoIP2LookupResult, "get_value", rb_geoip2_lr_get_value, -1);
420
+ rb_define_method(rb_cGeoIP2LookupResult, "to_h", rb_geoip2_lr_to_h, 0);
421
+ }
data/geoip2_c.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'geoip2/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "geoip2_c"
8
+ spec.version = GeoIP2::VERSION
9
+ spec.authors = ["okkez"]
10
+ spec.email = ["okkez000@gmail.com"]
11
+
12
+ spec.summary = %q{Write a short summary, because Rubygems requires one.}
13
+ spec.description = %q{Write a longer description or delete this line.}
14
+ spec.homepage = ""
15
+ spec.license = "Apache-2.0"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "bin"
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+ spec.extensions = ["ext/geoip2/extconf.rb"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.13"
26
+ spec.add_development_dependency "rake", "~> 11.0"
27
+ spec.add_development_dependency "rake-compiler"
28
+ spec.add_development_dependency "test-unit", "~> 3.2"
29
+ end
@@ -0,0 +1,4 @@
1
+ module GeoIP2
2
+ class Database
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module GeoIP2
2
+ class LookupResult
3
+ def dig(*keys)
4
+ get_value(*keys)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module GeoIP2
2
+ VERSION = "0.1.0"
3
+ end
data/lib/geoip2.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "geoip2/version"
2
+ require "geoip2/geoip2"
3
+ require "geoip2/database"
4
+ require "geoip2/lookup_result"
5
+
6
+ module GeoIP2
7
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geoip2_c
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - okkez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-20 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.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ description: Write a longer description or delete this line.
70
+ email:
71
+ - okkez000@gmail.com
72
+ executables: []
73
+ extensions:
74
+ - ext/geoip2/extconf.rb
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".gitmodules"
79
+ - ".travis.yml"
80
+ - Dockerfile
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - docker-compose.yml
86
+ - ext/geoip2/extconf.rb
87
+ - ext/geoip2/geoip2.c
88
+ - geoip2_c.gemspec
89
+ - lib/geoip2.rb
90
+ - lib/geoip2/database.rb
91
+ - lib/geoip2/lookup_result.rb
92
+ - lib/geoip2/version.rb
93
+ homepage: ''
94
+ licenses:
95
+ - Apache-2.0
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.6.4
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Write a short summary, because Rubygems requires one.
117
+ test_files: []