ipdb 1.0.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.
@@ -0,0 +1,11 @@
1
+ doc
2
+ pkg
3
+ tmp/*
4
+ .DS_Store
5
+ .yardoc
6
+ *.db
7
+ *.log
8
+ *.swp
9
+ *~
10
+ *.gemspec
11
+ *.gem
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2009-11-25
2
+
3
+ * Initial release.
4
+ * Query IP addressses and domains for geographical information.
5
+ * Convenience methods for google maps integration.
6
+
@@ -0,0 +1,95 @@
1
+ = ipdb
2
+
3
+ * Source: http://www.github.com/mephux/ipdb
4
+ * Documentation: http://yardoc.com/docs/mephux-ipdb
5
+ * My Website: http://www.packetport.net
6
+
7
+ == DESCRIPTION:
8
+
9
+ IpDB is a simple ruby interface to the ipinfodb IP geographical locator api.
10
+
11
+ == INSTALL:
12
+
13
+ $ sudo gem install ipdb
14
+
15
+ == SYNOPSIS:
16
+
17
+ Using IpDB is super simple. Here are a few example of how one may use this gem.
18
+
19
+ Look up my current external address:
20
+
21
+ ip = Ipdb::Query.new.parse
22
+
23
+ puts ip.address #=> '127.0.0.1'
24
+
25
+ Get geographical information for a given address:
26
+
27
+ ip = Ipdb::Query.new('173.45.230.150').parse
28
+
29
+ puts ip.latitude #=> 38.6446
30
+ puts ip.longitude #=> -90.2533
31
+ puts ip.country #=> United States
32
+ puts ip.region #=> Missouri
33
+ puts ip.city #=> Saint Louis
34
+
35
+ Return the hostname & city for each address and/or domain in an array.
36
+
37
+ ips = ['127.0.0.1', 'snorby.org', '64.13.134.52']
38
+
39
+ Ipdb::Query.new(ips, :timeout => 1).each do |ip|
40
+ puts ip.hostname
41
+ puts ip.city
42
+ end
43
+
44
+ Render a google map from an array of IP addresses:
45
+
46
+ map = Ipdb::Map.new(ip_array, :width => 600, :height => 350, :units => :px)
47
+ map.render
48
+
49
+ Thats It! Below is a screenshot of its output:
50
+
51
+ http://snorby.org/images/ipdb.png
52
+
53
+ Nice! If you zoom out some you get this:
54
+
55
+ http://snorby.org/images/ipdb2.png
56
+
57
+ == FEATURES/PROBLEMS:
58
+
59
+ * IP/Domain geographical location
60
+ * Look up multiple addresses at once.
61
+ * Convenience Methods for Google Maps
62
+ * No API usage limit.
63
+ * Timezone data is from Geonames. Please refer to Geonames.org for more info about timezones.
64
+
65
+ * A max of 25 addresses can be parsed during a single query.
66
+ * There is a one second pause when querying domain names.
67
+
68
+ == REQUIREMENTS:
69
+
70
+ * nokogiri http://nokogiri.rubyforge.org >= 1.4.0
71
+
72
+ == LICENSE:
73
+
74
+ (The MIT License)
75
+
76
+ Copyright (c) 2009 Dustin Willis Webber
77
+
78
+ Permission is hereby granted, free of charge, to any person obtaining
79
+ a copy of this software and associated documentation files (the
80
+ 'Software'), to deal in the Software without restriction, including
81
+ without limitation the rights to use, copy, modify, merge, publish,
82
+ distribute, sublicense, and/or sell copies of the Software, and to
83
+ permit persons to whom the Software is furnished to do so, subject to
84
+ the following conditions:
85
+
86
+ The above copyright notice and this permission notice shall be
87
+ included in all copies or substantial portions of the Software.
88
+
89
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
90
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
91
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
92
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
93
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
94
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
95
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ require './tasks/spec.rb'
5
+ require './tasks/yard.rb'
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gem|
10
+ gem.name = "ipdb"
11
+ gem.summary = "ipdb is a simple IP geographical locator."
12
+ gem.description = "ipdb is a ruby interface to the ipinfodb IP geographical locator api."
13
+ gem.email = "dustin.webber@gmail.com"
14
+ gem.homepage = "http://github.com/mephux/ipdb"
15
+ gem.authors = ["Dustin Willis Webber"]
16
+ gem.add_dependency "nokogiri", ">= 1.4.0"
17
+ gem.add_development_dependency "rspec", ">= 1.2.9"
18
+ gem.add_development_dependency "yard", ">=0.2.3.5"
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ # vim: syntax=ruby
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'ipdb'
@@ -0,0 +1 @@
1
+ require 'ipdb/query'
@@ -0,0 +1,191 @@
1
+ require 'ipdb/map'
2
+ require 'resolv'
3
+
4
+ module Ipdb
5
+ class Location
6
+ # Location
7
+ attr_reader :location
8
+
9
+ #
10
+ # Creates a new Location object.
11
+ #
12
+ # @param [Nokogiri::XML::Node] node
13
+ # The XML node that contains the location information.
14
+ #
15
+ # @yield [location]
16
+ # If a block is given, it will be passed the newly created Location
17
+ # object.
18
+ #
19
+ # @param [String] timeout
20
+ # The timeout for the location object.
21
+ #
22
+ def initialize(location, timeout=10)
23
+ @xml = location
24
+ @timeout = timeout
25
+ end
26
+
27
+ #
28
+ # Return the Location address.
29
+ #
30
+ # @return [String] address
31
+ #
32
+ def address
33
+ @address = @xml.at('Ip').inner_text
34
+ end
35
+
36
+ #
37
+ # Return the Location status.
38
+ #
39
+ # @return [String] status
40
+ #
41
+ def status
42
+ @status = @xml.at('Status').inner_text
43
+ end
44
+
45
+ #
46
+ # Return the Location hostname.
47
+ #
48
+ # @return [String] hostname
49
+ #
50
+ def hostname
51
+ Timeout::timeout(@timeout) do
52
+ @hostname = Resolv.getname(address)
53
+ end
54
+ rescue Timeout::Error
55
+ rescue
56
+ end
57
+
58
+ #
59
+ # Return the Location Country Coce.
60
+ #
61
+ # @return [String] country_code
62
+ #
63
+ def country_code
64
+ @country_code = @xml.at('CountryCode').inner_text
65
+ end
66
+
67
+ #
68
+ # Return the Location Country.
69
+ #
70
+ # @return [String] country
71
+ #
72
+ def country
73
+ @country_name = @xml.at('CountryName').inner_text
74
+ end
75
+
76
+ #
77
+ # Return the Location Region Code.
78
+ #
79
+ # @return [String] region_code
80
+ #
81
+ def region_code
82
+ @region_code = @xml.at('RegionCode').inner_text
83
+ end
84
+
85
+ #
86
+ # Return the Location Region.
87
+ #
88
+ # @return [String] region
89
+ #
90
+ def region
91
+ @region_name = @xml.at('RegionName').inner_text
92
+ end
93
+
94
+ #
95
+ # Return the Location City.
96
+ #
97
+ # @return [String] city
98
+ #
99
+ def city
100
+ @city = @xml.at('City').inner_text
101
+ end
102
+
103
+ #
104
+ # Return the Location Zip Code.
105
+ #
106
+ # @return [Integer] zip_code
107
+ #
108
+ # @see Location#zipcode
109
+ #
110
+ def zip_code
111
+ @zip_code = @xml.at('ZipPostalCode').inner_text.to_i
112
+ end
113
+ alias zipcode zip_code
114
+
115
+ #
116
+ # Return the Location Latitude.
117
+ #
118
+ # @return [Float] latitude
119
+ #
120
+ def latitude
121
+ @latitude = @xml.at('Latitude').inner_text.to_f
122
+ end
123
+
124
+ #
125
+ # Return the Location Longitude.
126
+ #
127
+ # @return [Float] longitude
128
+ #
129
+ def longitude
130
+ @longitude = @xml.at('Longitude').inner_text.to_f
131
+ end
132
+
133
+ #
134
+ # Return the Location Time Zone Offset.
135
+ #
136
+ # @return [Integer] time_zone
137
+ #
138
+ # @see http://www.geonames.org/
139
+ # @see Location#timezone
140
+ #
141
+ def time_zone
142
+ @timezone = @xml.at('Timezone').inner_text.to_i
143
+ end
144
+ alias timezone time_zone
145
+
146
+ #
147
+ # Return the Location GMT Offset.
148
+ # The gmtOffset/dstOffset fields names are a little misleading => gmtOffset: offset to GMT at 1st January.
149
+ #
150
+ # @return [Integer] gmt_offset
151
+ #
152
+ # @see http://www.geonames.org/
153
+ #
154
+ def gmt_offset
155
+ @gmt_offset = @xml.at('Gmtoffset').inner_text.to_i
156
+ end
157
+
158
+ #
159
+ # Return the Location DST Offset.
160
+ # The gmtOffset/dstOffset fields names are a little misleading => dstOffset: offset to GMT at 1st July.
161
+ #
162
+ # @return [Integer] dst_offset
163
+ #
164
+ # @see http://www.geonames.org/
165
+ #
166
+ def dst_offset
167
+ @dst_offset = @xml.at('Dstoffset').inner_text.to_i
168
+ end
169
+
170
+ #
171
+ # Return the Location Current Time.
172
+ #
173
+ # @return [DateTime] current_time
174
+ #
175
+ # @todo Make this method work correctly! =]
176
+ #
177
+ def current_time
178
+ (Time.now + timezone)
179
+ end
180
+
181
+ #
182
+ # Return the Location as a string
183
+ #
184
+ # @return [String] location
185
+ #
186
+ def to_s
187
+ "#{address} #{hostname} #{country} #{region} #{city}"
188
+ end
189
+
190
+ end
191
+ end
@@ -0,0 +1,136 @@
1
+ require 'ipdb/location'
2
+ module Ipdb
3
+
4
+ class Map
5
+
6
+ #
7
+ # Creates a new Map object.
8
+ #
9
+ # @param [Array] addresses/domians
10
+ # An array of addresses or domains.
11
+ #
12
+ # @param [Hash] options The options to create a Map with.
13
+ #
14
+ # @option options [Integer] :timeout ('10') The Timeout.
15
+ # @option options [Symbol] :units (':px') The units for width and height.
16
+ # @option options [Integer] :width ('600') The width of the Map.
17
+ # @option options [Integer] :height ('350') The height of the Map.
18
+ # @option options [Integer] :zoom ('10') The zoom of the Map.
19
+ # @option options [String] :div_id ('map_canvas') The div id of the Map container.
20
+ # @option options [String] :div_class ('ipdb') The div class of the Map container.
21
+ #
22
+ # @return [MAP] map The newly created Map Object.
23
+ #
24
+ # @example
25
+ # Ipdb::Map.new(@ips, :zoom => 1, :width => 100, :height => 100, :units => :%)
26
+ def initialize(addr=nil, options={})
27
+ @timeout = options[:timeout] || 10
28
+ @units = (options[:units] || :px).to_sym
29
+ @width = options[:width] || 600
30
+ @height = options[:height] || 350
31
+ @zoom = options[:zoom] || 10
32
+ @div_id = options[:div_id] || 'map_canvas'
33
+ @div_class = options[:div_class] || 'ipdb'
34
+
35
+ ip = [addr].flatten
36
+ @url = "#{SCRIPT}?ip=#{URI.escape(ip.join(','))}"
37
+ @xml = Nokogiri::XML.parse(open(@url)).xpath('//Location')
38
+ end
39
+
40
+ #
41
+ # Return a Google Map for a Query Object
42
+ #
43
+ # @return [String<HTML, JavaScript>] map The Google Map html and JavaScript.
44
+ #
45
+ def render
46
+ @map = ""; @id = 0
47
+ @xml.each do |x|
48
+ location = Location.new(x, @timeout)
49
+ id = "ip_#{@id += 1}_id"
50
+ @start = new_location(location.latitude, location.longitude) if @id == 1
51
+ @map += add_marker(id, location.address, location.latitude, location.longitude)
52
+ @map += add_window(id, location.address, location.city, location.country)
53
+ @map += add_listener(id)
54
+ end
55
+ build_map(@start, @map)
56
+ end
57
+
58
+ private
59
+
60
+ #
61
+ # Build the Google maps options hash.
62
+ #
63
+ # @private
64
+ #
65
+ def build_options(start)
66
+ "var myOptions = {zoom: #{@zoom},center: #{start},mapTypeId: google.maps.MapTypeId.ROADMAP};var map = new google.maps.Map(document.getElementById('#{@div_id}'), myOptions);"
67
+ end
68
+
69
+ #
70
+ # Build a new Google Map Location object.
71
+ #
72
+ # @param [Float] latitude The new location objects latitude.
73
+ # @param [Float] longitude The new location objects longitude.
74
+ #
75
+ # @private
76
+ #
77
+ def new_location(latitude,longitude)
78
+ "new google.maps.LatLng(#{latitude}, #{longitude})"
79
+ end
80
+
81
+ #
82
+ # Build a Google Map marker for the Location.
83
+ #
84
+ # @param [String] id The Location id.
85
+ # @param [String] address The Location address.
86
+ # @param [Float] latitude The new location objects latitude.
87
+ # @param [Float] longitude The new location objects longitude.
88
+ #
89
+ # @private
90
+ #
91
+ def add_marker(id,address,latitude,longitude)
92
+ "var marker_#{id} = new google.maps.Marker({position: new google.maps.LatLng(#{latitude}, #{longitude}), map: map, title: '#{address}'});"
93
+ end
94
+
95
+ #
96
+ # Build a Google Map Window for the Location.
97
+ #
98
+ # @param [String] id The Location id.
99
+ # @param [String] address The Location address.
100
+ # @param [String] city The location city.
101
+ # @param [String] country The location country.
102
+ #
103
+ # @private
104
+ #
105
+ def add_window(id, address, city, country)
106
+ "var infowindow_#{id} = new google.maps.InfoWindow({content: 'IP Address: #{address}<br />#{city}, #{country}'});"
107
+ end
108
+
109
+ #
110
+ # Build a Google map Listener to watch for marker clicks.
111
+ #
112
+ # @param [String] id The Location id.
113
+ #
114
+ def add_listener(id)
115
+ "google.maps.event.addListener(marker_#{id}, 'click', function() {infowindow_#{id}.open(map,marker_#{id});});"
116
+ end
117
+
118
+ #
119
+ # Build The Google Map.
120
+ #
121
+ # @param [String] start A Google Map Location object to use as a starting point.
122
+ # @param [String] data The Google Map js built from the Location object.
123
+ #
124
+ # @private
125
+ #
126
+ def build_map(start, data)
127
+ return <<-EOF
128
+ <script type="text/javascript" src="http://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3A%22maps%22%2Cversion%3A3%2Cother_params%3A%22sensor%3Dfalse%22%7D%5D%7D"></script>
129
+ <script type="text/javascript">function ipdb() {#{build_options(start)}#{data}};google.setOnLoadCallback(ipdb);</script>
130
+ <div id="#{@div_id}" class="#{@div_class}" style="width: #{@width}#{@units}; height: #{@height}#{@units}"></div>
131
+ EOF
132
+ end
133
+
134
+ end
135
+
136
+ end
@@ -0,0 +1,123 @@
1
+ require 'ipdb/location'
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+ require 'enumerator'
5
+ require 'uri'
6
+
7
+ module Ipdb
8
+
9
+ #
10
+ # The IPinfoDB url
11
+ #
12
+ # @example http://ipinfodb.com/ip_query.php?ip=127.0.0.1&output=json
13
+ #
14
+ SCRIPT = 'http://ipinfodb.com/ip_query2.php'
15
+
16
+ class Query
17
+ include Enumerable
18
+
19
+ #
20
+ # Creates a new Query object.
21
+ #
22
+ # @param [Array] addresses/domians
23
+ # An array of addresses or domains.
24
+ #
25
+ # @param [Hash<Options>]
26
+ # Options for the new Query Object.
27
+ #
28
+ # @option opts [Integer] :timeout The Timeout. (Default: 10)
29
+ #
30
+ def initialize(addr=nil, options={})
31
+ @timeout = options[:timeout]
32
+
33
+ ip = [addr].flatten
34
+ @url = "#{SCRIPT}?ip=#{URI.escape(ip.join(','))}"
35
+ @xml = Nokogiri::XML.parse(open(@url))
36
+ end
37
+
38
+ #
39
+ # Process The Query Object And Return A Location Object
40
+ #
41
+ # @return [Location]
42
+ # The Location object returned from the Query.
43
+ #
44
+ def parse
45
+ Location.new(@xml.xpath('//Location'), @timeout)
46
+ end
47
+
48
+ #
49
+ # Parses the Locations from the Query.
50
+ #
51
+ # @yield [Query]
52
+ # Each query will be passed to a given block.
53
+ #
54
+ # @yieldparam [Location] location
55
+ # A location from the query.
56
+ #
57
+ # @return [XML]
58
+ # The XML object.
59
+ #
60
+ def each(&block)
61
+ @xml.xpath('//Location').each do |location|
62
+ block.call(Location.new(location, @timeout)) if block
63
+ end
64
+ end
65
+
66
+ #
67
+ # Return the url of the Query
68
+ #
69
+ # @return [String] url
70
+ #
71
+ def url
72
+ @url
73
+ end
74
+
75
+ #
76
+ # Return the Query object in json format.
77
+ #
78
+ # @return [Query] json
79
+ #
80
+ def to_json
81
+ json = "#{@url}&output=json"
82
+ @doc = Nokogiri::HTML(open(json))
83
+ return @doc.xpath('//body/.').inner_text
84
+ end
85
+
86
+ #
87
+ # Return the Query in XML format.
88
+ #
89
+ # @return [Query] xml
90
+ #
91
+ def to_s
92
+ @xml
93
+ end
94
+
95
+ alias to_xml to_s
96
+ alias all to_a
97
+
98
+ #
99
+ # Return a map url of addresses from the Query
100
+ #
101
+ # @return [String] url
102
+ #
103
+ def simple_map_url
104
+ @country_codes = []
105
+ @data = []
106
+ Enumerator.new(self,:each).to_a.collect {|x| @country_codes << x.country_code }
107
+ @country_codes = @country_codes.uniq
108
+ 1.upto(@country_codes.size) { |x| @data << '0' }
109
+ url = "http://chart.apis.google.com/chart?cht=t&chs=440x220&chd=t:#{@data.join(',')}&chco=FFFFFF,4A4A4A,EBEBEB&chld=#{@country_codes}&chtm=world&chf=bg,s,EAF7FE"
110
+ return url
111
+ end
112
+
113
+ #
114
+ # Convenient Method to render the map url as an image in Rails.
115
+ #
116
+ # @return [String] image
117
+ #
118
+ def simple_map_image
119
+ "image_path(#{simple_map_url})"
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Ipdb' do
4
+ it "should have a SCRIPT constant" do
5
+ Ipdb.const_defined?('SCRIPT').should == true
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Location" do
4
+
5
+ before(:all) do
6
+ @ip = Ipdb::Query.new('64.13.134.52').parse
7
+ end
8
+
9
+ it "should return the Location hostname" do
10
+ @ip.hostname.should == 'scanme.nmap.org'
11
+ end
12
+
13
+ it "should return the Location ip address" do
14
+ @ip.address.should == '64.13.134.52'
15
+ end
16
+
17
+ it "should return the Location Country" do
18
+ @ip.country.should == 'United States'
19
+ end
20
+
21
+ it "should return the Location Region" do
22
+ @ip.region.should == 'California'
23
+ end
24
+
25
+ it "should return the Location City" do
26
+ @ip.city.should == 'Sunnyvale'
27
+ end
28
+
29
+ it "should return the Location Status" do
30
+ @ip.status.should == 'OK'
31
+ end
32
+
33
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Query" do
4
+
5
+ before(:all) do
6
+ @query = Ipdb::Query.new('64.13.134.52')
7
+ end
8
+
9
+ it "should return the Query url" do
10
+ @query.url.should == 'http://ipinfodb.com/ip_query2.php?ip=64.13.134.52'
11
+ end
12
+
13
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>=1.1.12'
3
+ require 'spec'
4
+ require 'spec/autorun'
5
+
6
+ require "ipdb"
@@ -0,0 +1,10 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ desc "Run all specifications"
4
+ Spec::Rake::SpecTask.new(:spec) do |t|
5
+ t.libs += ['lib', 'spec']
6
+ t.spec_opts = ['--colour', '--format', 'specdoc']
7
+ end
8
+
9
+ task :test => :spec
10
+ task :default => :spec
@@ -0,0 +1,12 @@
1
+ require 'yard'
2
+
3
+ YARD::Rake::YardocTask.new do |t|
4
+ t.files = ['lib/**/*.rb']
5
+ t.options = [
6
+ '--protected',
7
+ '--files', 'History.txt',
8
+ '--title', 'Ipdb'
9
+ ]
10
+ end
11
+
12
+ task :docs => :yard
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ipdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Dustin Willis Webber
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-27 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.4.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.2.9
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.2.3.5
44
+ version:
45
+ description: ipdb is a ruby interface to the ipinfodb IP geographical locator api.
46
+ email: dustin.webber@gmail.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - README.rdoc
53
+ files:
54
+ - .gitignore
55
+ - History.txt
56
+ - README.rdoc
57
+ - Rakefile
58
+ - VERSION
59
+ - init.rb
60
+ - lib/ipdb.rb
61
+ - lib/ipdb/location.rb
62
+ - lib/ipdb/map.rb
63
+ - lib/ipdb/query.rb
64
+ - spec/ipdb_spec.rb
65
+ - spec/location_spec.rb
66
+ - spec/query_spec.rb
67
+ - spec/spec_helper.rb
68
+ - tasks/spec.rb
69
+ - tasks/yard.rb
70
+ has_rdoc: true
71
+ homepage: http://github.com/mephux/ipdb
72
+ licenses: []
73
+
74
+ post_install_message:
75
+ rdoc_options:
76
+ - --charset=UTF-8
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ version:
91
+ requirements: []
92
+
93
+ rubyforge_project:
94
+ rubygems_version: 1.3.5
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: ipdb is a simple IP geographical locator.
98
+ test_files:
99
+ - spec/ipdb_spec.rb
100
+ - spec/location_spec.rb
101
+ - spec/query_spec.rb
102
+ - spec/spec_helper.rb