google-civic-ruby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +28 -0
- data/Rakefile +1 -0
- data/google-civic-ruby.gemspec +28 -0
- data/lib/google-civic.rb +9 -0
- data/lib/google-civic/client.rb +34 -0
- data/lib/google-civic/connection.rb +42 -0
- data/lib/google-civic/election.rb +14 -0
- data/lib/google-civic/elections.rb +34 -0
- data/lib/google-civic/requester.rb +19 -0
- data/lib/google-civic/router.rb +35 -0
- data/lib/google-civic/version.rb +5 -0
- data/spec/google-civic/client_spec.rb +18 -0
- data/spec/google-civic/election_spec.rb +13 -0
- data/spec/google-civic/elections_spec.rb +29 -0
- data/spec/google-civic/requester_spec.rb +11 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/fixtures/elections.json +20 -0
- data/spec/support/fixtures/representative_info.json +769 -0
- data/spec/support/fixtures/voter_info.json +290 -0
- data/spec/support/helpers/fixtures.rb +15 -0
- data/spec/support/helpers/requests.rb +5 -0
- data/spec/support/shared_examples/connection_to_the_client.rb +16 -0
- metadata +195 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ecf478592957b5fc9111b2f913dbc780eeae1fc9
|
4
|
+
data.tar.gz: d6ad081f1789c5b78160b765ed184be3c6de9ad1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 348df3a75d235aa9fb9090364b8f9d350801fa1511a6559a3f56d1510c16a8e10f624bc3a1c45a6ff2686f5f93166f120798ed51ed2e9e1a89a9622d3448c1e2
|
7
|
+
data.tar.gz: 38a8a77b5263029ad0821ad7dbf63baaf266a69374c82e62166cd916ce8efa1525fda257f68898c8f98f43b2b6f93d37bc25433b69b24618bd89fb10f263d6fc
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Adam Cuppy
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Google::Civic
|
2
|
+
[![Build Status](https://travis-ci.org/CodingZeal/google-civic-ruby.svg?branch=master)](https://travis-ci.org/CodingZeal/google-civic-ruby) [![Code Climate](https://codeclimate.com/github/CodingZeal/google-civic-ruby.png)](https://codeclimate.com/github/CodingZeal/google-civic-ruby)
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
gem 'google-civic-ruby'
|
9
|
+
|
10
|
+
And then execute:
|
11
|
+
|
12
|
+
$ bundle
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
|
16
|
+
$ gem install google-civic-ruby
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
## Contributing
|
23
|
+
|
24
|
+
1. Fork it ( http://github.com/<my-github-username>/google-civic-api-ruby/fork )
|
25
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
26
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
27
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
28
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'google-civic/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "google-civic-ruby"
|
8
|
+
spec.version = Google::Civic::VERSION
|
9
|
+
spec.authors = ["Coding ZEAL", "Adam Cuppy"]
|
10
|
+
spec.email = ["adam@codingzeal.com"]
|
11
|
+
spec.summary = %q{Ruby wrapper for the Google Civic API}
|
12
|
+
spec.homepage = "https://github.com/CodingZeal/google-civic-ruby"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.test_files = spec.files.grep(%r{^(spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_dependency "multi_json", "~> 1.10"
|
20
|
+
spec.add_dependency "hashie", "~> 3.0"
|
21
|
+
spec.add_dependency "faraday", "~> 0.9"
|
22
|
+
spec.add_dependency "faraday_middleware", "~> 0.9"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
26
|
+
spec.add_development_dependency "pry"
|
27
|
+
spec.add_development_dependency "webmock", "~> 1.18"
|
28
|
+
end
|
data/lib/google-civic.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'google-civic/version'
|
2
|
+
require 'google-civic/election'
|
3
|
+
require 'google-civic/elections'
|
4
|
+
# require 'google-civic/address'
|
5
|
+
# require 'google-civic/voter_info'
|
6
|
+
require 'google-civic/client'
|
7
|
+
require 'google-civic/router'
|
8
|
+
require 'google-civic/requester'
|
9
|
+
require "google-civic/connection"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Google
|
2
|
+
module Civic
|
3
|
+
class Client
|
4
|
+
def initialize(api_key, connection)
|
5
|
+
@api_key = api_key
|
6
|
+
@connection = connection
|
7
|
+
end
|
8
|
+
|
9
|
+
def elections(zipcode)
|
10
|
+
Elections.for_zipcode(zipcode, self)
|
11
|
+
end
|
12
|
+
|
13
|
+
def voter_info(address)
|
14
|
+
VoterInfo.for_address(address, self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def request(*args)
|
18
|
+
@request ||= {}
|
19
|
+
@request[args] ||= Requester.new(connection, { key: api_key }).request(*args)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def connection
|
25
|
+
@connection or raise "Connection not established"
|
26
|
+
end
|
27
|
+
|
28
|
+
def api_key
|
29
|
+
@api_key or raise "No Google API key defined"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "faraday_middleware"
|
3
|
+
|
4
|
+
module Google
|
5
|
+
module Civic
|
6
|
+
class Connection
|
7
|
+
attr_writer :base_url
|
8
|
+
|
9
|
+
def initialize(params={})
|
10
|
+
@base_url = params.delete(:base_url)
|
11
|
+
establish!
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(*args, &block)
|
15
|
+
resource.get(*args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def post(*args, &block)
|
19
|
+
resource.post(*args, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def establish!
|
25
|
+
@resource = Faraday.new(base_url) do |builder|
|
26
|
+
builder.request :json
|
27
|
+
builder.request :url_encoded
|
28
|
+
builder.use FaradayMiddleware::ParseJson
|
29
|
+
builder.adapter Faraday.default_adapter
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def resource
|
34
|
+
@resource or raise "Connection not established"
|
35
|
+
end
|
36
|
+
|
37
|
+
def base_url
|
38
|
+
@base_url or ""
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "multi_json"
|
2
|
+
require "hashie"
|
3
|
+
|
4
|
+
module Google
|
5
|
+
module Civic
|
6
|
+
class Election < Hashie::Dash
|
7
|
+
include Hashie::Extensions::Dash::IndifferentAccess
|
8
|
+
|
9
|
+
property :id, required: true
|
10
|
+
property :name, required: true
|
11
|
+
property :electionDay, required: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "multi_json"
|
2
|
+
|
3
|
+
module Google
|
4
|
+
module Civic
|
5
|
+
module Elections
|
6
|
+
|
7
|
+
class InvalidZipcode < Exception; end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def for_zipcode(zipcode, client)
|
12
|
+
raise InvalidZipcode if not zipcode?(zipcode)
|
13
|
+
elections_from_response collection(zipcode, client)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def elections_from_response(response)
|
19
|
+
response.body.fetch("elections").map do |election|
|
20
|
+
Election.new(election)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def collection(zipcode, client)
|
25
|
+
client.request(:elections, zipcode: zipcode)
|
26
|
+
end
|
27
|
+
|
28
|
+
def zipcode?(zipcode)
|
29
|
+
zipcode =~ /\A\d{5}(?:[-\s]\d{4})?\z/
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Google
|
2
|
+
module Civic
|
3
|
+
class Requester
|
4
|
+
include Router
|
5
|
+
|
6
|
+
def initialize(connection, request_params={})
|
7
|
+
@connection = connection
|
8
|
+
@connection.base_url = BASE_URL
|
9
|
+
@request_params = request_params
|
10
|
+
end
|
11
|
+
|
12
|
+
def request(kind, params={})
|
13
|
+
@connection.send method_for(kind) do |request|
|
14
|
+
request.url path_for(kind), @request_params.merge(params)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Google
|
2
|
+
module Civic
|
3
|
+
module Router
|
4
|
+
|
5
|
+
BASE_URL = "https://www.googleapis.com"
|
6
|
+
BASE_PATH = "/civicinfo/v1"
|
7
|
+
ROUTES = {
|
8
|
+
elections: {
|
9
|
+
method: :get,
|
10
|
+
path: "/elections",
|
11
|
+
klass: Election
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def route_map_for(kind)
|
18
|
+
ROUTES.fetch(kind)
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_for(kind)
|
22
|
+
route_map_for(kind).fetch(:method)
|
23
|
+
end
|
24
|
+
|
25
|
+
def path_for(kind)
|
26
|
+
[BASE_PATH, route_map_for(kind).fetch(:path)].join('')
|
27
|
+
end
|
28
|
+
|
29
|
+
def klass_for(kind)
|
30
|
+
route_map_for(kind).fetch(:klass)
|
31
|
+
end
|
32
|
+
alias :class_for :klass_for
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Google
|
4
|
+
module Civic
|
5
|
+
describe Client do
|
6
|
+
include_context "a connection to the client"
|
7
|
+
|
8
|
+
describe "#request" do
|
9
|
+
subject { client.request(request_type, request_params) }
|
10
|
+
let(:zipcode) { "12345" }
|
11
|
+
let(:request_type) { :elections }
|
12
|
+
let(:request_params) { Hash[ zipcode: zipcode ] }
|
13
|
+
|
14
|
+
it { expect(subject).to be_a_kind_of Faraday::Response }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "multi_json"
|
3
|
+
|
4
|
+
module Google::Civic
|
5
|
+
describe Election do
|
6
|
+
subject { Election.new(response) }
|
7
|
+
let(:response) { MultiJson.load(load_fixture("elections"))["elections"][0] }
|
8
|
+
|
9
|
+
its(:id) { should_not be_nil }
|
10
|
+
its(:name) { should_not be_nil }
|
11
|
+
its(:electionDay) { should_not be_nil }
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Google
|
4
|
+
module Civic
|
5
|
+
describe Elections do
|
6
|
+
include_context "a connection to the client"
|
7
|
+
|
8
|
+
describe ".for_zipcode" do
|
9
|
+
subject { Elections.for_zipcode(zipcode, client) }
|
10
|
+
|
11
|
+
context "with an invalid zipcode" do
|
12
|
+
let(:zipcode) { "1234567890" }
|
13
|
+
it { expect { subject }.to raise_error(Elections::InvalidZipcode) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "with a valid 9 digit zipcode" do
|
17
|
+
let(:zipcode) { "12345-1234" }
|
18
|
+
it { expect { subject }.not_to raise_error }
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with a valid 5 digit zipcode" do
|
22
|
+
let(:zipcode) { "12345" }
|
23
|
+
it { expect(subject).to have(3).record }
|
24
|
+
it { expect(subject.first).to be_a_kind_of Election }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec'
|
3
|
+
require 'rspec/autorun'
|
4
|
+
require 'pry'
|
5
|
+
require 'webmock/rspec'
|
6
|
+
|
7
|
+
PROJECT_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')).freeze
|
8
|
+
$LOAD_PATH << File.join(PROJECT_ROOT, 'lib')
|
9
|
+
Dir[File.join(PROJECT_ROOT, 'spec/support/**/*.rb')].each { |file| require(file) }
|
10
|
+
|
11
|
+
WebMock.disable_net_connect!(allow_localhost: true)
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include Fixtures
|
15
|
+
config.include Requests
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'google-civic'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"kind": "civicinfo#electionsqueryresponse",
|
3
|
+
"elections": [
|
4
|
+
{
|
5
|
+
"id": "2000",
|
6
|
+
"name": "VIP Test Election",
|
7
|
+
"electionDay": "2013-06-06"
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"id": "2124",
|
11
|
+
"name": "Rhode Island 2012 Primary Election",
|
12
|
+
"electionDay": "2012-09-11"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"id": "2126",
|
16
|
+
"name": "Delaware 2012 Primary Election",
|
17
|
+
"electionDay": "2012-09-11"
|
18
|
+
}
|
19
|
+
]
|
20
|
+
}
|