ipgeolocation 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ === 0.1.0 / 2009-03-24
2
+
3
+ * First release
4
+
5
+ * Supports 3 remote IP Geolocation services: blogama.org, netgeo, and iphost
6
+
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/ipgeolocation.rb
6
+ test/test_ipgeolocation.rb
@@ -0,0 +1,62 @@
1
+ = ipgeolocation
2
+
3
+ * http://beforefilter.blogspot.com/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Remote, IP-Based Geolocation for everyone!
8
+
9
+ Seriously, this gem gives you 3 different IP-location services as
10
+ 1-liners. Example:
11
+
12
+ IPGeolocation.locate("12.345.678.90", :blogama)
13
+
14
+ That's all there is to it! And you get a bunch of information, especially
15
+ from blogama's API.
16
+
17
+ == FEATURES/PROBLEMS:
18
+
19
+ * 3 supported IP-Location services
20
+ * no local DB support - this will come in the future once licensing issues
21
+ are determined
22
+
23
+ == SYNOPSIS:
24
+
25
+ IPGeolocation.locate("74.125.45.100", :blogama)
26
+
27
+ gives
28
+
29
+ #<struct IPGeolocation::Location ip="74.125.45.100", country_code="US", country_name="United States", region_code="CA", region_name=nil, city="Mountain View", postal_code="94043", latitude="37.4192", longitude="-122.057">
30
+
31
+ == REQUIREMENTS:
32
+
33
+ * nothing!
34
+
35
+ == INSTALL:
36
+
37
+ * sudo gem install ipgeolocation
38
+
39
+ == LICENSE:
40
+
41
+ (The MIT License)
42
+
43
+ Copyright (c) 2009 Michael J. Edgar
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining
46
+ a copy of this software and associated documentation files (the
47
+ 'Software'), to deal in the Software without restriction, including
48
+ without limitation the rights to use, copy, modify, merge, publish,
49
+ distribute, sublicense, and/or sell copies of the Software, and to
50
+ permit persons to whom the Software is furnished to do so, subject to
51
+ the following conditions:
52
+
53
+ The above copyright notice and this permission notice shall be
54
+ included in all copies or substantial portions of the Software.
55
+
56
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
57
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
58
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
59
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
60
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
61
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
62
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,76 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/ipgeolocation.rb'
6
+
7
+ Hoe.new('ipgeolocation', IPGeolocation::VERSION) do |p|
8
+ # p.rubyforge_name = 'ipgeolocationx' # if different than lowercase project name
9
+ p.developer('Michael J. Edgar', 'edgar@triqweb.com')
10
+ p.remote_rdoc_dir = ''
11
+
12
+ desc 'Post your blog announcement to blogger.'
13
+ task :post_blogger do
14
+ require 'net/http'
15
+ require 'net/https'
16
+ p.with_config do |config, path|
17
+ break unless config['blogs']
18
+ subject, title, body, urls = p.announcement
19
+ #body += "\n\n#{urls}"
20
+
21
+ config['blogs'].each do |site|
22
+ next unless site['url'] =~ /www\.blogger\.com/
23
+ google_email = site['user']
24
+ google_passwd = site['password']
25
+ source = 'beforefilter.blogspot.com-rubypost'
26
+
27
+ http = Net::HTTP.new('www.google.com', 443)
28
+ http.use_ssl = true
29
+ login_url = '/accounts/ClientLogin'
30
+
31
+ # Setup HTTPS request post data to obtain authentication token.
32
+ data = 'Email=' + google_email +'&Passwd=' + google_passwd + '&source=' + source + '&service=blogger'
33
+ headers = {
34
+ 'Content-Type' => 'application/x-www-form-urlencoded'
35
+ }
36
+
37
+ # Submit HTTPS post request
38
+ resp, data = http.post(login_url, data, headers)
39
+
40
+ unless resp.code.eql? '200'
41
+ puts "Error during authentication, blog at #{site['url']}, ##{site['blog_id']}: #{resp.message}\n"
42
+ else
43
+
44
+ # Parse for the authentication token.
45
+ authToken = data.split("\n").map {|l| l.split("=")}.assoc("Auth")[1]
46
+
47
+ headers = {
48
+ 'Authorization' => 'GoogleLogin auth=' + authToken,
49
+ 'Content-Type' => 'application/atom+xml'
50
+ }
51
+
52
+ data = <<-EOF
53
+ <entry xmlns='http://www.w3.org/2005/Atom'>
54
+ <title type='text'>#{title}</title>
55
+ <content type='xhtml'>
56
+ <div xmlns="http://www.w3.org/1999/xhtml">
57
+ #{body}
58
+ </div>
59
+ </content>
60
+ #{p.blog_categories.inject("") {|acc,cat| acc + "<category scheme=\"http://www.blogger.com/atom/ns#\" term=\"#{cat}\" />\n"}}
61
+ </entry>
62
+ EOF
63
+
64
+ http = Net::HTTP.new('www.blogger.com')
65
+ path = '/feeds/' + site['blog_id'] + '/posts/default'
66
+
67
+ resp, data = http.post(path, data, headers)
68
+ puts "Error while posting, blog at #{site['url']}, ##{site['blog_id']}: #{resp.message}" unless resp.code == 200
69
+ # Expect resp.code == 200 and resp.message == 'OK' for a successful.
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ # vim: syntax=Ruby
@@ -0,0 +1,118 @@
1
+ require 'rexml/document'
2
+ require 'open-uri'
3
+ require 'net/http'
4
+ # = IPGeolocation
5
+ #
6
+ # This library enables IP-Location lookups via remote services.
7
+ # Simply call:
8
+ # IPGeolocation.locate("12.345.678.90", :blogama) # OR
9
+ # IPGeolocation.locate("12.345.678.90", :netgeo) # OR
10
+ # IPGeolocation.locate("12.345.678.90", :hostip)
11
+ #
12
+ # and you will be given a struct with a bunch of nifty information!
13
+ # to its credit, blogama seems to be very, very accurate.
14
+ #
15
+ module IPGeolocation
16
+ VERSION = '0.1.0'
17
+
18
+ ACCEPTABLE_LOCATORS = [:blogama, :netgeo, :hostip]
19
+
20
+ # Fields you can get from the different services
21
+ RESULT_FIELDS = [:ip, :country_code, :country_name, :region_code, :region_name,
22
+ :city, :postal_code, :latitude, :longitude]
23
+
24
+ # Main Location thread. You must choose from one of the available
25
+ # location services. In future versions this will support a local database.
26
+ #
27
+ # Available locators:
28
+ # [:blogama] The Blogama IP database - highly accurate
29
+ # [:netgeo] Netgeo, a legacy IP geolocation service. Doesn't offer zip-codes.
30
+ # [:hostip] Hostip.info - this is a newer location service, but coverage is somewhat spotty.
31
+ #
32
+ # Usage:
33
+ # IPgeolocation.locate("12.345.678.90", :blogama)
34
+ #
35
+ def locate(ip, locator)
36
+ raise ArgumentError.new("Invalid locator: #{locator}") unless ACCEPTABLE_LOCATORS.include?(locator)
37
+ klass = case locator
38
+ when :blogama
39
+ IPGeolocation::BlogamaLocator
40
+ when :netgeo
41
+ IPGeolocation::NetGeoLocator
42
+ when :hostip
43
+ IPGeolocation::HostIPLocator
44
+ end
45
+
46
+ klass.locate(ip)
47
+ end
48
+ module_function :locate
49
+
50
+ # Location interface for hostip.info. Doesn't need to be used directly.
51
+ class HostIPLocator
52
+ HOST_IP_QUERY_URL = "http://api.hostip.info/?"
53
+
54
+ def self.locate ip
55
+ doc = REXML::Document.new(open(IPGeolocation::HostIPLocator::HOST_IP_QUERY_URL+"ip=#{ip}"))
56
+
57
+ result = IPGeolocation::Location.new
58
+ result.ip = ip
59
+ result.country_code = REXML::XPath.first( doc, "//countryAbbrev" ).text.strip
60
+ result.country_name = REXML::XPath.first( doc, "//countryName" ).text.strip
61
+ result.region_code = REXML::XPath.first( doc, "//gml:name" ).text.split(",").last.strip
62
+ result.city = REXML::XPath.first( doc, "//gml:name" ).text.split(",").first.strip
63
+
64
+ coords = REXML::XPath.first( doc, "//gml:coordinates" )
65
+ if coords
66
+ result.latitude = coords.text.split(",").last.strip
67
+ result.longitude = coords.text.split(",").first.strip
68
+ end
69
+ result
70
+ end
71
+ end
72
+
73
+ # Location interface for netgeo.caida.org. Doesn't need to be used directly.
74
+ class NetGeoLocator
75
+
76
+ def self.locate ip
77
+ resp = Net::HTTP.new("netgeo.caida.org").get("/perl/netgeo.cgi?target=#{ip}")
78
+ result = IPGeolocation::Location.new
79
+ fakehash = resp.body.gsub(/<\/?[^>]*>/, "").split("\n").map {|a| a.split ":"}
80
+
81
+ result.ip = fakehash.assoc("TARGET")[1].strip
82
+ result.city = fakehash.assoc("CITY")[1].strip
83
+ result.region_name = fakehash.assoc("STATE")[1].strip
84
+ result.country_code = fakehash.assoc("COUNTRY")[1].strip
85
+ result.latitude = fakehash.assoc("LAT")[1].strip
86
+ result.longitude = fakehash.assoc("LONG")[1].strip
87
+ result
88
+ end
89
+ end
90
+
91
+ # Location interface for blogama.org. Doesn't need to be used directly.
92
+ class BlogamaLocator
93
+ BLOGAMA_QUERY_URL = "http://blogama.org/ip_query.php?"
94
+
95
+ def self.locate ip
96
+ doc = REXML::Document.new(open(IPGeolocation::BlogamaLocator::BLOGAMA_QUERY_URL+"ip=#{ip}&output=xml"))
97
+
98
+ root = doc.root
99
+ puts root
100
+ result = IPGeolocation::Location.new
101
+ result.ip = root.elements["Ip"].text
102
+ result.country_code = root.elements["CountryCode"].text
103
+ result.country_name = root.elements["CountryName"].text
104
+ result.region_code = root.elements["RegionCode"].text
105
+ result.region_name = root.elements["RegionName"].text
106
+ result.city = root.elements["City"].text
107
+ result.postal_code = root.elements["ZipPostalCode"].text
108
+ result.latitude = root.elements["Latitude"].text
109
+ result.longitude = root.elements["Longitude"].text
110
+
111
+ result
112
+ end
113
+ end
114
+
115
+ # Struct for holding all relevant info from GeoLocation services
116
+ class Location < Struct.new(*IPGeolocation::RESULT_FIELDS)
117
+ end
118
+ end
@@ -0,0 +1,8 @@
1
+ require "test/unit"
2
+ require "ipgeolocation"
3
+
4
+ class TestIpgeolocation < Test::Unit::TestCase
5
+ def test_sanity
6
+ flunk "write tests or I will kneecap you"
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ipgeolocation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael J. Edgar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-25 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.11.0
24
+ version:
25
+ description: "Remote, IP-Based Geolocation for everyone! Seriously, this gem gives you 3 different IP-location services as 1-liners. Example: IPGeolocation.locate(\"12.345.678.90\", :blogama) That's all there is to it! And you get a bunch of information, especially from blogama's API."
26
+ email:
27
+ - edgar@triqweb.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ files:
37
+ - History.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - lib/ipgeolocation.rb
42
+ - test/test_ipgeolocation.rb
43
+ has_rdoc: true
44
+ homepage: http://beforefilter.blogspot.com/
45
+ post_install_message:
46
+ rdoc_options:
47
+ - --main
48
+ - README.txt
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project: ipgeolocation
66
+ rubygems_version: 1.3.1
67
+ signing_key:
68
+ specification_version: 2
69
+ summary: Remote, IP-Based Geolocation for everyone! Seriously, this gem gives you 3 different IP-location services as 1-liners
70
+ test_files:
71
+ - test/test_ipgeolocation.rb