DCGOV 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ == DC311
2
+
3
+ Copyright (c) 2009 Zvi Band and skeevisArts LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,29 @@
1
+ = DC Government GeoCoder and 311 API
2
+
3
+ ... a ruby gem for the not-yet-complete API published by the DC OCTO
4
+
5
+ == Install
6
+
7
+ sudo gem install dcgov
8
+
9
+ == Example
10
+
11
+ Here's a quick example of how you could use it.
12
+
13
+ require 'rubygems'
14
+ require 'dcgov'
15
+ results = DCGOV::GeoCoder.get({:address=>"441 4th str, nw"})
16
+ print results.inspect
17
+
18
+ == Usage
19
+
20
+ Honestly, I haven't had a chance yet. But I will say this. If you go into the spec directory you'll find tests for the geocoder and open_311 APIs.
21
+ The rspec tests
22
+
23
+ If you feel like helping out, expand this readme for me :-)
24
+
25
+ Zvi Band, 2009
26
+ zvi@skeevisarts.com
27
+ http://skeevisarts.com
28
+
29
+ @skeevis on the twitter.
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ #
2
+ # To change this template, choose Tools | Templates
3
+ # and open the template in the editor.
4
+
5
+
6
+ require 'rubygems'
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/gempackagetask'
10
+ require 'rake/rdoctask'
11
+ require 'rake/testtask'
12
+ require 'spec/rake/spectask'
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = 'DCGOV'
16
+ s.version = '0.0.1'
17
+ s.has_rdoc = true
18
+ s.extra_rdoc_files = ['README', 'LICENSE']
19
+ s.summary = 'A basic interface to the citywide API published by the District of Columbia'
20
+ s.description = s.summary
21
+ s.author = 'Zvi Band'
22
+ s.email = 'zvi@skeevisarts.com'
23
+ s.homepage = 'http://skeevisarts.com'
24
+ # s.executables = ['your_executable_here']
25
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec}/**/*")
26
+ s.require_path = "lib"
27
+ s.bindir = "bin"
28
+ s.add_dependency("json")
29
+ end
30
+
31
+ Rake::GemPackageTask.new(spec) do |p|
32
+ p.gem_spec = spec
33
+ p.need_tar = true
34
+ p.need_zip = true
35
+ end
36
+
37
+ Rake::RDocTask.new do |rdoc|
38
+ files =['README', 'LICENSE', 'lib/**/*.rb']
39
+ rdoc.rdoc_files.add(files)
40
+ rdoc.main = "README" # page to start on
41
+ rdoc.title = "DCGOV Docs"
42
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
43
+ rdoc.options << '--line-numbers'
44
+ end
45
+
46
+ Rake::TestTask.new do |t|
47
+ t.test_files = FileList['test/**/*.rb']
48
+ end
49
+
50
+ Spec::Rake::SpecTask.new do |t|
51
+ t.spec_files = FileList['spec/**/*.rb']
52
+ end
data/lib/dcgov.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'uri'
2
+ require 'cgi'
3
+ require 'net/http'
4
+ require 'rubygems'
5
+ require 'json'
6
+
7
+ $:.unshift(File.dirname(__FILE__))
8
+ require 'dcgov/easy_class_maker'
9
+ require 'dcgov/geocoder'
10
+ require 'dcgov/open311'
11
+ require 'dcgov/service_request_field'
12
+ require 'dcgov/service_type'
13
+ require 'dcgov/address'
14
+ require 'dcgov/util'
15
+
16
+ module DCGOV
17
+ #Not too much in here...
18
+
19
+ end
@@ -0,0 +1,48 @@
1
+ module DCGOV
2
+ class Address
3
+ include EasyClassMaker
4
+
5
+ # just a sample of what dc returns, for reference purposes.
6
+ # [{"aid"=>"285552"}, {"status"=>"ACTIVE"}, {"fulladdress"=>"441 4TH STREET NW"}, {"addrnum"=>"441"}, {"stname"=>"4TH"}, {"street_type"=>"STREET"},
7
+ # {"quadrant"=>"NW"}, {"city"=>"WASHINGTON"}, {"state"=>"DC"}, {"xcoord"=>"398642.18"}, {"ycoord"=>"136399.84"},
8
+ # {"ssl"=>"0532 0020"}, {"anc"=>"ANC 6C"}, {"psa"=>"Police Service Area 101"}, {"ward"=>"Ward 6"}, {"nbhd_action"=>" "},
9
+ # {"cluster"=>"Cluster 8"}, {"poldist"=>"Police District - First District"}, {"roc"=>"-"}, {"census_tract"=>"59"},
10
+ # {"vote_prcnct"=>"Precinct 143"}, {"smd"=>"SMD02 6C09"}, {"zipcode"=>"20001"}, {"latitude"=>"38.89544591"},
11
+ # {"longitude"=>"-77.01565221"}, {"distance"=>"0"}]
12
+
13
+ attributes :aid,:status,:fulladdress,:addrnum,:stname,:street_type,:quadrant,:city,:state,:xoord,:ycoord,:ssl,:anc,:psa,:ward,:nbhd,:clust,:poldist,:roc,:census_tract,
14
+ :vote_prcnct,:smd,:zipcode,:latitude,:longitude,:distance
15
+
16
+ # Creates a new user from a piece of xml
17
+ def self.new_from_hash(hsh)
18
+ u = new
19
+ u.aid = hsh['aid']
20
+ u.status = hsh['status']
21
+ u.fulladdress = hsh['fulladdress']
22
+ u.addrnum = hsh['addrnum']
23
+ u.stname = hsh['stname']
24
+ u.street_type = hsh['street_type']
25
+ u.quadrant = hsh['quadrant']
26
+ u.city = hsh['city']
27
+ u.state = hsh['state']
28
+ u.xoord = hsh['xoord']
29
+ u.ycoord = hsh['ycoord']
30
+ u.ssl = hsh['ssl']
31
+ u.anc = hsh['anc']
32
+ u.psa = hsh['psa']
33
+ u.ward = hsh['ward']
34
+ u.nbhd = hsh['nbhd']
35
+ u.clust = hsh['clust']
36
+ u.poldist = hsh['poldist']
37
+ u.roc = hsh['roc']
38
+ u.census_tract = hsh['census_tract']
39
+ u.vote_prcnct = hsh['vote_prcnct']
40
+ u.smd = hsh['smd']
41
+ u.zipcode = hsh['zipcode']
42
+ u.latitude = hsh['latitude']
43
+ u.longitude = hsh['longitude']
44
+ u.distance = hsh['distance']
45
+ u
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,45 @@
1
+ # This is pretty much just a macro for creating a class that allows
2
+ # using a block to initialize stuff and to define getters and setters
3
+ # really quickly.
4
+ #
5
+ # I stole this from the Twitter gem. Who knows who they stole it from.
6
+ module DCGOV
7
+ module EasyClassMaker
8
+
9
+ def self.included(base)
10
+ base.extend(ClassMethods)
11
+ end
12
+
13
+ module ClassMethods
14
+ # creates the attributes class variable and creates each attribute's accessor methods
15
+ def attributes(*attrs)
16
+ @@attributes = attrs
17
+ @@attributes.each { |a| attr_accessor a }
18
+ end
19
+
20
+ # read method for attributes class variable
21
+ def self.attributes; @@attributes end
22
+ end
23
+
24
+ # allows for any class that includes this to use a block to initialize
25
+ # variables instead of assigning each one seperately
26
+ #
27
+ # Example:
28
+ #
29
+ # instead of...
30
+ #
31
+ # s = Status.new
32
+ # s.foo = 'thing'
33
+ # s.bar = 'another thing'
34
+ #
35
+ # you can ...
36
+ #
37
+ # Status.new do |s|
38
+ # s.foo = 'thing'
39
+ # s.bar = 'another thing'
40
+ # end
41
+ def initialize
42
+ yield self if block_given?
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,60 @@
1
+ module DCGOV
2
+ class GeoCoder
3
+ #master dispatcher
4
+ def self.get(options)
5
+ if options[:address]
6
+ find_by_address(options[:address])
7
+ elsif options[:lat] && options[:lon]
8
+ find_by_lat_lon(options[:lat],options[:lon])
9
+ elsif options[:mar_id]
10
+ find_by_id(options[:mar_id])
11
+ else
12
+ nil #dumbass.
13
+ end
14
+ end
15
+
16
+
17
+ #do a search via latitude and longitude.
18
+ def self.find_by_lat_lon(lat,lon)
19
+ begin
20
+ request_url = "/geocoding/v1/getFromLatLong.json?lat=#{CGI::escape(lat)}&long=#{CGI::escape(lon)}"
21
+ result_json = DCGOV::Util.pull_from_json(request_url)
22
+ return result_json["addresses"].collect { |address| DCGOV::Address.new_from_hash(address["address"][0]) }
23
+ rescue
24
+ #crap, something went wrong
25
+ return nil
26
+ end
27
+ end
28
+
29
+
30
+ #find via a normal street address... "1600 pennsylvania"
31
+ def self.find_by_address(address)
32
+ begin
33
+ request_url = "/geocoding/v1/search.json?address=#{CGI::escape(address)}"
34
+ result_json = DCGOV::Util.pull_from_json(request_url)
35
+ return result_json["addresses"].collect { |address| DCGOV::Address.new_from_hash(address["address"][0]) }
36
+ rescue
37
+ #crap, something went wrong
38
+ return nil
39
+ end
40
+ end
41
+
42
+ #find by a mar ID
43
+ def self.find_by_id(mar_id)
44
+ begin
45
+ request_url = "/geocoding/v1/get.json?aid=#{mar_id}"
46
+ result_json = DCGOV::Util.pull_from_json(request_url)
47
+ return DCGOV::Address.new_from_hash(result_json["address"][0])
48
+ rescue
49
+ #crap, something went wrong
50
+ return nil
51
+ end
52
+ end
53
+
54
+ # just so I could make sure rspec was working.
55
+ def self.foo
56
+ "bar"
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,36 @@
1
+ module DCGOV
2
+ class Open311
3
+ def self.get_service_types()
4
+ request_url = "/open311/v1/meta_getTypesList.json"
5
+ result_json = DCGOV::Util.pull_from_json(request_url)
6
+ return result_json["servicetypeslist"].collect { |st| DCGOV::ServiceType.new_from_hash(st["servicetype"]) }
7
+ end
8
+
9
+ def self.get_request_fields(sr_id)
10
+ request_url = "/open311/v1/meta_getTypeDefinition.json?servicecode=#{CGI::escape(sr_id)}"
11
+ result_json = DCGOV::Util.pull_from_json(request_url)
12
+ #print result_json.inspect
13
+ return result_json["servicetypedefinition"].collect { |st| DCGOV::ServiceRequestField.new_from_hash(st["servicetype"]) }
14
+ end
15
+
16
+ def self.get(request_id)
17
+ request_url = "/open311/v1/get.json?servicerequestid=#{CGI::escape(request_id)}"
18
+ result_json = DCGOV::Util.pull_from_json(request_url)
19
+ results_fixed = DCGOV::Util::fix_hash(result_json["servicerequest"])
20
+ return results_fixed
21
+ end
22
+
23
+ def self.resolve_token(token_id)
24
+ request_url = "/open311/v1/getFromToken.json?token=#{token_id}"
25
+ result_json = DCGOV::Util.pull_from_json(request_url)
26
+ result_json["servicerequestid"]
27
+ end
28
+
29
+ def self.submit(values)
30
+ request_url = "/open311/v1/submit.json"
31
+ result_json = DCGOV::Util.post_to_json(values,request_url)
32
+ result_json["token"]
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ module DCGOV
2
+ class ServiceRequest
3
+
4
+ include EasyClassMaker
5
+
6
+ attributes :anc,:lattitude,:serviceorderdate,:resolution,:servicerequestid,:siteaddress,:serviceorderstatus,:district,:zipcode,:servicenotes,:servicetypecodedescription,:servicecodedescription,:servicecode,:neighborhoodcluster,:servicepriority,:aid,:serviceduedate,:resolutiondate,:psa,:longitude,:smd,:ward,:agencyabbreviation,:servicetypeocde
7
+
8
+ # Creates a new user from a piece of xml
9
+ def self.new_from_hash(hsh)
10
+ u = new
11
+ u.anc = hsh['anc']
12
+ u.lattitude = hsh['lattitude']
13
+ u.serviceorderdate = hsh['serviceorderdate']
14
+ u.resolution = hsh['resolution']
15
+ u.servicerequestid = hsh['servicerequestid']
16
+ u.siteaddress = hsh['siteaddress']
17
+ u.serviceorderstatus = hsh['serviceorderstatus']
18
+ u.district = hsh['district']
19
+ u.zipcode = hsh['zipcode']
20
+ u.servicenotes = hsh['servicenotes']
21
+ u.servicetypecodedescription = hsh['servicetypecodedescription']
22
+ u.servicecodedescription = hsh['servicecodedescription']
23
+ u.servicecode = hsh['servicecode']
24
+ u.neighborhoodcluster = hsh['neighborhoodcluster']
25
+ u.servicepriority = hsh['servicepriority']
26
+ u.aid = hsh['aid']
27
+ u.serviceduedate = hsh['serviceduedate']
28
+ u.resolutiondate = hsh['resolutiondate']
29
+ u.psa = hsh['psa']
30
+ u.longitude = hsh['longitude']
31
+ u.smd = hsh['smd']
32
+ u.ward = hsh['ward']
33
+ u.agencyabbreviation = hsh['agencyabbreviation']
34
+ u.servicetypeocde = hsh['servicetypeocde']
35
+
36
+
37
+ u
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ module DCGOV
2
+ class ServiceRequestField
3
+ include EasyClassMaker
4
+ #{"servicetype"=>[{"servicetype"=>"Abandoned Bicycles"}, {"servicecode"=>"S0021"},
5
+ #{"name"=>"ABDBIC-HOWLONG"}, {"prompt"=>"How long has the bicycle been abandoned?"},
6
+ # {"required"=>"Y"}, {"type"=>"TextBox "}, {"width"=>"200"}, {"itemlist"=>"\r"}]}
7
+
8
+ attributes :service_type,:service_code,:field_name,:field_label,:field_required,:field_type,:field_width,:item_list
9
+
10
+ # Creates a new user from a piece of xml
11
+ def self.new_from_hash(hsh)
12
+ u = new
13
+ u.service_type = hsh[0]['servicetype']
14
+ u.service_code = hsh[1]['servicecode']
15
+ u.field_name = hsh[2]['name']
16
+ u.field_label = hsh[3]['prompt']
17
+ u.field_required = hsh[4]['required']
18
+ u.field_type = hsh[5]['type']
19
+ u.field_width = hsh[6]['width']
20
+ u.item_list = hsh[7]['itemlist']
21
+ u
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,16 @@
1
+ module DCGOV
2
+ class ServiceType
3
+ include EasyClassMaker
4
+ attributes :service_type,:service_code
5
+
6
+ # Creates a new user from a piece of xml
7
+ def self.new_from_hash(hsh)
8
+ hash_to_proc = hsh.to_a
9
+ u = new
10
+ u.service_type = hash_to_proc[0]['servicetype']
11
+ u.service_code = hash_to_proc[1]['servicecode']
12
+ u
13
+ end
14
+
15
+ end
16
+ end
data/lib/dcgov/util.rb ADDED
@@ -0,0 +1,42 @@
1
+ module DCGOV
2
+ class Util
3
+
4
+ # just about all there is.
5
+ def self.pull_from_json(params)
6
+
7
+ #why am I wrapping the entire deal in a rescue block? Well, the API has no error handling at all
8
+ # so if you enter in something bad, it just craps on you.
9
+ begin
10
+ @resp
11
+ Net::HTTP.start('api.dc.gov') {|http|
12
+ req = Net::HTTP::Get.new(params)
13
+ response = http.request(req)
14
+ @resp = response.body
15
+ }
16
+ JSON.parse @resp
17
+ rescue
18
+ #so the caller can catch a "better" error than some JSON parsing or HTTP bs.
19
+ raise "An error occurred while attempting to grab and parse the results"
20
+ end
21
+ end
22
+
23
+ def self.post_to_json(params,url)
24
+ @resp
25
+ Net::HTTP.start('api.dc.gov') {|http|
26
+ req = Net::HTTP::Post.new(url)
27
+ req.set_form_data(params)
28
+ response = http.request(req)
29
+ @resp = response.body
30
+ }
31
+ JSON.parse @resp
32
+ end
33
+
34
+ def self.fix_hash(hsh)
35
+ results = Hash.new
36
+ hsh.each { |i|
37
+ results.merge!(i)
38
+ }
39
+ return results
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe "DCGOV::GeoCoder" do
4
+
5
+ it "should be able to look up an address that exists" do
6
+ results = DCGOV::GeoCoder.get({:address=>"441 4th str, nw"})
7
+ results.length.should == 1
8
+ end
9
+
10
+ it "should be able to look up an address that doesn't exist" do
11
+ results = DCGOV::GeoCoder.get({:address=>"1dsggdsdgssdgdsgdsgdsgdgsW"})
12
+ results.length.should == 0
13
+ end
14
+
15
+ it "should be able to look up an address that has multiple results" do
16
+ results = DCGOV::GeoCoder.get({:address=>"441 4th str"})
17
+ results.length.should == 2
18
+ end
19
+
20
+ it "should be able to look up a latitude and a longitude" do
21
+ results = DCGOV::GeoCoder.get({:lat=>"38.89544591",:lon=>"-77.01565221"})
22
+ results[0].aid.should=="285552"
23
+ results.length.should > 0
24
+ end
25
+
26
+ it "should be able to look up via a mar ID" do
27
+ aid = 285552
28
+ result = DCGOV::GeoCoder.get({:mar_id=>aid})
29
+ result.aid.to_i.should == aid
30
+ end
31
+
32
+ it "should return nil when a nonsensical mar is thrown" do
33
+ results = DCGOV::GeoCoder.get({:mar_id=>'adslkfhjdgsalkjgdlksdgjlgkds'})
34
+ results.should == nil
35
+ end
36
+
37
+ #stupid test. for fun.
38
+ it "should work" do
39
+ DCGOV::GeoCoder.foo.should == "bar"
40
+ end
41
+
42
+ end
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe "DCGOV::Open311" do
4
+
5
+ it "should return a list of service types" do
6
+ service_types = DCGOV::Open311.get_service_types()
7
+ service_types.length.should > 0
8
+ service_types[0].class.to_s.should == "DCGOV::ServiceType"
9
+ service_types[0].service_type.should =="Abandoned Bicycles"
10
+ service_types[0].service_code.should =="S0021"
11
+ end
12
+
13
+ it "should return a list of fields for a service type" do
14
+ service_code="S0021"
15
+ request_fields = DCGOV::Open311.get_request_fields(service_code)
16
+ request_fields.length.should > 0
17
+ request_fields[0].service_type.should == "Abandoned Bicycles"
18
+ request_fields[0].field_name.should == "ABDBIC-HOWLONG"
19
+ request_fields[0].field_label.should == "How long has the bicycle been abandoned?"
20
+
21
+ end
22
+
23
+ it "should return a request based on a service ID" do
24
+ request_id="123456"
25
+ request = DCGOV::Open311.get(request_id)
26
+ request.class.to_s.should == "Hash"
27
+ end
28
+
29
+ it "should convert a token into a service request id" do
30
+ token_id = "123456"
31
+ service_request_id = DCGOV::Open311.resolve_token(token_id)
32
+ service_request_id.should_not == nil
33
+ end
34
+
35
+ it "should post a service request" do
36
+ values = Hash.new
37
+ token_id = DCGOV::Open311.submit(values)
38
+ token_id.should_not == nil
39
+ end
40
+
41
+ end
@@ -0,0 +1,23 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ dir = File.dirname(__FILE__)
10
+
11
+ $:.unshift(File.join(dir, '/../lib/'))
12
+ require dir + '/../lib/dcgov'
13
+
14
+
15
+ def stdout_for(&block)
16
+ # Inspired by http://www.ruby-forum.com/topic/58647
17
+ old_stdout = $stdout
18
+ $stdout = StringIO.new
19
+ yield
20
+ output = $stdout.string
21
+ $stdout = old_stdout
22
+ output
23
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: DCGOV
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Zvi Band
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-06 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: A basic interface to the citywide API published by the District of Columbia
26
+ email: zvi@skeevisarts.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - LICENSE
34
+ files:
35
+ - LICENSE
36
+ - README
37
+ - Rakefile
38
+ - lib/dcgov
39
+ - lib/dcgov/address.rb
40
+ - lib/dcgov/easy_class_maker.rb
41
+ - lib/dcgov/geocoder.rb
42
+ - lib/dcgov/open311.rb
43
+ - lib/dcgov/service_request.rb
44
+ - lib/dcgov/service_request_field.rb
45
+ - lib/dcgov/service_type.rb
46
+ - lib/dcgov/util.rb
47
+ - lib/dcgov.rb
48
+ - spec/geocoder_spec.rb
49
+ - spec/open_311_spec.rb
50
+ - spec/spec_helper.rb
51
+ has_rdoc: true
52
+ homepage: http://skeevisarts.com
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.1
74
+ signing_key:
75
+ specification_version: 2
76
+ summary: A basic interface to the citywide API published by the District of Columbia
77
+ test_files: []
78
+