ip2location 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,4 @@
1
+ lib/**/*.rb
2
+ README.rdoc
3
+ ChangeLog.rdoc
4
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake', '~> 0.8.7'
7
+ gem 'ore-tasks', '~> 0.4'
8
+ gem 'rspec', '~> 2.4'
9
+ gem 'guard', '~> 0.4.2'
10
+ gem 'guard-rspec', '~> 0.4.0'
11
+ gem 'growl', '~> 1.0.3'
12
+ end
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Ezekiel Templin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ ip2location
2
+ ===========
3
+
4
+ Description
5
+ -----------
6
+ This is a stupid simple client for [IP2LocationAPI](http://www.ip2locationapi.com/) written with [David Balatero](https://github.com/dbalatero)'s awesome [monster_mash](https://github.com/dbalatero/monster_mash) library. I wrote it more or less
7
+ as practice and to continue to familiarize myself with Ruby 1.9, RSpec, and Typhoeus.
8
+
9
+ Usage
10
+ --------
11
+ require 'ip2location'
12
+
13
+ # Ip2Location.api_key = YOUR_API_KEY
14
+ # Ip2Location.user = YOUR_API_USERNAME
15
+ #
16
+ # OR
17
+
18
+ Ip2Location.setup do |s|
19
+ s.api_key = YOUR_API_KEY
20
+ s.user = YOUR_API_USERNAME
21
+ end
22
+
23
+ puts Ip2Location.ip2l('8.8.8.8')
24
+ #=> <struct Ip2Location::Location ip="8.8.8.8", country_code="US", country="United States", region="California", city="Mountain View", latitude="34.305", longitude="-86.2981">
25
+
26
+
27
+ Requirements
28
+ ------------
29
+ * monster_mash (~> 0.2.3)
30
+ * A username and API key from [IP2LocationAPI](http://www.ip2locationapi.com/geoip-location-api/signup.php) (free)
31
+
32
+
33
+ Install
34
+ -------
35
+ gem install ip2location
36
+
37
+
38
+ Copyright
39
+ ---------
40
+ Copyright (c) 2011 Ezekiel Templin
41
+
42
+ See LICENSE.txt for details.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ STDERR.puts e.message
9
+ STDERR.puts "Run `gem install bundler` to install Bundler."
10
+ exit e.status_code
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ STDERR.puts e.message
17
+ STDERR.puts "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+
23
+ require 'ore/tasks'
24
+ Ore::Tasks.new
25
+
26
+ require 'rake/rdoctask'
27
+ Rake::RDocTask.new do |rdoc|
28
+ rdoc.title = "ip2location"
29
+ end
30
+ task :doc => :rdoc
31
+
32
+ require 'rspec/core/rake_task'
33
+ RSpec::Core::RakeTask.new
34
+
35
+ task :test => :spec
36
+ task :default => :spec
37
+
data/gemspec.yml ADDED
@@ -0,0 +1,12 @@
1
+ name: ip2location
2
+ summary: "Client for the IP2Location API"
3
+ description: "A simple client for the free IP2Location API."
4
+ license: MIT
5
+ authors: "Ezekiel Templin"
6
+ homepage: http://github.com/ezkl/ip2location
7
+
8
+ runtime_dependencies:
9
+ monster_mash: ~> 0.2
10
+
11
+ development_dependencies:
12
+ bundler: ~> 1.0.0
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gemspec|
6
+ files = if File.directory?('.git')
7
+ `git ls-files`.split($/)
8
+ elsif File.directory?('.hg')
9
+ `hg manifest`.split($/)
10
+ elsif File.directory?('.svn')
11
+ `svn ls -R`.split($/).select { |path| File.file?(path) }
12
+ else
13
+ Dir['{**/}{.*,*}'].select { |path| File.file?(path) }
14
+ end
15
+
16
+ filter_files = lambda { |paths|
17
+ case paths
18
+ when Array
19
+ (files & paths)
20
+ when String
21
+ (files & Dir[paths])
22
+ end
23
+ }
24
+
25
+ version = {
26
+ :file => 'lib/ip2location/version.rb',
27
+ :constant => 'Ip2Location::VERSION'
28
+ }
29
+
30
+ defaults = {
31
+ 'name' => File.basename(File.dirname(__FILE__)),
32
+ 'files' => files,
33
+ 'test_files' => filter_files['{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'],
34
+ 'extra_doc_files' => filter_files['*.{txt,rdoc,md,markdown,tt,textile}'],
35
+ }
36
+
37
+ metadata = defaults.merge(YAML.load_file('gemspec.yml'))
38
+
39
+ gemspec.name = metadata.fetch('name',defaults[:name])
40
+ gemspec.version = if metadata['version']
41
+ metadata['version']
42
+ elsif File.file?(version[:file])
43
+ require File.join('.',version[:file])
44
+ eval(version[:constant])
45
+ end
46
+
47
+ gemspec.summary = metadata.fetch('summary',metadata['description'])
48
+ gemspec.description = metadata.fetch('description',metadata['summary'])
49
+
50
+ case metadata['license']
51
+ when Array
52
+ gemspec.licenses = metadata['license']
53
+ when String
54
+ gemspec.license = metadata['license']
55
+ end
56
+
57
+ case metadata['authors']
58
+ when Array
59
+ gemspec.authors = metadata['authors']
60
+ when String
61
+ gemspec.author = metadata['authors']
62
+ end
63
+
64
+ gemspec.email = metadata['email']
65
+ gemspec.homepage = metadata['homepage']
66
+
67
+ case metadata['require_paths']
68
+ when Array
69
+ gemspec.require_paths = metadata['require_paths']
70
+ when String
71
+ gemspec.require_path = metadata['require_paths']
72
+ end
73
+
74
+ gemspec.files = filter_files[metadata['files']]
75
+
76
+ gemspec.executables = metadata['executables']
77
+ gemspec.extensions = metadata['extensions']
78
+
79
+ if Gem::VERSION < '1.7.'
80
+ gemspec.default_executable = gemspec.executables.first
81
+ end
82
+
83
+ gemspec.test_files = filter_files[metadata['test_files']]
84
+
85
+ unless gemspec.files.include?('.document')
86
+ gemspec.extra_rdoc_files = metadata['extra_doc_files']
87
+ end
88
+
89
+ gemspec.post_install_message = metadata['post_install_message']
90
+ gemspec.requirements = metadata['requirements']
91
+
92
+ if gemspec.respond_to?(:required_ruby_version=)
93
+ gemspec.required_ruby_version = metadata['required_ruby_version']
94
+ end
95
+
96
+ if gemspec.respond_to?(:required_rubygems_version=)
97
+ gemspec.required_rubygems_version = metadata['required_ruby_version']
98
+ end
99
+
100
+ parse_versions = lambda { |versions|
101
+ case versions
102
+ when Array
103
+ versions.map { |v| v.to_s }
104
+ when String
105
+ versions.split(/,\s*/)
106
+ end
107
+ }
108
+
109
+ if metadata['dependencies']
110
+ metadata['dependencies'].each do |name,versions|
111
+ gemspec.add_dependency(name,parse_versions[versions])
112
+ end
113
+ end
114
+
115
+ if metadata['runtime_dependencies']
116
+ metadata['runtime_dependencies'].each do |name,versions|
117
+ gemspec.add_runtime_dependency(name,parse_versions[versions])
118
+ end
119
+ end
120
+
121
+ if metadata['development_dependencies']
122
+ metadata['development_dependencies'].each do |name,versions|
123
+ gemspec.add_development_dependency(name,parse_versions[versions])
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,30 @@
1
+ require 'ostruct'
2
+ require 'monster_mash'
3
+
4
+ require 'ip2location/version'
5
+ require 'ip2location/base'
6
+ require 'ip2location/request'
7
+
8
+ module Ip2Location
9
+ BASE_URI = "http://api.ip2locationapi.com/"
10
+ @api_key = nil
11
+ @user = nil
12
+
13
+ class << self
14
+ attr_accessor :api_key, :user
15
+
16
+ def setup
17
+ yield self if block_given?
18
+ end
19
+
20
+ def request(ip)
21
+ Ip2Location::Request.ip2l(ip)
22
+ end
23
+ alias_method :ip2l, :request
24
+
25
+ end
26
+
27
+ class InvalidApiKeyError < StandardError; end
28
+ class NoLocationDataError < StandardError; end
29
+ class APIConnectionError < StandardError; end
30
+ end
@@ -0,0 +1,10 @@
1
+ module Ip2Location
2
+ class Base < MonsterMash::Base
3
+ defaults do
4
+ cache_timeout 999999
5
+ user_agent "Ip2LocationAPI Ruby (v#{VERSION})[https://github.com/ezkl/ip2location]"
6
+ params :key => Ip2Location.api_key,
7
+ :user => Ip2Location.user
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,36 @@
1
+ module Ip2Location
2
+ Location = Struct.new(:ip, :country_code, :country, :region, :city, :latitude, :longitude)
3
+
4
+ class Request < Base
5
+ get(:ip2l) do |ip|
6
+ uri "#{BASE_URI}"
7
+ params :user => Ip2Location.user,
8
+ :key => Ip2Location.api_key,
9
+ :ip => ip
10
+ handler do |response|
11
+ if response.success? && (parsed = parse_response(response.body, ip))
12
+ parsed
13
+ else
14
+ raise APIConnectionError, "There was a problem making your request!"
15
+ end
16
+ end
17
+ end
18
+
19
+ def self.parse_response(body, ip)
20
+ check_response_for_errors(body)
21
+ location_parts = body.split(/,/)
22
+ Location.new(ip, location_parts[0], location_parts[1], location_parts[2], location_parts[3], location_parts[4], location_parts[5])
23
+ end
24
+
25
+ def self.check_response_for_errors(body)
26
+ case body
27
+ when /Invalid user name or API key/
28
+ raise InvalidApiKeyError, "The API key [#{Ip2Location.api_key}] or Username [#{Ip2Location.user}] is invalid!"
29
+ when /NO DATA/
30
+ raise NoLocationDataError, "The IP you requested has no associated location data."
31
+ else
32
+ body
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Ip2Location
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'ip2location'
3
+
4
+ describe Ip2Location::Request do
5
+ it "should return a properly parsed Location structure" do
6
+ @api_key = "1fe480f5bac2c5261cf686f6265eed138953b98c"
7
+ @user = "ip2location_ruby"
8
+
9
+ Ip2Location.setup do |s|
10
+ s.api_key = @api_key
11
+ s.user = @user
12
+ end
13
+
14
+ Ip2Location.request("8.8.8.8").should eq Location.new("8.8.8.8", "US","United States","California","Mountain View","34.305","-86.2981")
15
+ end
16
+
17
+ describe "Parsing" do
18
+ before(:all) do
19
+ @no_data = "NO DATA"
20
+ @bad_api = "Sorry, Invalid user name or API key!"
21
+ @good_response = "US,United States,California,Mountain View,34.305,-86.2981"
22
+ end
23
+
24
+ it "should process responses properly" do
25
+ ->{ Ip2Location::Request.check_response_for_errors(@no_data) }.should raise_error(NoLocationDataError, "The IP you requested has no associated location data.")
26
+ ->{ Ip2Location::Request.check_response_for_errors(@bad_api) }.should raise_error(InvalidApiKeyError)
27
+ ->{ Ip2Location::Request.check_response_for_errors(@good_response) }.should_not raise_error
28
+ end
29
+
30
+ it "should return body unless response matches an error" do
31
+ Ip2Location::Request.check_response_for_errors(@good_response).should eq @good_response
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+ require 'ip2location'
3
+
4
+ describe Ip2Location do
5
+ it "should have a VERSION constant" do
6
+ subject.const_get('VERSION').should_not be_empty
7
+ end
8
+
9
+ describe "#setup" do
10
+ it "should take @api_key and @user" do
11
+ Ip2Location.setup do |s|
12
+ s.api_key = "1234"
13
+ s.user = "username"
14
+ end
15
+
16
+ Ip2Location.api_key.should eq "1234"
17
+ Ip2Location.user.should eq "username"
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,4 @@
1
+ require 'rspec'
2
+ require 'ip2location'
3
+
4
+ include Ip2Location
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ip2location
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Ezekiel Templin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-29 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: monster_mash
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: "0.2"
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ description: A simple client for the free IP2Location API.
38
+ email: []
39
+
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files:
45
+ - README.md
46
+ files:
47
+ - .document
48
+ - .rspec
49
+ - Gemfile
50
+ - Guardfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - gemspec.yml
55
+ - ip2location.gemspec
56
+ - lib/ip2location.rb
57
+ - lib/ip2location/base.rb
58
+ - lib/ip2location/request.rb
59
+ - lib/ip2location/version.rb
60
+ - spec/ip2location/request_spec.rb
61
+ - spec/ip2location_spec.rb
62
+ - spec/spec_helper.rb
63
+ homepage: http://github.com/ezkl/ip2location
64
+ licenses:
65
+ - MIT
66
+ post_install_message:
67
+ rdoc_options: []
68
+
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.6
83
+ requirements: []
84
+
85
+ rubyforge_project: ip2location
86
+ rubygems_version: 1.8.5
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Client for the IP2Location API
90
+ test_files:
91
+ - spec/ip2location/request_spec.rb
92
+ - spec/ip2location_spec.rb