rubbish_collection 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|