rubbish_collection 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,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rubbish_collection.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Craig R Webster
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,48 @@
1
+ # RubbishCollection
2
+
3
+ When does my rubbish get picked up?
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'rubbish_collection'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install rubbish_collection
19
+
20
+
21
+ ## Usage
22
+
23
+ collection_times = RubbishCollection.times_at_postcode 'SE1 1EY'
24
+ collection_times.each do |t|
25
+ puts t.to_s
26
+ end
27
+
28
+
29
+ ## TODO
30
+
31
+ There are a lot of unsupported local authorities still. I'd very much appreciate
32
+ pull requests adding support for your local authority. See the Southwark and
33
+ Redbridge examples for how they should be structured and what the should return.
34
+
35
+ You can get the ID to register your local authority adapter against by looking
36
+ at the [local authority database][0] in my [local\_authority gem][1]. It's the
37
+ last column of the CSV row.
38
+
39
+ [0]: https://raw.github.com/craigw/local_authority/master/db/local_authorities.csv
40
+ [1]: https://github.com/craigw/local_authority
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,32 @@
1
+ module RubbishCollection
2
+ class RedbridgeAdapter
3
+ DAYS = %w( SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY ).map(&:freeze).freeze
4
+
5
+ def self.load
6
+ require 'nokogiri'
7
+ end
8
+
9
+ def initialize local_authority
10
+ end
11
+
12
+ def collection_times_at postcode
13
+ Net::HTTP.start "www.redbridge.gov.uk", 80 do |http|
14
+ req = Net::HTTP::Get.new '/RecycleRefuse'
15
+ req['Cookie'] = "RedbridgeIV3LivePref=postcode=#{postcode}"
16
+ response = http.request req
17
+ doc = Nokogiri::HTML response.body
18
+ info = doc.xpath "//*[@id='RegularCollectionDay']"
19
+ instructions = info.xpath ".//*[@class='instructions']/text()"
20
+ hour, modifier = instructions.to_s.strip.scan(/(\d+)(am|pm)/)[0]
21
+ hour = hour.to_i
22
+ hour += 12 if modifier == "pm"
23
+ time = hour * 100
24
+ day = info.xpath ".//*[@class='day']/text()"
25
+ day_index = DAYS.index day.to_s.strip
26
+ [ CollectionTime.new(day_index, time) ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ RubbishCollection.register_adapter 'http://mapit.mysociety.org/area/2497', RubbishCollection::RedbridgeAdapter
@@ -0,0 +1,50 @@
1
+ module RubbishCollection
2
+ class SouthwarkAdapter
3
+ DAYS = %w( Sunday Monday Tuesday Wednesday Thursday Friday Saturday ).map(&:freeze).freeze
4
+
5
+ def self.load
6
+ require 'nokogiri'
7
+ end
8
+
9
+ def initialize local_authority
10
+ end
11
+
12
+ def collection_times_at postcode
13
+ Net::HTTP.start "wasteservices.southwark.gov.uk", 80 do |http|
14
+ req = Net::HTTP::Get.new "/findAddress.asp?pc=#{postcode.gsub(/\s+/, '')}"
15
+ response = http.request req
16
+ addresses = Nokogiri::HTML.fragment response.body
17
+ first_address = addresses.xpath(".//option").detect { |o| o['value'].to_s.strip != '' }
18
+ uprn = first_address['value'].to_s
19
+ req = Net::HTTP::Get.new "/findSummary.asp?uprn=#{uprn}"
20
+ response = http.request req
21
+ times = []
22
+ response.body.split(/<br><br><br><br>/).each do |fragment|
23
+ fragment_doc = Nokogiri::HTML.fragment fragment
24
+ link = fragment_doc.at_xpath('.//a')
25
+ link_text = link.inner_text.to_s.strip
26
+ collection_type = case link_text
27
+ when /refuse bin/
28
+ :domestic_refuse
29
+ when /communal recycling bins/
30
+ :communal_recycling
31
+ when /mixed recycling bag/
32
+ :mixed_recycling_bag
33
+ else
34
+ link_text.to_sym
35
+ end
36
+ DAYS.inject([]) { |a,e|
37
+ a << DAYS.index(e) if fragment =~ /#{e}/i
38
+ a
39
+ }.each do |d|
40
+ t = CollectionTime.new d, :unknown, collection_type
41
+ times << t
42
+ end
43
+ end
44
+ times
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ RubbishCollection.register_adapter 'http://mapit.mysociety.org/area/2491', RubbishCollection::SouthwarkAdapter
@@ -0,0 +1,3 @@
1
+ module RubbishCollection
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,100 @@
1
+ require "rubbish_collection/version"
2
+ require 'local_authority'
3
+
4
+ module RubbishCollection
5
+ class UnknownAdapter
6
+ attr_accessor :local_authority
7
+ private :local_authority=, :local_authority
8
+
9
+ def initialize local_authority
10
+ self.local_authority = local_authority
11
+ end
12
+
13
+ def collection_times_at postcode
14
+ raise "I don't know how to fetch times for #{local_authority.name} #{local_authority.map_it_id}"
15
+ end
16
+ end
17
+
18
+ class CollectionTimes
19
+ attr_accessor :times
20
+ private :times=, :times
21
+
22
+ def initialize
23
+ self.times = []
24
+ end
25
+
26
+ def each
27
+ times.each { |t| yield t }
28
+ end
29
+ include Enumerable
30
+
31
+ def << time
32
+ times << time
33
+ end
34
+ end
35
+
36
+ class CollectionTime
37
+ DAYS = %w( Sunday Monday Tuesday Wednesday Thursday Friday Saturday ).map(&:freeze).freeze
38
+
39
+ attr_accessor :day
40
+ private :day=, :day
41
+
42
+ attr_accessor :time
43
+ private :time=, :time
44
+
45
+ attr_accessor :pickup_type
46
+ private :pickup_type=, :pickup_type
47
+
48
+ def initialize day, time = :unknown, pickup_type = :domestic_refuse
49
+ self.day = day
50
+ self.time = time
51
+ self.pickup_type = pickup_type
52
+ end
53
+
54
+ def human_day
55
+ DAYS[day]
56
+ end
57
+
58
+ def human_time
59
+ return if time == :unknown
60
+ t = time.to_s.rjust 4, '0'
61
+ t[0..1] + ':' + t[2..3]
62
+ end
63
+
64
+ def human_type
65
+ pickup_type.to_s.split(/_/).join(' ')
66
+ end
67
+
68
+ def to_s
69
+ [ human_day, human_time ].compact.join(' ') + " - #{human_type}"
70
+ end
71
+ end
72
+
73
+ def self.times_at_postcode postcode
74
+ times = CollectionTimes.new
75
+ local_authority = LocalAuthority::LocalAuthority.find_by_postcode postcode
76
+ return times if local_authority.nil?
77
+ adaptor = adapter_for local_authority
78
+ adaptor.collection_times_at(postcode).each do |t|
79
+ times << t
80
+ end
81
+ times
82
+ end
83
+
84
+ def self.adapters
85
+ @@adapters ||= Hash.new UnknownAdapter
86
+ end
87
+
88
+ def self.adapter_for local_authority
89
+ adapter = adapters[local_authority.map_it_id]
90
+ adapter.load if adapter.respond_to? :load
91
+ adapter.new local_authority
92
+ end
93
+
94
+ def self.register_adapter map_it_id, adapter
95
+ adapters[map_it_id] = adapter
96
+ end
97
+ end
98
+
99
+ require 'rubbish_collection/redbridge'
100
+ require 'rubbish_collection/southwark'
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/rubbish_collection/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Craig R Webster"]
6
+ gem.email = ["craig@barkingiguana.com"]
7
+ gem.description = %q{When is my rubbish collected?}
8
+ gem.summary = %q{When is my rubbish collected?}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "rubbish_collection"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = RubbishCollection::VERSION
17
+
18
+ gem.add_runtime_dependency 'local_authority', '~> 0.0.5'
19
+ gem.add_runtime_dependency 'nokogiri'
20
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubbish_collection
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Craig R Webster
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: local_authority
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.0.5
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.0.5
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: When is my rubbish collected?
47
+ email:
48
+ - craig@barkingiguana.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE
56
+ - README.md
57
+ - Rakefile
58
+ - lib/rubbish_collection.rb
59
+ - lib/rubbish_collection/redbridge.rb
60
+ - lib/rubbish_collection/southwark.rb
61
+ - lib/rubbish_collection/version.rb
62
+ - rubbish_collection.gemspec
63
+ homepage: ''
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.24
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: When is my rubbish collected?
87
+ test_files: []