open311 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .DS_Store
3
+ .bundle
4
+ .yardoc
5
+ coverage/*
6
+ doc/*
7
+ log/*
8
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=nested
3
+ --backtrace
@@ -0,0 +1,7 @@
1
+ --no-private
2
+ --protected
3
+ --tag format:"Supported formats"
4
+ --tag key:"Requires API key"
5
+ --markup markdown
6
+ -
7
+ LICENSE.mkd
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify the gem's dependencies in open311.gemspec
4
+ gemspec
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ open311 (0.0.0)
5
+ faraday (~> 0.5.2)
6
+ faraday_middleware (~> 0.2.3)
7
+ hashie (~> 0.4.0)
8
+ multi_json (~> 0.0.5)
9
+ multi_xml (~> 0.2.0)
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ ZenTest (4.4.0)
15
+ addressable (2.2.2)
16
+ crack (0.1.8)
17
+ diff-lcs (1.1.2)
18
+ faraday (0.5.2)
19
+ addressable (~> 2.2.2)
20
+ multipart-post (~> 1.0.1)
21
+ rack (>= 1.1.0, < 2)
22
+ faraday_middleware (0.2.3)
23
+ faraday (~> 0.5.2)
24
+ hashie (0.4.0)
25
+ libxml-ruby (1.1.4)
26
+ multi_json (0.0.5)
27
+ multi_xml (0.2.0)
28
+ multipart-post (1.0.1)
29
+ rack (1.2.1)
30
+ rake (0.8.7)
31
+ rcov (0.9.9)
32
+ rspec (2.0.1)
33
+ rspec-core (~> 2.0.1)
34
+ rspec-expectations (~> 2.0.1)
35
+ rspec-mocks (~> 2.0.1)
36
+ rspec-core (2.0.1)
37
+ rspec-expectations (2.0.1)
38
+ diff-lcs (>= 1.1.2)
39
+ rspec-mocks (2.0.1)
40
+ rspec-core (~> 2.0.1)
41
+ rspec-expectations (~> 2.0.1)
42
+ webmock (1.5.0)
43
+ addressable (>= 2.2.2)
44
+ crack (>= 0.1.7)
45
+ yajl-ruby (0.7.8)
46
+ yard (0.6.1)
47
+
48
+ PLATFORMS
49
+ ruby
50
+
51
+ DEPENDENCIES
52
+ ZenTest (~> 4.4)
53
+ bundler (~> 1.0)
54
+ faraday (~> 0.5.2)
55
+ faraday_middleware (~> 0.2.3)
56
+ hashie (~> 0.4.0)
57
+ libxml-ruby (~> 1.1)
58
+ multi_json (~> 0.0.5)
59
+ multi_xml (~> 0.2.0)
60
+ open311!
61
+ rake (~> 0.8)
62
+ rcov (~> 0.9)
63
+ rspec (~> 2.0.1)
64
+ webmock (~> 1.5)
65
+ yajl-ruby (~> 0.7)
66
+ yard (~> 0.6)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Code for America Laboratories
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.
@@ -0,0 +1,71 @@
1
+ Open311
2
+ =======
3
+ A Ruby wrapper for the Open311 API v2.
4
+
5
+ Does your project or company use this gem?
6
+ ------------------------------------------
7
+ Add it to the [apps](http://github.com/cfalabs/open311/wiki/apps) wiki!
8
+
9
+ Installation
10
+ ------------
11
+ $ [sudo] gem install open311
12
+
13
+ Documentation
14
+ -------------
15
+ <http://rdoc.info/gems/open311>
16
+
17
+ Usage Examples
18
+ --------------
19
+ require 'open311'
20
+
21
+ # Certain methods require an API key
22
+ Open311.configure do |config|
23
+ config.api_key = YOUR_API_KEY
24
+ config.endpoint = 'https://open311.sfgov.org/'
25
+ config.jurisdiction = 'sfgov.org'
26
+ end
27
+
28
+ # Provide a list of acceptable 311 service request types and their associated service codes
29
+ Open311.service_list
30
+
31
+ Contributing
32
+ ------------
33
+ In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.
34
+
35
+ Here are some ways *you* can contribute:
36
+
37
+ * by using alpha, beta, and prerelease versions
38
+ * by reporting bugs
39
+ * by suggesting new features
40
+ * by writing or editing documentation
41
+ * by writing specifications
42
+ * by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
43
+ * by refactoring code
44
+ * by resolving [issues](http://github.com/cfalabs/open311/issues)
45
+ * by reviewing patches
46
+
47
+ Submitting an Issue
48
+ -------------------
49
+ We use the [GitHub issue tracker](http://github.com/cfalabs/open311/issues) to track bugs and
50
+ features. Before submitting a bug report or feature request, check to make sure it hasn't already
51
+ been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
52
+ bug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any
53
+ details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
54
+ operating system. Ideally, a bug report should include a pull request with failing specs.
55
+
56
+ Submitting a Pull Request
57
+ -------------------------
58
+ 1. Fork the project.
59
+ 2. Create a topic branch.
60
+ 3. Implement your feature or bug fix.
61
+ 4. Add documentation for your feature or bug fix.
62
+ 5. Run <tt>bundle exec rake doc:yard</tt>. If your changes are not 100% documented, go back to step 4.
63
+ 6. Add specs for your feature or bug fix.
64
+ 7. Run <tt>bundle exec rake spec:rcov</tt>. If your changes are not 100% covered, go back to step 6.
65
+ 8. Commit and push your changes.
66
+ 9. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)
67
+
68
+ Copyright
69
+ ---------
70
+ Copyright (c) 2010 Code for America Laboratories
71
+ See [LICENSE](https://github.com/cfalabs/open311/blob/master/LICENSE.mkd) for details.
@@ -0,0 +1,34 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ namespace :spec do
8
+ desc "Run all examples using rcov"
9
+ RSpec::Core::RakeTask.new(:rcov => :cleanup_rcov_files) do |task|
10
+ task.rcov = true
11
+ task.rcov_opts = %[-Ilib -Ispec --exclude "gems/*,features,specs" --text-report --sort coverage]
12
+ end
13
+ end
14
+
15
+ task :cleanup_rcov_files do
16
+ rm_rf 'coverage'
17
+ end
18
+
19
+ task :default => ["spec:rcov"]
20
+
21
+ namespace :doc do
22
+ require 'yard'
23
+ YARD::Rake::YardocTask.new do |task|
24
+ task.files = ['LICENSE.mkd', 'lib/**/*.rb']
25
+ task.options = [
26
+ '--no-private',
27
+ '--protected',
28
+ '--output-dir', 'doc/yard',
29
+ '--tag', 'format:Supported formats',
30
+ '--tag', 'key:Requires API key',
31
+ '--markup', 'markdown',
32
+ ]
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,29 @@
1
+ require 'faraday'
2
+
3
+ # @api private
4
+ module Faraday
5
+ class Request::Multipart < Faraday::Middleware
6
+ def call(env)
7
+ if env[:body].is_a?(Hash)
8
+ env[:body].each do |key, value|
9
+ if value.is_a?(File)
10
+ env[:body][key] = Faraday::UploadIO.new(value, mime_type(value), value.path)
11
+ end
12
+ end
13
+ end
14
+
15
+ @app.call(env)
16
+ end
17
+
18
+ private
19
+
20
+ def mime_type(file)
21
+ case file.path
22
+ when /\.jpe?g/i then 'image/jpeg'
23
+ when /\.gif$/i then 'image/gif'
24
+ when /\.png$/i then 'image/png'
25
+ else 'application/octet-stream'
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ require 'faraday'
2
+
3
+ # @api private
4
+ module Faraday
5
+ class Response::RaiseError < Response::Middleware
6
+ def self.register_on_complete(env)
7
+ env[:response].on_complete do |response|
8
+ case response[:status].to_i
9
+ when 400
10
+ raise Open311::BadRequest, error_message(response)
11
+ when 401
12
+ raise Open311::Unauthorized, error_message(response)
13
+ when 403
14
+ raise Open311::Forbidden, error_message(response)
15
+ when 404
16
+ raise Open311::NotFound, error_message(response)
17
+ when 406
18
+ raise Open311::NotAcceptable, error_message(response)
19
+ when 500
20
+ raise Open311::InternalServerError, error_message(response)
21
+ when 502
22
+ raise Open311::BadGateway, error_message(response)
23
+ when 503
24
+ raise Open311::ServiceUnavailable, error_message(response)
25
+ end
26
+ end
27
+ end
28
+
29
+ def initialize(app)
30
+ super
31
+ @parser = nil
32
+ end
33
+
34
+ private
35
+
36
+ def self.error_message(response)
37
+ "#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:response_headers]['status']}#{(': ' + response[:body]['error']) if response[:body] && response[:body]['error']}"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path('../open311/configuration', __FILE__)
2
+ require File.expand_path('../open311/client', __FILE__)
3
+
4
+ module Open311
5
+ extend Configuration
6
+
7
+ # Alias for Open311::Client.new
8
+ #
9
+ # @return [Open311::Client]
10
+ def self.client(options={})
11
+ Open311::Client.new(options)
12
+ end
13
+
14
+ # Delegate to Open311::Client
15
+ def self.method_missing(method, *args, &block)
16
+ return super unless client.respond_to?(method)
17
+ client.send(method, *args, &block)
18
+ end
19
+
20
+ # Custom error class for rescuing from all Open311 errors
21
+ class Error < StandardError; end
22
+
23
+ # Raised when Open311 returns a 400 HTTP status code
24
+ class BadRequest < Error; end
25
+
26
+ # Raised when Open311 returns a 401 HTTP status code
27
+ class Unauthorized < Error; end
28
+
29
+ # Raised when Open311 returns a 403 HTTP status code
30
+ class Forbidden < Error; end
31
+
32
+ # Raised when Open311 returns a 404 HTTP status code
33
+ class NotFound < Error; end
34
+
35
+ # Raised when Open311 returns a 406 HTTP status code
36
+ class NotAcceptable < Error; end
37
+
38
+ # Raised when Open311 returns a 500 HTTP status code
39
+ class InternalServerError < Error; end
40
+
41
+ # Raised when Open311 returns a 502 HTTP status code
42
+ class BadGateway < Error; end
43
+
44
+ # Raised when Open311 returns a 503 HTTP status code
45
+ class ServiceUnavailable < Error; end
46
+ end
@@ -0,0 +1,19 @@
1
+ Dir[File.expand_path('../client/*.rb', __FILE__)].each{|file| require file}
2
+
3
+ module Open311
4
+ class Client
5
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
6
+
7
+ def initialize(options={})
8
+ options = Open311.options.merge(options)
9
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
10
+ send("#{key}=", options[key])
11
+ end
12
+ end
13
+
14
+ include Open311::Client::Connection
15
+ include Open311::Client::Request
16
+
17
+ include Open311::Client::Service
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ require 'faraday_middleware'
2
+ Dir[File.expand_path('../../../faraday/*.rb', __FILE__)].each{|file| require file}
3
+
4
+ module Open311
5
+ class Client
6
+ # @private
7
+ module Connection
8
+ private
9
+
10
+ def connection(raw=false)
11
+ options = {
12
+ # :headers => {'Accept' => "*/#{format}", 'User-Agent' => user_agent},
13
+ :proxy => proxy,
14
+ :ssl => {:verify => false},
15
+ :url => endpoint
16
+ }
17
+
18
+ Faraday::Connection.new(options) do |builder|
19
+ builder.use Faraday::Request::Multipart
20
+ builder.adapter(adapter)
21
+ builder.use Faraday::Response::RaiseError
22
+ builder.use Faraday::Response::Parse unless raw
23
+ builder.use Faraday::Response::Mashify unless raw
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ module Open311
2
+ class Client
3
+ module Request
4
+ def get(path, options={}, raw=false)
5
+ request(:get, path, options, raw)
6
+ end
7
+
8
+ def post(path, options={}, raw=false)
9
+ request(:post, path, options, raw)
10
+ end
11
+
12
+ def put(path, options={}, raw=false)
13
+ request(:put, path, options, raw)
14
+ end
15
+
16
+ def delete(path, options={}, raw=false)
17
+ request(:delete, path, options, raw)
18
+ end
19
+
20
+ private
21
+
22
+ def request(method, path, options, raw)
23
+ response = connection(raw).send(method) do |request|
24
+ case method
25
+ when :get, :delete
26
+ request.url(formatted_path(path), options)
27
+ when :post, :put
28
+ request.path = formatted_path(path)
29
+ request.body = options
30
+ end
31
+ end
32
+ raw ? response : response.body
33
+ end
34
+
35
+ def formatted_path(path)
36
+ [path, format].compact.join('.')
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ module Open311
2
+ class Client
3
+ module Service
4
+ # Provide a list of acceptable 311 service request types and their associated service codes
5
+ #
6
+ # @todo Overload the method to allow fetching of the authenticated user's screen name from configurati
7
+ # @format :xml
8
+ # @key false
9
+ # @param options [Hash] A customizable set of options.
10
+ # @return [Array]
11
+ # @see http://wiki.open311.org/GeoReport_v2#GET_Service_List
12
+ # @example Provide a list of acceptable 311 service request types and their associated service codes
13
+ # Open311.service_list
14
+ def service_list(options={})
15
+ options.merge!(:jurisdiction_id => jurisdiction)
16
+ response = get('dev/v2/services', options)
17
+ format.to_s.downcase == 'xml' ? response['services']['service'] : response
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require 'faraday'
2
+ require File.expand_path('../version', __FILE__)
3
+
4
+ module Open311
5
+ module Configuration
6
+ VALID_OPTIONS_KEYS = [:adapter, :api_key, :endpoint, :format, :jurisdiction, :proxy, :user_agent].freeze
7
+ VALID_FORMATS = [:json, :xml].freeze
8
+
9
+ DEFAULT_ADAPTER = Faraday.default_adapter.freeze
10
+ DEFAULT_API_KEY = nil.freeze
11
+ DEFAULT_ENDPOINT = nil.freeze
12
+ DEFAULT_FORMAT = :json.freeze
13
+ DEFAULT_JURISDICTION = nil.freeze
14
+ DEFAULT_PROXY = nil.freeze
15
+ DEFAULT_USER_AGENT = "Open311 Ruby Gem #{Open311::VERSION}".freeze
16
+
17
+ attr_accessor *VALID_OPTIONS_KEYS
18
+
19
+ def self.extended(base)
20
+ base.reset
21
+ end
22
+
23
+ def configure
24
+ yield self
25
+ end
26
+
27
+ def options
28
+ VALID_OPTIONS_KEYS.inject({}){|o,k| o.merge!(k => send(k)) }
29
+ end
30
+
31
+ def reset
32
+ self.adapter = DEFAULT_ADAPTER
33
+ self.api_key = DEFAULT_API_KEY
34
+ self.endpoint = DEFAULT_ENDPOINT
35
+ self.format = DEFAULT_FORMAT
36
+ self.jurisdiction = DEFAULT_JURISDICTION
37
+ self.proxy = DEFAULT_PROXY
38
+ self.user_agent = DEFAULT_USER_AGENT
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module Open311
2
+ VERSION = "0.0.0"
3
+ end
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/open311/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.add_development_dependency("bundler", "~> 1.0")
6
+ s.add_development_dependency("libxml-ruby", "~> 1.1")
7
+ s.add_development_dependency("rake", "~> 0.8")
8
+ s.add_development_dependency("rcov", "~> 0.9")
9
+ s.add_development_dependency("rspec", "~> 2.0.1")
10
+ s.add_development_dependency("webmock", "~> 1.5")
11
+ s.add_development_dependency("yajl-ruby", "~> 0.7")
12
+ s.add_development_dependency("yard", "~> 0.6")
13
+ s.add_development_dependency("ZenTest", "~> 4.4")
14
+ s.add_runtime_dependency("hashie", "~> 0.4.0")
15
+ s.add_runtime_dependency("faraday", "~> 0.5.2")
16
+ s.add_runtime_dependency("faraday_middleware", "~> 0.2.3")
17
+ s.add_runtime_dependency("multi_json", "~> 0.0.5")
18
+ s.add_runtime_dependency("multi_xml", "~> 0.2.0")
19
+ s.authors = ["Dan Melton", "Erik Michaels-Ober"]
20
+ s.description = %q{A Ruby wrapper for the Open311 API v2.}
21
+ s.post_install_message =<<eos
22
+ Using this gem for your project or company? Add it to the apps wiki!
23
+ https://github.com/cfalabs/open311/wiki/apps
24
+ eos
25
+ s.email = ["dan@codeforamerica.org"]
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.files = `git ls-files`.split("\n")
28
+ s.homepage = "http://rubygems.org/gems/open311"
29
+ s.name = "open311"
30
+ s.platform = Gem::Platform::RUBY
31
+ s.require_paths = ["lib"]
32
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
33
+ s.summary = s.description
34
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
35
+ s.version = Open311::VERSION
36
+ end
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <services xmlns:m="http://org/sfgov/sf311v2/services" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><service><service_code>001</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Litter Receptacles</group><service_name>Cans_Left_Out_24x7</service_name><description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.
3
+ </description></service><service><service_code>002</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street Defects</group><service_name>Construction_Plate_Shifted</service_name><description>Metal construction plate covering the street or sidewalk has been moved.
4
+ </description></service><service><service_code>003</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sidewalk or Curb</group><service_name>Curb_or_Curb_Ramp_Defect</service_name><description>Sidewalk curb or ramp has problems such as cracking, missing pieces, holes, and/or chipped curb.
5
+ </description></service><service><service_code>004</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Litter Receptacles</group><service_name>Damaged_City_Can</service_name><description>Damage to a city garbage receptacle such as missing parts (lid, door, liner) or other physical damage.
6
+ </description></service><service><service_code>005</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sidewalk or Curb</group><service_name>Damaged_Side_Sewer_Vent_Cover</service_name><description>Damage to a side sewer vent cover with problems such as cracking, bending, rusting, or denting</description></service><service><service_code>006</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Tree Maintenance</group><service_name>Damaged_Tree</service_name><description>Damage to a city maintained tree. To check whether a tree is city maintained: http://bit.ly/6hsDk1</description></service><service><service_code>007</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Graffiti - Public - Bike_rack</service_name><description>Graffiti on a bike rack that does not contain racial slurs, profanity, or gang related language</description></service><service><service_code>008</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Graffiti - Public - News_rack</service_name><description>Graffiti on a news rack that does not contain racial slurs, profanity, or gang related language
7
+ </description></service><service><service_code>009</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Graffiti - Public - Parking_meter</service_name><description>Graffiti on a parking meter that does not contain racial slurs, profanity, or gang related language
8
+ </description></service><service><service_code>010</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Graffiti - Public - Pay_phone</service_name><description>Graffiti on a pay phone that does not contain racial slurs, profanity, or gang related language.
9
+ </description></service><service><service_code>011</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Graffiti - Private - Not_Offensive</service_name><description>Graffiti on a privately owned building or structure that does not contain racial slurs, profanity, or gang related language
10
+ </description></service><service><service_code>012</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Graffiti - Private - Offensive</service_name><description>Graffiti on a privately owned building or structure that contains racial slurs, profanity, or gang related language
11
+ </description></service><service><service_code>013</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Graffiti - Public - Other_enter_additional_details_below</service_name><description>Graffiti on public property (building, pole, sidewalk, hydrant, etc) with racial slurs, profanity, or gang related language
12
+ </description></service><service><service_code>015</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Illegal Dumping</group><service_name>Illegal_Dumping</service_name><description>Identify someone that has dumped or is dumping furniture or garbage onto the street or sidewalk. Violators will be cited
13
+ </description></service><service><service_code>016</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Tree Maintenance</group><service_name>Landscaping</service_name><description>Request maintenance on public property (except on park property) such as lawn mowing, bush or strip trimming and removal
14
+ </description></service><service><service_code>017</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street and Sidewalk Cleaning</group><service_name>Missed_Route_Mechanical_Sweeping</service_name><description>Street cleaning sweeper did not show up as scheduled according to the street cleaning signs
15
+ </description></service><service><service_code>018</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sidewalk or Curb</group><service_name>Missing_Side_Sewer_Vent_Cover</service_name><description>The 4" side sewer vent cover (http://bit.ly/57BlOv) is missing from the sidewalk
16
+ </description></service><service><service_code>019</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Overflowing City Receptacle or Dumpster</group><service_name>Overflowing_City_Receptacle_or_Dumpster</service_name><description>City receptacle is overflowing and/or has garbage on and around the container
17
+ </description></service><service><service_code>020</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Tree Maintenance</group><service_name>Overgrown_Tree</service_name><description>Request that a city maintained tree (except on park property) be trimmed. To check whether a tree is city maintained: http://bit.ly/6hsDk1
18
+ </description></service><service><service_code>021</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street Defects</group><service_name>Pavement_Defect</service_name><description>Defect on the street such as broken, cracked, and sinking asphalt or concrete
19
+ </description></service><service><service_code>022</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sewer Issues</group><service_name>Sewage_Back_Up Out_of_catch_basin</service_name><description>Sewage or dirty water coming out of a catchbasin (located at the corner of intersections)
20
+ </description></service><service><service_code>023</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sewer Issues</group><service_name>Side_Sewer_issues Water_coming_out</service_name><description>Sewage or odor coming out of a 4 inch side sewer (http://bit.ly/57BlOv) located on the sidewalk
21
+ </description></service><service><service_code>024</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sidewalk Cleaning</group><service_name>Sidewalk_Cleaning</service_name><description>Have garbage or human waste removed from the sidewalk and/or request services such as steam cleaning of sidewalks
22
+ </description></service><service><service_code>025</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sidewalk Defect</group><service_name>Sidewalk_Defect</service_name><description>Defect on the sidewalk such as broken, cracked, and/or sinking concrete
23
+ </description></service><service><service_code>026</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street Cleaning</group><service_name>Street_Cleaning</service_name><description>Request to have garbage or human waste removed from the street
24
+ </description></service><service><service_code>027</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Tree Maintenance</group><service_name>Damaging_Property</service_name><description>Tree is damaging property (except for parks) or housing structure. City will address problem if it is a city maintained tree otherwise the property owner is notified to correct the issue
25
+ </description></service><service><service_code>028</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Water_Main_Break</service_name><description>Street is flooding due to water coming from within the asphalt or from a catchbasin
26
+ </description></service><service><service_code>029</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Graffiti</group><service_name>Sign - Defaced</service_name><description>Graffiti on a street sign such as a stop sign, street name, and/or other parking and traffic signs
27
+ </description></service><service><service_code>030</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sewer Issues</group><service_name>Side_Sewer_issues Odor</service_name><description>Odor coming out of a 4 inch side sewer (http://bit.ly/57BlOv) located on the sidewalk.
28
+ </description></service><service><service_code>031</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sewer Issues</group><service_name>Sewage_Back_up Out_of_manhole_cover</service_name><description>Sewage or dirty water coming out of a manhole cover (typically located in the a street or alley)
29
+ </description></service><service><service_code>032</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Sewer Issues</group><service_name>Sewage_Back_up Outofsewervent4inch</service_name><description>Sewage or dirty water coming out of a sewer vent (located on the sidewalk)
30
+ </description></service><service><service_code>375</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street or Sidewalk</group><service_name>Damaged_Benches_on_Sidewalk</service_name><description>Report a damaged bench on city property.</description></service><service><service_code>376</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street or Sidewalk</group><service_name>Damaged_Bike_Rack</service_name><description>Report a damaged bike rack on city property.</description></service><service><service_code>377</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street or Sidewalk</group><service_name>Damaged_Kiosk_or_Public_Toilet</service_name><description>Report a damaged kiosk or public toilet on city property.</description></service><service><service_code>378</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street or Sidewalk</group><service_name>Damaged_News_Rack</service_name><description>Report a damaged news rack on city property.</description></service><service><service_code>379</service_code><metadata>false</metadata><type>realtime</type><keywords/><group>Street or Sidewalk</group><service_name>Damaged_Parking_Meter</service_name><description>Report a damaged parking meter on city property.</description></service></services>
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Open311, ".service_list" do
4
+ before do
5
+ Open311.configure do |config|
6
+ config.endpoint = 'https://open311.sfgov.org/'
7
+ config.format = 'xml'
8
+ config.jurisdiction = 'sfgov.org'
9
+ end
10
+ stub_request(:get, 'https://open311.sfgov.org/dev/v2/services.xml').
11
+ with(:query => {:jurisdiction_id => 'sfgov.org'}).
12
+ to_return(:body => fixture('services.xml'), :headers => {'Content-Type' => 'text/xml; charset=utf-8'})
13
+ end
14
+
15
+ it "should request the correct resource" do
16
+ Open311.service_list
17
+ a_request(:get, 'https://open311.sfgov.org/dev/v2/services.xml').
18
+ with(:query => {:jurisdiction_id => 'sfgov.org'}).
19
+ should have_been_made
20
+ end
21
+
22
+ it "should return the correct results" do
23
+ services = Open311.service_list
24
+ services.should be_an Array
25
+ services.first.service_code.should == '001'
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../../lib/open311', __FILE__)
2
+
3
+ require 'webmock/rspec'
4
+ RSpec.configure do |config|
5
+ config.include WebMock::API
6
+ end
7
+
8
+ def fixture_path
9
+ File.expand_path("../fixtures", __FILE__)
10
+ end
11
+
12
+ def fixture(file)
13
+ File.new(fixture_path + '/' + file)
14
+ end
metadata ADDED
@@ -0,0 +1,312 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: open311
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 0
10
+ version: 0.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Dan Melton
14
+ - Erik Michaels-Ober
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-11-08 00:00:00 -08:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: bundler
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 15
31
+ segments:
32
+ - 1
33
+ - 0
34
+ version: "1.0"
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: libxml-ruby
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 13
46
+ segments:
47
+ - 1
48
+ - 1
49
+ version: "1.1"
50
+ type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: rake
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 27
61
+ segments:
62
+ - 0
63
+ - 8
64
+ version: "0.8"
65
+ type: :development
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: rcov
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ hash: 25
76
+ segments:
77
+ - 0
78
+ - 9
79
+ version: "0.9"
80
+ type: :development
81
+ version_requirements: *id004
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ prerelease: false
85
+ requirement: &id005 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ hash: 13
91
+ segments:
92
+ - 2
93
+ - 0
94
+ - 1
95
+ version: 2.0.1
96
+ type: :development
97
+ version_requirements: *id005
98
+ - !ruby/object:Gem::Dependency
99
+ name: webmock
100
+ prerelease: false
101
+ requirement: &id006 !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ~>
105
+ - !ruby/object:Gem::Version
106
+ hash: 5
107
+ segments:
108
+ - 1
109
+ - 5
110
+ version: "1.5"
111
+ type: :development
112
+ version_requirements: *id006
113
+ - !ruby/object:Gem::Dependency
114
+ name: yajl-ruby
115
+ prerelease: false
116
+ requirement: &id007 !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ~>
120
+ - !ruby/object:Gem::Version
121
+ hash: 5
122
+ segments:
123
+ - 0
124
+ - 7
125
+ version: "0.7"
126
+ type: :development
127
+ version_requirements: *id007
128
+ - !ruby/object:Gem::Dependency
129
+ name: yard
130
+ prerelease: false
131
+ requirement: &id008 !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ~>
135
+ - !ruby/object:Gem::Version
136
+ hash: 7
137
+ segments:
138
+ - 0
139
+ - 6
140
+ version: "0.6"
141
+ type: :development
142
+ version_requirements: *id008
143
+ - !ruby/object:Gem::Dependency
144
+ name: ZenTest
145
+ prerelease: false
146
+ requirement: &id009 !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ~>
150
+ - !ruby/object:Gem::Version
151
+ hash: 19
152
+ segments:
153
+ - 4
154
+ - 4
155
+ version: "4.4"
156
+ type: :development
157
+ version_requirements: *id009
158
+ - !ruby/object:Gem::Dependency
159
+ name: hashie
160
+ prerelease: false
161
+ requirement: &id010 !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ~>
165
+ - !ruby/object:Gem::Version
166
+ hash: 15
167
+ segments:
168
+ - 0
169
+ - 4
170
+ - 0
171
+ version: 0.4.0
172
+ type: :runtime
173
+ version_requirements: *id010
174
+ - !ruby/object:Gem::Dependency
175
+ name: faraday
176
+ prerelease: false
177
+ requirement: &id011 !ruby/object:Gem::Requirement
178
+ none: false
179
+ requirements:
180
+ - - ~>
181
+ - !ruby/object:Gem::Version
182
+ hash: 15
183
+ segments:
184
+ - 0
185
+ - 5
186
+ - 2
187
+ version: 0.5.2
188
+ type: :runtime
189
+ version_requirements: *id011
190
+ - !ruby/object:Gem::Dependency
191
+ name: faraday_middleware
192
+ prerelease: false
193
+ requirement: &id012 !ruby/object:Gem::Requirement
194
+ none: false
195
+ requirements:
196
+ - - ~>
197
+ - !ruby/object:Gem::Version
198
+ hash: 17
199
+ segments:
200
+ - 0
201
+ - 2
202
+ - 3
203
+ version: 0.2.3
204
+ type: :runtime
205
+ version_requirements: *id012
206
+ - !ruby/object:Gem::Dependency
207
+ name: multi_json
208
+ prerelease: false
209
+ requirement: &id013 !ruby/object:Gem::Requirement
210
+ none: false
211
+ requirements:
212
+ - - ~>
213
+ - !ruby/object:Gem::Version
214
+ hash: 21
215
+ segments:
216
+ - 0
217
+ - 0
218
+ - 5
219
+ version: 0.0.5
220
+ type: :runtime
221
+ version_requirements: *id013
222
+ - !ruby/object:Gem::Dependency
223
+ name: multi_xml
224
+ prerelease: false
225
+ requirement: &id014 !ruby/object:Gem::Requirement
226
+ none: false
227
+ requirements:
228
+ - - ~>
229
+ - !ruby/object:Gem::Version
230
+ hash: 23
231
+ segments:
232
+ - 0
233
+ - 2
234
+ - 0
235
+ version: 0.2.0
236
+ type: :runtime
237
+ version_requirements: *id014
238
+ description: A Ruby wrapper for the Open311 API v2.
239
+ email:
240
+ - dan@codeforamerica.org
241
+ executables: []
242
+
243
+ extensions: []
244
+
245
+ extra_rdoc_files: []
246
+
247
+ files:
248
+ - .gitignore
249
+ - .rspec
250
+ - .yardopts
251
+ - Gemfile
252
+ - Gemfile.lock
253
+ - LICENSE.mkd
254
+ - README.mkd
255
+ - Rakefile
256
+ - autotest/discover.rb
257
+ - lib/faraday/multipart.rb
258
+ - lib/faraday/raise_error.rb
259
+ - lib/open311.rb
260
+ - lib/open311/client.rb
261
+ - lib/open311/client/connection.rb
262
+ - lib/open311/client/request.rb
263
+ - lib/open311/client/service.rb
264
+ - lib/open311/configuration.rb
265
+ - lib/open311/version.rb
266
+ - open311.gemspec
267
+ - spec/fixtures/services.xml
268
+ - spec/open311_spec.rb
269
+ - spec/spec_helper.rb
270
+ has_rdoc: true
271
+ homepage: http://rubygems.org/gems/open311
272
+ licenses: []
273
+
274
+ post_install_message: |
275
+ Using this gem for your project or company? Add it to the apps wiki!
276
+ https://github.com/cfalabs/open311/wiki/apps
277
+
278
+ rdoc_options: []
279
+
280
+ require_paths:
281
+ - lib
282
+ required_ruby_version: !ruby/object:Gem::Requirement
283
+ none: false
284
+ requirements:
285
+ - - ">="
286
+ - !ruby/object:Gem::Version
287
+ hash: 3
288
+ segments:
289
+ - 0
290
+ version: "0"
291
+ required_rubygems_version: !ruby/object:Gem::Requirement
292
+ none: false
293
+ requirements:
294
+ - - ">="
295
+ - !ruby/object:Gem::Version
296
+ hash: 23
297
+ segments:
298
+ - 1
299
+ - 3
300
+ - 6
301
+ version: 1.3.6
302
+ requirements: []
303
+
304
+ rubyforge_project:
305
+ rubygems_version: 1.3.7
306
+ signing_key:
307
+ specification_version: 3
308
+ summary: A Ruby wrapper for the Open311 API v2.
309
+ test_files:
310
+ - spec/fixtures/services.xml
311
+ - spec/open311_spec.rb
312
+ - spec/spec_helper.rb