govkit-ca 0.0.1
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +44 -0
- data/Rakefile +9 -0
- data/USAGE +1 -0
- data/govkit-ca.gemspec +27 -0
- data/lib/data/rid_to_edid.yml +309 -0
- data/lib/gov_kit-ca.rb +18 -0
- data/lib/gov_kit-ca/postal_code.rb +68 -0
- data/lib/gov_kit-ca/postal_code/strategy.rb +45 -0
- data/lib/gov_kit-ca/postal_code/strategy/base.rb +45 -0
- data/lib/gov_kit-ca/postal_code/strategy/cbc-ca.rb +46 -0
- data/lib/gov_kit-ca/postal_code/strategy/conservative-ca.rb +29 -0
- data/lib/gov_kit-ca/postal_code/strategy/digital_copyright-ca.rb +27 -0
- data/lib/gov_kit-ca/postal_code/strategy/elections-ca.rb +30 -0
- data/lib/gov_kit-ca/postal_code/strategy/liberal-ca.rb +27 -0
- data/lib/gov_kit-ca/postal_code/strategy/ndp-ca.rb +29 -0
- data/lib/gov_kit-ca/postal_code/strategy/parl-gc-ca.rb +29 -0
- data/lib/gov_kit-ca/version.rb +5 -0
- data/lib/govkit-ca.rb +1 -0
- data/spec/postal_code_spec.rb +3 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/rid_to_edid.rb +136 -0
- metadata +148 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 James McKinney
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# GovKit-CA
|
2
|
+
|
3
|
+
GovKit-CA is a Ruby gem that provides easy access to Canadian civic data around the web. It currently provides an API for free postal code to electoral district lookups, using the following sources:
|
4
|
+
|
5
|
+
* [elections.ca](http://elections.ca/)
|
6
|
+
* [cbc.ca](http://www.cbc.ca/)
|
7
|
+
* [ndp.ca](http://www.ndp.ca/)
|
8
|
+
* [digital-copyright.ca](http://www.digital-copyright.ca/)
|
9
|
+
* [liberal.ca](http://www.liberal.ca/)
|
10
|
+
|
11
|
+
GovKit-CA follows from [Participatory Politics Foundation](http://www.participatorypolitics.org/)'s [GovKit](https://github.com/opengovernment/govkit) gem. GovKit-CA is not affiliated with the Participatory Politics Foundation or GovKit.
|
12
|
+
|
13
|
+
# Installation
|
14
|
+
|
15
|
+
gem install govkit
|
16
|
+
|
17
|
+
# Examples
|
18
|
+
|
19
|
+
>> require 'govkit-ca'
|
20
|
+
|
21
|
+
>> GovKit::CA::PostalCode.find_electoral_districts_by_postal_code('A1A1A1')
|
22
|
+
=> [10007]
|
23
|
+
>> GovKit::CA::PostalCode.find_electoral_districts_by_postal_code('K0A1K0')
|
24
|
+
=> [35087, 35025, 35052, 35012, 35040, 35063, 35064]
|
25
|
+
|
26
|
+
>> GovKit::CA::PostalCode.find_province_by_postal_code('A1A1A1')
|
27
|
+
=> "Newfoundland and Labrador"
|
28
|
+
>> GovKit::CA::PostalCode.find_province_by_postal_code('K0A1K0')
|
29
|
+
=> "Ontario"
|
30
|
+
|
31
|
+
Postal codes may contain lowercase letters. Spaces and non-alphanumeric characters are removed before processing.
|
32
|
+
|
33
|
+
GovKit-CA will raise GovKit::CA::ResourceNotFound if the electoral districts within a postal code cannot be determined.
|
34
|
+
|
35
|
+
# Bugs? Questions?
|
36
|
+
|
37
|
+
Govkit-CA's main repository is on GitHub: [http://github.com/jpmckinney/govkit-ca](http://github.com/jpmckinney/govkit-ca), where your contributions, forks, bug reports, feature requests, and feedback are greatly welcomed.
|
38
|
+
|
39
|
+
# TODOs
|
40
|
+
|
41
|
+
* Write tests
|
42
|
+
* Add a `ElectoralDistrict` class to convert IDs to English and french names.
|
43
|
+
|
44
|
+
Copyright (c) 2011 James McKinney, released under the MIT license
|
data/Rakefile
ADDED
data/USAGE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
See README.md for full usage details.
|
data/govkit-ca.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "gov_kit-ca/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "govkit-ca"
|
7
|
+
s.version = GovKit::CA::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["James McKinney"]
|
10
|
+
s.email = ["james@slashpoundbang.com"]
|
11
|
+
s.homepage = "http://github.com/jpmckinney/govkit-ca"
|
12
|
+
s.summary = %q{Easy access to Canadian civic data around the web}
|
13
|
+
s.description = %q{GovKit-CA lets you quickly get encapsulated Ruby objects for Canadian civic data.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "govkit-ca"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
#s.add_runtime_dependency('graticule', '>= 0.2.8')
|
23
|
+
s.add_runtime_dependency('httparty', '>= 0.6.1')
|
24
|
+
s.add_runtime_dependency('nokogiri', '>= 1.4.4')
|
25
|
+
s.add_runtime_dependency('yajl-ruby', '>= 0.7.8')
|
26
|
+
s.add_development_dependency('rspec', '>= 2')
|
27
|
+
end
|
@@ -0,0 +1,309 @@
|
|
1
|
+
---
|
2
|
+
1: 10001
|
3
|
+
2: 10002
|
4
|
+
3: 10003
|
5
|
+
4: 10004
|
6
|
+
5: 10005
|
7
|
+
6: 10006
|
8
|
+
7: 10007
|
9
|
+
8: 11001
|
10
|
+
9: 11002
|
11
|
+
10: 11003
|
12
|
+
11: 11004
|
13
|
+
12: 12001
|
14
|
+
13: 12002
|
15
|
+
14: 12007
|
16
|
+
15: 12003
|
17
|
+
16: 12004
|
18
|
+
17: 12005
|
19
|
+
18: 12006
|
20
|
+
19: 12008
|
21
|
+
20: 12009
|
22
|
+
21: 12010
|
23
|
+
22: 12011
|
24
|
+
23: 13001
|
25
|
+
24: 13002
|
26
|
+
25: 13003
|
27
|
+
26: 13004
|
28
|
+
27: 13005
|
29
|
+
28: 13006
|
30
|
+
29: 13007
|
31
|
+
30: 13008
|
32
|
+
31: 13009
|
33
|
+
32: 13010
|
34
|
+
33: 24046
|
35
|
+
34: 24001
|
36
|
+
35: 24002
|
37
|
+
36: 24003
|
38
|
+
37: 24004
|
39
|
+
38: 24054
|
40
|
+
39: 24005
|
41
|
+
40: 24006
|
42
|
+
41: 24007
|
43
|
+
42: 24008
|
44
|
+
43: 24009
|
45
|
+
44: 24010
|
46
|
+
45: 24011
|
47
|
+
46: 24012
|
48
|
+
47: 24013
|
49
|
+
48: 24015
|
50
|
+
49: 24016
|
51
|
+
50: 24017
|
52
|
+
51: 24018
|
53
|
+
52: 24019
|
54
|
+
53: 24020
|
55
|
+
54: 24041
|
56
|
+
55: 24021
|
57
|
+
56: 24022
|
58
|
+
57: 24023
|
59
|
+
58: 24024
|
60
|
+
59: 24025
|
61
|
+
60: 24026
|
62
|
+
61: 24027
|
63
|
+
62: 24028
|
64
|
+
63: 24029
|
65
|
+
64: 24030
|
66
|
+
65: 24031
|
67
|
+
66: 24032
|
68
|
+
67: 24033
|
69
|
+
68: 24034
|
70
|
+
69: 24035
|
71
|
+
70: 24036
|
72
|
+
71: 24037
|
73
|
+
72: 24038
|
74
|
+
73: 24039
|
75
|
+
74: 24040
|
76
|
+
75: 24042
|
77
|
+
76: 24043
|
78
|
+
77: 24058
|
79
|
+
78: 24014
|
80
|
+
79: 24044
|
81
|
+
80: 24045
|
82
|
+
81: 24047
|
83
|
+
82: 24048
|
84
|
+
83: 24049
|
85
|
+
84: 24050
|
86
|
+
85: 24051
|
87
|
+
86: 24052
|
88
|
+
87: 24053
|
89
|
+
88: 24055
|
90
|
+
89: 24056
|
91
|
+
90: 24057
|
92
|
+
91: 24059
|
93
|
+
92: 24060
|
94
|
+
93: 24061
|
95
|
+
94: 24062
|
96
|
+
95: 24063
|
97
|
+
96: 24064
|
98
|
+
97: 24065
|
99
|
+
98: 24066
|
100
|
+
99: 24067
|
101
|
+
100: 24068
|
102
|
+
101: 24069
|
103
|
+
102: 24070
|
104
|
+
103: 24071
|
105
|
+
104: 24072
|
106
|
+
105: 24073
|
107
|
+
106: 24074
|
108
|
+
107: 24075
|
109
|
+
108: 35001
|
110
|
+
109: 35002
|
111
|
+
110: 35003
|
112
|
+
111: 35004
|
113
|
+
112: 35005
|
114
|
+
113: 35006
|
115
|
+
114: 35007
|
116
|
+
115: 35008
|
117
|
+
116: 35009
|
118
|
+
117: 35026
|
119
|
+
118: 35010
|
120
|
+
119: 35011
|
121
|
+
120: 35012
|
122
|
+
121: 35013
|
123
|
+
122: 35015
|
124
|
+
123: 35016
|
125
|
+
124: 35017
|
126
|
+
125: 35018
|
127
|
+
126: 35014
|
128
|
+
127: 35019
|
129
|
+
128: 35020
|
130
|
+
129: 35021
|
131
|
+
130: 35022
|
132
|
+
131: 35023
|
133
|
+
132: 35024
|
134
|
+
133: 35025
|
135
|
+
134: 35027
|
136
|
+
135: 35028
|
137
|
+
136: 35029
|
138
|
+
137: 35030
|
139
|
+
138: 35031
|
140
|
+
139: 35032
|
141
|
+
140: 35033
|
142
|
+
141: 35034
|
143
|
+
142: 35035
|
144
|
+
143: 35036
|
145
|
+
144: 35037
|
146
|
+
145: 35038
|
147
|
+
146: 35039
|
148
|
+
147: 35046
|
149
|
+
148: 35040
|
150
|
+
149: 35041
|
151
|
+
150: 35042
|
152
|
+
151: 35043
|
153
|
+
152: 35044
|
154
|
+
153: 35045
|
155
|
+
154: 35047
|
156
|
+
155: 35048
|
157
|
+
156: 35049
|
158
|
+
157: 35050
|
159
|
+
158: 35051
|
160
|
+
159: 35052
|
161
|
+
160: 35053
|
162
|
+
161: 35054
|
163
|
+
162: 35055
|
164
|
+
163: 35056
|
165
|
+
164: 35057
|
166
|
+
165: 35058
|
167
|
+
166: 35059
|
168
|
+
167: 35060
|
169
|
+
168: 35061
|
170
|
+
169: 35062
|
171
|
+
170: 35063
|
172
|
+
171: 35064
|
173
|
+
172: 35065
|
174
|
+
173: 35066
|
175
|
+
174: 35067
|
176
|
+
175: 35068
|
177
|
+
176: 35069
|
178
|
+
177: 35070
|
179
|
+
178: 35071
|
180
|
+
179: 35072
|
181
|
+
180: 35073
|
182
|
+
181: 35074
|
183
|
+
182: 35075
|
184
|
+
183: 35076
|
185
|
+
184: 35077
|
186
|
+
185: 35078
|
187
|
+
186: 35079
|
188
|
+
187: 35080
|
189
|
+
188: 35081
|
190
|
+
189: 35082
|
191
|
+
190: 35083
|
192
|
+
191: 35084
|
193
|
+
192: 35085
|
194
|
+
193: 35086
|
195
|
+
194: 35087
|
196
|
+
195: 35088
|
197
|
+
196: 35089
|
198
|
+
197: 35090
|
199
|
+
198: 35091
|
200
|
+
199: 35092
|
201
|
+
200: 35093
|
202
|
+
201: 35094
|
203
|
+
202: 35095
|
204
|
+
203: 35096
|
205
|
+
204: 35097
|
206
|
+
205: 35098
|
207
|
+
206: 35099
|
208
|
+
207: 35100
|
209
|
+
208: 35101
|
210
|
+
209: 35102
|
211
|
+
210: 35103
|
212
|
+
211: 35104
|
213
|
+
212: 35105
|
214
|
+
213: 35106
|
215
|
+
214: 46001
|
216
|
+
215: 46002
|
217
|
+
216: 46003
|
218
|
+
217: 46004
|
219
|
+
218: 46005
|
220
|
+
219: 46006
|
221
|
+
220: 46007
|
222
|
+
221: 46008
|
223
|
+
222: 46009
|
224
|
+
223: 46010
|
225
|
+
224: 46011
|
226
|
+
225: 46012
|
227
|
+
226: 46013
|
228
|
+
227: 46014
|
229
|
+
228: 47001
|
230
|
+
229: 47002
|
231
|
+
230: 47004
|
232
|
+
231: 47003
|
233
|
+
232: 47005
|
234
|
+
233: 47006
|
235
|
+
234: 47007
|
236
|
+
235: 47008
|
237
|
+
236: 47009
|
238
|
+
237: 47010
|
239
|
+
238: 47011
|
240
|
+
239: 47012
|
241
|
+
240: 47013
|
242
|
+
241: 47014
|
243
|
+
242: 48006
|
244
|
+
243: 48003
|
245
|
+
244: 48002
|
246
|
+
245: 48004
|
247
|
+
246: 48005
|
248
|
+
247: 48007
|
249
|
+
248: 48008
|
250
|
+
249: 48009
|
251
|
+
250: 48010
|
252
|
+
251: 48012
|
253
|
+
252: 48013
|
254
|
+
253: 48014
|
255
|
+
254: 48011
|
256
|
+
255: 48015
|
257
|
+
256: 48016
|
258
|
+
257: 48017
|
259
|
+
258: 48018
|
260
|
+
259: 48001
|
261
|
+
260: 48019
|
262
|
+
261: 48020
|
263
|
+
262: 48021
|
264
|
+
263: 48022
|
265
|
+
264: 48023
|
266
|
+
265: 48024
|
267
|
+
266: 48025
|
268
|
+
267: 48026
|
269
|
+
268: 48027
|
270
|
+
269: 48028
|
271
|
+
270: 59001
|
272
|
+
271: 59026
|
273
|
+
272: 59002
|
274
|
+
273: 59003
|
275
|
+
274: 59004
|
276
|
+
275: 59005
|
277
|
+
276: 59006
|
278
|
+
277: 59008
|
279
|
+
278: 59009
|
280
|
+
279: 59010
|
281
|
+
280: 59011
|
282
|
+
281: 59012
|
283
|
+
282: 59013
|
284
|
+
283: 59014
|
285
|
+
284: 59015
|
286
|
+
285: 59016
|
287
|
+
286: 59017
|
288
|
+
287: 59019
|
289
|
+
288: 59020
|
290
|
+
289: 59018
|
291
|
+
290: 59007
|
292
|
+
291: 59021
|
293
|
+
292: 59022
|
294
|
+
293: 59023
|
295
|
+
294: 59024
|
296
|
+
295: 59025
|
297
|
+
296: 59027
|
298
|
+
297: 59028
|
299
|
+
298: 59029
|
300
|
+
299: 59030
|
301
|
+
300: 59031
|
302
|
+
301: 59032
|
303
|
+
302: 59033
|
304
|
+
303: 59034
|
305
|
+
304: 59035
|
306
|
+
305: 59036
|
307
|
+
306: 60001
|
308
|
+
307: 61001
|
309
|
+
308: 62001
|
data/lib/gov_kit-ca.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
#require 'graticule'
|
7
|
+
require 'httparty'
|
8
|
+
require 'nokogiri'
|
9
|
+
require 'yajl'
|
10
|
+
|
11
|
+
module GovKit
|
12
|
+
module CA
|
13
|
+
autoload :PostalCode, 'gov_kit-ca/postal_code'
|
14
|
+
|
15
|
+
class GovKitError < StandardError; end
|
16
|
+
class ResourceNotFound < GovKitError; end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'gov_kit-ca/postal_code/strategy'
|
2
|
+
|
3
|
+
module GovKit
|
4
|
+
module CA
|
5
|
+
# A collection of postal code helpers.
|
6
|
+
# @see http://en.wikipedia.org/wiki/Postal_codes_in_Canada Postal codes in Canada
|
7
|
+
module PostalCode
|
8
|
+
# Returns the electoral districts within a postal code.
|
9
|
+
#
|
10
|
+
# Statistics Canada charges for its Postal Codes by Federal Ridings File
|
11
|
+
# (PCFRF). A free alternative requires scraping data from other sources.
|
12
|
+
#
|
13
|
+
# @param [String] postal_code a postal code
|
14
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
15
|
+
# @raise [ResourceNotFound] if the electoral districts cannot be determined
|
16
|
+
# @see http://www.statcan.gc.ca/bsolc/olc-cel/olc-cel?lang=eng&catno=92F0193X Statistics Canada's product page for the Postal Codes by Federal Ridings File (PCFRF)
|
17
|
+
def self.find_electoral_districts_by_postal_code(postal_code)
|
18
|
+
StrategySet.run format_postal_code(postal_code)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the province that a postal code belongs to.
|
22
|
+
# @param [String] postal_code a postal code
|
23
|
+
# @return [String] the province that the postal code belongs to
|
24
|
+
# @raise [ResourceNotFound] if the province cannot be determined
|
25
|
+
# @see http://en.wikipedia.org/wiki/List_of_postal_codes_in_Canada List of postal codes in Canada
|
26
|
+
def self.find_province_by_postal_code(postal_code)
|
27
|
+
case format_postal_code(postal_code)
|
28
|
+
when /\AA/
|
29
|
+
'Newfoundland and Labrador'
|
30
|
+
when /\AB/
|
31
|
+
'Nova Scotia'
|
32
|
+
when /\AC/
|
33
|
+
'Prince Edward Island'
|
34
|
+
when /\AE/
|
35
|
+
'New Brunswick'
|
36
|
+
when /\A[GHJ]/
|
37
|
+
'Quebec'
|
38
|
+
when /\A[KLMNP]/
|
39
|
+
'Ontario'
|
40
|
+
when /\AR/
|
41
|
+
'Manitoba'
|
42
|
+
when /\AS/
|
43
|
+
'Saskatchewan'
|
44
|
+
when /\AT/
|
45
|
+
'Alberta'
|
46
|
+
when /\AV/
|
47
|
+
'British Columbia'
|
48
|
+
# http://en.wikipedia.org/wiki/List_of_X_postal_codes_of_Canada
|
49
|
+
when /\AX0[ABC]/
|
50
|
+
'Nunavut'
|
51
|
+
when /\AX0[EG]/, /\AX1A/
|
52
|
+
'Northwest Territories'
|
53
|
+
when /\AY/
|
54
|
+
'Yukon'
|
55
|
+
else
|
56
|
+
raise ResourceNotFound, "The province cannot be determined from the postal code"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Formats a postal code as A1A1A1. Removes non-alphanumeric characters.
|
61
|
+
# @param [String] postal_code a postal code
|
62
|
+
# @return [String] a formatted postal code
|
63
|
+
def self.format_postal_code(postal_code)
|
64
|
+
postal_code.upcase.gsub(/[^A-Z0-9]/, '')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
# The set of postal code to electoral district strategies.
|
5
|
+
class StrategySet
|
6
|
+
# Stores the strategy set.
|
7
|
+
# @return [Array<Strategy::Base>] the strategy set
|
8
|
+
def self.strategies
|
9
|
+
@@strategies ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
# Adds a strategy to the strategy set.
|
13
|
+
# @param [Strategy::Base] strategy a strategy
|
14
|
+
# @return [Array<Strategy::Base>] the strategy set
|
15
|
+
def self.register(strategy)
|
16
|
+
strategies << strategy
|
17
|
+
end
|
18
|
+
|
19
|
+
# Runs through the strategies in order of registration. Returns the
|
20
|
+
# output of the first strategy to successfully determine electoral
|
21
|
+
# districts from a postal code.
|
22
|
+
# @param [String] postal_code a postal code
|
23
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
24
|
+
# @raise [ResourceNotFound] if no strategy succeeds
|
25
|
+
def self.run(postal_code)
|
26
|
+
strategies.each do |strategy|
|
27
|
+
electoral_districts = strategy.new(postal_code).electoral_districts
|
28
|
+
return electoral_districts if electoral_districts
|
29
|
+
end
|
30
|
+
|
31
|
+
raise ResourceNotFound
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
require 'gov_kit-ca/postal_code/strategy/base'
|
39
|
+
require 'gov_kit-ca/postal_code/strategy/elections-ca'
|
40
|
+
require 'gov_kit-ca/postal_code/strategy/cbc-ca'
|
41
|
+
require 'gov_kit-ca/postal_code/strategy/ndp-ca'
|
42
|
+
require 'gov_kit-ca/postal_code/strategy/digital_copyright-ca'
|
43
|
+
require 'gov_kit-ca/postal_code/strategy/liberal-ca'
|
44
|
+
#require 'gov_kit-ca/postal_code/strategy/parl-gc-ca'
|
45
|
+
#require 'gov_kit-ca/postal_code/strategy/conservative-ca'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# Abstract class for implementing postal code to electoral district
|
6
|
+
# strategies.
|
7
|
+
#
|
8
|
+
# The following methods must be implemented in sub-classes:
|
9
|
+
#
|
10
|
+
# * `electoral_districts!`
|
11
|
+
class Base
|
12
|
+
include HTTParty
|
13
|
+
follow_redirects false
|
14
|
+
headers 'User-Agent' => 'GovKit-CA +http://govkit.org'
|
15
|
+
|
16
|
+
# Creates a new postal code to electoral district strategy.
|
17
|
+
# @param [String] postal_code a postal code
|
18
|
+
def initialize(postal_code)
|
19
|
+
@postal_code = postal_code
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the electoral districts within a postal code.
|
23
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
24
|
+
def electoral_districts
|
25
|
+
valid? && electoral_districts!.map(&:to_i)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Returns the electoral districts within a postal code, without
|
31
|
+
# passing validation first.
|
32
|
+
# @return [Array<Fixnum>] the electoral districts within the postal code
|
33
|
+
def electoral_districts!
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Boolean] whether the electoral districts can be determined
|
38
|
+
def valid?
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# cbc.ca ought to be a reliable source. It is unknown if its database
|
6
|
+
# is kept up-to-date between elections, however.
|
7
|
+
# @see https://github.com/danielharan/pc_scraper
|
8
|
+
class CbcCa < Base
|
9
|
+
base_uri 'www.cbc.ca'
|
10
|
+
|
11
|
+
def initialize(postal_code)
|
12
|
+
@fsa, @letter, @ldu = postal_code.downcase.match(/\A((.).{2})(.{3})\Z/)[1..3]
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def json_response # Yajl barfs on bad encoding
|
17
|
+
Yajl::Parser.parse(response.parsed_response) rescue JSON.parse(response.parsed_response)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def electoral_districts!
|
23
|
+
json_response.map{|x| self.class.rid_to_edid[x['rid']]}
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid?
|
27
|
+
!!response.headers['expires']
|
28
|
+
end
|
29
|
+
|
30
|
+
def response
|
31
|
+
@response ||= self.class.get "/news/canadavotes/myriding/postalcodes/#{@letter}/#{@fsa}/#{@ldu}.html"
|
32
|
+
end
|
33
|
+
|
34
|
+
# cbc.ca uses an internal riding ID, which must be matched to a
|
35
|
+
# canonical electoral district ID.
|
36
|
+
# @return [Hash] a map of cbc.ca riding ID to electoral district ID
|
37
|
+
def self.rid_to_edid
|
38
|
+
@@yml ||= YAML.load_file(File.expand_path('../../../../data/rid_to_edid.yml', __FILE__))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
StrategySet.register CbcCa
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# conservative.ca seems unreliable. In the case of B0J2L0, for example,
|
6
|
+
# it does not return three ridings like other sources.
|
7
|
+
class ConservativeCa < Base
|
8
|
+
base_uri 'www.conservative.ca'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def electoral_districts!
|
13
|
+
# TODO returns HTML with electoral district names only
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
# TODO
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
@response ||= self.class.get "/?section_id=1051&postal_code=#{@postal_code}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
StrategySet.register ConservativeCa
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
class DigitalCopyrightCa < Base
|
6
|
+
base_uri 'www.digital-copyright.ca'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def electoral_districts!
|
11
|
+
Nokogiri::HTML(response.parsed_response).css('.node .content a').map{|a| a[:href][/\d+\Z/]}
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
!response.parsed_response.match /\binvalid postal code\b/
|
16
|
+
end
|
17
|
+
|
18
|
+
def response
|
19
|
+
@response ||= self.class.get "/edid/postal?postalcode=#{@postal_code}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
StrategySet.register DigitalCopyrightCa
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# elections.ca is a reliable source, but it does not return electoral
|
6
|
+
# districts for postal codes that contain multiple electoral districts.
|
7
|
+
# @see https://github.com/danielharan/postal_code_to_edid_webservice
|
8
|
+
class ElectionsCa < Base
|
9
|
+
base_uri 'elections.ca'
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def electoral_districts!
|
14
|
+
[ response.headers['location'][/&ED=(\d{5})&/, 1] ]
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
!!response.headers['location']
|
19
|
+
end
|
20
|
+
|
21
|
+
def response
|
22
|
+
@response ||= self.class.head "/scripts/pss/FindED.aspx?PC=#{@postal_code}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
StrategySet.register ElectionsCa
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
class LiberalCa < Base
|
6
|
+
base_uri 'www.liberal.ca'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def electoral_districts!
|
11
|
+
Nokogiri::HTML(response.parsed_response).css('img.RidingListImage').map{|img| img[:src][/\d{5}/]}
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?
|
15
|
+
!response.parsed_response.match /\bOopsies!/
|
16
|
+
end
|
17
|
+
|
18
|
+
def response
|
19
|
+
@response ||= self.class.get "/riding/postal/#{@postal_code}/"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
StrategySet.register LiberalCa
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# ndp.ca does not return electoral districts for postal codes that
|
6
|
+
# contain multiple electoral districts.
|
7
|
+
class NDPCa < Base
|
8
|
+
base_uri 'www.ndp.ca'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def electoral_districts!
|
13
|
+
[ response.headers['location'][/\d+\Z/] ]
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
response.headers['location'] != 'http://www.ndp.ca/'
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
@response ||= self.class.head "http://www.ndp.ca/riding/#{@postal_code}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
StrategySet.register NDPCa
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module GovKit
|
2
|
+
module CA
|
3
|
+
module PostalCode
|
4
|
+
module Strategy
|
5
|
+
# parl.gc.ca seems unreliable. In the case of K0A1K0, for example, it
|
6
|
+
# does not return seven ridings like other sources.
|
7
|
+
class ParlGcCa < Base
|
8
|
+
base_uri 'www2.parl.gc.ca'
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def electoral_districts!
|
13
|
+
# TODO returns HTML with electoral district names only
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
# TODO
|
18
|
+
end
|
19
|
+
|
20
|
+
def response
|
21
|
+
@response ||= self.class.get "/parlinfo/Compilations/HouseOfCommons/MemberByPostalCode.aspx?PostalCode=#{@postal_code}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
StrategySet.register ParlGcCa
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/govkit-ca.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'gov_kit-ca'
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'open-uri'
|
3
|
+
require File.expand_path('../../lib/gov_kit-ca', __FILE__)
|
4
|
+
|
5
|
+
# http://www.digital-copyright.ca/pcfrf/pcfrf.tgz contains
|
6
|
+
# `postal-code-for-districts.csv`, "which is 308 postal codes that should
|
7
|
+
# map to each of the 308 different electoral districts." However, six of the
|
8
|
+
# postal codes are invalid (G0A2C0, J8M1R8, J0W1B0, J0B1H0, L0J1B0, N2A1A3),
|
9
|
+
# 14 are duplicate, and the remaining 294 map to 246 electoral districts.
|
10
|
+
desc "Picks the set cover for postal codes to cbc.ca riding IDs"
|
11
|
+
task :trim_postal_codes do |t,args|
|
12
|
+
abort "Usage: rake #{t.name} file=postal-codes-for-districts.csv" unless args[:file]
|
13
|
+
|
14
|
+
# Get the riding IDs that each postal code covers
|
15
|
+
postal_to_rid = {}
|
16
|
+
File.read(args[:file]).split("\n").uniq.each do |postal_code| # Remove duplicate postal codes
|
17
|
+
begin
|
18
|
+
postal_to_rid[postal_code] = GovKit::CA::PostalCode::Strategy::CbcCa.new(postal_code).json_response.map{|hash| hash['rid'].to_i}
|
19
|
+
rescue JSON::ParserError => e # Ignore invalid postal codes
|
20
|
+
puts "ERROR: #{postal_code} is invalid"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the minimum number of postal codes to cover all riding IDs. This is an
|
25
|
+
# instance of the set cover problem, which is NP-complete. We use the greedy
|
26
|
+
# algorithm, which is the best-possible polynomial time approximation
|
27
|
+
# algorithm for set cover. http://en.wikipedia.org/wiki/Set_cover_problem
|
28
|
+
postal_codes = []
|
29
|
+
until postal_to_rid.empty?
|
30
|
+
postal_code, rids = postal_to_rid.find{|k,v| v.size == postal_to_rid.map{|k,v| v.size}.max}
|
31
|
+
postal_to_rid.each{|k,v| postal_to_rid[k] -= rids}
|
32
|
+
postal_to_rid.reject!{|k,v| v.empty?}
|
33
|
+
postal_codes << postal_code
|
34
|
+
end
|
35
|
+
|
36
|
+
puts postal_codes.sort
|
37
|
+
end
|
38
|
+
|
39
|
+
# Use https://github.com/danielharan/pc_scraper/raw/master/data/index.csv and
|
40
|
+
# https://github.com/danielharan/canadian-postal-code-to-electoral-districts/raw/master/pc_edid.yml
|
41
|
+
# The YAML file may contain invalid postal codes, e.g. M5V1L6, and does not
|
42
|
+
# contain every electoral district, e.g. 35061. 35061 corresponds to riding ID
|
43
|
+
# 168, which contains the postal code L1H1X8.
|
44
|
+
desc "Generates postal codes within the given list of cbc.ca riding IDs"
|
45
|
+
task :riding_id_to_postal_code do |t,args|
|
46
|
+
abort "Usage: rake #{t.name} file=riding-ids.csv csv=index.csv yml=pc_edid.yml" unless args[:file] && args[:csv] && args[:yml]
|
47
|
+
|
48
|
+
# The YML file maps postal codes to electoral districts
|
49
|
+
yml = YAML.load_file(args[:yml])
|
50
|
+
|
51
|
+
# Get an old map of riding IDs to electoral districts
|
52
|
+
rid_to_edid = {}
|
53
|
+
CSV.foreach(args[:csv]) do |row|
|
54
|
+
rid_to_edid[row[1]] = row[0]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Map riding IDs to postal codes
|
58
|
+
rid_to_postal = {}
|
59
|
+
File.read(args[:file]).split("\n").each do |riding_id|
|
60
|
+
match = yml.find{|k,v| v == rid_to_edid[riding_id]}
|
61
|
+
if match
|
62
|
+
rid_to_postal[riding_id] = match[0]
|
63
|
+
else
|
64
|
+
puts "ERROR: No postal code for riding ID #{riding_id}, electoral district #{rid_to_edid[riding_id]}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
puts rid_to_postal.values.sort
|
69
|
+
end
|
70
|
+
|
71
|
+
# Pass postal-code-for-districts.csv from http://www.digital-copyright.ca/pcfrf/pcfrf.tgz
|
72
|
+
# through `rake trim_postal_codes`. This rake task will print a list of riding
|
73
|
+
# IDs which none of the given postal codes belong to. Pass this list through
|
74
|
+
# `rake riding_id_to_postal_code` to get a list of postal codes belonging to
|
75
|
+
# those riding IDs. Manually add postal codes for any remaining riding IDs.
|
76
|
+
desc "Generates YAML mapping cbc.ca riding IDs to electoral districts"
|
77
|
+
task :riding_id_to_electoral_district do |t,args|
|
78
|
+
abort "Usage: rake #{t.name} file=postal-codes-for-districts.csv" unless args[:file]
|
79
|
+
|
80
|
+
def transliterate_elections_ca(string)
|
81
|
+
{
|
82
|
+
/\342\200\223/ => '-',
|
83
|
+
/\303\242/ => 'a',
|
84
|
+
/\303[\251\250]/ => 'e',
|
85
|
+
/\303\264/ => 'o',
|
86
|
+
/\303\211/ => 'E',
|
87
|
+
/\303\216/ => 'I',
|
88
|
+
}.reduce(string) do |string,map|
|
89
|
+
string.gsub(map[0], map[1])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Map electoral district names to electoral district IDs
|
94
|
+
name_to_edid = {}
|
95
|
+
doc = Nokogiri::HTML(open("http://www.elections.ca/content.aspx?section=res&dir=cir/list&document=index&lang=e").read)
|
96
|
+
doc.css('sup').remove
|
97
|
+
edids = doc.css('table[summary^="List"] th.normal').map{|x| x.text.to_i}
|
98
|
+
doc.css('table[summary^="List"] th.normal + td').map{|x| x.text.gsub(/\s+/, ' ').strip}.each_with_index do |name,index|
|
99
|
+
name_to_edid[transliterate_elections_ca(name)] = edids[index]
|
100
|
+
end
|
101
|
+
|
102
|
+
def transliterate_cbc_ca(string)
|
103
|
+
{
|
104
|
+
/ - / => '-',
|
105
|
+
/\342/ => 'a',
|
106
|
+
/[\350\351]/ => 'e',
|
107
|
+
/\364/ => 'o',
|
108
|
+
/\311/ => 'E',
|
109
|
+
/\316/ => 'I',
|
110
|
+
}.reduce(string) do |string,map|
|
111
|
+
string.gsub(map[0], map[1])
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Map electoral district names to riding IDs
|
116
|
+
name_to_rid = {}
|
117
|
+
File.read(args[:file]).split("\n").each do |postal_code|
|
118
|
+
GovKit::CA::PostalCode::Strategy::CbcCa.new(postal_code).json_response.each do |hash|
|
119
|
+
name_to_rid[transliterate_cbc_ca(hash['name'])] = hash['rid'].to_i
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Can we generate a complete mapping?
|
124
|
+
missing = name_to_edid.keys - name_to_rid.keys
|
125
|
+
unless missing.empty?
|
126
|
+
abort "The postal codes in #{args[:file]} do not cover #{missing.size} electoral districts:\n#{missing.sort.join("\n")}\n\nThe missing cbc.ca riding IDs are:\n#{([*1..308] - name_to_rid.map{|k,v| v}.flatten).sort.join("\n")}"
|
127
|
+
end
|
128
|
+
|
129
|
+
# Map riding IDs to electoral districts
|
130
|
+
rid_to_edid = {}
|
131
|
+
name_to_edid.keys.each do |name|
|
132
|
+
rid_to_edid[name_to_rid[name]] = name_to_edid[name]
|
133
|
+
end
|
134
|
+
|
135
|
+
puts rid_to_edid.to_yaml
|
136
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: govkit-ca
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- James McKinney
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-03-01 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: httparty
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 6
|
31
|
+
- 1
|
32
|
+
version: 0.6.1
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: nokogiri
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 1
|
45
|
+
- 4
|
46
|
+
- 4
|
47
|
+
version: 1.4.4
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: yajl-ruby
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
- 7
|
61
|
+
- 8
|
62
|
+
version: 0.7.8
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: rspec
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 2
|
75
|
+
version: "2"
|
76
|
+
type: :development
|
77
|
+
version_requirements: *id004
|
78
|
+
description: GovKit-CA lets you quickly get encapsulated Ruby objects for Canadian civic data.
|
79
|
+
email:
|
80
|
+
- james@slashpoundbang.com
|
81
|
+
executables: []
|
82
|
+
|
83
|
+
extensions: []
|
84
|
+
|
85
|
+
extra_rdoc_files: []
|
86
|
+
|
87
|
+
files:
|
88
|
+
- .gitignore
|
89
|
+
- Gemfile
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- USAGE
|
94
|
+
- govkit-ca.gemspec
|
95
|
+
- lib/data/rid_to_edid.yml
|
96
|
+
- lib/gov_kit-ca.rb
|
97
|
+
- lib/gov_kit-ca/postal_code.rb
|
98
|
+
- lib/gov_kit-ca/postal_code/strategy.rb
|
99
|
+
- lib/gov_kit-ca/postal_code/strategy/base.rb
|
100
|
+
- lib/gov_kit-ca/postal_code/strategy/cbc-ca.rb
|
101
|
+
- lib/gov_kit-ca/postal_code/strategy/conservative-ca.rb
|
102
|
+
- lib/gov_kit-ca/postal_code/strategy/digital_copyright-ca.rb
|
103
|
+
- lib/gov_kit-ca/postal_code/strategy/elections-ca.rb
|
104
|
+
- lib/gov_kit-ca/postal_code/strategy/liberal-ca.rb
|
105
|
+
- lib/gov_kit-ca/postal_code/strategy/ndp-ca.rb
|
106
|
+
- lib/gov_kit-ca/postal_code/strategy/parl-gc-ca.rb
|
107
|
+
- lib/gov_kit-ca/version.rb
|
108
|
+
- lib/govkit-ca.rb
|
109
|
+
- spec/postal_code_spec.rb
|
110
|
+
- spec/spec.opts
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
- tasks/rid_to_edid.rb
|
113
|
+
has_rdoc: true
|
114
|
+
homepage: http://github.com/jpmckinney/govkit-ca
|
115
|
+
licenses: []
|
116
|
+
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
version: "0"
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
version: "0"
|
138
|
+
requirements: []
|
139
|
+
|
140
|
+
rubyforge_project: govkit-ca
|
141
|
+
rubygems_version: 1.3.7
|
142
|
+
signing_key:
|
143
|
+
specification_version: 3
|
144
|
+
summary: Easy access to Canadian civic data around the web
|
145
|
+
test_files:
|
146
|
+
- spec/postal_code_spec.rb
|
147
|
+
- spec/spec.opts
|
148
|
+
- spec/spec_helper.rb
|