rubbish_collection 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -0
- data/lib/rubbish_collection.rb +153 -22
- data/lib/rubbish_collection/redbridge.rb +5 -3
- data/lib/rubbish_collection/rushmoor.rb +15 -10
- data/lib/rubbish_collection/southwark.rb +9 -7
- data/lib/rubbish_collection/version.rb +1 -1
- data/rubbish_collection.gemspec +1 -0
- metadata +18 -2
data/README.md
CHANGED
@@ -20,6 +20,15 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
+
require 'ostruct'
|
24
|
+
|
25
|
+
address = OpenStruct.new :house_number => "43",
|
26
|
+
:street_name => "Redcross Way", :postcode => "SE1 1EY"
|
27
|
+
collection_times = RubbishCollection.times_at_address address
|
28
|
+
collection_times.each do |t|
|
29
|
+
puts t.to_s
|
30
|
+
end
|
31
|
+
|
23
32
|
address = OpenStruct.new :house_number => "2",
|
24
33
|
:street_name => "Beech Road", :postcode => "GU14 8EU"
|
25
34
|
collection_times = RubbishCollection.times_at_address address
|
data/lib/rubbish_collection.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require "rubbish_collection/version"
|
2
2
|
require 'local_authority'
|
3
|
+
require 'runt'
|
3
4
|
|
4
5
|
module RubbishCollection
|
6
|
+
DOMESTIC_RUBBISH = 'Domestic Rubbish'.freeze
|
7
|
+
DOMESTIC_RECYCLING = 'Domestic Recycling'.freeze
|
8
|
+
COMMUNAL_RECYCLING = 'Communal Recycling'.freeze
|
9
|
+
|
5
10
|
class UnknownAdapter
|
6
11
|
attr_accessor :local_authority
|
7
12
|
private :local_authority=, :local_authority
|
@@ -15,64 +20,190 @@ module RubbishCollection
|
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
18
|
-
class
|
19
|
-
attr_accessor :
|
20
|
-
private :
|
23
|
+
class Collections
|
24
|
+
attr_accessor :collections
|
25
|
+
private :collections=, :collections
|
21
26
|
|
22
27
|
def initialize
|
23
|
-
self.
|
28
|
+
self.collections = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def << collection
|
32
|
+
collections << collection
|
24
33
|
end
|
25
34
|
|
26
35
|
def each
|
27
|
-
|
36
|
+
upto(Time.now + (86400 * 31)).each { |t| yield t }
|
28
37
|
end
|
29
|
-
include
|
38
|
+
include Comparable
|
30
39
|
|
31
|
-
def
|
32
|
-
|
40
|
+
def upto until_date
|
41
|
+
now = Time.now
|
42
|
+
collections.map { |c| c.realise now, until_date }.flatten.sort
|
33
43
|
end
|
34
44
|
end
|
35
45
|
|
36
|
-
class
|
46
|
+
class Resolution
|
47
|
+
attr_accessor :name
|
48
|
+
private :name=
|
49
|
+
|
50
|
+
attr_accessor :step
|
51
|
+
private :step=
|
52
|
+
|
53
|
+
def initialize name, step
|
54
|
+
self.name = name
|
55
|
+
self.step = step
|
56
|
+
end
|
57
|
+
|
58
|
+
def <=> other
|
59
|
+
other.step <=> step
|
60
|
+
end
|
61
|
+
include Comparable
|
62
|
+
|
63
|
+
def match_resolution time
|
64
|
+
args = [ time.year, time.month, time.day, time.hour, time.min, time.sec, time.usec ]
|
65
|
+
case step
|
66
|
+
when 1
|
67
|
+
Runt::PDate.sec *args
|
68
|
+
when 60
|
69
|
+
Runt::PDate.min *args
|
70
|
+
when 3600
|
71
|
+
Runt::PDate.hour *args
|
72
|
+
when 86400
|
73
|
+
Runt::PDate.day *args
|
74
|
+
else
|
75
|
+
raise "Don't know how to represent a time with resolution of #{step}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
SECOND = new "Second", 1
|
80
|
+
MINUTE = new "Minute", 60
|
81
|
+
HOUR = new "Hour", 3600
|
82
|
+
DAY = new "Day", 86400
|
83
|
+
end
|
84
|
+
|
85
|
+
class Schedule
|
86
|
+
attr_accessor :condition
|
87
|
+
private :condition=, :condition
|
88
|
+
|
89
|
+
attr_accessor :resolution
|
90
|
+
private :resolution=
|
91
|
+
|
92
|
+
def initialize resolution
|
93
|
+
self.resolution = resolution
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.day_of_week day_name
|
97
|
+
normalised_name = day_name[0,1].upcase + day_name[1..-1].downcase
|
98
|
+
day_const = Runt.const_get normalised_name
|
99
|
+
Runt::DIWeek.new day_const
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.hour hour
|
103
|
+
Runt::REDay.new hour, 0, hour, 59, true
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_rule rule
|
107
|
+
if condition.nil?
|
108
|
+
self.condition = rule
|
109
|
+
return
|
110
|
+
end
|
111
|
+
self.condition = condition & rule
|
112
|
+
end
|
113
|
+
|
114
|
+
def include? time
|
115
|
+
time_with_resolution = resolution.match_resolution time
|
116
|
+
condition.include? time_with_resolution
|
117
|
+
end
|
37
118
|
|
38
|
-
|
39
|
-
|
119
|
+
def to_s
|
120
|
+
condition.to_s
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class Collection
|
125
|
+
attr_accessor :pickup_type
|
126
|
+
private :pickup_type=
|
127
|
+
|
128
|
+
attr_accessor :schedule
|
129
|
+
private :schedule=, :schedule
|
130
|
+
|
131
|
+
def initialize pickup_type, schedule
|
132
|
+
self.pickup_type = pickup_type
|
133
|
+
self.schedule = schedule
|
134
|
+
end
|
135
|
+
|
136
|
+
def realise from, to
|
137
|
+
times = []
|
138
|
+
now = from
|
139
|
+
resolution = schedule.resolution
|
140
|
+
rem = now.to_i % resolution.step
|
141
|
+
diff = resolution.step - rem
|
142
|
+
now += diff
|
143
|
+
while now < to
|
144
|
+
if schedule.include? now
|
145
|
+
time = CollectionTime.new pickup_type, now, resolution
|
146
|
+
times << time
|
147
|
+
end
|
148
|
+
now += resolution.step
|
149
|
+
end
|
150
|
+
times
|
151
|
+
end
|
152
|
+
|
153
|
+
def to_s
|
154
|
+
[ pickup_type, schedule.to_s ].join ' - '
|
155
|
+
end
|
156
|
+
end
|
40
157
|
|
158
|
+
class CollectionTime
|
41
159
|
attr_accessor :time
|
42
160
|
private :time=, :time
|
43
161
|
|
162
|
+
attr_accessor :resolution
|
163
|
+
private :resolution=, :resolution
|
164
|
+
|
44
165
|
attr_accessor :pickup_type
|
45
166
|
private :pickup_type=, :pickup_type
|
46
167
|
|
47
|
-
def initialize
|
48
|
-
self.day = day
|
168
|
+
def initialize pickup_type, time, resolution
|
49
169
|
self.time = time
|
170
|
+
self.resolution = resolution
|
50
171
|
self.pickup_type = pickup_type
|
51
172
|
end
|
52
173
|
|
53
|
-
def
|
54
|
-
|
174
|
+
def human_time
|
175
|
+
return unless resolution > Resolution::DAY
|
176
|
+
start_time = time
|
177
|
+
end_time = time + resolution.step
|
178
|
+
|
179
|
+
[ start_time, end_time ].map { |t| t.strftime('%l.%M%P').strip }.join(' to ')
|
55
180
|
end
|
56
181
|
|
57
|
-
def
|
58
|
-
|
59
|
-
t = time.to_s.rjust 4, '0'
|
60
|
-
t[0..1] + ':' + t[2..3]
|
182
|
+
def human_date
|
183
|
+
time.strftime '%A %d %B %Y'
|
61
184
|
end
|
62
185
|
|
63
186
|
def human_type
|
64
|
-
pickup_type
|
187
|
+
pickup_type
|
188
|
+
end
|
189
|
+
|
190
|
+
def <=> other
|
191
|
+
sort_key <=> other.sort_key
|
192
|
+
end
|
193
|
+
|
194
|
+
def sort_key
|
195
|
+
[ time, resolution, pickup_type ]
|
65
196
|
end
|
66
197
|
|
67
198
|
def to_s
|
68
|
-
[
|
199
|
+
[ human_date, human_time ].compact.join(' from ') + " - #{human_type}"
|
69
200
|
end
|
70
201
|
end
|
71
202
|
|
72
203
|
def self.times_at_address address
|
73
204
|
pc = address.postcode
|
74
205
|
local_authority = LocalAuthority::LocalAuthority.find_by_postcode pc
|
75
|
-
times =
|
206
|
+
times = Collections.new
|
76
207
|
return times if local_authority.nil?
|
77
208
|
adaptor = adapter_for local_authority
|
78
209
|
adaptor.collection_times_at(address).each do |t|
|
@@ -21,9 +21,11 @@ module RubbishCollection
|
|
21
21
|
hour = hour.to_i
|
22
22
|
hour += 12 if modifier == "pm"
|
23
23
|
time = hour * 100
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
day_name = info.xpath(".//*[@class='day']/text()").to_s
|
25
|
+
s = Schedule.new Resolution::HOUR
|
26
|
+
s.add_rule Schedule.day_of_week day_name
|
27
|
+
s.add_rule Schedule.hour hour
|
28
|
+
[ Collection.new(DOMESTIC_RUBBISH, s) ]
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -24,17 +24,22 @@ module RubbishCollection
|
|
24
24
|
times = []
|
25
25
|
container.xpath("p").each do |rubbish_div|
|
26
26
|
lines = rubbish_div.text.split("\n")
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
day_name = lines[2].to_s.strip.split(" ")[0]
|
28
|
+
s = Schedule.new Resolution::DAY
|
29
|
+
collection = case lines[1]
|
30
|
+
when /rubbish bin collection/
|
31
|
+
s.add_rule Schedule.day_of_week day_name
|
32
|
+
Collection.new DOMESTIC_RUBBISH, s
|
33
|
+
when /recycling collection/
|
34
|
+
nc = Time.parse lines[2]
|
35
|
+
start_date = Runt::PDate.day nc.year, nc.month, nc.day
|
36
|
+
s.add_rule Runt::EveryTE.new(start_date, 2, Runt::DPrecision::WEEK)
|
37
|
+
s.add_rule Schedule.day_of_week day_name
|
38
|
+
Collection.new DOMESTIC_RECYCLING, s
|
39
|
+
else
|
40
|
+
next
|
35
41
|
end
|
36
|
-
|
37
|
-
times << CollectionTime.new(day_index, :unknown, collection_type)
|
42
|
+
times << collection
|
38
43
|
end
|
39
44
|
times
|
40
45
|
end
|
@@ -25,20 +25,22 @@ module RubbishCollection
|
|
25
25
|
link_text = link.inner_text.to_s.strip
|
26
26
|
collection_type = case link_text
|
27
27
|
when /refuse bin/
|
28
|
-
|
28
|
+
DOMESTIC_RUBBISH
|
29
29
|
when /communal recycling bins/
|
30
|
-
|
30
|
+
COMMUNAL_RECYCLING
|
31
31
|
when /mixed recycling bag/
|
32
|
-
|
32
|
+
DOMESTIC_RECYCLING
|
33
33
|
else
|
34
|
-
|
34
|
+
next
|
35
35
|
end
|
36
36
|
DAYS.inject([]) { |a,e|
|
37
|
-
a <<
|
37
|
+
a << e if fragment =~ /#{e}/i
|
38
38
|
a
|
39
39
|
}.each do |d|
|
40
|
-
|
41
|
-
|
40
|
+
s = Schedule.new Resolution::DAY
|
41
|
+
s.add_rule Schedule.day_of_week(d)
|
42
|
+
c = Collection.new collection_type, s
|
43
|
+
times << c
|
42
44
|
end
|
43
45
|
end
|
44
46
|
times
|
data/rubbish_collection.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubbish_collection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: local_authority
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: runt19
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.7.7
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.7.7
|
46
62
|
description: When is my rubbish collected?
|
47
63
|
email:
|
48
64
|
- craig@barkingiguana.com
|