simplegeo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.swp
2
+ *.swo
3
+ *.swn
4
+ .tmp_*
5
+ .project
6
+ ._*
7
+ .DS_Store
8
+ pkg/*
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Scott Windsor
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.rdoc ADDED
@@ -0,0 +1,21 @@
1
+ = simplegeo-ruby
2
+
3
+ This is a Ruby client for the Simplegeo API (Version 0.1)
4
+
5
+ For the specific documentation on APIs (and the full list of parameters) see:
6
+
7
+ http://help.simplegeo.com/faqs/api-documentation/endpoints
8
+
9
+ == Note on Patches/Pull Requests
10
+
11
+ * Fork the project.
12
+ * Make your feature addition or bug fix.
13
+ * Add tests for it. This is important so I don't break it in a
14
+ future version unintentionally.
15
+ * Commit, do not mess with rakefile, version, or history.
16
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
17
+ * Send me a pull request. Bonus points for topic branches.
18
+
19
+ == Copyright
20
+
21
+ Copyright (c) 2010 Scott Windsor. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "simplegeo"
8
+ gem.summary = %Q{a simplegeo client written in ruby}
9
+ gem.description = %Q{a simplegeo client written in ruby. see http://help.simplegeo.com/faqs/api-documentation/endpoints for more info.}
10
+ gem.email = "swindsor@gmail.com"
11
+ gem.homepage = "http://github.com/sentientmonkey/simplegeo-ruby"
12
+ gem.authors = ["Scott Windsor"]
13
+ gem.add_development_dependency "rspec", ">= 1.3.0"
14
+ gem.add_dependency('oauth', '>= 0.3.6')
15
+ gem.add_dependency('crack', '>= 0.1.7')
16
+ gem.add_dependency('json', '>= 1.2.2')
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "simplegeo #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/lib/simplegeo.rb ADDED
@@ -0,0 +1,179 @@
1
+ require 'rubygems'
2
+
3
+ gem 'crack', '~> 0.1.7'
4
+ require 'crack'
5
+
6
+ gem 'oauth', '~> 0.3.6'
7
+ require 'oauth'
8
+
9
+ gem 'json', '~> 1.2.2'
10
+ require 'json'
11
+
12
+ require 'forwardable'
13
+ require 'uri'
14
+
15
+ # This is a client for accessing Simplegeo's REST APIs
16
+ # for full documentation see:
17
+ # http://help.simplegeo.com/faqs/api-documentation/endpoints
18
+
19
+ class Simplegeo
20
+ BASE_URI = 'http://api.simplegeo.com'
21
+ VER = '0.1'
22
+ attr_accessor :layer
23
+ attr_reader :access_token
24
+
25
+ extend Forwardable
26
+ def_delegators :access_token, :get, :post, :put, :delete
27
+
28
+ class NotAuthorized < StandardError; end
29
+ class NotFound < StandardError; end
30
+ class InternalError < StandardError; end
31
+
32
+ # initialize a new client with a acess key, secret key, and a default layer
33
+ def initialize(key, secret, layer = nil)
34
+ @access_token = self.class.get_access_token(key, secret)
35
+ @layer = layer
36
+ end
37
+
38
+ # find nearby objects given a lat & lng
39
+ # by default, only searches the the current layer
40
+ def nearby(lat, lng, options = {})
41
+ options = {}
42
+ options[:layers] ||= [self.layer]
43
+ perform_get("/nearby/#{lat},#{lng}.json", :query => options)
44
+ end
45
+
46
+ # reverse geocodes a lat & lng
47
+ def nearby_address(lat, lng, options = {})
48
+ options = {}
49
+ perform_get("/nearby/address/#{lat},#{lng}.json", :query => options)
50
+ end
51
+
52
+ def user_stats
53
+ perform_get("/stats.json")
54
+ end
55
+
56
+ def layer_stats
57
+ perform_get("/stats/#{layer}.json")
58
+ end
59
+
60
+ class Records
61
+ def initialize(simplegeo) #:nodoc:
62
+ @simplegeo = simplegeo
63
+ end
64
+
65
+ # get a record by id
66
+ def get(id)
67
+ @simplegeo.records_dispatch(:get, id)
68
+ end
69
+
70
+ # put a record by id
71
+ # data should be a hash with at least lat & lon keys, as well as extra data
72
+ def put(id, data)
73
+ @simplegeo.records_dispatch(:put, id, data)
74
+ end
75
+
76
+ # delete a record by id
77
+ def delete(id)
78
+ @simplegeo.records_dispatch(:delete, id)
79
+ end
80
+
81
+ # get the history of a record by id
82
+ def history(id)
83
+ @simplegeo.records_dispatch(:get_history, id)
84
+ end
85
+ end
86
+
87
+ # used to access record APIs
88
+ # i.e. client.records.get(1)
89
+ def records
90
+ Records.new(self)
91
+ end
92
+
93
+ def records_dispatch(operation, id, body = nil) #:nodoc:
94
+ case operation
95
+ when :get_history
96
+ perform(:get, "/records/#{layer}/#{id}/history.json")
97
+ when :put
98
+ perform(:put, "/records/#{layer}/#{id}.json", :body => build_feature(id, body))
99
+ else
100
+ perform(operation, "/records/#{layer}/#{id}.json")
101
+ end
102
+ end
103
+
104
+ protected
105
+
106
+ def self.get_access_token(key, secret)
107
+ consumer = OAuth::Consumer.new(key,secret, :site => BASE_URI)
108
+ OAuth::AccessToken.new(consumer)
109
+ end
110
+
111
+ def perform(operation, path, options = {})
112
+ case operation
113
+ when :put, :post
114
+ handle_response(self.send(operation, build_uri(path, options), options[:body].to_json))
115
+ else
116
+ handle_response(self.send(operation, build_uri(path, options)))
117
+ end
118
+ end
119
+
120
+ def perform_get(path, options = {})
121
+ perform(:get, path, options)
122
+ end
123
+
124
+ def perform_delete(path, options = {})
125
+ perform(:delete, path, options)
126
+ end
127
+
128
+ def perform_put(path, options = {})
129
+ perform(:put, path, options)
130
+ end
131
+
132
+ def perform_post(path, options = {})
133
+ perform(:post, path, options)
134
+ end
135
+
136
+ def build_uri(path, options = {})
137
+ uri = URI.parse("/#{VER}#{path}")
138
+ uri.query = build_query(options[:query])
139
+ uri.to_s
140
+ end
141
+
142
+ def build_query(query)
143
+ if query && query != {}
144
+ query.map do |k,v|
145
+ [k.to_s,v.to_s].join('=')
146
+ end.join('&')
147
+ end
148
+ end
149
+
150
+ def build_feature(id, body)
151
+ {:type => 'Feature',
152
+ :id => id,
153
+ :created => body[:created],
154
+ :geometry => { :type => 'Point',
155
+ :coordinates => [body[:lon], body[:lat]]},
156
+ :properties => body.reject{|k,v| [:created, :lat, :lon].include?(k) }}
157
+ end
158
+
159
+ def handle_response(response)
160
+ raise_errors(response)
161
+ parse(response)
162
+ end
163
+
164
+ def raise_errors(response)
165
+ case response.code.to_i
166
+ when 401
167
+ raise NotAuthorized.new "(#{response.code}): #{response.message}"
168
+ when 404
169
+ raise NotFound.new "(#{response.code}): #{response.message}"
170
+ when 500
171
+ raise InternalError.new "(#{response.code}): #{response.message}"
172
+ end
173
+ end
174
+
175
+ def parse(response)
176
+ Crack::JSON.parse(response.body)
177
+ end
178
+
179
+ end
data/simplegeo.gemspec ADDED
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{simplegeo}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Scott Windsor"]
12
+ s.date = %q{2010-03-08}
13
+ s.description = %q{a simplegeo client written in ruby. see http://help.simplegeo.com/faqs/api-documentation/endpoints for more info.}
14
+ s.email = %q{swindsor@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/simplegeo.rb",
26
+ "simplegeo.gemspec",
27
+ "spec/simplegeo_spec.rb",
28
+ "spec/spec.opts",
29
+ "spec/spec_helper.rb",
30
+ "spec/test_keys.yml"
31
+ ]
32
+ s.homepage = %q{http://github.com/sentientmonkey/simplegeo-ruby}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.5}
36
+ s.summary = %q{a simplegeo client written in ruby}
37
+ s.test_files = [
38
+ "spec/simplegeo_spec.rb",
39
+ "spec/spec_helper.rb"
40
+ ]
41
+
42
+ if s.respond_to? :specification_version then
43
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
47
+ s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
48
+ s.add_runtime_dependency(%q<oauth>, [">= 0.3.6"])
49
+ s.add_runtime_dependency(%q<crack>, [">= 0.1.7"])
50
+ s.add_runtime_dependency(%q<json>, [">= 1.2.2"])
51
+ else
52
+ s.add_dependency(%q<rspec>, [">= 1.3.0"])
53
+ s.add_dependency(%q<oauth>, [">= 0.3.6"])
54
+ s.add_dependency(%q<crack>, [">= 0.1.7"])
55
+ s.add_dependency(%q<json>, [">= 1.2.2"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<rspec>, [">= 1.3.0"])
59
+ s.add_dependency(%q<oauth>, [">= 0.3.6"])
60
+ s.add_dependency(%q<crack>, [">= 0.1.7"])
61
+ s.add_dependency(%q<json>, [">= 1.2.2"])
62
+ end
63
+ end
64
+
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Simplegeo" do
4
+ it "should be able to get an access token" do
5
+ access_token = Simplegeo.get_access_token(@test_keys['key'], @test_keys['secret'])
6
+ result = access_token.get("/0.1/records/com.simplegeo.us.zip/98122.json")
7
+ result.should be_a_kind_of(Net::HTTPOK)
8
+ end
9
+
10
+ it "should be able to find a record" do
11
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.simplegeo.us.zip')
12
+ result = simple.records.get(98122)
13
+ result.should be_a_kind_of(Hash)
14
+ result['id'].should eql('98122')
15
+ end
16
+
17
+ it "should be able to find history for a record" do
18
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.simplegeo.us.zip')
19
+ result = simple.records.history(98122)
20
+ result.should be_a_kind_of(Hash)
21
+ end
22
+
23
+ it "should be able to find nearby" do
24
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.simplegeo.us.zip')
25
+ result = simple.nearby(47.607089,-122.332034)
26
+ result.should be_a_kind_of(Hash)
27
+ end
28
+
29
+ it "should be able to find nearby address" do
30
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'])
31
+ result = simple.nearby_address(47.607089,-122.332034)
32
+ result.should be_a_kind_of(Hash)
33
+ result['properties'].should_not be_nil
34
+ result['properties']['place_name'].should eql('Seattle')
35
+ result['properties']['state_name'].should eql('Washington')
36
+ result['properties']['street'].should eql('5th Ave')
37
+ result['properties']['postal_code'].should eql('98104')
38
+ result['properties']['county_name'].should eql('King')
39
+ result['properties']['country'].should eql('US')
40
+ end
41
+
42
+ it "should be able to find user stats" do
43
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.simplegeo.us.zip')
44
+ result = simple.user_stats
45
+ result.should be_a_kind_of(Hash)
46
+ result['requests'].should_not be_nil
47
+ result['requests']['nearby'].should_not be_nil
48
+ end
49
+
50
+ it "should be able to put record" do
51
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.sentientmonkey.test')
52
+ result = simple.records.put(1, {:lat => 47.607089, :lon => -122.332034, :test => 'one'})
53
+ result = simple.records.get(1)
54
+ #TODO assertions
55
+ end
56
+
57
+ it "should be able to delete record" do
58
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.sentientmonkey.test')
59
+ result = simple.records.put(2, {:lat => 47.607089, :lon => -122.332034, :test => 'two'})
60
+ result = simple.records.delete(2)
61
+ result = simple.records.get(2)
62
+ #TODO assertions
63
+ end
64
+
65
+ it "should be able to find layer stats" do
66
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.sentientmonkey.test')
67
+ result = simple.layer_stats
68
+ result.should be_a_kind_of(Hash)
69
+ result['requests'].should_not be_nil
70
+ end
71
+
72
+ it "should raise NotFound exception on invalid record" do
73
+ simple = Simplegeo.new(@test_keys['key'], @test_keys['secret'], 'com.simplegeo.us.zip')
74
+ lambda{ simple.records.get(1) }.should raise_exception(Simplegeo::NotFound)
75
+ end
76
+
77
+ it "should raise NotAuthorized exception on invalid keys" do
78
+ simple = Simplegeo.new('bad key', 'bad secret', 'com.simplegeo.us.zip')
79
+ lambda{ simple.records.get(98122) }.should raise_exception(Simplegeo::NotAuthorized)
80
+ end
81
+
82
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'simplegeo'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+ require 'yaml'
7
+
8
+ Spec::Runner.configure do |config|
9
+ config.before(:all) do
10
+ @test_keys = YAML::load_file(File.join(File.dirname(__FILE__), "test_keys.yml"))
11
+ if @test_keys['key'] == 'key' || @test_keys['secret'] == 'secret'
12
+ raise 'test keys not set! add your keys to test_keys.yml'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,2 @@
1
+ key: 'Bg3Ys84hRtnUUzrtazaWCbbsxGfKuuNj'
2
+ secret: 'Vme9ZtxkexyZXeFNQhjTyJQqmaVS7cAN'
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simplegeo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Scott Windsor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-08 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.3.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: oauth
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.6
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: crack
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.1.7
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: json
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.2.2
54
+ version:
55
+ description: a simplegeo client written in ruby. see http://help.simplegeo.com/faqs/api-documentation/endpoints for more info.
56
+ email: swindsor@gmail.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - LICENSE
63
+ - README.rdoc
64
+ files:
65
+ - .gitignore
66
+ - LICENSE
67
+ - README.rdoc
68
+ - Rakefile
69
+ - VERSION
70
+ - lib/simplegeo.rb
71
+ - simplegeo.gemspec
72
+ - spec/simplegeo_spec.rb
73
+ - spec/spec.opts
74
+ - spec/spec_helper.rb
75
+ - spec/test_keys.yml
76
+ has_rdoc: true
77
+ homepage: http://github.com/sentientmonkey/simplegeo-ruby
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --charset=UTF-8
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ version:
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: "0"
96
+ version:
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 1.3.5
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: a simplegeo client written in ruby
104
+ test_files:
105
+ - spec/simplegeo_spec.rb
106
+ - spec/spec_helper.rb