trifle 0.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.
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +36 -0
- data/README.md +54 -0
- data/Rakefile +1 -0
- data/lib/trifle.rb +29 -0
- data/lib/trifle/finder.rb +46 -0
- data/lib/trifle/initialize_with_redis.rb +10 -0
- data/lib/trifle/loader.rb +69 -0
- data/lib/trifle/version.rb +3 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/trifle/finder_spec.rb +37 -0
- data/spec/trifle/initialize_with_redis_spec.rb +22 -0
- data/spec/trifle/loader_spec.rb +169 -0
- data/spec/trifle_spec.rb +37 -0
- data/trifle.gemspec +24 -0
- metadata +101 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/caius/fakeredis.git
|
3
|
+
revision: ab336ff1edf50c259b557559f42316fe15a4feb7
|
4
|
+
branch: redis-rb-3
|
5
|
+
specs:
|
6
|
+
fakeredis (0.3.1)
|
7
|
+
redis (>= 3.0.0)
|
8
|
+
|
9
|
+
PATH
|
10
|
+
remote: .
|
11
|
+
specs:
|
12
|
+
trifle (0.0.1)
|
13
|
+
|
14
|
+
GEM
|
15
|
+
remote: http://rubygems.org/
|
16
|
+
specs:
|
17
|
+
diff-lcs (1.1.3)
|
18
|
+
redis (3.0.1)
|
19
|
+
rspec (2.10.0)
|
20
|
+
rspec-core (~> 2.10.0)
|
21
|
+
rspec-expectations (~> 2.10.0)
|
22
|
+
rspec-mocks (~> 2.10.0)
|
23
|
+
rspec-core (2.10.1)
|
24
|
+
rspec-expectations (2.10.0)
|
25
|
+
diff-lcs (~> 1.1.3)
|
26
|
+
rspec-mocks (2.10.1)
|
27
|
+
rujitsu (0.3.3)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
fakeredis!
|
34
|
+
rspec
|
35
|
+
rujitsu
|
36
|
+
trifle!
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Trifle
|
2
|
+
|
3
|
+
Stores the GeoIP databases in Redis and gives it a simple way to lookup IPs and map them to countries/country codes.
|
4
|
+
|
5
|
+
Get your GeoIP country CSVs from http://www.maxmind.com/app/geolite.
|
6
|
+
|
7
|
+
Trifle supports both the IPV4 and IPV6 databases.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Install the gem
|
12
|
+
|
13
|
+
```
|
14
|
+
gem install trifle
|
15
|
+
```
|
16
|
+
|
17
|
+
or add it to your Gemfile and bundle
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem "trifle"
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
### Loading
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# Initialize
|
29
|
+
trifle = Trifle.new(Redis.new)
|
30
|
+
# Load data from file
|
31
|
+
trifle.load filename: "file.csv"
|
32
|
+
# or files
|
33
|
+
trifle.load filenames: ["file1.csv", "file2.csv"]
|
34
|
+
# or directly as an array
|
35
|
+
trifle.load data: preloaded_array
|
36
|
+
```
|
37
|
+
|
38
|
+
### Lookup
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
# Initialize
|
42
|
+
trifle = Trifle.new(Redis.new)
|
43
|
+
|
44
|
+
# Lookup for existing data
|
45
|
+
trifle.find "223.255.128.0"
|
46
|
+
# => ["HK", "Hong Kong"]
|
47
|
+
|
48
|
+
# Lookup for missing data
|
49
|
+
trifle.find "192.168.1.1"
|
50
|
+
# => nil
|
51
|
+
```
|
52
|
+
|
53
|
+
|
54
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/trifle.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Trifle is a simple storage and lookup gem for GeoIP data
|
2
|
+
# using Redis as storage
|
3
|
+
require "trifle/loader"
|
4
|
+
require "trifle/finder"
|
5
|
+
require "trifle/initialize_with_redis"
|
6
|
+
|
7
|
+
class Trifle
|
8
|
+
include InitializeWithRedis
|
9
|
+
|
10
|
+
KEY = "trifle".freeze
|
11
|
+
|
12
|
+
def load options = {}
|
13
|
+
loader.handle options
|
14
|
+
end
|
15
|
+
|
16
|
+
def find ip
|
17
|
+
finder.handle ip
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def loader
|
23
|
+
@loader = Loader.new(redis)
|
24
|
+
end
|
25
|
+
|
26
|
+
def finder
|
27
|
+
@finder = Finder.new(redis)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative "initialize_with_redis"
|
2
|
+
require 'ipaddr'
|
3
|
+
|
4
|
+
class Trifle
|
5
|
+
class Finder
|
6
|
+
include InitializeWithRedis
|
7
|
+
|
8
|
+
def handle ip
|
9
|
+
ip_i = IPAddr.new(ip).to_i
|
10
|
+
find(ip_i, 0, max)
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def find ip_i, lower, upper
|
16
|
+
return nil if lower > upper
|
17
|
+
|
18
|
+
index = (lower+upper)/2
|
19
|
+
|
20
|
+
current = entry_for(index)
|
21
|
+
|
22
|
+
if in_range(current, ip_i)
|
23
|
+
current.last(2)
|
24
|
+
elsif ip_i < current[0]
|
25
|
+
find ip_i, lower, index-1
|
26
|
+
else
|
27
|
+
find ip_i, index+1, upper
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def max
|
32
|
+
redis.llen Trifle::KEY
|
33
|
+
end
|
34
|
+
|
35
|
+
def entry_for index
|
36
|
+
entry = redis.lindex(Trifle::KEY, index).split(":")
|
37
|
+
entry[0] = entry[0].to_i
|
38
|
+
entry[1] = entry[1].to_i
|
39
|
+
entry
|
40
|
+
end
|
41
|
+
|
42
|
+
def in_range range, ip_i
|
43
|
+
ip_i >= range[0] && ip_i <= range[1]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative "initialize_with_redis"
|
2
|
+
require "csv"
|
3
|
+
|
4
|
+
class Trifle
|
5
|
+
class Loader
|
6
|
+
include InitializeWithRedis
|
7
|
+
|
8
|
+
def handle options = {}
|
9
|
+
if options[:filename]
|
10
|
+
load_files [options[:filename]]
|
11
|
+
elsif options[:filenames]
|
12
|
+
load_files options[:filenames]
|
13
|
+
elsif options[:data]
|
14
|
+
load_data options[:data]
|
15
|
+
else
|
16
|
+
raise ArgumentError.new("Please provide a :filename, :filenames or an array of :data as an argument.")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_files filenames
|
21
|
+
raise ArgumentError.new("filenames must be an array of strings") unless filenames.is_a?(Array) && !filenames.map{|element| element.is_a?(String)}.include?(false)
|
22
|
+
|
23
|
+
data = []
|
24
|
+
filenames.each do |filename|
|
25
|
+
contents = File.open(filename, "rb").read
|
26
|
+
data += parse(contents)
|
27
|
+
end
|
28
|
+
load_data data
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_data data
|
32
|
+
raise ArgumentError.new("data must be an array as loaded from a GeoIP data set") unless valid?(data)
|
33
|
+
clear
|
34
|
+
sort(data)
|
35
|
+
data.each {|row| append(row) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def append row
|
39
|
+
entry = row.values_at(2,3,4,5).join(":")
|
40
|
+
redis.rpush Trifle::KEY, entry
|
41
|
+
end
|
42
|
+
|
43
|
+
def sort data
|
44
|
+
data.sort {|a,b| a[2] <=> b[2] }
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse contents
|
48
|
+
contents.gsub!('", "', '","')
|
49
|
+
CSV.parse(contents)
|
50
|
+
end
|
51
|
+
|
52
|
+
def valid? data
|
53
|
+
if data.is_a?(Array) && data.count > 0
|
54
|
+
return data.map do |row|
|
55
|
+
is_number(row[2]) && is_number(row[3])
|
56
|
+
end.select{|valid| !valid}.count == 0
|
57
|
+
end
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_number field
|
62
|
+
field.is_a?(Numeric) || field =~ /^\d+$/
|
63
|
+
end
|
64
|
+
|
65
|
+
def clear
|
66
|
+
redis.del(Trifle::KEY)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Trifle::Finder do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@valid_data = [
|
7
|
+
["223.255.128.0","223.255.191.255","3758063616","3758079999","HK","Hong Kong"],
|
8
|
+
["223.255.192.0","223.255.223.255","3758080000","3758088191","KR","Korea, Republic of"],
|
9
|
+
["223.255.224.0","223.255.231.255","3758088192","3758090239","ID","Indonesia"],
|
10
|
+
["223.255.232.0","223.255.235.255","3758090240","3758091263","AU","Australia"],
|
11
|
+
["223.255.236.0","223.255.239.255","3758091264","3758092287","CN","China"],
|
12
|
+
["223.255.240.0","223.255.243.255","3758092288","3758093311","HK","Hong Kong"],
|
13
|
+
["223.255.244.0","223.255.247.255","3758093312","3758094335","IN","India"],
|
14
|
+
["223.255.248.0","223.255.251.255","3758094336","3758095359","AU","Australia"],
|
15
|
+
["223.255.252.0","223.255.253.255","3758095360","3758095871","CN","China"],
|
16
|
+
["223.255.254.0","223.255.254.255","3758095872","3758096127","SG","Singapore"],
|
17
|
+
["223.255.255.0","223.255.255.255","3758096128","3758096383","AU","Australia"]
|
18
|
+
]
|
19
|
+
@redis = Redis.new
|
20
|
+
trifle = Trifle.new(@redis)
|
21
|
+
@finder = Trifle::Finder.new(@redis)
|
22
|
+
trifle.load(data: @valid_data)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#handle" do
|
26
|
+
it "should find the right entry" do
|
27
|
+
@finder.handle("223.255.128.0").should be == ["HK", "Hong Kong"]
|
28
|
+
@finder.handle("223.255.244.10").should be == ["IN", "India"]
|
29
|
+
@finder.handle("223.255.255.255").should be == ["AU","Australia"]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return nil if the entry wasn't found" do
|
33
|
+
@finder.handle("127.0.0.1").should be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Trifle::InitializeWithRedis do
|
4
|
+
|
5
|
+
describe "#initialize" do
|
6
|
+
before do
|
7
|
+
@klass = Class.new do
|
8
|
+
include Trifle::InitializeWithRedis
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should accept a redis instance" do
|
13
|
+
@klass.new(Redis.new).should be_a(@klass)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should fail without a redis instance" do
|
17
|
+
-> { @klass.new(nil) }.should raise_error(ArgumentError)
|
18
|
+
-> { @klass.new("http://127.0.0.1:3000/") }.should raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Trifle::Loader do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@loader = Trifle::Loader.new(Redis.new)
|
7
|
+
@valid_data = [
|
8
|
+
["223.255.254.0","223.255.254.255","3758095872","3758096127","SG","Singapore"],
|
9
|
+
["223.255.255.0","223.255.255.255","3758096128","3758096383","AU","Australia"]
|
10
|
+
]
|
11
|
+
@csv = <<-EOD
|
12
|
+
"223.255.254.0","223.255.254.255","3758095872","3758096127","SG","Singapore"
|
13
|
+
"223.255.255.0","223.255.255.255","3758096128","3758096383","AU","Australia"
|
14
|
+
EOD
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should extend InitializeWithRedis" do
|
18
|
+
Trifle::Loader.included_modules.should include(Trifle::InitializeWithRedis)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#handle" do
|
22
|
+
|
23
|
+
context "when given the :filename option" do
|
24
|
+
it "should pass it on to load_files" do
|
25
|
+
filename = 'data.csv'
|
26
|
+
@loader.should_receive(:load_files).with([filename])
|
27
|
+
@loader.handle(filename: filename)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when given the :filenames option" do
|
32
|
+
it "should pass it on to load_files" do
|
33
|
+
filenames = ['data1.csv', 'data2.csv']
|
34
|
+
@loader.should_receive(:load_files).with(filenames)
|
35
|
+
@loader.handle(filenames: filenames)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when given the :data option" do
|
40
|
+
it "should pass it on to load_data" do
|
41
|
+
data = [:foo, :bar]
|
42
|
+
@loader.should_receive(:load_data).with(data)
|
43
|
+
@loader.handle(data: data)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when given anything else" do
|
48
|
+
it "should raise an error" do
|
49
|
+
-> { @loader.handle(foo: :bar) }.should raise_error(ArgumentError)
|
50
|
+
-> { @loader.handle }.should raise_error(ArgumentError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#load_files" do
|
56
|
+
context "when given a valid list of files" do
|
57
|
+
before do
|
58
|
+
@filenames = ['foo.csv', 'bar.csv']
|
59
|
+
file = mock File
|
60
|
+
file.should_receive(:read).twice.and_return(@csv)
|
61
|
+
File.should_receive(:open).twice.and_return(file)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should read the files" do
|
65
|
+
@loader.load_files @filenames
|
66
|
+
@loader.redis.llen(Trifle::KEY).should be == 4
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when given anything but an array of strings" do
|
71
|
+
it "should raise an error" do
|
72
|
+
-> { @loader.load_files "" }.should raise_error(ArgumentError)
|
73
|
+
-> { @loader.load_files [:foo] }.should raise_error(ArgumentError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when given a filename for a file that's missing" do
|
78
|
+
it "should raise an error" do
|
79
|
+
-> { @loader.load_files ["foobar.csv"] }.should raise_error(/No such file or directory - foobar.csv/)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#load_data" do
|
85
|
+
|
86
|
+
context "when given valid data" do
|
87
|
+
it "should clear out existing data" do
|
88
|
+
@loader.should_receive(:clear)
|
89
|
+
@loader.load_data @valid_data
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should validate the data" do
|
93
|
+
@loader.should_receive(:valid?).and_return(true)
|
94
|
+
@loader.load_data @valid_data
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should load it in redis" do
|
98
|
+
@loader.load_data @valid_data
|
99
|
+
@loader.redis.llen(Trifle::KEY).should be == 2
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "when given invalid data" do
|
104
|
+
it "should raise an error" do
|
105
|
+
@loader.should_receive(:valid?).and_return(false)
|
106
|
+
-> { @loader.load_data @valid_data }.should raise_error(ArgumentError)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when given anything but an array" do
|
111
|
+
it "should raise an error" do
|
112
|
+
-> { @loader.load_data :rubbish }.should raise_error(ArgumentError)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#parse" do
|
118
|
+
it "should parse valid csv data" do
|
119
|
+
@loader.parse(@csv).should be == @valid_data
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should raise an error for invalid csv data" do
|
123
|
+
-> { @loader.parse('"foo",","#') }.should raise_error(CSV::MalformedCSVError)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should handle ipv6 data" do
|
127
|
+
@ipv6csv = <<-CSV
|
128
|
+
"2c0f:ffe8::", "2c0f:ffe8:ffff:ffff:ffff:ffff:ffff:ffff", "58569106662796955307479896348547874816", "58569106742025117821744233942091825151", "NG", "Nigeria"
|
129
|
+
"2c0f:fff0::", "2c0f:fff0:ffff:ffff:ffff:ffff:ffff:ffff", "58569107296622255421594597096899477504", "58569107375850417935858934690443427839", "NG", "Nigeria"
|
130
|
+
CSV
|
131
|
+
-> { @loader.parse(@ipv6csv) }.should_not raise_error
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#sort" do
|
136
|
+
it "should sort the data" do
|
137
|
+
@loader.sort(@valid_data.reverse).should be == @valid_data
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
describe "#valid?" do
|
143
|
+
it "should mark valid data as such" do
|
144
|
+
@loader.valid?(@valid_data).should be_true
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should mark invalid data as such" do
|
148
|
+
invalid_data = []
|
149
|
+
@loader.valid?(invalid_data).should be_false
|
150
|
+
invalid_data = [
|
151
|
+
["223.255.254.0","223.255.254.255","not_a_number","3758096127","SG","Singapore"]
|
152
|
+
]
|
153
|
+
@loader.valid?(invalid_data).should be_false
|
154
|
+
invalid_data = [
|
155
|
+
["223.255.254.0","223.255.254.255","3758095872","not_a_number","SG","Singapore"]
|
156
|
+
]
|
157
|
+
@loader.valid?(invalid_data).should be_false
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "#clear" do
|
162
|
+
it "should clear existing data" do
|
163
|
+
@loader.load_data @valid_data
|
164
|
+
@loader.clear
|
165
|
+
@loader.redis.llen(Trifle::KEY).should be == 0
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
data/spec/trifle_spec.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Trifle do
|
4
|
+
|
5
|
+
it "should extend InitializeWithRedis" do
|
6
|
+
Trifle.included_modules.should include(Trifle::InitializeWithRedis)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#load" do
|
10
|
+
before do
|
11
|
+
@trifle = Trifle.new(Redis.new)
|
12
|
+
@options = { filenames: "foobar.csv" }
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should pass this to the loader" do
|
16
|
+
loader = mock Trifle::Loader
|
17
|
+
Trifle::Loader.should_receive(:new).and_return(loader)
|
18
|
+
loader.should_receive(:handle).with(@options)
|
19
|
+
@trifle.load @options
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#find" do
|
24
|
+
before do
|
25
|
+
@trifle = Trifle.new(Redis.new)
|
26
|
+
@ip = "127.0.0.1"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should pass this to the finder" do
|
30
|
+
finder = mock Trifle::Finder
|
31
|
+
Trifle::Finder.should_receive(:new).and_return(finder)
|
32
|
+
finder.should_receive(:handle).with(@ip)
|
33
|
+
@trifle.find @ip
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/trifle.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "trifle/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "trifle"
|
7
|
+
s.version = Trifle::VERSION
|
8
|
+
s.authors = ["Cristiano Betta"]
|
9
|
+
s.email = ["cristiano@emberads.com"]
|
10
|
+
s.homepage = "http://emberads.com"
|
11
|
+
s.summary = "A GeoIP lookup in Redis"
|
12
|
+
s.description = "Stores the GeoIP databases in Redis and gives it a simple way to lookup IPs and map them to countries"
|
13
|
+
|
14
|
+
s.rubyforge_project = "trifle"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency 'rspec'
|
22
|
+
s.add_development_dependency 'rujitsu'
|
23
|
+
s.add_development_dependency "fakeredis", "~> 0.3.0"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: trifle
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Cristiano Betta
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70353203055680 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70353203055680
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rujitsu
|
27
|
+
requirement: &70353203079000 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70353203079000
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: fakeredis
|
38
|
+
requirement: &70353203078460 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.3.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70353203078460
|
47
|
+
description: Stores the GeoIP databases in Redis and gives it a simple way to lookup
|
48
|
+
IPs and map them to countries
|
49
|
+
email:
|
50
|
+
- cristiano@emberads.com
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- .rspec
|
57
|
+
- Gemfile
|
58
|
+
- Gemfile.lock
|
59
|
+
- README.md
|
60
|
+
- Rakefile
|
61
|
+
- lib/trifle.rb
|
62
|
+
- lib/trifle/finder.rb
|
63
|
+
- lib/trifle/initialize_with_redis.rb
|
64
|
+
- lib/trifle/loader.rb
|
65
|
+
- lib/trifle/version.rb
|
66
|
+
- spec/spec_helper.rb
|
67
|
+
- spec/trifle/finder_spec.rb
|
68
|
+
- spec/trifle/initialize_with_redis_spec.rb
|
69
|
+
- spec/trifle/loader_spec.rb
|
70
|
+
- spec/trifle_spec.rb
|
71
|
+
- trifle.gemspec
|
72
|
+
homepage: http://emberads.com
|
73
|
+
licenses: []
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project: trifle
|
92
|
+
rubygems_version: 1.8.10
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: A GeoIP lookup in Redis
|
96
|
+
test_files:
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
- spec/trifle/finder_spec.rb
|
99
|
+
- spec/trifle/initialize_with_redis_spec.rb
|
100
|
+
- spec/trifle/loader_spec.rb
|
101
|
+
- spec/trifle_spec.rb
|